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

📄 regx86.c

📁 一款拥有一定历史的C语言编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
    case am_ind:	reg = ap->preg;	if (is_temporary_address_register (reg) && reg_alloc[ap->deep].pushed) {	    g_pop (reg, ap->deep);	}	break;    case am_indx2:	reg = ap->sreg;	if (is_data_or_address_register (reg) && reg_alloc[ap->deep].pushed) {	    g_pop (reg, ap->deep);	}	break;    case am_indx:	reg = ap->preg;	if (is_data_or_address_register (reg) && reg_alloc[ap->deep].pushed) {	    g_pop (reg, ap->deep);	}	break;    default:	return;    }}/* *   Return the next register of type 'regtype' */static REG next_reg P2 (REG, reg, REGTYPE, regtype){    for (;;) {	if (reg > ST7) {	    reg = EAX;	}	if ((regtypes[reg] & regtype) == regtype) {	    return reg;	}	reg++;    }}static REG allocate_register P3 (REG, reg, REG, nreg, REGTYPE, regtype){    reg = next_reg (reg, regtype);    /*     *       if the register is in use, push it to the stack     */    if (reg_in_use[reg] != UNUSED) {	g_push (reg, reg_in_use[reg]);    }    reg_in_use[reg] = alloc_depth;    reg_alloc[alloc_depth].reg = reg;    reg_alloc[alloc_depth].next_reg = nreg;    reg_alloc[alloc_depth].regtype = regtype;    reg_alloc[alloc_depth].pushed = FALSE;    if (alloc_depth++ >= MAX_REG_STACK) {	FATAL ((__FILE__, "allocate_register", "register stack overflow"));    }    return reg;}static void deallocate_register P1 (REG, reg){    DEEP    depth;    if (!is_temporary_register (reg)) {	return;    }    depth = reg_in_use[reg];    if (reg_alloc[depth].reg != reg) {	FATAL (	       (__FILE__, "deallocate_register", "register order (%d,%d)",		(int) reg_alloc[depth].reg, (int) reg));    }    switch (reg_alloc[depth].regtype) {    case D_REG | T_REG:    case X_REG | T_REG:    case C_REG | T_REG:	next_dreg = reg_alloc[depth].next_reg;	break;    case A_REG | T_REG:	next_areg = reg_alloc[depth].next_reg;	break;#ifdef FLOAT_IEEE    case F_REG | T_REG:	next_freg = reg_alloc[depth].next_reg;	break;#endif /* FLOAT_IEEE */    default:	CANNOT_REACH_HERE ();    }    reg_in_use[reg] = UNUSED;    /* we should only free the most recently allocated register */    if (alloc_depth-- == EMPTY) {	FATAL (	       (__FILE__, "deallocate_register", "register %d stack empty",		(int) reg));    }    if (alloc_depth != depth) {	FATAL (	       (__FILE__, "deallocate_register",		"register %d stack order (%d,%d)", (int) reg,		(int) alloc_depth, (int) depth));    }    /* the just freed register should not be on stack */    if (reg_alloc[depth].pushed) {	FATAL (	       (__FILE__, "deallocate_register", "register %d pushed",		(int) reg));    }}/* *   Allocates a temporary register which is appropriate to the *   regtype parameter. */static ADDRESS *temp_register P1 (REGTYPE, regtype){    REG     reg, reg2;    ADDRESS *ap;    switch (regtype) {    case D_REG | T_REG:	reg = allocate_register (next_dreg, next_dreg, regtype);	ap = mk_reg (reg);	next_dreg = (REG) ((int) reg + 1);	ap->mode = am_dreg;	break;    case A_REG | T_REG:	reg = allocate_register (next_areg, next_areg, regtype);	ap = mk_reg (reg);	next_areg = (REG) ((int) reg + 1);	ap->mode = am_areg;	break;    case M_REG | T_REG:	reg = allocate_register (next_dreg, next_dreg, D_REG | T_REG);	reg2 =	    allocate_register ((REG) ((int) reg + 1), (REG) ((int) reg + 1),			       D_REG | T_REG);	ap = mk_mreg (reg, reg2);	next_dreg = (REG) ((int) reg2 + 1);	break;    case X_REG | T_REG:	reg = allocate_register (EAX, next_dreg, regtype);	reg2 =	    allocate_register ((REG) ((int) reg + 1), (REG) ((int) reg + 1),			       regtype);	ap = mk_mreg (reg, reg2);	next_dreg = (REG) ((int) reg2 + 1);	break;    case F_REG | T_REG:	reg = allocate_register (next_freg, next_freg, regtype);	ap = mk_reg (reg);	next_freg = (REG) ((int) reg + 1);	ap->mode = am_freg;	break;    case C_REG | T_REG:	reg = allocate_register (ECX, next_dreg, regtype);	ap = mk_reg (reg);	next_dreg = (REG) ((int) reg + 1);	ap->mode = am_dreg;	break;    default:	CANNOT_REACH_HERE ();    }    ap->deep = reg_in_use[ap->preg];    return ap;}/* *   Allocate a data register */ADDRESS *data_register P0 (void){    return temp_register (D_REG | T_REG);}ADDRESS *axdx_register P0 (void){    return temp_register (X_REG | T_REG);}ADDRESS *cx_register P0 (void){    return temp_register (C_REG | T_REG);}/* *   Allocate an index register */ADDRESS *address_register P0 (void){    return temp_register (A_REG | T_REG);}/* *   Allocate 2 registers */ADDRESS *mdata_register P0 (void){    return temp_register (M_REG | T_REG);}#ifdef FLOAT_IEEEADDRESS *float_register P0 (void){    return temp_register (F_REG | T_REG);}#endif /* FLOAT_IEEE *//* *   Returns TRUE is the specified register is not available at "no cost" *   (no push). */BOOL is_register_used P1 (REG, reg){    return (reg_in_use[reg] != UNUSED);}/* * tells if an address mode uses a scratch register */BOOL uses_temp P1 (const ADDRESS *, ap){    if (ap == NIL_ADDRESS) {	FATAL ((__FILE__, "uses_temp", ""));    }    switch (ap->mode) {    case am_dreg:    case am_areg:    case am_freg:    case am_ind:    case am_indx:	return (is_temporary_register (ap->preg));    case am_indx2:	return (is_temporary_register (ap->sreg) &&		is_temporary_register (ap->preg));    default:	return FALSE;    }}/* * release any temporary registers used in an addressing mode. */void freeop P1 (const ADDRESS *, ap){    DEEP    depth;    REG     reg;    if (ap == NIL_ADDRESS) {	/* This can happen freeing a NOVALUE result */	return;    }    switch (ap->mode) {    case am_mreg:    case am_indx2:	deallocate_register (ap->sreg);	/*lint -fallthrough */    case am_dreg:    case am_areg:    case am_freg:    case am_ind:    case am_indx:	reg = ap->preg;	break;    default:	return;    }    if (!is_temporary_register (reg)) {	return;    }    depth = reg_in_use[reg];    deallocate_register (reg);    /* some consistency checks */    if (depth != ap->deep) {	FATAL (	       (__FILE__, "freeop", "(%d, %d, %d)", (int) reg, (int) depth,		(int) ap->deep));    }}/* *   push any used temporary registers. * *   This is necessary across function calls. *   The reason for this hacking is actually that temp_inv should dump *   the registers in the correct order, *   the least recently allocate register first. *   the most recently allocated register last. */void temp_inv P0 (void){    DEEP    deep;    for (deep = EMPTY; deep < alloc_depth; deep++) {	if (!reg_alloc[deep].pushed) {	    g_push (reg_alloc[deep].reg, deep);	    /* mark the register void */	    reg_in_use[reg_alloc[deep].reg] = UNUSED;	}    }}/* *   Converts a list of registers into a register mask */REGMASK reglist_to_mask P1 (const REGLIST *, rp){    REGMASK mask = (REGMASK) 0;    int     num;    for (num = 0; num < rp->number; num++) {	mask |= REGBIT (rp->reg[num]);    }    return mask;}#endif /* INTEL */

⌨️ 快捷键说明

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