本文整理汇总了C++中tr::Machine类的典型用法代码示例。如果您正苦于以下问题:C++ Machine类的具体用法?C++ Machine怎么用?C++ Machine使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Machine类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: cg
void TR::ARMSystemLinkage::createEpilogue(TR::Instruction *cursor)
{
TR::CodeGenerator *codeGen = cg();
const TR::ARMLinkageProperties& properties = getProperties();
TR::Machine *machine = codeGen->machine();
TR::Node *lastNode = cursor->getNode();
TR::ResolvedMethodSymbol* bodySymbol = comp()->getJittedMethodSymbol();
TR::RealRegister *stackPtr = machine->getRealRegister(properties.getStackPointerRegister());
// restore link register (r14)
auto *stackSlot = new (trHeapMemory()) TR::MemoryReference(stackPtr, bodySymbol->getLocalMappingCursor(), codeGen);
cursor = generateMemSrc1Instruction(cg(), ARMOp_ldr, lastNode, stackSlot, machine->getRealRegister(TR::RealRegister::gr14), cursor);
// restore all preserved registers
for (int r = TR::RealRegister::gr4; r <= TR::RealRegister::gr11; ++r)
{
auto *stackSlot = new (trHeapMemory()) TR::MemoryReference(stackPtr, (TR::RealRegister::gr11 - r + 1)*4 + bodySymbol->getLocalMappingCursor(), codeGen);
cursor = generateMemSrc1Instruction(cg(), ARMOp_ldr, lastNode, stackSlot, machine->getRealRegister((TR::RealRegister::RegNum)r), cursor);
}
// remove space for preserved registers
auto frameSize = codeGen->getFrameSizeInBytes();
cursor = generateTrg1Src1ImmInstruction(codeGen, ARMOp_add, lastNode, stackPtr, stackPtr, frameSize, 0, cursor);
// return using `mov r15, r14`
TR::RealRegister *gr14 = machine->getRealRegister(TR::RealRegister::gr14);
TR::RealRegister *gr15 = machine->getRealRegister(TR::RealRegister::gr15);
cursor = generateTrg1Src1Instruction(codeGen, ARMOp_mov, lastNode, gr15, gr14, cursor);
}
示例2: cg
void TR::ARM64Trg1Src2Instruction::assignRegisters(TR_RegisterKinds kindToBeAssigned)
{
TR::Machine *machine = cg()->machine();
TR::Register *target1Virtual = getTargetRegister();
TR::Register *source1Virtual = getSource1Register();
TR::Register *source2Virtual = getSource2Register();
if (getDependencyConditions())
getDependencyConditions()->assignPostConditionRegisters(this, kindToBeAssigned, cg());
source1Virtual->block();
target1Virtual->block();
TR::RealRegister *assignedSource2Register = machine->assignOneRegister(this, source2Virtual);
target1Virtual->unblock();
source1Virtual->unblock();
source2Virtual->block();
target1Virtual->block();
TR::RealRegister *assignedSource1Register = machine->assignOneRegister(this, source1Virtual);
target1Virtual->unblock();
source2Virtual->unblock();
source2Virtual->block();
source1Virtual->block();
TR::RealRegister *assignedTarget1Register = machine->assignOneRegister(this, target1Virtual);
source1Virtual->unblock();
source2Virtual->unblock();
if (getDependencyConditions())
getDependencyConditions()->assignPreConditionRegisters(this->getPrev(), kindToBeAssigned, cg());
setTargetRegister(assignedTarget1Register);
setSource1Register(assignedSource1Register);
setSource2Register(assignedSource2Register);
}
示例3: getDependencyConditions
void TR::ARM64Trg1Instruction::assignRegisters(TR_RegisterKinds kindToBeAssigned)
{
if (getDependencyConditions())
getDependencyConditions()->assignPostConditionRegisters(this, kindToBeAssigned, cg());
TR::Machine *machine = cg()->machine();
TR::Register *targetVirtual = getTargetRegister();
setTargetRegister(machine->assignOneRegister(this, targetVirtual));
if (getDependencyConditions())
getDependencyConditions()->assignPreConditionRegisters(this->getPrev(), kindToBeAssigned, cg());
}
示例4: self
TR::MemoryReference *OMR::Power::Linkage::getOutgoingArgumentMemRef(int32_t argSize, TR::Register *argReg, TR::InstOpCode::Mnemonic opCode, TR::PPCMemoryArgument &memArg, uint32_t length)
{
TR::Machine *machine = self()->machine();
const TR::PPCLinkageProperties& properties = self()->getProperties();
TR::MemoryReference *result = new (self()->trHeapMemory()) TR::MemoryReference(machine->getRealRegister(properties.getNormalStackPointerRegister()),
argSize+properties.getOffsetToFirstParm(), length, self()->cg());
memArg.argRegister = argReg;
memArg.argMemory = result;
memArg.opCode = opCode;
return(result);
}
示例5: cg
void
TR::ARM64SystemLinkage::createEpilogue(TR::Instruction *cursor)
{
TR::CodeGenerator *codeGen = cg();
const TR::ARM64LinkageProperties& properties = getProperties();
TR::Machine *machine = codeGen->machine();
TR::Node *lastNode = cursor->getNode();
TR::ResolvedMethodSymbol *bodySymbol = comp()->getJittedMethodSymbol();
TR::RealRegister *sp = machine->getRealRegister(properties.getStackPointerRegister());
// restore callee-saved registers
uint32_t offset = bodySymbol->getLocalMappingCursor() + 8; // +8 for LR
for (int r = TR::RealRegister::x19; r <= TR::RealRegister::x28; r++)
{
TR::RealRegister *rr = machine->getRealRegister((TR::RealRegister::RegNum)r);
if (rr->getHasBeenAssignedInMethod())
{
TR::MemoryReference *stackSlot = new (trHeapMemory()) TR::MemoryReference(sp, offset, codeGen);
cursor = generateTrg1MemInstruction(cg(), TR::InstOpCode::ldrimmx, lastNode, rr, stackSlot, cursor);
offset += 8;
}
}
for (int r = TR::RealRegister::v8; r <= TR::RealRegister::v15; r++)
{
TR::RealRegister *rr = machine->getRealRegister((TR::RealRegister::RegNum)r);
if (rr->getHasBeenAssignedInMethod())
{
TR::MemoryReference *stackSlot = new (trHeapMemory()) TR::MemoryReference(sp, offset, codeGen);
cursor = generateTrg1MemInstruction(cg(), TR::InstOpCode::vldrimmd, lastNode, rr, stackSlot, cursor);
offset += 8;
}
}
// restore link register (x30)
TR::RealRegister *lr = machine->getRealRegister(TR::RealRegister::lr);
TR::MemoryReference *stackSlot = new (trHeapMemory()) TR::MemoryReference(sp, bodySymbol->getLocalMappingCursor(), codeGen);
cursor = generateTrg1MemInstruction(cg(), TR::InstOpCode::ldrimmx, lastNode, lr, stackSlot, cursor);
// remove space for preserved registers
uint32_t frameSize = codeGen->getFrameSizeInBytes();
if (constantIsUnsignedImm12(frameSize))
{
cursor = generateTrg1Src1ImmInstruction(codeGen, TR::InstOpCode::addimmx, lastNode, sp, sp, frameSize, cursor);
}
else
{
TR_ASSERT(false, "Not implemented yet.");
}
// return
cursor = generateRegBranchInstruction(codeGen, TR::InstOpCode::ret, lastNode, lr, cursor);
}
示例6: cg
void
TR::ARM64SystemLinkage::initARM64RealRegisterLinkage()
{
TR::Machine *machine = cg()->machine();
TR::RealRegister *reg;
int icount;
reg = machine->getRealRegister(TR::RealRegister::RegNum::x16); // IP0
reg->setState(TR::RealRegister::Locked);
reg->setAssignedRegister(reg);
reg = machine->getRealRegister(TR::RealRegister::RegNum::x17); // IP1
reg->setState(TR::RealRegister::Locked);
reg->setAssignedRegister(reg);
reg = machine->getRealRegister(TR::RealRegister::RegNum::x29); // FP
reg->setState(TR::RealRegister::Locked);
reg->setAssignedRegister(reg);
reg = machine->getRealRegister(TR::RealRegister::RegNum::x30); // LR
reg->setState(TR::RealRegister::Locked);
reg->setAssignedRegister(reg);
reg = machine->getRealRegister(TR::RealRegister::RegNum::sp); // SP
reg->setState(TR::RealRegister::Locked);
reg->setAssignedRegister(reg);
reg = machine->getRealRegister(TR::RealRegister::RegNum::xzr); // zero
reg->setState(TR::RealRegister::Locked);
reg->setAssignedRegister(reg);
// assign "maximum" weight to registers x0-x15
for (icount = TR::RealRegister::x0; icount <= TR::RealRegister::x15; icount++)
machine->getRealRegister((TR::RealRegister::RegNum)icount)->setWeight(0xf000);
// assign "maximum" weight to registers x18-x28
for (icount = TR::RealRegister::x18; icount <= TR::RealRegister::x28; icount++)
machine->getRealRegister((TR::RealRegister::RegNum)icount)->setWeight(0xf000);
// assign "maximum" weight to registers v0-v31
for (icount = TR::RealRegister::v0; icount <= TR::RealRegister::v31; icount++)
machine->getRealRegister((TR::RealRegister::RegNum)icount)->setWeight(0xf000);
}
示例7: assignFreeRegisters
static void assignFreeRegisters(TR::Instruction *currentInstruction,
TR::RegisterDependency *dep,
TR_PPCRegisterDependencyMap& map,
TR::CodeGenerator *cg)
{
// *this swipeable for debugging purposes
TR::Machine *machine = cg->machine();
// Assign a chain of dependencies where the head of the chain depends on a free reg
while (dep)
{
TR_ASSERT(machine->getPPCRealRegister(dep->getRealRegister())->getState() == TR::RealRegister::Free, "Expecting free target register");
TR::RealRegister *assignedReg = dep->getRegister()->getAssignedRealRegister() ?
toRealRegister(dep->getRegister()->getAssignedRealRegister()) : NULL;
machine->coerceRegisterAssignment(currentInstruction, dep->getRegister(), dep->getRealRegister());
dep->getRegister()->block();
dep = assignedReg ?
map.getDependencyWithTarget(assignedReg->getRegisterNumber()) : NULL;
}
}
示例8: new
void OMR::Power::RegisterDependencyConditions::bookKeepingRegisterUses(TR::Instruction *instr, TR::CodeGenerator *cg)
{
// *this swipeable for debugging purposes
TR::Register *virtReg;
TR::RealRegister::RegNum regNum;
TR::RegisterDependencyConditions *assoc;
int numAssoc = 0;
if (instr->getOpCodeValue() == TR::InstOpCode::assocreg)
return;
// Don't track associations or emit assocregs in outlined code
// Register assigner can save/restore associations across outlined sections properly, however no such mechanism exists for instruction selection
// so we don't want these associations to clobber the associations that were set in main line code, which are more important
// TODO: Fix this by saving/restoring the associations in swapInstructionListsWithCompilation()
bool isOOL = cg->getIsInOOLSection();
TR::Machine *machine = cg->machine();
assoc = !isOOL ? new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0,_addCursorForPre, cg->trMemory()) : 0;
for (int i = 0; i < _addCursorForPre; i++)
{
virtReg = _preConditions->getRegisterDependency(i)->getRegister();
regNum = _preConditions->getRegisterDependency(i)->getRealRegister();
if (!isOOL)
{
// Add to the association condition when the association is changed
// from one virtual register to another
if (machine->getVirtualAssociatedWithReal(regNum) != virtReg && machine->getVirtualAssociatedWithReal(regNum) != 0)
{
assoc->addPostCondition(machine->getVirtualAssociatedWithReal(regNum), regNum);
numAssoc++;
}
// Keep track of the virtual register map to real registers!
machine->setVirtualAssociatedWithReal(regNum, virtReg);
}
instr->useRegister(virtReg);
if (!isOOL)
{
cg->setRealRegisterAssociation(virtReg, regNum);
if (_preConditions->getRegisterDependency(i)->getExcludeGPR0())
cg->addRealRegisterInterference(virtReg, TR::RealRegister::gr0);
}
}
if (numAssoc > 0)
{
// Emit an AssocRegs instruction to track the previous association
assoc->setNumPostConditions(numAssoc, cg->trMemory());
generateDepInstruction(cg, TR::InstOpCode::assocreg, instr->getNode(), assoc, instr->getPrev());
}
for (int j = 0; j < _addCursorForPost; j++)
{
virtReg = _postConditions->getRegisterDependency(j)->getRegister();
regNum = _postConditions->getRegisterDependency(j)->getRealRegister();
instr->useRegister(virtReg);
if (!isOOL)
{
cg->setRealRegisterAssociation(virtReg, regNum);
if (_postConditions->getRegisterDependency(j)->getExcludeGPR0())
cg->addRealRegisterInterference(virtReg, TR::RealRegister::gr0);
}
}
}
示例9: if
void OMR::X86::Instruction::assignRegisters(TR_RegisterKinds kindsToBeAssigned)
{
if (!self()->getDependencyConditions())
{
// Fast path when there are no dependency conditions.
//
return;
}
if (self()->getOpCodeValue() != ASSOCREGS)
{
self()->aboutToAssignRegDeps();
if ((self()->cg()->getAssignmentDirection() == self()->cg()->Backward))
{
self()->getDependencyConditions()->assignPostConditionRegisters(self(), kindsToBeAssigned, self()->cg());
self()->getDependencyConditions()->assignPreConditionRegisters(self(), kindsToBeAssigned, self()->cg());
}
else
{
self()->getDependencyConditions()->assignPreConditionRegisters(self()->getPrev(), kindsToBeAssigned, self()->cg());
self()->getDependencyConditions()->assignPostConditionRegisters(self(), kindsToBeAssigned, self()->cg());
}
}
else if ((self()->getOpCodeValue() == ASSOCREGS) && self()->cg()->enableRegisterAssociations())
{
if (kindsToBeAssigned & TR_GPR_Mask)
{
TR::Machine *machine = self()->cg()->machine();
// First traverse the existing associations and remove them
// so that they don't interfere with the new ones
//
for (int i = TR::RealRegister::FirstGPR;
i <= TR::RealRegister::LastAssignableGPR;
++i)
{
// Skip non-assignable registers
//
if (machine->getX86RealRegister((TR::RealRegister::RegNum)i)->getState() == TR::RealRegister::Locked)
continue;
TR::Register *virtReg = machine->getVirtualAssociatedWithReal((TR::RealRegister::RegNum)i);
if (virtReg)
{
virtReg->setAssociation(TR::RealRegister::NoReg);
}
}
// Next loop through and set up the new associations (both on the machine
// and by associating the virtual registers with their real dependencies)
//
TR_X86RegisterDependencyGroup *depGroup = self()->getDependencyConditions()->getPostConditions();
for (int j = 0; j < self()->getDependencyConditions()->getNumPostConditions(); ++j)
{
TR::RegisterDependency *dep = depGroup->getRegisterDependency(j);
machine->setVirtualAssociatedWithReal(dep->getRealRegister(), dep->getRegister());
}
machine->setGPRWeightsFromAssociations();
}
}
}
示例10: printSnippetLabel
void
TR_Debug::print(TR::FILE *pOutFile, TR::AMD64FPConversionSnippet * snippet)
{
if (pOutFile == NULL)
return;
uint8_t *bufferPos = snippet->getSnippetLabel()->getCodeLocation();
printSnippetLabel(pOutFile, snippet->getSnippetLabel(), bufferPos, getName(snippet));
TR::Machine *machine = _cg->machine();
TR::RealRegister *sourceRegister = toRealRegister(snippet->getConvertInstruction()->getSourceRegister());
TR::RealRegister *targetRegister = toRealRegister(snippet->getConvertInstruction()->getTargetRegister());
uint8_t sreg = sourceRegister->getRegisterNumber();
uint8_t treg = targetRegister->getRegisterNumber();
TR::ILOpCodes opCode = snippet->getConvertInstruction()->getNode()->getOpCodeValue();
TR_RegisterSizes size = TR_DoubleWordReg;
if (treg != TR::RealRegister::eax)
{
int instrSize = IS_REX(*bufferPos)? 3 : 2;
printPrefix(pOutFile, NULL, bufferPos, instrSize);
trfprintf(pOutFile, "mov \t");
print(pOutFile, targetRegister, size);
trfprintf(pOutFile, ", ");
print(pOutFile, machine->getX86RealRegister(TR::RealRegister::eax), size);
trfprintf(pOutFile, "\t%s preserve helper return reg",
commentString());
bufferPos += instrSize;
}
if (sreg != TR::RealRegister::xmm0)
{
printPrefix(pOutFile, NULL, bufferPos, 4);
trfprintf(pOutFile, "sub \trsp, 8");
printPrefix(pOutFile, NULL, bufferPos, 5);
trfprintf(pOutFile, "movsd\t[rsp], xmm0\t%s save xmm0",
commentString());
bufferPos += 9;
int instrSize = IS_REX(*bufferPos)? 5 : 4;
printPrefix(pOutFile, NULL, bufferPos, instrSize);
trfprintf(pOutFile, "movsd\txmm0, ");
print(pOutFile, sourceRegister, TR_QuadWordReg);
trfprintf(pOutFile, "\t%s load parameter",
commentString());
bufferPos += instrSize;
}
printPrefix(pOutFile, NULL, bufferPos, 5);
trfprintf(pOutFile, "call\t%s", getName(snippet->getHelperSymRef()));
bufferPos += 5;
if (sreg != TR::RealRegister::xmm0)
{
printPrefix(pOutFile, NULL, bufferPos, 5);
trfprintf(pOutFile, "movsd\txmm0, [rsp]\t%s restore xmm0",
commentString());
printPrefix(pOutFile, NULL, bufferPos, 4);
trfprintf(pOutFile, "add \trsp, 8");
bufferPos += 9;
}
if (treg != TR::RealRegister::eax)
{
int instrSize = IS_REX(*bufferPos)? 2 : 1;
printPrefix(pOutFile, NULL, bufferPos, instrSize);
trfprintf(pOutFile, "xchg\t");
print(pOutFile, targetRegister, size);
trfprintf(pOutFile, ", ");
print(pOutFile, machine->getX86RealRegister(TR::RealRegister::eax), size);
trfprintf(pOutFile, "\t%s restore result reg & put result in target reg",
commentString());
bufferPos += instrSize;
}
printRestartJump(pOutFile, snippet, bufferPos);
}
示例11: assignContendedRegisters
static void assignContendedRegisters(TR::Instruction *currentInstruction,
TR::RegisterDependency *dep,
TR_PPCRegisterDependencyMap& map,
bool depsBlocked,
TR::CodeGenerator *cg)
{
// *this swipeable for debugging purposes
TR::Machine *machine = cg->machine();
dep = findDependencyChainHead(dep, map);
TR::Register *virtReg = dep->getRegister();
TR::RealRegister::RegNum targetRegNum = dep->getRealRegister();
TR::RealRegister *targetReg = machine->getPPCRealRegister(targetRegNum);
TR::RealRegister *assignedReg = virtReg->getAssignedRealRegister() ?
toRealRegister(virtReg->getAssignedRealRegister()) : NULL;
// Chain of length 1
if (!assignedReg || !map.getDependencyWithTarget(assignedReg->getRegisterNumber()))
{
machine->coerceRegisterAssignment(currentInstruction, virtReg, targetRegNum);
virtReg->block();
return;
}
// Chain of length 2, handled here instead of below to get 3*xor exchange on GPRs
if (map.getDependencyWithTarget(assignedReg->getRegisterNumber()) == map.getDependencyWithAssigned(targetRegNum))
{
TR::Register *targetVirtReg = targetReg->getAssignedRegister();
machine->coerceRegisterAssignment(currentInstruction, virtReg, targetRegNum);
virtReg->block();
targetVirtReg->block();
return;
}
// Grab a spare reg in order to free the target of the first dep
// At this point the first dep's target could be blocked, assigned, or NoReg
// If it's blocked or assigned we allocate a spare and assign the target's virtual to it
// If it's NoReg, the spare reg will be used as the first dep's actual target
TR::RealRegister *spareReg = machine->findBestFreeRegister(currentInstruction, virtReg->getKind(),
targetRegNum == TR::RealRegister::NoReg ? dep->getExcludeGPR0() : false, false,
targetRegNum == TR::RealRegister::NoReg ? virtReg : targetReg->getAssignedRegister());
bool haveFreeSpare = spareReg != NULL;
if (!spareReg)
{
// If the regs in this dep group are not blocked we need to make sure we don't spill a reg that's in the middle of the chain
if (!depsBlocked)
{
if (targetRegNum == TR::RealRegister::NoReg)
spareReg = machine->freeBestRegister(currentInstruction,
map.getDependencyWithTarget(assignedReg->getRegisterNumber())->getRegister(),
assignedReg, false);
else
spareReg = machine->freeBestRegister(currentInstruction, virtReg, targetReg, false);
}
else
{
if (targetRegNum == TR::RealRegister::NoReg)
spareReg = machine->freeBestRegister(currentInstruction, virtReg, NULL, dep->getExcludeGPR0());
else
spareReg = machine->freeBestRegister(currentInstruction, targetReg->getAssignedRegister(), NULL, false);
}
}
if (targetRegNum != TR::RealRegister::NoReg && spareReg != targetReg)
{
machine->coerceRegisterAssignment(currentInstruction, targetReg->getAssignedRegister(), spareReg->getRegisterNumber());
}
TR_ASSERT(targetRegNum == TR::RealRegister::NoReg ||
targetReg->getState() == TR::RealRegister::Free, "Expecting free target register");
if (depsBlocked || targetRegNum != TR::RealRegister::NoReg || haveFreeSpare)
{
machine->coerceRegisterAssignment(currentInstruction, virtReg,
targetRegNum == TR::RealRegister::NoReg ?
spareReg->getRegisterNumber() : targetRegNum);
virtReg->block();
}
dep = map.getDependencyWithTarget(assignedReg->getRegisterNumber());
while (dep)
{
virtReg = dep->getRegister();
targetRegNum = dep->getRealRegister();
targetReg = machine->getPPCRealRegister(targetRegNum);
assignedReg = virtReg->getAssignedRealRegister() ?
toRealRegister(virtReg->getAssignedRealRegister()) : NULL;
TR_ASSERT(targetReg->getState() == TR::RealRegister::Free || targetReg == spareReg,
"Expecting free target register or target to have been filled to free spare register");
machine->coerceRegisterAssignment(currentInstruction, virtReg, targetRegNum);
virtReg->block();
dep = assignedReg ?
map.getDependencyWithTarget(assignedReg->getRegisterNumber()) : NULL;
}
//.........这里部分代码省略.........
示例12: assignRegisters
void TR_PPCRegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstruction,
TR_RegisterKinds kindToBeAssigned,
uint32_t numberOfRegisters,
TR::CodeGenerator *cg)
{
// *this swipeable for debugging purposes
TR::Machine *machine = cg->machine();
TR::Register *virtReg;
TR::RealRegister::RegNum dependentRegNum;
TR::RealRegister *dependentRealReg, *assignedRegister, *realReg;
int i, j;
TR::Compilation *comp = cg->comp();
int num_gprs = 0;
int num_fprs = 0;
int num_vrfs = 0;
// Use to do lookups using real register numbers
TR_PPCRegisterDependencyMap map(_dependencies, numberOfRegisters);
if (!comp->getOption(TR_DisableOOL))
{
for (i = 0; i< numberOfRegisters; i++)
{
virtReg = _dependencies[i].getRegister();
dependentRegNum = _dependencies[i].getRealRegister();
if (dependentRegNum == TR::RealRegister::SpilledReg)
{
TR_ASSERT(virtReg->getBackingStorage(),"should have a backing store if dependentRegNum == spillRegIndex()\n");
if (virtReg->getAssignedRealRegister())
{
// this happens when the register was first spilled in main line path then was reverse spilled
// and assigned to a real register in OOL path. We protected the backing store when doing
// the reverse spill so we could re-spill to the same slot now
traceMsg (comp,"\nOOL: Found register spilled in main line and re-assigned inside OOL");
TR::Node *currentNode = currentInstruction->getNode();
TR::RealRegister *assignedReg = toRealRegister(virtReg->getAssignedRegister());
TR::MemoryReference *tempMR = new (cg->trHeapMemory()) TR::MemoryReference(currentNode, (TR::SymbolReference*)virtReg->getBackingStorage()->getSymbolReference(), sizeof(uintptr_t), cg);
TR::InstOpCode::Mnemonic opCode;
TR_RegisterKinds rk = virtReg->getKind();
switch (rk)
{
case TR_GPR:
opCode =TR::InstOpCode::Op_load;
break;
case TR_FPR:
opCode = virtReg->isSinglePrecision() ? TR::InstOpCode::lfs : TR::InstOpCode::lfd;
break;
default:
TR_ASSERT(0, "\nRegister kind not supported in OOL spill\n");
break;
}
TR::Instruction *inst = generateTrg1MemInstruction(cg, opCode, currentNode, assignedReg, tempMR, currentInstruction);
assignedReg->setAssignedRegister(NULL);
virtReg->setAssignedRegister(NULL);
assignedReg->setState(TR::RealRegister::Free);
if (comp->getDebug())
cg->traceRegisterAssignment("Generate reload of virt %s due to spillRegIndex dep at inst %p\n",comp->getDebug()->getName(virtReg),currentInstruction);
cg->traceRAInstruction(inst);
}
if (!(std::find(cg->getSpilledRegisterList()->begin(), cg->getSpilledRegisterList()->end(), virtReg) != cg->getSpilledRegisterList()->end()))
cg->getSpilledRegisterList()->push_front(virtReg);
}
// we also need to free up all locked backing storage if we are exiting the OOL during backwards RA assignment
else if (currentInstruction->isLabel() && virtReg->getAssignedRealRegister())
{
TR::PPCLabelInstruction *labelInstr = (TR::PPCLabelInstruction *)currentInstruction;
TR_BackingStore * location = virtReg->getBackingStorage();
TR_RegisterKinds rk = virtReg->getKind();
int32_t dataSize;
if (labelInstr->getLabelSymbol()->isStartOfColdInstructionStream() && location)
{
traceMsg (comp,"\nOOL: Releasing backing storage (%p)\n", location);
if (rk == TR_GPR)
dataSize = TR::Compiler->om.sizeofReferenceAddress();
else
dataSize = 8;
location->setMaxSpillDepth(0);
cg->freeSpill(location,dataSize,0);
virtReg->setBackingStorage(NULL);
}
}
}
}
for (i = 0; i < numberOfRegisters; i++)
{
map.addDependency(_dependencies[i], i);
virtReg = _dependencies[i].getRegister();
dependentRegNum = _dependencies[i].getRealRegister();
if (dependentRegNum != TR::RealRegister::SpilledReg)
{
if (virtReg->getKind() == TR_GPR)
num_gprs++;
else if (virtReg->getKind() == TR_FPR)
//.........这里部分代码省略.........
示例13: switch
uint8_t *
TR::S390CallSnippet::S390flushArgumentsToStack(uint8_t * buffer, TR::Node * callNode, int32_t argSize, TR::CodeGenerator * cg)
{
int32_t intArgNum = 0, floatArgNum = 0, offset;
TR::Machine *machine = cg->machine();
TR::Linkage * linkage = cg->getLinkage(callNode->getSymbol()->castToMethodSymbol()->getLinkageConvention());
int32_t argStart = callNode->getFirstArgumentIndex();
bool rightToLeft = linkage->getRightToLeft() &&
//we want the arguments for induceOSR to be passed from left to right as in any other non-helper call
!callNode->getSymbolReference()->isOSRInductionHelper();
if (rightToLeft)
{
offset = linkage->getOffsetToFirstParm();
}
else
{
offset = argSize + linkage->getOffsetToFirstParm();
}
for (int32_t i = argStart; i < callNode->getNumChildren(); i++)
{
TR::Node * child = callNode->getChild(i);
switch (child->getDataType())
{
case TR::Int8:
case TR::Int16:
case TR::Int32:
if (!rightToLeft)
{
offset -= TR::Compiler->target.is64Bit() ? 8 : 4;
}
if (intArgNum < linkage->getNumIntegerArgumentRegisters())
{
buffer = storeArgumentItem(TR::InstOpCode::ST, buffer,
machine->getRealRegister(linkage->getIntegerArgumentRegister(intArgNum)), offset, cg);
}
intArgNum++;
if (rightToLeft)
{
offset += TR::Compiler->target.is64Bit() ? 8 : 4;
}
break;
case TR::Address:
if (!rightToLeft)
{
offset -= TR::Compiler->target.is64Bit() ? 8 : 4;
}
if (intArgNum < linkage->getNumIntegerArgumentRegisters())
{
buffer = storeArgumentItem(TR::InstOpCode::getStoreOpCode(), buffer,
machine->getRealRegister(linkage->getIntegerArgumentRegister(intArgNum)), offset, cg);
}
intArgNum++;
if (rightToLeft)
{
offset += TR::Compiler->target.is64Bit() ? 8 : 4;
}
break;
case TR::Int64:
if (!rightToLeft)
{
offset -= (TR::Compiler->target.is64Bit() ? 16 : 8);
}
if (intArgNum < linkage->getNumIntegerArgumentRegisters())
{
if (TR::Compiler->target.is64Bit())
{
buffer = storeArgumentItem(TR::InstOpCode::STG, buffer,
machine->getRealRegister(linkage->getIntegerArgumentRegister(intArgNum)), offset, cg);
}
else
{
buffer = storeArgumentItem(TR::InstOpCode::ST, buffer,
machine->getRealRegister(linkage->getIntegerArgumentRegister(intArgNum)), offset, cg);
if (intArgNum < linkage->getNumIntegerArgumentRegisters() - 1)
{
buffer = storeArgumentItem(TR::InstOpCode::ST, buffer,
machine->getRealRegister(linkage->getIntegerArgumentRegister(intArgNum + 1)), offset + 4, cg);
}
}
}
intArgNum += TR::Compiler->target.is64Bit() ? 1 : 2;
if (rightToLeft)
{
offset += TR::Compiler->target.is64Bit() ? 16 : 8;
}
break;
case TR::Float:
if (!rightToLeft)
{
offset -= TR::Compiler->target.is64Bit() ? 8 : 4;
}
if (floatArgNum < linkage->getNumFloatArgumentRegisters())
{
buffer = storeArgumentItem(TR::InstOpCode::STE, buffer,
//.........这里部分代码省略.........
示例14: cg
// Copies parameters from where they enter the method (either on stack or in a
// linkage register) to their "home location" where the method body will expect
// to find them (either on stack or in a global register).
//
TR::Instruction *
TR::X86SystemLinkage::copyParametersToHomeLocation(TR::Instruction *cursor)
{
TR::Machine *machine = cg()->machine();
TR::RealRegister *framePointer = machine->getX86RealRegister(TR::RealRegister::vfp);
TR::ResolvedMethodSymbol *bodySymbol = comp()->getJittedMethodSymbol();
ListIterator<TR::ParameterSymbol> paramIterator(&(bodySymbol->getParameterList()));
TR::ParameterSymbol *paramCursor;
const TR::RealRegister::RegNum noReg = TR::RealRegister::NoReg;
TR_ASSERT(noReg == 0, "noReg must be zero so zero-initializing movStatus will work");
TR::MovStatus movStatus[TR::RealRegister::NumRegisters] = {{(TR::RealRegister::RegNum)0,(TR::RealRegister::RegNum)0,(TR_MovDataTypes)0}};
// We must always do the stores first, then the reg-reg copies, then the
// loads, so that we never clobber a register we will need later. However,
// the logic is simpler if we do the loads and stores in the same loop.
// Therefore, we maintain a separate instruction cursor for the loads.
//
// We defer the initialization of loadCursor until we generate the first
// load. Otherwise, if we happen to generate some stores first, then the
// store cursor would get ahead of the loadCursor, and the instructions
// would end up in the wrong order despite our efforts.
//
TR::Instruction *loadCursor = NULL;
// Phase 1: generate RegMem and MemReg movs, and collect information about
// the required RegReg movs.
//
for (paramCursor = paramIterator.getFirst();
paramCursor != NULL;
paramCursor = paramIterator.getNext())
{
int8_t lri = paramCursor->getLinkageRegisterIndex(); // How the parameter enters the method
TR::RealRegister::RegNum ai // Where method body expects to find it
= (TR::RealRegister::RegNum)paramCursor->getAllocatedIndex();
int32_t offset = paramCursor->getParameterOffset(); // Location of the parameter's stack slot
TR_MovDataTypes movDataType = paramMovType(paramCursor); // What sort of MOV instruction does it need?
// Copy the parameter to wherever it should be
//
if (lri == NOT_LINKAGE) // It's on the stack
{
if (ai == NOT_ASSIGNED) // It only needs to be on the stack
{
// Nothing to do
}
else // Method body expects it to be in the ai register
{
if (loadCursor == NULL)
loadCursor = cursor;
if (debug("traceCopyParametersToHomeLocation"))
diagnostic("copyParametersToHomeLocation: Loading %d\n", ai);
// ai := stack
loadCursor = generateRegMemInstruction(
loadCursor,
TR::Linkage::movOpcodes(RegMem, movDataType),
machine->getX86RealRegister(ai),
generateX86MemoryReference(framePointer, offset, cg()),
cg()
);
}
}
else // It's in a linkage register
{
TR::RealRegister::RegNum sourceIndex = getProperties().getArgumentRegister(lri, isFloat(movDataType));
// Copy to the stack if necessary
//
if (ai == NOT_ASSIGNED || hasToBeOnStack(paramCursor))
{
if (comp()->getOption(TR_TraceCG))
traceMsg(comp(), "copyToHomeLocation param %p, linkage reg index %d, allocated index %d, parameter offset %d, hasToBeOnStack %d, parm->isParmHasToBeOnStack() %d.\n", paramCursor, lri, ai, offset, hasToBeOnStack(paramCursor), paramCursor->isParmHasToBeOnStack());
if (debug("traceCopyParametersToHomeLocation"))
diagnostic("copyParametersToHomeLocation: Storing %d\n", sourceIndex);
// stack := lri
cursor = generateMemRegInstruction(
cursor,
TR::Linkage::movOpcodes(MemReg, movDataType),
generateX86MemoryReference(framePointer, offset, cg()),
machine->getX86RealRegister(sourceIndex),
cg()
);
}
// Copy to the ai register if necessary
//
if (ai != NOT_ASSIGNED && ai != sourceIndex)
{
// This parameter needs a RegReg move. We don't know yet whether
// we need the value in the target register, so for now we just
// remember that we need to do this and keep going.
//
TR_ASSERT(movStatus[ai ].sourceReg == noReg, "Each target reg must have only one source");
//.........这里部分代码省略.........
示例15: assignRegisters
void TR_ARMRegisterDependencyGroup::assignRegisters(TR::Instruction *currentInstruction,
TR_RegisterKinds kindToBeAssigned,
uint32_t numberOfRegisters,
TR::CodeGenerator *cg)
{
TR::Compilation *comp = cg->comp();
TR::Machine *machine = cg->machine();
TR::Register *virtReg;
TR::RealRegister::RegNum dependentRegNum;
TR::RealRegister *dependentRealReg, *assignedRegister;
uint32_t i, j;
bool changed;
if (!comp->getOption(TR_DisableOOL))
{
for (i = 0; i< numberOfRegisters; i++)
{
virtReg = dependencies[i].getRegister();
dependentRegNum = dependencies[i].getRealRegister();
if (dependentRegNum == TR::RealRegister::SpilledReg)
{
TR_ASSERT(virtReg->getBackingStorage(),"should have a backing store if dependentRegNum == spillRegIndex()\n");
if (virtReg->getAssignedRealRegister())
{
// this happens when the register was first spilled in main line path then was reverse spilled
// and assigned to a real register in OOL path. We protected the backing store when doing
// the reverse spill so we could re-spill to the same slot now
traceMsg (comp,"\nOOL: Found register spilled in main line and re-assigned inside OOL");
TR::Node *currentNode = currentInstruction->getNode();
TR::RealRegister *assignedReg = toRealRegister(virtReg->getAssignedRegister());
TR::MemoryReference *tempMR = new (cg->trHeapMemory()) TR::MemoryReference(currentNode, (TR::SymbolReference*)virtReg->getBackingStorage()->getSymbolReference(), sizeof(uintptr_t), cg);
TR_ARMOpCodes opCode;
TR_RegisterKinds rk = virtReg->getKind();
switch (rk)
{
case TR_GPR:
opCode = ARMOp_ldr;
break;
case TR_FPR:
opCode = virtReg->isSinglePrecision() ? ARMOp_ldfs : ARMOp_ldfd;
break;
default:
TR_ASSERT(0, "\nRegister kind not supported in OOL spill\n");
break;
}
TR::Instruction *inst = generateTrg1MemInstruction(cg, opCode, currentNode, assignedReg, tempMR, currentInstruction);
assignedReg->setAssignedRegister(NULL);
virtReg->setAssignedRegister(NULL);
assignedReg->setState(TR::RealRegister::Free);
if (comp->getDebug())
cg->traceRegisterAssignment("Generate reload of virt %s due to spillRegIndex dep at inst %p\n", cg->comp()->getDebug()->getName(virtReg),currentInstruction);
cg->traceRAInstruction(inst);
}
if (!(std::find(cg->getSpilledRegisterList()->begin(), cg->getSpilledRegisterList()->end(), virtReg) != cg->getSpilledRegisterList()->end()))
cg->getSpilledRegisterList()->push_front(virtReg);
}
// we also need to free up all locked backing storage if we are exiting the OOL during backwards RA assignment
else if (currentInstruction->isLabel() && virtReg->getAssignedRealRegister())
{
TR::ARMLabelInstruction *labelInstr = (TR::ARMLabelInstruction *)currentInstruction;
TR_BackingStore *location = virtReg->getBackingStorage();
TR_RegisterKinds rk = virtReg->getKind();
int32_t dataSize;
if (labelInstr->getLabelSymbol()->isStartOfColdInstructionStream() && location)
{
traceMsg (comp,"\nOOL: Releasing backing storage (%p)\n", location);
if (rk == TR_GPR)
dataSize = TR::Compiler->om.sizeofReferenceAddress();
else
dataSize = 8;
location->setMaxSpillDepth(0);
cg->freeSpill(location,dataSize,0);
virtReg->setBackingStorage(NULL);
}
}
}
}
for (i = 0; i < numberOfRegisters; i++)
{
virtReg = dependencies[i].getRegister();
if (virtReg->getAssignedRealRegister()!=NULL)
{
if (dependencies[i].getRealRegister() == TR::RealRegister::NoReg)
{
virtReg->block();
}
else
{
dependentRegNum = toRealRegister(virtReg->getAssignedRealRegister())->getRegisterNumber();
for (j=0; j<numberOfRegisters; j++)
{
if (dependentRegNum == dependencies[j].getRealRegister())
{
virtReg->block();
break;
}
//.........这里部分代码省略.........