Skip to content

Commit

Permalink
AArch64: Implement large offset path for loadaddrEvaluator()
Browse files Browse the repository at this point in the history
This commit implements the path in AArch64 OMRMemoryReference for
handling offsets wider than 12 bits.
It is used by loadaddrEvaluator().

Signed-off-by: KONNO Kazuhiro <konno@jp.ibm.com>
  • Loading branch information
knn-k committed Jan 14, 2020
1 parent 947946e commit 5649e62
Showing 1 changed file with 19 additions and 5 deletions.
24 changes: 19 additions & 5 deletions compiler/aarch64/codegen/OMRMemoryReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -850,20 +850,34 @@ uint8_t *OMR::ARM64::MemoryReference::generateBinaryEncoding(TR::Instruction *cu
}
else
{
// loadaddrEvaluator() uses addimmx in generateTrgMemInstruction
// loadaddrEvaluator() uses addimmx in generateTrg1MemInstruction
TR_ASSERT(index == NULL, "MemoryReference with unexpected indexed form");

base->setRegisterFieldRN(wcursor);

if (constantIsUnsignedImm12(displacement))
{
*wcursor |= (displacement & 0xfff) << 10; /* imm12 */
cursor += ARM64_INSTRUCTION_LENGTH;
}
else
{
TR_ASSERT_FATAL(false, "Offset is too large for specified instruction.");
TR_ASSERT(currentInstruction->getKind() == OMR::Instruction::IsTrg1Mem, "unexpected instruction kind");
TR::RealRegister *treg = toRealRegister(((TR::ARM64Trg1MemInstruction *)currentInstruction)->getTargetRegister());
// movzw treg, low16bit
// movkw treg, high16bit, LSL #16
// addx treg, basereg, treg, SXTW
*wcursor = TR::InstOpCode::getOpCodeBinaryEncoding(TR::InstOpCode::movzw) | ((displacement & 0xFFFF) << 5);
treg->setRegisterFieldRD(wcursor);
wcursor++;
*wcursor = TR::InstOpCode::getOpCodeBinaryEncoding(TR::InstOpCode::movkw) | ((((displacement >> 16) & 0xFFFF) | TR::MOV_LSL16) << 5);
treg->setRegisterFieldRD(wcursor);
wcursor++;
*wcursor = TR::InstOpCode::getOpCodeBinaryEncoding(TR::InstOpCode::addx) | (TR::EXT_SXTW << 13);
treg->setRegisterFieldRD(wcursor);
treg->setRegisterFieldRM(wcursor);
cursor += ARM64_INSTRUCTION_LENGTH * 3;
}

base->setRegisterFieldRN(wcursor);
}
}

Expand Down Expand Up @@ -953,7 +967,7 @@ uint32_t OMR::ARM64::MemoryReference::estimateBinaryLength(TR::InstOpCode op)
}
else
{
TR_ASSERT_FATAL(false, "Offset is too large for specified instruction.");
return ARM64_INSTRUCTION_LENGTH*3;
}
}
}
Expand Down

0 comments on commit 5649e62

Please sign in to comment.