void LinearScan::allocRegToTmp(SSATmp* ssaTmp, uint32_t index) { bool preferCallerSaved = true; if (RuntimeOption::EvalHHIREnableCalleeSavedOpt) { // Prefer caller-saved registers iff <ssaTmp> doesn't span native. preferCallerSaved = (ssaTmp->getLastUseId() <= getNextNativeId()); } RegState* reg = NULL; if (!preferCallerSaved) { reg = getFreeReg(false); if (reg->isCallerSaved()) { // If we are out of callee-saved registers, fall into the logic of // assigning a caller-saved register. pushFreeReg(reg); // getFreeReg pins the reg. Need restore it here. reg->m_pinned = false; reg = NULL; } } if (reg == NULL && RuntimeOption::EvalHHIREnablePreColoring) { // Pre-colors ssaTmp if it's used as an argument of next native. // Search for the original tmp instead of <ssaTmp> itself, because // the pre-coloring hint is not aware of reloaded tmps. RegNumber targetRegNo = m_preColoringHint.getPreColoringReg(getOrigTmp(ssaTmp), index); if (targetRegNo != reg::noreg) { reg = getReg(&m_regs[int(targetRegNo)]); } } if (reg == NULL && RuntimeOption::EvalHHIREnablePreColoring && ssaTmp->getInstruction()->isNative()) { // Pre-colors ssaTmp if it's the return value of a native. ASSERT(index == 0); reg = getReg(&m_regs[int(rax)]); } if (reg == NULL) { // No pre-coloring for this tmp. // Pick a regular caller-saved reg. reg = getFreeReg(true); } ASSERT(reg); if (!preferCallerSaved && reg->isCallerSaved()) { // ssaTmp spans native, but we failed to find a free callee-saved reg. // We eagerly add a spill ssaTmp, and update ssaTmp's live range // to end with next native, because we know we have to spill it at // the next native. // Setting the last use ID to the next native is conservative. // Setting it to the last use before the next native would be more precise, // but that would be more expensive to compute. if (ssaTmp->getSpillSlot() == -1) { createSpillSlot(ssaTmp); } ssaTmp->setLastUseId(getNextNativeId()); } allocRegToTmp(reg, ssaTmp, index); }
int CodeGen(NODPTR ptr) { int t1, t2, t; switch(ptr->NodeType) { case CONST: t = getFreeReg(); fprintf(fp, "MOV R%d %d\n", t, ptr->value); return t; break; case VARIABLE: t = getFreeReg(); fprintf(fp, "MOV R%d [%d]\n", t, ptr->stptr->binding); return t; break; case RD: t = getFreeReg(); fprintf(fp,"IN R%d\n", t); fprintf(fp, "MOV [%d] R%d\n", ptr->Lptr->stptr->binding, t); reg[t] = 0; return 0; break; //Recursive cases. case WE: t2 = CodeGen(ptr->Lptr); t1 = getFreeReg(); fprintf(fp, "MOV R%d R%d \n", t1, t2); fprintf(fp,"OUT R%d\n", t1); reg[t1] = 0; reg[t2] = 0; return 0; break; case PLUS: t1 = CodeGen(ptr->Rptr); t2 = CodeGen(ptr->Lptr); fprintf(fp, "ADD R%d R%d\n", t2, t1); reg[t1] = 0; return t2; break; case MINUS: t1 = CodeGen(ptr->Rptr); t2 = CodeGen(ptr->Lptr); fprintf(fp, "SUB R%d R%d\n", t2, t1); reg[t1] = 0; return t2; break; case MUL: t1 = CodeGen(ptr->Rptr); t2 = CodeGen(ptr->Lptr); fprintf(fp, "MUL R%d R%d\n", t2, t1); reg[t1] = 0; return t2; break; case DIV: t1 = CodeGen(ptr->Rptr); t2 = CodeGen(ptr->Lptr); fprintf(fp, "DIV R%d R%d\n", t2, t1); reg[t1] = 0; return t2; break; case SEQ: CodeGen(ptr->Lptr); if(ptr->Rptr) CodeGen(ptr->Rptr); return 0; break; case EQUAL: t1 = CodeGen(ptr->Rptr); fprintf(fp, "MOV [%d] R%d\n", ptr->Lptr->stptr->binding, t1); return 0; break; } }