/* 产生滙编指令 @ EmitMove @ EmitAssign @ EmitBranch @ EmitJump @ EmitCall @ EmitReturn */ void Compiler::EmitMove(IRInst inst) { if (SRC1->kind == SK_Constant) { Move(DST, SRC1); } else { AllocateReg(inst, 1); AllocateReg(inst, 0); if (SRC1->reg == NULL && DST->reg == NULL) { Symbol reg; reg = GetRegInternal(); Move(reg, SRC1); Move(DST, reg); } else { Move(DST, SRC1); } } if (DST) DST->ref--; if (SRC1) SRC1->ref--; }
Symbol Compiler::PutInReg(Symbol p) { Symbol reg; if (p->reg != NULL) { return p->reg; } reg = GetRegInternal(); Move(reg, p); return reg; }
void Compiler::AllocateReg(IRInst inst, int index) { Symbol reg; Symbol p; p = inst->opds[index]; // 只分配给临时变量 if (p->kind != SK_Temp) return; // if it is already in a register, mark the register as used by current uil if (p->reg != NULL) { UsedRegs |= 1 << p->reg->val; return; } if (index == 0 && SRC1->ref == 1 && SRC1->reg != NULL) { reg = SRC1->reg; reg->link = NULL; //Add Var To Reg p->link = reg->link; reg->link = p; p->reg = reg; return; } reg = GetRegInternal(); if (index != 0) { Move(reg, p); } //Add Var To Reg p->link = reg->link; reg->link = p; p->reg = reg; }
void Compiler::EmitAssign(IRInst inst) { switch (OP) { case $ADD: case $SUB: AllocateReg(inst, 1); AllocateReg(inst, 2); AllocateReg(inst, 0); //char name[40]; //sprintf(name, "%s", SRC1->reg->name.c_str()); //PutString(name); if (DST->reg != SRC1->reg) { Move(DST, SRC1); } if (OP == $ADD) PutASMCode(X86_ADDI4, inst->opds); if (OP == $SUB) PutASMCode(X86_SUBI4, inst->opds); break; case $MUL: case $DIV: if (SRC1->reg == Regs[EAX]) { SpillReg(Regs[EAX]); } else { Symbol sym = Regs[EAX]->link; if (sym != NULL && sym->ref > 0) { Symbol reg = GetRegInternal(); SpillReg(Regs[EAX]); Move(reg, Regs[EAX]); sym->reg = reg; reg->link = sym; } else { SpillReg(Regs[EAX]); } Move(Regs[EAX], SRC1); } // SpillReg(Regs[EDX]); // 将SRC1扩展后放在EAX与EDX UsedRegs = 1 << EAX ; if (SRC2->kind == SK_Constant) { Symbol reg = GetRegInternal(); Move(reg, SRC2); SRC2 = reg; } else { AllocateReg(inst, 2); } if (OP == $MUL) PutASMCode(X86_MULI4, inst->opds); if (OP == $DIV) PutASMCode(X86_DIVI4, inst->opds); DST->link = Regs[EAX]->link; Regs[EAX]->link = DST; DST->reg = Regs[EAX]; break; default: break; } if (DST) DST->ref--; if (SRC1) SRC1->ref--; if (SRC2) SRC2->ref--; }
Symbol GetReg(void) { return GetRegInternal(4); }
Symbol GetWordReg(void) { return GetRegInternal(2); }
Symbol GetByteReg(void) { return GetRegInternal(1); }