Skip to content

Commit

Permalink
AArch64: Allow negative immediate offset for memory access
Browse files Browse the repository at this point in the history
This commit rewrites the instruction "ldrimmw" (12-bit unsigned offset)
to "ldur" (9-bit signed offset) when a negative value is used as the
offset.

Signed-off-by: KONNO Kazuhiro <konno@jp.ibm.com>
  • Loading branch information
knn-k committed Dec 3, 2019
1 parent 8093d43 commit d436fa9
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions compiler/aarch64/codegen/OMRMemoryReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,16 @@ uint8_t *OMR::ARM64::MemoryReference::generateBinaryEncoding(TR::Instruction *cu
}
else
{
TR_ASSERT(false, "Offset is too large for specified instruction.");
if (op.getMnemonic() == TR::InstOpCode::ldrimmw && displacement < 0 && constantIsImm9(displacement))
{
*wcursor &= 0xFEFFFFFF; /* rewrite the instruction ldrimmw -> ldurw */
*wcursor |= (displacement & 0x1ff) << 12; /* imm9 */
cursor += ARM64_INSTRUCTION_LENGTH;
}
else
{
TR_ASSERT(false, "Offset is too large for specified instruction.");
}
}
}
else if (isExclusiveMemAccessInstruction(op.getMnemonic()))
Expand Down Expand Up @@ -910,7 +919,14 @@ uint32_t OMR::ARM64::MemoryReference::estimateBinaryLength(TR::InstOpCode op)
}
else
{
TR_ASSERT(false, "Offset is too large for specified instruction.");
if (op.getMnemonic() == TR::InstOpCode::ldrimmw && displacement < 0 && constantIsImm9(displacement))
{
return ARM64_INSTRUCTION_LENGTH;
}
else
{
TR_ASSERT(false, "Offset is too large for specified instruction.");
}
}
}
else if (isExclusiveMemAccessInstruction(op.getMnemonic()))
Expand Down

0 comments on commit d436fa9

Please sign in to comment.