int32_t TR::PPCAlignedLabelInstruction::estimateBinaryLength(int32_t currentEstimate) { TR_ASSERT((getAlignment() % PPC_INSTRUCTION_LENGTH) == 0, "label alignment must be a multiple of the instruction length, alignment = %d", getAlignment()); TR_ASSERT(getOpCodeValue() == TR::InstOpCode::label, "AlignedLabel only supported for TR::InstOpCode::Label opcodes"); setEstimatedBinaryLength(getAlignment() - PPC_INSTRUCTION_LENGTH); return currentEstimate + getEstimatedBinaryLength(); }
void TR::ValidateChildTypes::validate(TR::Node *node) { auto opcode = node->getOpCode(); if (opcode.expectedChildCount() != ILChildProp::UnspecifiedChildCount) { const auto expChildCount = opcode.expectedChildCount(); const auto actChildCount = node->getNumChildren(); /* Validate child types. */ for (auto i = 0; i < actChildCount; ++i) { auto childOpcode = node->getChild(i)->getOpCode(); if (childOpcode.getOpCodeValue() != TR::GlRegDeps) { const auto expChildType = opcode.expectedChildType(i); const auto actChildType = childOpcode.getDataType().getDataType(); const auto expChildTypeName = (expChildType >= TR::NumTypes) ? "UnspecifiedChildType" : TR::DataType::getName(expChildType); const auto actChildTypeName = TR::DataType::getName(actChildType); TR::checkILCondition(node, (expChildType >= TR::NumTypes || actChildType == expChildType), comp(), "Child %d has unexpected type %s (expected %s)", i, actChildTypeName, expChildTypeName); } else { /** * Make sure the node is allowed to have a GlRegDeps child * and check that it is the last child. */ TR::checkILCondition(node, opcode.canHaveGlRegDeps() && (i == actChildCount - 1), comp(), "Unexpected GlRegDeps child %d", i); } } } }
int32_t TR::PPCControlFlowInstruction::estimateBinaryLength(int32_t currentEstimate) { switch(getOpCodeValue()) { case TR::InstOpCode::iflong: case TR::InstOpCode::setbool: case TR::InstOpCode::idiv: case TR::InstOpCode::ldiv: case TR::InstOpCode::ifx: case TR::InstOpCode::iternary: if (useRegPairForResult()) { if (!useRegPairForCond()) setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 6); else setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 8); } else { if (!useRegPairForCond()) setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 4); else setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 6); } break; case TR::InstOpCode::setbflt: setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 5); break; case TR::InstOpCode::setblong: case TR::InstOpCode::flcmpg: case TR::InstOpCode::flcmpl: case TR::InstOpCode::irem: case TR::InstOpCode::lrem: case TR::InstOpCode::d2i: case TR::InstOpCode::setbx: setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 6); break; case TR::InstOpCode::d2l: if (TR::Compiler->target.is64Bit()) setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 6); else setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 8); break; case TR::InstOpCode::lcmp: setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 11); break; case TR::InstOpCode::cfnan: setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 2); break; case TR::InstOpCode::cdnan: setEstimatedBinaryLength(PPC_INSTRUCTION_LENGTH * 3); break; default: TR_ASSERT(false,"unknown control flow instruction (estimateBinaryLength)"); } return currentEstimate + getEstimatedBinaryLength(); }
uint8_t *TR::PPCTrg1Src1ImmInstruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; cursor = getOpCode().copyBinaryToBuffer(instructionStart); insertTargetRegister(toPPCCursor(cursor)); insertSource1Register(toPPCCursor(cursor)); if (getOpCodeValue() == TR::InstOpCode::srawi || getOpCodeValue() == TR::InstOpCode::srawi_r || getOpCodeValue() == TR::InstOpCode::sradi || getOpCodeValue() == TR::InstOpCode::sradi_r || getOpCodeValue() == TR::InstOpCode::extswsli) { insertShiftAmount(toPPCCursor(cursor)); } else if (getOpCodeValue() == TR::InstOpCode::dtstdg) { setSourceImmediate(getSourceImmediate() << 10); insertImmediateField(toPPCCursor(cursor)); } else { insertImmediateField(toPPCCursor(cursor)); } addMetaDataForCodeAddress(cursor); cursor += PPC_INSTRUCTION_LENGTH; setBinaryLength(PPC_INSTRUCTION_LENGTH); setBinaryEncoding(instructionStart); return cursor; }
uint8_t *TR::PPCSrc1Instruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; cursor = getOpCode().copyBinaryToBuffer(instructionStart); insertSource1Register(toPPCCursor(cursor)); if (getOpCodeValue() == TR::InstOpCode::mtfsf | getOpCodeValue() == TR::InstOpCode::mtfsfl || getOpCodeValue() == TR::InstOpCode::mtfsfw) { insertMaskField(toPPCCursor(cursor)); } else { insertImmediateField(toPPCCursor(cursor)); } cursor += PPC_INSTRUCTION_LENGTH; setBinaryLength(PPC_INSTRUCTION_LENGTH); setBinaryEncoding(instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()) ; return cursor; }
uint8_t *TR::PPCTrg1ImmInstruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; cursor = getOpCode().copyBinaryToBuffer(instructionStart); insertTargetRegister(toPPCCursor(cursor)); if (getOpCodeValue() == TR::InstOpCode::mtcrf || getOpCodeValue() == TR::InstOpCode::mfocrf) { *((int32_t *)cursor) |= (getSourceImmediate()<<12); if ((TR::Compiler->target.cpu.id() >= TR_PPCgp) && ((getSourceImmediate() & (getSourceImmediate() - 1)) == 0)) // convert to PPC AS single field form *((int32_t *)cursor) |= 0x00100000; } else if (getOpCodeValue() == TR::InstOpCode::mfcr) { if ((TR::Compiler->target.cpu.id() >= TR_PPCgp) && ((getSourceImmediate() & (getSourceImmediate() - 1)) == 0)) // convert to PPC AS single field form *((int32_t *)cursor) |= (getSourceImmediate()<<12) | 0x00100000; else TR_ASSERT(getSourceImmediate() == 0xFF, "Bad field mask on mfcr"); } else { insertImmediateField(toPPCCursor(cursor)); } addMetaDataForCodeAddress(cursor); cursor += PPC_INSTRUCTION_LENGTH; setBinaryLength(PPC_INSTRUCTION_LENGTH); setBinaryEncoding(instructionStart); return cursor; }
uint8_t *TR::PPCTrg1Src1Imm2Instruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; cursor = getOpCode().copyBinaryToBuffer(instructionStart); insertTargetRegister(toPPCCursor(cursor)); insertSource1Register(toPPCCursor(cursor)); insertShiftAmount(toPPCCursor(cursor)); insertMaskField(toPPCCursor(cursor), getOpCodeValue(), getLongMask()); cursor += PPC_INSTRUCTION_LENGTH; setBinaryLength(PPC_INSTRUCTION_LENGTH); setBinaryEncoding(instructionStart); return cursor; }
void TR::Validate_ireturnReturnType::validate(TR::Node *node) { auto opcode = node->getOpCode(); if (opcode.getOpCodeValue() == TR::ireturn) { const auto childCount = node->getNumChildren(); for (auto i = 0; i < childCount; ++i) { auto childOpcode = node->getChild(i)->getOpCode(); const auto actChildType = childOpcode.getDataType().getDataType(); const auto childTypeName = TR::DataType::getName(actChildType); TR::checkILCondition(node, (actChildType == TR::Int32 || actChildType == TR::Int16 || actChildType == TR::Int8), comp(),"ireturn has an invalid child type %s (expected Int{8,16,32})", childTypeName); } } }
uint8_t *TR::PPCConditionalBranchInstruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); TR::LabelSymbol *label = getLabelSymbol(); uint8_t *cursor = instructionStart; TR::Compilation *comp = cg()->comp(); cursor = getOpCode().copyBinaryToBuffer(instructionStart); // bclr doesn't have a label if (label) { if (label->getCodeLocation() != NULL) { if (!getFarRelocation()) { insertConditionRegister((uint32_t *)cursor); *(int32_t *)cursor |= ((label->getCodeLocation()-cursor) & 0xffff); } else // too far - need fix up { TR::InstOpCode::Mnemonic reversedOp; bool linkForm = reversedConditionalBranchOpCode(getOpCodeValue(), &reversedOp); TR::InstOpCode reversedOpCode(reversedOp); TR::InstOpCode extraOpCode(linkForm?TR::InstOpCode::bl:TR::InstOpCode::b); cursor = reversedOpCode.copyBinaryToBuffer(cursor); insertConditionRegister((uint32_t *)cursor); *(int32_t *)cursor |= 0x0008; cursor += 4; cursor = extraOpCode.copyBinaryToBuffer(cursor); *(int32_t *)cursor |= ((label->getCodeLocation() - cursor) & 0x03fffffc); } } else { if (!getFarRelocation()) { insertConditionRegister((uint32_t *)cursor); cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative16BitRelocation(cursor, label)); } else // too far - need fix up { TR::InstOpCode::Mnemonic reversedOp; bool linkForm = reversedConditionalBranchOpCode(getOpCodeValue(), &reversedOp); TR::InstOpCode reversedOpCode(reversedOp); TR::InstOpCode extraOpCode(linkForm?TR::InstOpCode::bl:TR::InstOpCode::b); cursor = reversedOpCode.copyBinaryToBuffer(cursor); insertConditionRegister((uint32_t *)cursor); *(int32_t *)cursor |= 0x0008; cursor += 4; cursor = extraOpCode.copyBinaryToBuffer(cursor); cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative24BitRelocation(cursor, label)); } } } else insertConditionRegister((uint32_t *)cursor); // set up prediction bits if there is any. if (haveHint()) { if (getFarRelocation()) reverseLikeliness(); if (getOpCode().setsCTR()) *(int32_t *)instructionStart |= (getLikeliness() ? PPCOpProp_BranchLikelyMaskCtr : PPCOpProp_BranchUnlikelyMaskCtr); else *(int32_t *)instructionStart |= (getLikeliness() ? PPCOpProp_BranchLikelyMask : PPCOpProp_BranchUnlikelyMask) ; } cursor += 4; setBinaryLength(cursor - instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); setBinaryEncoding(instructionStart); return cursor; }
bool TR::ILValidator::treesAreValid(TR::TreeTop *start, TR::TreeTop *stop) { checkSoundness(start, stop); for (PostorderNodeOccurrenceIterator iter(start, _comp, "VALIDATOR"); iter != stop; ++iter) { updateNodeState(iter); // General node validation // validateNode(iter); // // Additional specific kinds of validation // TR::Node *node = iter.currentNode(); if (node->getOpCodeValue() == TR::BBEnd) { // Determine whether this is the end of an extended block // bool isEndOfExtendedBlock = false; TR::TreeTop *nextTree = iter.currentTree()->getNextTreeTop(); if (nextTree) { validityRule(iter, nextTree->getNode()->getOpCodeValue() == TR::BBStart, "Expected BBStart after BBEnd"); isEndOfExtendedBlock = ! nextTree->getNode()->getBlock()->isExtensionOfPreviousBlock(); } else { isEndOfExtendedBlock = true; } if (isEndOfExtendedBlock) validateEndOfExtendedBlock(iter); } auto opcode = node->getOpCode(); if (opcode.expectedChildCount() != ILChildProp::UnspecifiedChildCount) { // Validate child expectations // const auto expChildCount = opcode.expectedChildCount(); const auto actChildCount = node->getNumChildren(); // validate child count if (!opcode.canHaveGlRegDeps()) { // in the common case, no GlRegDeps child is expect nor present validityRule(iter, actChildCount == expChildCount, "Child count %d does not match expected value of %d", actChildCount, expChildCount); } else if (actChildCount == (expChildCount + 1)) { // adjust expected child number to account for a possible extra GlRegDeps // child and make sure the last child is actually a GlRegDeps validityRule(iter, node->getChild(actChildCount - 1)->getOpCodeValue() == TR::GlRegDeps, "Child count %d does not match expected value of %d (%d without GlRegDeps) and last child is not a GlRegDeps", actChildCount, expChildCount + 1, expChildCount); } else { // if expected and actual child counts don't match, then the child // count is just wrong, even with an expected GlRegDeps validityRule(iter, actChildCount == expChildCount, "Child count %d matches neither expected values of %d (without GlRegDeps) nor %d (with GlRegDeps)", actChildCount, expChildCount, expChildCount + 1); } // validate child types for (auto i = 0; i < actChildCount; ++i) { auto childOpcode = node->getChild(i)->getOpCode(); if (childOpcode.getOpCodeValue() != TR::GlRegDeps) { const auto expChildType = opcode.expectedChildType(i); const auto actChildType = childOpcode.getDataType().getDataType(); const auto expChildTypeName = expChildType == ILChildProp::UnspecifiedChildType ? "UnspecifiedChildType" : TR::DataType::getName(expChildType); const auto actChildTypeName = TR::DataType::getName(actChildType); validityRule(iter, expChildType == ILChildProp::UnspecifiedChildType || actChildType == expChildType, "Child %d has unexpected type %s (expected %s)" , i, actChildTypeName, expChildTypeName); } else { // make sure the node is allowed to have a GlRegDeps child // and make sure that it is the last child validityRule(iter, opcode.canHaveGlRegDeps() && (i == actChildCount - 1), "Unexpected GlRegDeps child %d", i); } } } } return _isValidSoFar; }