📄 regx86.c
字号:
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 + -