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

📄 peepx86.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 3 页
字号:
 * movzbl %al,%eax * since %di,%si have no byte-components. */static void peep_xtend P1 (CODE *, ip){    CODE   *prev = ip->back;    ILEN    size;    if (prev != NIL_CODE && prev->opcode == op_mov &&	is_equal_address (prev->oper2, ip->oper1) &&	is_equal_address (ip->oper1, ip->oper2)) {	if ((prev->oper1->mode == am_dreg || prev->oper1->mode == am_areg) &&	    (prev->oper1->preg == ESI || prev->oper1->preg == EDI))	    return;	ip->oper1 = prev->oper1;	peep_delete (prev);    }    /*     * the code generator, or this procedure, may generate code like     *     * movsbl $const, %reg     *     * this is not a legal instruction.     * we will change it to a mov instruction here     */    if (ip->oper1->mode != am_immed) {	return;    }    if (ip->opcode == op_movsbw || ip->opcode == op_movzbw) {	size = IL2;    } else {	size = IL4;    }    ip->length = size;    ip->opcode = op_mov;}/* * changes: *		add #1	=> inc *		add #-1 => dec *		sub #1	=> dec *		sub #-1 => inc */static void peep_addsub P2 (CODE *, ip, IVAL, flag){    if (ip->oper1->mode != am_immed	|| ip->oper1->u.offset->nodetype != en_icon) {	return;    }    if (ip->oper2->preg == STACKPTR && is_dest_overwritten (ip->oper2, ip)) {	peep_delete (ip);	return;    }    if (ip->fwd && (ip->fwd->opcode == op_adc || ip->fwd->opcode == op_sbb)) {	return;    }    flag *= ip->oper1->u.offset->v.i;    switch (flag) {    case 1l:	ip->opcode = op_inc;	ip->oper1 = ip->oper2;	ip->oper2 = NIL_ADDRESS;	break;    case -1l:	ip->opcode = op_dec;	ip->oper1 = ip->oper2;	ip->oper2 = NIL_ADDRESS;	break;    case -2l:	if (ip->length == IL2 &&	    (ip->oper2->mode == am_dreg || ip->oper2->mode == am_areg) &&	    ip->oper2->preg == ESP) {	    ip->opcode = op_push;	    ip->oper1 = mk_reg (ECX);	    ip->oper2 = NIL_ADDRESS;	}	break;    case -4l:	if (ip->length == IL4 &&	    (ip->oper2->mode == am_dreg || ip->oper2->mode == am_areg) &&	    ip->oper2->preg == ESP) {	    ip->opcode = op_push;	    ip->oper1 = mk_reg (ECX);	    ip->oper2 = NIL_ADDRESS;	}	break;    default:	break;    }}/* * peephole optimization for unconditional transfers. deletes instructions * which have no path. applies to bra, jmp, and rts instructions. */static void peep_uctran P1 (CODE *, ip){    while (ip->fwd != NIL_CODE && ip->fwd->opcode != op_label)	peep_delete (ip->fwd);}/* * optimizes conditional branch over a bra. */static void peep_bxx P1 (CODE *, ip){    static OPCODE revcond[] = { op_jne, op_je,	op_jge, op_jg, op_jle, op_jl,	op_jbe, op_jb, op_jae, op_ja    };    CODE   *next = ip->fwd;    if (next == NIL_CODE) {	return;    }    if (next->opcode == op_bra) {	/* peep_uctran increases the 'hit' probability */	peep_uctran (next);	next = next->fwd;	if (next == NIL_CODE) {	    return;	}	if (next->opcode == op_label &&	    ip->oper1->u.offset->v.l == next->oper1->u.offset->v.l) {	    ip->fwd->opcode = revcond[(int) ip->opcode - (int) op_je];	    peep_delete (ip);	}    }}/* * if a label is followed by a branch to another label, the * branch statement can be deleted when the label is moved */static void peep_label P1 (CODE *, ip){    CODE   *prev, *next, *target;    SWITCH *sw;    LABEL   i, lab, label;    if ((next = ip->fwd) == NIL_CODE) {	return;    }    if (!optimize_option) {	return;    }    lab = ip->oper1->u.offset->v.l;    switch (next->opcode) {    case op_label:	/* if a label is followed by a label then common them up */	label = next->oper1->u.offset->v.l;	for (target = peep_head; target != NIL_CODE; target = target->fwd) {	    if (is_label_used (target->oper1, label)) {		target->oper1->u.offset->v.l = lab;	    }	    if (is_label_used (target->oper2, label)) {		target->oper2->u.offset->v.l = lab;	    }	}	for (sw = swtables; sw != NIL_SWITCH; sw = sw->next) {	    for (i = (LABEL) 0; i < sw->numlabs; i++) {		if (sw->labels[i] == label) {		    sw->labels[i] = ip->oper1->u.offset->v.l;		    changes++;		}	    }	}	peep_delete (next);	break;    case op_bra:	prev = ip->back;	/*	 * To make this fast, assume that the label number is really	 * next->oper1->u.offset->v.l	 */	label = next->oper1->u.offset->v.l;	if (label == ip->oper1->u.offset->v.l) {	    return;	}	target = peep_head;	/*	 * look for the label	 */	while (target != NIL_CODE) {	    if (target->opcode == op_label		&& target->oper1->u.offset->v.l == label) break;	    target = target->fwd;	}	/* we should have found it */	if (target == NIL_CODE) {	    message (MSG_PEEPLABEL);	    return;	}	/* move label */	peep_delete (ip);	ip->fwd = target->fwd;	ip->back = target;	target->fwd = ip;	if (ip->fwd != NIL_CODE) {	    ip->fwd->back = ip;	}	/* possibly remove branches */	/* in fact, prev is always != 0 if peep_delete has succeeded */	if (prev != NIL_CODE) {	    if (prev->opcode == op_bra || prev->opcode == op_jmp		|| prev->opcode == op_ret)		peep_uctran (prev);	}	break;    default:	/* check that there are still references to this label */	label = ip->oper1->u.offset->v.l;	for (target = peep_head; target != NIL_CODE; target = target->fwd) {	    if ((target != ip) &&		(is_label_used (target->oper1, lab) ||		 is_label_used (target->oper2, lab)))		return;	}	for (sw = swtables; sw != NIL_SWITCH; sw = sw->next) {	    for (i = 0; i < sw->numlabs; i++) {		if (sw->labels[i] == label) {		    return;		}	    }	}	peep_delete (ip);	break;    }}/* delete branches to the following statement */static void peep_bra P1 (CODE *, ip){    CODE   *p = ip->fwd;    CODE   *target;    LABEL   label = ip->oper1->u.offset->v.l;    int     count;    /* delete branches to the following statement */    while (p != NIL_CODE && p->opcode == op_label) {	if (p->oper1->u.offset->v.l == label) {	    peep_delete (ip);	    return;	}	p = p->fwd;    }    if (!optimize_option) {	return;    }    target = find_label (label);    /* we should have found it */    if (target == NIL_CODE) {	FATAL ((__FILE__, "peep_bra", "target == 0"));    }    /* Space optimisation:     * if the code before the target of the branch is itself a branch     * then we can move the destination block of code to eliminate the     * branch     */    p = target->back;    if (p != NIL_CODE && ((p->opcode == op_bra)			  || (p->opcode == op_jmp)			  || (p->opcode == op_ret))) {	p = block_end (target);	if (p != NIL_CODE && p != ip) {	    if (ip->fwd) {		ip->fwd->back = p;	    }	    if (p->fwd) {		p->fwd->back = target->back;	    }	    target->back->fwd = p->fwd;	    p->fwd = ip->fwd;	    target->back = ip;	    ip->fwd = target;	    peep_delete (ip);	    return;	}    }    /* Space optimisation:     * if the code before the branch instruction is the same as the     * instruction before the label the branch can be moved back an     * instruction.     */    p = ip->back;    previous_instruction (target);    if (p == target) {	return;    }    /* now skip back over identical instruction sequences */    while (is_same_instruction (p, target)) {	p = p->back;	previous_instruction (target);	peep_delete (p->fwd);    }    check_label (ip, target);    label = ip->oper1->u.offset->v.l;    /*      Space optimisation:     *      Optimise for the situation where two branches to the same     *      target label have identical instruction sequences     *      leading up to the branch.       We can instead eliminate one     *      of these instruction sequences by branching to the other one.     */    for (target = peep_head; target != NIL_CODE; target = target->fwd) {	if ((target != ip) &&	    (target->opcode == op_bra) &&	    (target->oper1->u.offset->v.l == label)) {	    CODE   *t = target;	    p = ip->back;	    previous_instruction (t);	    count = 0;	    while (is_same_instruction (p, t)) {		p = p->back;		previous_instruction (t);		peep_delete (p->fwd);		count++;	    }	    if (count != 0) {		check_label (ip, t);		break;	    }	}    }    peep_uctran (ip);}/* delete multiple debugging line statements */static void peep_line P1 (CODE *, ip){    CODE   *ip2;    if (ip->fwd == NIL_CODE) {	return;    }    switch (ip->fwd->opcode) {    case op_line:	peep_delete (ip);	break;    case op_label:	/* move the line number to after the label */	ip2 = ip->fwd;	if (ip->back) {	    ip->back->fwd = ip2;	} else {	    peep_head = ip2;	}	if (ip2->fwd) {	    ip2->fwd->back = ip;	}	ip2->back = ip->back;	ip->fwd = ip2->fwd;	ip2->fwd = ip;	ip->back = ip2;	break;    default:	break;    }}/* * peephole optimizer. This routine calls the instruction specific * optimization routines above for each instruction in the peep list. */static void opt3 P1 (unsigned, level){    CODE   *ip;    if (level == PEEP_NONE) {	return;    }    do {	changes = 0;	if (is_peep_phase (level, PEEP_INSTRUCTION)) {	    /*	     *       Instruction specific optisations	     */	    for (next_ip = peep_head; (ip = next_ip) != NIL_CODE;		 next_ip = ip->fwd) {		switch (ip->opcode) {		case op_and:		    peep_and (ip);		    break;		case op_test:		    peep_test (ip);		    break;		case op_movzbw:		case op_movsbw:		case op_movzbl:		case op_movsbl:		case op_movzwl:		case op_movswl:		    peep_xtend (ip);		    break;		case op_lea:		    peep_lea (ip);		    break;		case op_mov:		    peep_mov (ip);		    break;		case op_add:		    peep_addsub (ip, 1l);		    break;		case op_sub:		    peep_addsub (ip, -1l);		    break;		case op_cmp:		    peep_cmp (ip);		    break;		default:		    break;		}	    }	}	if (is_peep_phase (level, PEEP_JUMPS)) {	    /*	     *       Flow control optimisations.	     */	    for (next_ip = peep_head; (ip = next_ip) != NIL_CODE;		 next_ip = ip->fwd) {		switch (ip->opcode) {		case op_je:		case op_jne:		case op_jg:		case op_jge:		case op_jle:		case op_jl:		case op_ja:		case op_jae:		case op_jbe:		case op_jb:		    peep_bxx (ip);		    break;		case op_bra:		    peep_bra (ip);		    break;		case op_jmp:		case op_ret:		    peep_uctran (ip);		    break;		case op_label:		    peep_label (ip);		    break;		case op_line:		    peep_line (ip);		    break;		default:		    break;		}	    }	}#ifdef VERBOSE	if (verbose_option && changes) {	    message (MSG_PEEPCHANGES, changes);	}#endif /* VERBOSE */    } while (changes);}#endif /* INTEL */

⌨️ 快捷键说明

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