diff options
author | Jonas Paulsson <paulsson@linux.vnet.ibm.com> | 2022-05-19 17:16:49 +0200 |
---|---|---|
committer | Tom Stellard <tstellar@redhat.com> | 2022-05-24 10:43:28 -0700 |
commit | 42fe7ccbeb444d1e22eac36035758dc17c4aa9c5 (patch) | |
tree | 1260d0015e14025306cab39d06c4815a3bd98aa2 | |
parent | f45a01e4a170385625d2a46f3b770b0f73a1af85 (diff) | |
download | llvm-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.cpp | 9 | ||||
-rw-r--r-- | llvm/test/MC/SystemZ/fixups.s | 5 |
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 |