Skip to content

Commit

Permalink
AArch64: Fix TestBitBranch instruction
Browse files Browse the repository at this point in the history
This commit fixes `TR::ARM64TestBitBranchInstruction`.
- Support branching to OOLCodeSection.
- Use correct relocation class as the destination is encoded in imm14 field.

Signed-off-by: Akira Saitoh <saiaki@jp.ibm.com>
  • Loading branch information
Akira Saitoh committed Oct 30, 2020
1 parent 4d32dfd commit 7640bd8
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 3 deletions.
4 changes: 2 additions & 2 deletions compiler/aarch64/codegen/ARM64BinaryEncoding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,13 +324,13 @@ uint8_t *TR::ARM64TestBitBranchInstruction::generateBinaryEncoding()
if (destination != 0)
{
intptr_t distance = destination - (uintptr_t)cursor;
TR_ASSERT_FATAL(-0x8000 <= distance && distance < 0x8000, "Branch destination is too far away for tbz/tbnz.");
TR_ASSERT_FATAL(constantIsSignedImm16(distance), "Branch destination is too far away for tbz/tbnz.");

insertImmediateField(toARM64Cursor(cursor), distance);
}
else
{
cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative24BitRelocation(cursor, label));
cg()->addRelocation(new (cg()->trHeapMemory()) TR::LabelRelative16BitRelocation(cursor, label));
}

cursor += ARM64_INSTRUCTION_LENGTH;
Expand Down
2 changes: 1 addition & 1 deletion compiler/aarch64/codegen/ARM64Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ void TR::ARM64LabelInstruction::assignRegistersForOutOfLineCodeSection(TR_Regist
TR::Compilation *comp = cg()->comp();

bool isLabel = getOpCodeValue() == TR::InstOpCode::label;
bool isBranch = (getOpCodeValue() == TR::InstOpCode::b) || (getKind() == IsConditionalBranch) || (getKind() == IsCompareBranch);
bool isBranch = (getOpCodeValue() == TR::InstOpCode::b) || (getKind() == IsConditionalBranch) || (getKind() == IsCompareBranch) || (getKind() == IsTestBitBranch);

cg()->freeUnlatchedRegisters();
// this is the return label from OOL
Expand Down
10 changes: 10 additions & 0 deletions compiler/aarch64/codegen/ARM64Instruction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ inline bool constantIsUnsignedImm12(uint64_t intValue)
return (intValue < (1<<12)); // 4096
}

/*
* @brief Answers if the signed integer value can be placed in a 16-bit field
* @param[in] intValue : signed integer value
* @return true if the value can be placed in 16-bit field, false otherwise
*/
inline bool constantIsSignedImm16(intptr_t intValue)
{
return (-0x8000 <= intValue && intValue < 0x8000);
}

/*
* @brief Answers if the unsigned integer value can be encoded in a 16-bit field
* @param[in] intValue : unsigned integer value
Expand Down
10 changes: 10 additions & 0 deletions compiler/aarch64/codegen/OMRCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,16 @@ TR_GlobalRegisterNumber OMR::ARM64::CodeGenerator::getLinkageGlobalRegisterNumbe
return result;
}

void OMR::ARM64::CodeGenerator::apply16BitLabelRelativeRelocation(int32_t *cursor, TR::LabelSymbol *label)
{
// for "tbz/tbnz" instruction
TR_ASSERT(label->getCodeLocation(), "Attempt to relocate to a NULL label address!");

intptr_t distance = reinterpret_cast<intptr_t>(label->getCodeLocation() - reinterpret_cast<uint8_t *>(cursor));
TR_ASSERT_FATAL(constantIsSignedImm16(distance), "offset (%d) is too large for imm14", distance);
*cursor |= ((distance >> 2) & 0x3fff) << 5; // imm14
}

void OMR::ARM64::CodeGenerator::apply24BitLabelRelativeRelocation(int32_t *cursor, TR::LabelSymbol *label)
{
// for "b.cond" instruction
Expand Down
8 changes: 8 additions & 0 deletions compiler/aarch64/codegen/OMRCodeGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,14 @@ class OMR_EXTENSIBLE CodeGenerator : public OMR::CodeGenerator
*/
TR::RealRegister *setMethodMetaDataRegister(TR::RealRegister *r) { return (_methodMetaDataRegister = r); }

using OMR::CodeGenerator::apply16BitLabelRelativeRelocation;
/**
* @brief Applies 16-bit Label relative relocation (for test bit branch)
* @param[in] cursor : instruction cursor
* @param[in] label : label
*/
void apply16BitLabelRelativeRelocation(int32_t *cursor, TR::LabelSymbol *label);

/**
* @brief Applies 24-bit Label relative relocation (for conditional branch)
* @param[in] cursor : instruction cursor
Expand Down

0 comments on commit 7640bd8

Please sign in to comment.