Example #1
0
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);
}
Example #2
0
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;
	}
}