TR::Register *IA32LinkageUtils::pushLongArg( TR::Node *child, TR::CodeGenerator *cg) { TR::Register *pushRegister; if (child->getRegister() == NULL) { if (child->getOpCode().isLoadConst()) { TR_X86OpCodes pushOp; int32_t highValue = child->getLongIntHigh(); if (highValue >= -128 && highValue <= 127) { pushOp = PUSHImms; } else { pushOp = PUSHImm4; } generateImmInstruction(pushOp, child, highValue, cg); int32_t lowValue = child->getLongIntLow(); if (lowValue >= -128 && lowValue <= 127) { pushOp = PUSHImms; } else { pushOp = PUSHImm4; } generateImmInstruction(pushOp, child, lowValue, cg); cg->decReferenceCount(child); return NULL; } else if (child->getOpCodeValue() == TR::dbits2l && !child->normalizeNanValues() && child->getReferenceCount() == 1) { pushRegister = pushDoubleArg(child->getFirstChild(), cg); cg->decReferenceCount(child); return pushRegister; } else if (child->getOpCode().isMemoryReference() && child->getReferenceCount() == 1) { TR::MemoryReference *lowMR = generateX86MemoryReference(child, cg); generateMemInstruction(PUSHMem, child, generateX86MemoryReference(*lowMR,4, cg), cg); generateMemInstruction(PUSHMem, child, lowMR, cg); lowMR->decNodeReferenceCounts(cg); return NULL; } } pushRegister = cg->evaluate(child); generateRegInstruction(PUSHReg, child, pushRegister->getHighOrder(), cg); generateRegInstruction(PUSHReg, child, pushRegister->getLowOrder(), cg); cg->decReferenceCount(child); return pushRegister; }
TR::Register *IA32LinkageUtils::pushFloatArg( TR::Node *child, TR::CodeGenerator *cg) { TR::Register *pushRegister; if (child->getRegister() == NULL) { if (child->getOpCodeValue() == TR::fconst) { int32_t value = child->getFloatBits(); TR_X86OpCodes pushOp; if (value >= -128 && value <= 127) { pushOp = PUSHImms; } else { pushOp = PUSHImm4; } generateImmInstruction(pushOp, child, value, cg); cg->decReferenceCount(child); return NULL; } else if (child->getReferenceCount() == 1) { if (child->getOpCode().isLoad()) { TR::MemoryReference *tempMR = generateX86MemoryReference(child, cg); generateMemInstruction(PUSHMem, child, tempMR, cg); tempMR->decNodeReferenceCounts(cg); cg->decReferenceCount(child); return NULL; } else if (child->getOpCodeValue() == TR::ibits2f) { pushRegister = pushIntegerWordArg(child->getFirstChild(), cg); cg->decReferenceCount(child); return pushRegister; } } } pushRegister = cg->evaluate(child); TR::RealRegister *espReal = cg->machine()->getRealRegister(TR::RealRegister::esp); generateRegImmInstruction(SUB4RegImms, child, espReal, 4, cg); if (cg->useSSEForSinglePrecision() && pushRegister->getKind() == TR_FPR) generateMemRegInstruction(MOVSSMemReg, child, generateX86MemoryReference(espReal, 0, cg), pushRegister, cg); else generateFPMemRegInstruction(FSTMemReg, child, generateX86MemoryReference(espReal, 0, cg), pushRegister, cg); cg->decReferenceCount(child); return pushRegister; }
TR::Register *IA32LinkageUtils::pushIntegerWordArg( TR::Node *child, TR::CodeGenerator *cg) { TR::Register *pushRegister; if (child->getRegister() == NULL) { if (child->getOpCode().isLoadConst()) { int32_t value = child->getInt(); TR_X86OpCodes pushOp; if (value >= -128 && value <= 127) { pushOp = PUSHImms; } else { pushOp = PUSHImm4; } generateImmInstruction(pushOp, child, value, cg); cg->decReferenceCount(child); return NULL; } else if (child->getOpCodeValue() == TR::loadaddr) { TR::SymbolReference * symRef = child->getSymbolReference(); TR::StaticSymbol *sym = symRef->getSymbol()->getStaticSymbol(); if (sym) { TR_ASSERT(!symRef->isUnresolved(), "pushIntegerWordArg loadaddr expecting resolved symbol"); generateImmSymInstruction(PUSHImm4, child, (uintptrj_t)sym->getStaticAddress(), symRef, cg); cg->decReferenceCount(child); return NULL; } } else if (child->getOpCodeValue() == TR::fbits2i && !child->normalizeNanValues() && child->getReferenceCount() == 1) { pushRegister = pushFloatArg(child->getFirstChild(), cg); cg->decReferenceCount(child); return pushRegister; } else if (child->getOpCode().isMemoryReference() && (child->getReferenceCount() == 1) && (child->getSymbolReference() != cg->comp()->getSymRefTab()->findVftSymbolRef())) { TR::MemoryReference *tempMR = generateX86MemoryReference(child, cg); generateMemInstruction(PUSHMem, child, tempMR, cg); tempMR->decNodeReferenceCounts(cg); cg->decReferenceCount(child); return NULL; } } pushRegister = cg->evaluate(child); generateRegInstruction(PUSHReg, child, pushRegister, cg); cg->decReferenceCount(child); return pushRegister; }
TR::Register *IA32LinkageUtils::pushDoubleArg( TR::Node *child, TR::CodeGenerator *cg) { TR::Register *pushRegister; if (child->getRegister() == NULL) { if (child->getOpCodeValue() == TR::dconst) { TR_X86OpCodes pushOp; int32_t highValue = child->getLongIntHigh(); if (highValue >= -128 && highValue <= 127) { pushOp = PUSHImms; } else { pushOp = PUSHImm4; } generateImmInstruction(pushOp, child, highValue, cg); int32_t lowValue = child->getLongIntLow(); if (lowValue >= -128 && lowValue <= 127) { pushOp = PUSHImms; } else { pushOp = PUSHImm4; } generateImmInstruction(pushOp, child, lowValue, cg); cg->decReferenceCount(child); return NULL; } else if (child->getReferenceCount() == 1) { if (child->getOpCode().isLoad()) { TR::MemoryReference *lowMR = generateX86MemoryReference(child, cg); generateMemInstruction(PUSHMem, child, generateX86MemoryReference(*lowMR, 4, cg), cg); generateMemInstruction(PUSHMem, child, lowMR, cg); lowMR->decNodeReferenceCounts(cg); cg->decReferenceCount(child); return NULL; } else if (child->getOpCodeValue() == TR::lbits2d) { pushRegister = pushLongArg(child->getFirstChild(), cg); cg->decReferenceCount(child); return pushRegister; } } } pushRegister = cg->evaluate(child); TR::RealRegister *espReal = cg->machine()->getRealRegister(TR::RealRegister::esp); generateRegImmInstruction(SUB4RegImms, child, espReal, 8, cg); if (cg->useSSEForSinglePrecision() && pushRegister->getKind() == TR_FPR) generateMemRegInstruction(MOVSDMemReg, child, generateX86MemoryReference(espReal, 0, cg), pushRegister, cg); else generateFPMemRegInstruction(DSTMemReg, child, generateX86MemoryReference(espReal, 0, cg), pushRegister, cg); cg->decReferenceCount(child); return pushRegister; }
void TR_OutlinedInstructions::generateOutlinedInstructionsDispatch() { // Switch to cold helper instruction stream. // TR::Register *vmThreadReg = _cg->getMethodMetaDataRegister(); TR::Instruction *savedFirstInstruction = comp()->getFirstInstruction(); TR::Instruction *savedAppendInstruction = comp()->getAppendInstruction(); comp()->setFirstInstruction(NULL); comp()->setAppendInstruction(NULL); new (_cg->trHeapMemory()) TR::X86LabelInstruction(NULL, LABEL, _entryLabel, _cg); if (_rematerializeVMThread) { generateRegInstruction(PUSHReg, _callNode, vmThreadReg, _cg); generateRestoreVMThreadInstruction ( _callNode, _cg); TR::MemoryReference *vmThreadMR = generateX86MemoryReference(vmThreadReg, (TR::Compiler->target.is64Bit()) ? 16 : 8, _cg); generateRegMemInstruction (LRegMem(), _callNode, vmThreadReg, vmThreadMR, _cg); } TR::Register *resultReg=NULL; if (_callNode->getOpCode().isCallIndirect()) resultReg = TR::TreeEvaluator::performCall(_callNode, true, false, _cg); else resultReg = TR::TreeEvaluator::performCall(_callNode, false, false, _cg); if (_rematerializeVMThread) { generateRegInstruction(POPReg, _callNode, vmThreadReg, _cg); } if (_targetReg) { TR_ASSERT(resultReg, "assertion failure"); TR::RegisterPair *targetRegPair = _targetReg->getRegisterPair(); TR::RegisterPair *resultRegPair = resultReg->getRegisterPair(); if (targetRegPair) { TR_ASSERT(resultRegPair, "OutlinedInstructions: targetReg is a register pair and resultReg is not"); generateRegRegInstruction(_targetRegMovOpcode, _callNode, targetRegPair->getLowOrder(), resultRegPair->getLowOrder(), _cg); generateRegRegInstruction(_targetRegMovOpcode, _callNode, targetRegPair->getHighOrder(), resultRegPair->getHighOrder(), _cg); } else { TR_ASSERT(!resultRegPair, "OutlinedInstructions: resultReg is a register pair and targetReg is not"); generateRegRegInstruction(_targetRegMovOpcode, _callNode, _targetReg, resultReg, _cg); } } _cg->decReferenceCount(_callNode); if (_restartLabel) generateLabelInstruction(JMP4, _callNode, _restartLabel, _cg); else { // Java-specific. // No restart label implies we're not coming back from this call, // so it's safe to put data after the call. In the case of calling a throw // helper, there's an ancient busted handshake that expects to find a 4-byte // offset here, so we have to comply... // // When the handshake is removed, we can delete this zero. // generateImmInstruction(DDImm4, _callNode, 0, _cg); } // Dummy label to delimit the end of the helper call dispatch sequence (for exception ranges). // generateLabelInstruction(LABEL, _callNode, TR::LabelSymbol::create(_cg->trHeapMemory(),_cg), _cg); // Switch from cold helper instruction stream. // _firstInstruction = comp()->getFirstInstruction(); _appendInstruction = comp()->getAppendInstruction(); comp()->setFirstInstruction(savedFirstInstruction); comp()->setAppendInstruction(savedAppendInstruction); }