summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Paulsson <paulsson@linux.vnet.ibm.com>2022-05-19 17:16:49 +0200
committerTom Stellard <tstellar@redhat.com>2022-05-24 10:43:28 -0700
commit42fe7ccbeb444d1e22eac36035758dc17c4aa9c5 (patch)
tree1260d0015e14025306cab39d06c4815a3bd98aa2
parentf45a01e4a170385625d2a46f3b770b0f73a1af85 (diff)
downloadllvm-42fe7ccbeb444d1e22eac36035758dc17c4aa9c5.tar.gz
[SystemZ] Bugfix for symbolic displacements.
Properly handle the case where only the second operand of e.g. an MVC instruction uses a fixup for the displacement. Reviewed By: Ulrich Weigand Differential Revision: https://reviews.llvm.org/D125982 (cherry picked from commit e547b04d5b2c20bb5d14e49a86837c77573b267a)
-rw-r--r--llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp9
-rw-r--r--llvm/test/MC/SystemZ/fixups.s5
2 files changed, 12 insertions, 2 deletions
diff --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
index c83796b8579b..9eb546d1b5dc 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
@@ -37,6 +37,8 @@ class SystemZMCCodeEmitter : public MCCodeEmitter {
const MCInstrInfo &MCII;
MCContext &Ctx;
+ mutable unsigned MemOpsEmitted;
+
public:
SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
: MCII(mcii), Ctx(ctx) {
@@ -165,6 +167,7 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
verifyInstructionPredicates(MI,
computeAvailableFeatures(STI.getFeatureBits()));
+ MemOpsEmitted = 0;
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
unsigned Size = MCII.get(MI.getOpcode()).getSize();
// Big-endian insertion of Size bytes.
@@ -191,12 +194,14 @@ getDispOpValue(const MCInst &MI, unsigned OpNum,
SmallVectorImpl<MCFixup> &Fixups,
SystemZ::FixupKind Kind) const {
const MCOperand &MO = MI.getOperand(OpNum);
- if (MO.isImm())
+ if (MO.isImm()) {
+ ++MemOpsEmitted;
return static_cast<uint64_t>(MO.getImm());
+ }
if (MO.isExpr()) {
// All instructions follow the pattern where the first displacement has a
// 2 bytes offset, and the second one 4 bytes.
- unsigned ByteOffs = Fixups.size() == 0 ? 2 : 4;
+ unsigned ByteOffs = MemOpsEmitted++ == 0 ? 2 : 4;
Fixups.push_back(MCFixup::create(ByteOffs, MO.getExpr(), (MCFixupKind)Kind,
MI.getLoc()));
assert(Fixups.size() <= 2 && "More than two memory operands in MI?");
diff --git a/llvm/test/MC/SystemZ/fixups.s b/llvm/test/MC/SystemZ/fixups.s
index 25202bb82c1c..77c71e3c987b 100644
--- a/llvm/test/MC/SystemZ/fixups.s
+++ b/llvm/test/MC/SystemZ/fixups.s
@@ -287,6 +287,11 @@
.align 16
vgeg %v0, src(%v0,%r1), 0
+## Fixup for second operand only
+# CHECK: mvc 32(8,%r0), src # encoding: [0xd2,0x07,0x00,0x20,0b0000AAAA,A]
+# CHECK-NEXT: # fixup A - offset: 4, value: src, kind: FK_390_12
+ .align 16
+ mvc 32(8,%r0),src
# Data relocs
# llvm-mc does not show any "encoding" string for data, so we just check the relocs