⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 peepx86.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef ASM	case op_asm:#endif /* ASM */	    return FALSE;	case op_line:	    break;	default:	    if (is_same_instruction (ip, ip2)) {		return TRUE;	    }	    altered = (BOOL) (op_flags[ip2->opcode] & DEST_ALTERED);	    overwritten = (BOOL) (op_flags[ip2->opcode] & DEST_OVERWRITE);	    if (ip2->oper2) {		/* two operand instruction */		if (is_equal_address (ip->oper1, ip2->oper2)) {		    if (overwritten && (ip->length <= ip2->length) &&			is_equal_address (ip->oper2, ip2->oper1))			return TRUE;		    if (altered) {			return FALSE;		    }		}		if (altered && is_address_used (ip2->oper2, ip->oper1)) {		    return FALSE;		}		switch (ip2->oper2->mode) {		case am_dreg:		case am_areg:		case am_mreg:		case am_direct:		case am_immed:		    if (altered && (is_equal_address (ip->oper2, ip2->oper2)				    || is_equal_address (ip->oper1,							 ip2->oper2))) {			return FALSE;		    }		    break;		case am_ind:		case am_indx:		    if (altered && memory) {			return FALSE;		    }		    break;		default:		    break;		}	    }	    if (ip2->oper1) {		switch (ip2->oper1->mode) {		case am_dreg:		case am_areg:		case am_mreg:		case am_direct:		case am_immed:		    if (ip2->oper2 != NIL_ADDRESS) {			break;		    }		    /* one operand instruction */		    if (altered && (is_equal_address (ip->oper2, ip2->oper1)				    || is_equal_address (ip->oper1,							 ip2->oper1))) return			    FALSE;		    break;		case am_ind:		case am_indx:		    if (ip2->oper2 != NIL_ADDRESS) {			break;		    }		    /* one operand instruction */		    if (altered && memory) {			return FALSE;		    }		    break;		default:		    break;		}	    }	    break;	}    }    return FALSE;}/* ensure we have a label to branch to (create if needed) */static void check_label P2 (CODE *, ip, CODE *, target){    if (target->fwd->opcode == op_label) {	ip->oper1->u.offset->v.l = target->fwd->oper1->u.offset->v.l;    } else {	CODE   *p;	p = code (op_label, IL0, mk_label (nextlabel), NIL_ADDRESS);	p->fwd = target->fwd;	p->back = target;	target->fwd = p->fwd->back = p;	ip->oper1->u.offset->v.l = nextlabel++;    }}static CODE *code P4 (OPCODE, op, ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){    CODE   *ip;    ip = (CODE *) xalloc (sizeof (CODE));    ip->opcode = op;    ip->length = len;    ip->oper1 = ap1;    ip->oper2 = ap2;    return ip;}/* * generate a code sequence into the peep list. */void g_code P4 (OPCODE, op, ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){    add_peep (code (op, len, ap1, ap2));}#ifdef FLOAT_IEEE/* * generate a floating point code sequence into the peep list. */void g_fcode P4 (OPCODE, op, ILEN, len, ADDRESS *, ap1, ADDRESS *, ap2){    if (len) {	len++;    }    g_code (op, len, ap1, ap2);}#endif /* FLOAT_IEEE *//* * add the instruction pointed to by new to the peep list. */static void add_peep P1 (CODE *, ip){    static CODE *peep_tail;    if (peep_head == NIL_CODE) {	peep_head = peep_tail = ip;	ip->fwd = NIL_CODE;	ip->back = NIL_CODE;    } else {	ip->fwd = NIL_CODE;	ip->back = peep_tail;	peep_tail->fwd = ip;	peep_tail = ip;    }}/* * output all code and labels in the peep list. */void flush_peep P1 (unsigned, level){    register CODE *ip;    SWITCH *sw;    EXPR   *ep;    LABEL   i;    /*     * perform peephole optimizations     */    opt3 (level);    /*     * generate assembler output     */    for (ip = peep_head; ip != NIL_CODE; ip = ip->fwd) {	if (ip->opcode == op_label) {	    put_label (ip->oper1->u.offset->v.l);	} else {	    put_code (ip);	}    }    peep_head = NIL_CODE;    ep = mk_lcon (UNDEF_LABEL);    for (sw = swtables; sw; sw = sw->next) {	put_kseg (alignment_of_type (tp_pointer));	put_label (sw->tablab);	for (i = 0; i < sw->numlabs; i++) {	    ep->v.l = sw->labels[i];	    put_pointer (ep);	}    }    swtables = NIL_SWITCH;}/* * delete an instruction referenced by ip */static void peep_delete P1 (CODE *, ip){    if (ip == NIL_CODE) {	FATAL ((__FILE__, "peep_delete", ""));    }    if (ip->back == NIL_CODE) {	peep_head = ip->fwd;	if (ip->fwd) {	    ip->fwd->back = NIL_CODE;	}	next_ip = ip->fwd;    } else {	if ((ip->back->fwd = ip->fwd) != NIL_CODE) {	    ip->fwd->back = ip->back;	}	next_ip = ip->back;    }    changes++;}/* * deletes lea (Rn),Rn */static void peep_lea P1 (CODE *, ip){    if (ip->oper1->mode == am_ind && ip->oper1->preg == ip->oper2->preg) {	peep_delete (ip);	return;    }}/* * optimizes and instructions */static void peep_and P1 (CODE *, ip){    CODE   *prev;    IVAL    val;    if ((ip->oper1->mode != am_immed) ||	(ip->oper1->u.offset->nodetype != en_icon)) {	return;    }    val = ip->oper1->u.offset->v.i;    if (val == -1L) {	/*	 *      AND #-1, <ea>	 *	 *      only sets flags, which the code generator does not know	 */	peep_delete (ip);	return;    }    prev = ip->back;    if (prev == NIL_CODE) {	return;    }    if ((prev->opcode == op_and) &&	(prev->oper1->mode == am_immed) &&	is_icon (prev->oper1->u.offset) &&	is_equal_address (ip->oper2, prev->oper2)) {	/*	 *       AND #M, <ea>     =>      AND #(M&N), <ea>	 *       AND #N, <ea>	 */	prev->oper1->u.offset->v.i &= val;	if (prev->length < ip->length) {	    prev->length = ip->length;	}	peep_delete (ip);	return;    }}static void peep_test P1 (CODE *, ip){    CODE   *prev = ip->back;    if (prev == NULL) {	return;    }    if (!is_equal_address (ip->oper1, ip->oper2)) {	return;    }    /* instruction is just setting the flags */    switch (prev->opcode) {    case op_add:    case op_sub:    case op_and:    case op_or:	if (is_equal_address (ip->oper2, prev->oper2)) {	    peep_delete (ip);	}	break;    default:	break;    }}static void peep_mov P1 (CODE *, ip){    CODE   *prev, *next;    BOOL    memory, altered;    if (is_equal_address (ip->oper1, ip->oper2)) {	/*	 * delete mov src,src	 */	peep_delete (ip);	return;    }    memory = FALSE;    switch (ip->oper1->mode) {    case am_ind:    case am_indx:	memory = TRUE;	if (ip->oper2->mode != am_dreg && ip->oper2->mode != am_areg) {	    break;	}	if (ip->oper1->preg == ip->oper2->preg) {	    break;	}	/*FALLTHRU */    case am_dreg:    case am_areg:	/*	 * eliminate redundant moves into a register when intervening	 * instructions only involve registers which cannot affect	 * the register.	 */	if (ip->oper2->mode != am_dreg && ip->oper2->mode != am_areg) {	    break;	}	for (next = ip->fwd; next != NIL_CODE; next = next->fwd) {	    switch (next->opcode) {	    case op_label:	    case op_bra:	    case op_call:	    case op_jmp:	    case op_ret:	    case op_leave:		return;	    default:		break;	    }	    if (is_same_instruction (ip, next)) {		peep_delete (next);		return;	    }	    altered = (BOOL) (op_flags[next->opcode] & DEST_ALTERED);	    if (next->oper2) {		/* two operand instruction */		if (altered && is_equal_oper (ip->oper1, next->oper2)) {		    return;		}		switch (next->oper2->mode) {		case am_dreg:		case am_areg:		    if (altered && ((ip->oper2->preg == next->oper2->preg) ||				    (ip->oper1->preg == next->oper2->preg)))			return;		    break;		case am_ind:		case am_indx:		    if (altered && memory) {			return;		    }		    break;		default:		    break;		}	    }	    if (next->oper1) {		switch (next->oper1->mode) {		case am_dreg:		case am_areg:		    if (next->oper2 != NIL_ADDRESS) {			break;		    }		    /* one operand instruction */		    if (altered && ((ip->oper2->preg == next->oper1->preg) ||				    (ip->oper1->preg == next->oper1->preg)))			return;		    break;		case am_ind:		case am_indx:		    if (next->oper2 != NIL_ADDRESS) {			break;		    }		    /* one operand instruction */		    if (altered && memory) {			return;		    }		    break;		default:		    break;		}	    }	}	break;    case am_immed:	if ((ip->oper2->mode == am_dreg || ip->oper2->mode == am_areg) &&	    is_icon (ip->oper1->u.offset) && ip->oper1->u.offset->v.i == 0L) {	    /*	     * change mov #0, reg   =>        xor reg, reg	     */	    ip->oper1 = ip->oper2;	    ip->opcode = op_xor;	    return;	}	break;    default:	if ((prev = ip->back) == NIL_CODE) {	    return;	}	/*	 * think about	 *	 * movl (%eax),eax                 I will make is_equal_address very restrictive!	 * movl eax,(%eax)	 *	 */	if (prev->opcode == op_mov && prev->length == ip->length &&	    is_equal_address (prev->oper1, ip->oper2) &&	    is_equal_address (prev->oper2, ip->oper1)) {	    /*	     * change mov src,dest  =>        mov src, dest	     *                mov dest,src	     */	    peep_delete (ip);	    return;	}    }}/* * changes cmp $0,reg to test reg,reg if followed by je, jne, jg, jge, jl, jle */static void peep_cmp P1 (CODE *, ip){    CODE   *next;    if (ip->oper1->mode == am_immed &&	is_icon (ip->oper1->u.offset) &&	ip->oper1->u.offset->v.i == 0L &&	(ip->oper2->mode == am_dreg || ip->oper2->mode == am_areg) &&	(next = ip->fwd) != NIL_CODE) {	switch (next->opcode) {	case op_je:	case op_jne:	case op_jg:	case op_jge:	case op_jl:	case op_jle:	    ip->opcode = op_test;	    ip->oper1 = ip->oper2;	    break;	default:	    break;	}    }}/* * changes things like * * movw src,%ax * movzwl %ax,%eax * * to * * movzwl src,%eax * * DO NOT DESTRUCT * movw %di,%ax

⌨️ 快捷键说明

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