peepc30.c

来自「一款拥有一定历史的C语言编译器」· C语言 代码 · 共 2,250 行 · 第 1/5 页

C
2,250
字号
    /* op_stf_stf  */ PAR_DEST_OVERWRITE | FLOAT_INSTR,    /* op_sti_sti  */ PAR_DEST_OVERWRITE,    /* op_ldf_ldf  */ PAR_DEST_OVERWRITE | FLOAT_INSTR,    /* op_ldi_ldi  */ PAR_DEST_OVERWRITE,    /* op_absf_stf */ PAR_DEST_OVERWRITE | SET_FLAGS | FLOAT_INSTR,    /* op_absi_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_addf3_stf */ PAR_DEST_OVERWRITE | SET_FLAGS | FLOAT_INSTR,    /* op_addi3_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_and3_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_ash3_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_fix_sti  */ PAR_DEST_OVERWRITE | SET_FLAGS | FLOAT_INSTR,    /* op_float_stf */ PAR_DEST_OVERWRITE | SET_FLAGS | FLOAT_INSTR,    /* op_ldf_stf  */ PAR_DEST_OVERWRITE | FLOAT_INSTR,    /* op_ldi_sti  */ PAR_DEST_OVERWRITE,    /* op_lsh3_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_mpyf3_stf */ PAR_DEST_OVERWRITE | SET_FLAGS | FLOAT_INSTR,    /* op_mpyi3_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_negf_stf */ PAR_DEST_OVERWRITE | SET_FLAGS | FLOAT_INSTR,    /* op_negi_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_not_sti  */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_or3_sti  */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_subf3_stf */ PAR_DEST_OVERWRITE | SET_FLAGS | FLOAT_INSTR,    /* op_subi3_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_xor3_sti */ PAR_DEST_OVERWRITE | SET_FLAGS,    /* op_divs     */ 0,    /* op_divu     */ 0,#ifdef ASM    /* op_asm      */ OP_ASM,#endif				/* ASM */    /* op_line     */ 0,    /* op_label    */ OP_LABEL,    /* op_abort    */ 0,};static OPCODE convert_op_to_op3[] = {    /* op_absf     */ (OPCODE) 0,    /* op_absi     */ (OPCODE) 0,#ifdef USE_ALL_OPCODES    /* op_addc     */ op_addc3,#endif				/* USE_ALL_OPCODES */    /* op_addf     */ op_addf3,    /* op_addi     */ op_addi3,    /* op_and      */ op_and3,    /* op_andn     */ op_andn3,    /* op_ash      */ op_ash3,    /* op_cmpf     */ (OPCODE) 0,    /* op_cmpi     */ (OPCODE) 0,    /* op_fix      */ (OPCODE) 0,    /* op_float    */ (OPCODE) 0,#ifdef USE_ALL_OPCODES    /* op_idle     */ (OPCODE) 0,    /* op_lde      */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_ldf      */ (OPCODE) 0,    /* op_popldf   */ (OPCODE) 0,#ifdef USE_ALL_OPCODES    /* op_ldfi     */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_ldi      */ (OPCODE) 0,    /* op_popldi   */ (OPCODE) 0,#ifdef USE_ALL_OPCODES    /* op_ldii     */ (OPCODE) 0,    /* op_ldm      */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_lsh      */ op_lsh3,    /* op_mpyf     */ op_mpyf3,    /* op_mpyi     */ op_mpyi3,#ifdef USE_ALL_OPCODES    /* op_negb     */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_negf     */ (OPCODE) 0,    /* op_negi     */ (OPCODE) 0,    /* op_nop      */ (OPCODE) 0,#ifdef USE_ALL_OPCODES    /* op_norm     */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_not      */ (OPCODE) 0,    /* op_pop      */ (OPCODE) 0,    /* op_popf     */ (OPCODE) 0,    /* op_push     */ (OPCODE) 0,    /* op_pushf    */ (OPCODE) 0,    /* op_pushnopeep */ (OPCODE) 0,    /* op_pushfnopeep */ (OPCODE) 0,    /* op_or       */ op_or3,#ifdef USE_ALL_OPCODES    /* op_rnd      */ (OPCODE) 0,    /* op_rol      */ (OPCODE) 0,    /* op_rolc     */ (OPCODE) 0,    /* op_ror      */ (OPCODE) 0,    /* op_rorc     */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_rpts     */ (OPCODE) 0,    /* op_stf      */ (OPCODE) 0,#ifdef USE_ALL_OPCODES    /* op_stfi     */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_sti      */ (OPCODE) 0,#ifdef USE_ALL_OPCODES    /* op_stii     */ (OPCODE) 0,    /* op_sigi     */ (OPCODE) 0,    /* op_subb     */ op_subb3,    /* op_subc     */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_subf     */ op_subf3,    /* op_subi     */ op_subi3,#ifdef USE_ALL_OPCODES    /* op_subrb    */ (OPCODE) 0,#endif				/* USE_ALL_OPCODES */    /* op_subrf    */ (OPCODE) 0,    /* op_subri    */ (OPCODE) 0,    /* op_tstb     */ (OPCODE) 0,    /* op_xor      */ op_xor3,#ifdef USE_ALL_OPCODES    /* op_iack     */ (OPCODE) 0#endif				/* USE_ALL_OPCODES */};static CODE *peep_head = NIL_CODE;static CODE *next_ip;static int changes;#ifdef VERBOSEstatic struct{    int     ldi_rx_rx;    int     ldf_rx_rx;    int     ldi_rx_ry_ldi_ry_rx;    int     ldf_rx_ry_ldf_ry_rx;    int     sti_rx_my_ldi_my_rx;    int     stf_rx_my_ldf_my_rx;    int     ldi_mx_ry_sti_ry_mx;    int     ldf_mx_ry_stf_ry_mx;    int     redundant_ldi;    int     redundant_ldf;#ifdef PEEP_REDUNDANT_STI    int     redundant_sti;    int     redundant_stf;#endif    int     commutative_i;    int     commutative_f;    int     ldi_opi_opi3;    int     ldf_opf_opf3;    int     opi_ldi_opi3;    int     opf_ldf_opf3;    int     par_ldf_stf;    int     par_stf_stf;    int     par_ldf_ldf;    int     par_ldi_sti;    int     par_sti_sti;    int     par_ldi_ldi;    int     convert_to_op3;    int     remap_register_fwd;    int     remap_register_bwd;    int     superfluous_load;    int     superfluous_tst;    int     superfluous_cmpf;    int     brd_cycles;    int     brd_memory;    int     brd_optimized;    int     br_to_next_line;    int     bxx_to_next_line;    int     bxx_to_ldcond;    int     bxx_over_br;    int     br_block_move;    int     br_branch_move;    int     br_commoned;    int     dead_code;    int     label_before_branch;    int     label_commoned;    int     label_removed;} PeepStatistic ={#ifdef PEEP_REDUNDANT_STI    0, 0,#endif /* PEEP_REDUNDANT_STI */	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0#ifdef DEBUG}, LastPeepStatistic = {#ifdef PEEP_REDUNDANT_STI    0, 0,#endif /* PEEP_REDUNDANT_STI */	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0#endif /* DEBUG */};static clock_t delay_time = 0;static clock_t tstb_time = 0;static clock_t pipe_time = 0;static clock_t paralel_time = 0;static clock_t remap_time = 0;static clock_t ldi_time = 0;static clock_t branch_time = 0;static clock_t cmpi_time = 0;static clock_t flow_time = 0;#endif /* VERBOSE */static int oldtot = 0;static int oldasm = 0;static int oldbranch = 0;static int oldreg = 0;static int newtot = 0;static int newasm = 0;static int newbranch = 0;static int newreg = 0;static PEEP_STAGES SelectedOptimizer = ENABLE_ALL;static int CurrentStage = 0;static unsigned peep_level = 0;/* * The following list is to find out, which sequence in optimizer is best * (Perhaps there isn't 'the best' but different goods, depending *  on the code). */static PEEP_STAGES DefaultOptimizerStages[] = {    REDUNDANT,    REMAPP,    COMMUTATIVE,    COMBINE_BWD,    COMBINE_FWD,    DATAFLOW,    REDUNDANT,    REMAPP,    COMMUTATIVE,    COMBINE_BWD,    COMBINE_FWD,    ENABLE_ALL,    0};static PEEP_STAGES *OptimizerStages = &(DefaultOptimizerStages[0]);/* *  table with the reverse condition for a given condition *  opcodetables must be in same order as this table for correctness */static OPCODE revcond[] = {    /* op_blo */ op_bhs,    /* op_bls */ op_bhi,    /* op_bhi */ op_bls,    /* op_bhs */ op_blo,    /* op_beq */ op_bne,    /* op_bne */ op_beq,    /* op_blt */ op_bge,    /* op_ble */ op_bgt,    /* op_bgt */ op_ble,    /* op_bge */ op_blt,    /* op_bz  */ op_bnz,    /* op_bnz */ op_bz,    /* op_bp  */ op_ble,    /* op_bn  */ op_bnn,    /* op_bnn */ op_bn};static CODE *codeP_ (    (OPCODE, ITYPE, ADDRESS *, ADDRESS *, ADDRESS *, ADDRESS *, ADDRESS *,     ADDRESS *));static void add_peep P_ ((CODE *));static void opt3 P_ ((unsigned));static void peep_delete P_ ((const CODE *));static void peep_line P_ ((CODE *));static void peep_label P_ ((CODE *));static void peep_uctran P_ ((const CODE *));static BOOL is_label_used P_ ((const ADDRESS *, LABEL));static BOOL is_restricted_indirect P_ ((const ADDRESS *));static BOOL is_memoryaccess_independent P_ ((const ADDRESS *, const ADDRESS *));#ifdef CHECK_LIST_INTEGRITYstatic void check_peep P_ ((void));#endif /* CHECK_LIST_INTEGRITY *//*****************************************************************************//* * Returns true if the <ea> is suitable for a 3op instruction. */static BOOL is_3op_possible P1 (const ADDRESS *, ap){    if (ap == NIL_ADDRESS) {	return (FALSE);    }    switch (ap->mode) {    case am_areg:    case am_ireg:    case am_dreg:    case am_freg:    case am_sreg:    case am_ind:    case am_const_ind:    case am_indx2:    case am_indxs:	return (TRUE);    case am_indx:    case am_ainc:    case am_adec:    case am_preinc:    case am_predec:	if ((ap->u.offset->nodetype == en_icon)	    && (ap->u.offset->v.i >= -1)	    && (ap->u.offset->v.i <= 1)) {	    return (TRUE);	}	break;    case am_immed:    case am_direct:    case am_const_direct:    default:	break;    }    return (FALSE);}#ifdef ASMstatic ADDRESS *mk_branchcomment P0 (void){    ADDRESS *ap;    EXPR   *ep;    ep = mk_node (en_str, NIL_EXPR, NIL_EXPR, tp_void);    ep->v.str = (const CHAR *) ";Branch occurs here";    ap = (ADDRESS *) xalloc ((size_t) sizeof (ADDRESS));    ap->mode = am_str;    ap->u.offset = ep;    return ap;}#endif /* ASM *//* * Find the end of a block of code. */static CODE *block_end P1 (CODE *, ip){    int     count = 0;    while (ip != NIL_CODE && ip->opcode != op_br	   && ip->opcode != op_bu	   && ip->opcode != op_retiu && ip->opcode != op_retsu) {	if (count == BRANCH_COUNT)	    return NIL_CODE;	if (branch (ip))	    count++;	ip = ip->fwd;    }    return ip;}/* * Find the node which contains the label 'lab'. */CODE   *find_label P1 (LABEL, lab){    register CODE *ip;    for (ip = peep_head; ip != NIL_CODE; ip = ip->fwd) {	if (ip->opcode == op_label && ip->src1->u.offset->v.l == lab)	    return ip;    }    /* we should have found it */    return NIL_CODE;}/* * Returns false if the <ea> is not a label or else isn't equal to label. */static BOOL is_label_used P2 (const ADDRESS *, ap, LABEL, label){    return (ap != NIL_ADDRESS &&	    ap->mode == am_immed &&	    ap->u.offset->nodetype == en_labcon &&	    ap->u.offset->v.l == label);}/* * Counts the number of times that a label node is referenced. */static int label_references P1 (const CODE *, ip){    CODE   *target;    struct swtab *sw;    LABEL   i;    LABEL   lab = ip->src1->u.offset->v.l;    int     count = 0;    for (target = peep_head; target != NIL_CODE; target = target->fwd) {	if ((target != ip) &&	    (is_label_used (target->src1, lab) ||	     is_label_used (target->dst, lab)))/* *  src2, src21, src22, dst2 can never contain a label (in this Positions *  only indirects and register are allowed) */	    count++;    }    for (sw = swtables; sw != NIL_SWITCH; sw = sw->next) {	for (i = 0; i < sw->numlabs; i++) {	    if (sw->labels[i] == lab)		count++;	}    }    if (ip->back != NIL_CODE && ip->back->opcode == op_label)	count++;    if (ip->fwd != NIL_CODE && ip->fwd->opcode == op_label)	count++;    return count;}/* * Compare two address nodes and return true if they are equivalent. * a/pre-inc/dec are not treated as same */BOOL is_equal_address P2 (const ADDRESS *, ap1, const ADDRESS *, ap2){    if (ap1 == NIL_ADDRESS || ap2 == NIL_ADDRESS)	return FALSE;    if (ap1->mode != ap2->mode)	return FALSE;    switch (ap1->mode) {    case am_areg:    case am_dreg:    case am_freg:    case am_ireg:    case am_sreg:    case am_ind:    case am_const_ind:	return ap1->preg == ap2->preg;    case am_indx:	return ap1->preg == ap2->preg &&	    is_equalnode (ap1->u.offset, ap2->u.offset);    case am_indx2:    case am_indxs:	return ap1->preg == ap2->preg && ap1->sreg == ap2->sreg;    case am_immed:    case am_direct:

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?