uint8_t *TR::PPCLabelInstruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); TR::LabelSymbol *label = getLabelSymbol(); uint8_t *cursor = instructionStart; if (getOpCode().isBranchOp()) { cursor = getOpCode().copyBinaryToBuffer(instructionStart); if (label->getCodeLocation() != NULL) { *(int32_t *)cursor |= ((label->getCodeLocation()-cursor) & 0x03fffffc); } else { cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative24BitRelocation(cursor, label)); } cursor += 4; } else // regular LABEL { label->setCodeLocation(instructionStart); } setBinaryLength(cursor - instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); setBinaryEncoding(instructionStart); return cursor; }
uint8_t *TR::PPCAlignedLabelInstruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); TR::LabelSymbol *label = getLabelSymbol(); uint8_t *cursor = instructionStart; int32_t alignment = getAlignment(); int32_t paddingNOPsNeeded = 0; if ((alignment-1) & (intptr_t)cursor) { paddingNOPsNeeded = (alignment - ((alignment-1) & (intptr_t)cursor))/(PPC_INSTRUCTION_LENGTH); } if ((paddingNOPsNeeded > 0) ^ getFlipAlignmentDecision()) { for (int32_t i = 0; i < paddingNOPsNeeded; i++) { TR::InstOpCode opCode(TR::InstOpCode::nop); opCode.copyBinaryToBuffer(cursor); cursor += PPC_INSTRUCTION_LENGTH; } } label->setCodeLocation(cursor); // point past any NOPs to the following instruction setBinaryLength(cursor - instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); setBinaryEncoding(instructionStart); return cursor; }
uint8_t *TR::PPCMemInstruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; getMemoryReference()->mapOpCode(this); cursor = getOpCode().copyBinaryToBuffer(instructionStart); cursor = getMemoryReference()->generateBinaryEncoding(this, cursor, cg()); setBinaryLength(cursor-instructionStart); setBinaryEncoding(instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); return cursor; }
uint8_t *TR::PPCImm2Instruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; cursor = getOpCode().copyBinaryToBuffer(instructionStart); insertImmediateField(toPPCCursor(cursor)); insertImmediateField2(toPPCCursor(cursor)); cursor += PPC_INSTRUCTION_LENGTH; setBinaryLength(PPC_INSTRUCTION_LENGTH); setBinaryEncoding(instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); return cursor; }
//------ topic 5.6 ------ //switch odd and even bit of a integer int switchOddandEven(int x){ int size = getBinaryLength(x); size = (size%2)?size+1:size; int r,l; r=0; l=0; for(int i=0;i<size;i++){ if(i%2==0) r += pow(2,i); else l += pow(2,i); } int m = x>>1 & r; int n = x<<1 & l; return m+n; }
uint8_t *TR::PPCImmInstruction::generateBinaryEncoding() { TR::Compilation *comp = cg()->comp(); uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; cursor = getOpCode().copyBinaryToBuffer(instructionStart); *(int32_t *)cursor = (int32_t)getSourceImmediate(); addMetaDataForCodeAddress(cursor); cursor += PPC_INSTRUCTION_LENGTH; setBinaryLength(PPC_INSTRUCTION_LENGTH); setBinaryEncoding(instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); return cursor; }
uint8_t *TR::PPCVirtualGuardNOPInstruction::generateBinaryEncoding() { uint8_t *cursor = cg()->getBinaryBufferCursor(); TR::LabelSymbol *label = getLabelSymbol(); int32_t length = 0; _site->setLocation(cursor); if (label->getCodeLocation() == NULL) { _site->setDestination(cursor); cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelAbsoluteRelocation((uint8_t *) (&_site->getDestination()), label)); #ifdef DEBUG if (debug("traceVGNOP")) printf("####> virtual location = %p, label (relocation) = %p\n", cursor, label); #endif } else { _site->setDestination(label->getCodeLocation()); #ifdef DEBUG if (debug("traceVGNOP")) printf("####> virtual location = %p, label location = %p\n", cursor, label->getCodeLocation()); #endif } setBinaryEncoding(cursor); if (cg()->sizeOfInstructionToBePatched(this) == 0 || // AOT needs an explicit nop, even if there are patchable instructions at this site because // 1) Those instructions might have AOT data relocations (and therefore will be incorrectly patched again) // 2) We might want to re-enable the code path and unpatch, in which case we would have to know what the old instruction was cg()->comp()->compileRelocatableCode()) { TR::InstOpCode opCode(TR::InstOpCode::nop); opCode.copyBinaryToBuffer(cursor); length = PPC_INSTRUCTION_LENGTH; } setBinaryLength(length); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); return cursor+length; }
uint8_t *TR::PPCTrg1Src1Instruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; if (isRegCopy() && (toRealRegister(getTargetRegister()) == toRealRegister(getSource1Register()))) { } else { cursor = getOpCode().copyBinaryToBuffer(instructionStart); insertTargetRegister(toPPCCursor(cursor)); insertSource1Register(toPPCCursor(cursor)); cursor += PPC_INSTRUCTION_LENGTH; } setBinaryLength(cursor - instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); 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::PPCTrg1MemInstruction::generateBinaryEncoding() { uint8_t *instructionStart = cg()->getBinaryBufferCursor(); uint8_t *cursor = instructionStart; getMemoryReference()->mapOpCode(this); cursor = getOpCode().copyBinaryToBuffer(instructionStart); insertTargetRegister(toPPCCursor(cursor)); // Set hint bit if there is any // The control for the different values is done through asserts in the constructor if (haveHint()) { *(int32_t *)instructionStart |= getHint(); } cursor = getMemoryReference()->generateBinaryEncoding(this, cursor, cg()); setBinaryLength(cursor-instructionStart); setBinaryEncoding(instructionStart); cg()->addAccumulatedInstructionLengthError(getEstimatedBinaryLength() - getBinaryLength()); return cursor; }
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; }