[llvm] 1c3ef9e - [SystemZ] Support symbolic displacements.

Jonas Paulsson via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 15 13:48:00 PST 2021


Author: Jonas Paulsson
Date: 2021-11-15T16:46:31-05:00
New Revision: 1c3ef9ef4a4dc84f36e9282b9cd1c7313a3d4a08

URL: https://github.com/llvm/llvm-project/commit/1c3ef9ef4a4dc84f36e9282b9cd1c7313a3d4a08
DIFF: https://github.com/llvm/llvm-project/commit/1c3ef9ef4a4dc84f36e9282b9cd1c7313a3d4a08.diff

LOG: [SystemZ] Support symbolic displacements.

This patch adds support for symbolic displacements, e.g. like 'lg %r0,
sym(%r1)', which is done using relocations. This is needed to compile the
kernel without disabling the integrated assembler.

Review: Ulrich Weigand

Differential Revision: https://reviews.llvm.org/D113341

Added: 
    llvm/test/MC/SystemZ/fixups-out-of-range.s
    llvm/test/MC/SystemZ/reloc-absolute.s

Modified: 
    llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
    llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp
    llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h
    llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
    llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
    llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h
    llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
    llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
    llvm/lib/Target/SystemZ/SystemZInstrInfo.h
    llvm/test/MC/SystemZ/fixups.s
    llvm/test/MC/SystemZ/reloc-directive.s

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
index 252452eb062f2..40ed417d0817c 100644
--- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
+++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
@@ -40,13 +40,15 @@
 
 using namespace llvm;
 
-// Return true if Expr is in the range [MinValue, MaxValue].
-static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue) {
+// Return true if Expr is in the range [MinValue, MaxValue]. If AllowSymbol
+// is true any MCExpr is accepted (address displacement).
+static bool inRange(const MCExpr *Expr, int64_t MinValue, int64_t MaxValue,
+                    bool AllowSymbol = false) {
   if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
     int64_t Value = CE->getValue();
     return Value >= MinValue && Value <= MaxValue;
   }
-  return false;
+  return AllowSymbol;
 }
 
 namespace {
@@ -265,10 +267,10 @@ class SystemZOperand : public MCParsedAsmOperand {
     return isMem(MemKind) && Mem.RegKind == RegKind;
   }
   bool isMemDisp12(MemoryKind MemKind, RegisterKind RegKind) const {
-    return isMem(MemKind, RegKind) && inRange(Mem.Disp, 0, 0xfff);
+    return isMem(MemKind, RegKind) && inRange(Mem.Disp, 0, 0xfff, true);
   }
   bool isMemDisp20(MemoryKind MemKind, RegisterKind RegKind) const {
-    return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287);
+    return isMem(MemKind, RegKind) && inRange(Mem.Disp, -524288, 524287, true);
   }
   bool isMemDisp12Len4(RegisterKind RegKind) const {
     return isMemDisp12(BDLMem, RegKind) && inRange(Mem.Length.Imm, 1, 0x10);

diff  --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp
index f3f3f096da339..0cb6bfaaebfb8 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp
@@ -24,9 +24,9 @@ using namespace llvm;
 #include "SystemZGenAsmWriter.inc"
 
 void SystemZInstPrinter::printAddress(const MCAsmInfo *MAI, unsigned Base,
-                                      int64_t Disp, unsigned Index,
+                                      const MCOperand &DispMO, unsigned Index,
                                       raw_ostream &O) {
-  O << Disp;
+  printOperand(DispMO, MAI, O);
   if (Base || Index) {
     O << '(';
     if (Index) {
@@ -194,23 +194,23 @@ void SystemZInstPrinter::printOperand(const MCInst *MI, int OpNum,
 
 void SystemZInstPrinter::printBDAddrOperand(const MCInst *MI, int OpNum,
                                             raw_ostream &O) {
-  printAddress(&MAI, MI->getOperand(OpNum).getReg(),
-               MI->getOperand(OpNum + 1).getImm(), 0, O);
+  printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
+               0, O);
 }
 
 void SystemZInstPrinter::printBDXAddrOperand(const MCInst *MI, int OpNum,
                                              raw_ostream &O) {
-  printAddress(&MAI, MI->getOperand(OpNum).getReg(),
-               MI->getOperand(OpNum + 1).getImm(),
+  printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
                MI->getOperand(OpNum + 2).getReg(), O);
 }
 
 void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
                                              raw_ostream &O) {
   unsigned Base = MI->getOperand(OpNum).getReg();
-  uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
+  const MCOperand &DispMO = MI->getOperand(OpNum + 1);
   uint64_t Length = MI->getOperand(OpNum + 2).getImm();
-  O << Disp << '(' << Length;
+  printOperand(DispMO, &MAI, O);
+  O << '(' << Length;
   if (Base) {
     O << ",";
     printRegName(O, Base);
@@ -221,9 +221,10 @@ void SystemZInstPrinter::printBDLAddrOperand(const MCInst *MI, int OpNum,
 void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
                                              raw_ostream &O) {
   unsigned Base = MI->getOperand(OpNum).getReg();
-  uint64_t Disp = MI->getOperand(OpNum + 1).getImm();
+  const MCOperand &DispMO = MI->getOperand(OpNum + 1);
   unsigned Length = MI->getOperand(OpNum + 2).getReg();
-  O << Disp << "(";
+  printOperand(DispMO, &MAI, O);
+  O << "(";
   printRegName(O, Length);
   if (Base) {
     O << ",";
@@ -234,8 +235,7 @@ void SystemZInstPrinter::printBDRAddrOperand(const MCInst *MI, int OpNum,
 
 void SystemZInstPrinter::printBDVAddrOperand(const MCInst *MI, int OpNum,
                                              raw_ostream &O) {
-  printAddress(&MAI, MI->getOperand(OpNum).getReg(),
-               MI->getOperand(OpNum + 1).getImm(),
+  printAddress(&MAI, MI->getOperand(OpNum).getReg(), MI->getOperand(OpNum + 1),
                MI->getOperand(OpNum + 2).getReg(), O);
 }
 

diff  --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h
index 0a57ca0082e61..008bf747e5a18 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h
@@ -33,8 +33,9 @@ class SystemZInstPrinter : public MCInstPrinter {
   static const char *getRegisterName(unsigned RegNo);
 
   // Print an address with the given base, displacement and index.
-  static void printAddress(const MCAsmInfo *MAI, unsigned Base, int64_t Disp,
-                           unsigned Index, raw_ostream &O);
+  static void printAddress(const MCAsmInfo *MAI, unsigned Base,
+                           const MCOperand &DispMO, unsigned Index,
+                           raw_ostream &O);
 
   // Print the given operand.
   static void printOperand(const MCOperand &MO, const MCAsmInfo *MAI,

diff  --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
index 28dad65fdeaae..0f5e0b9672a97 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp
@@ -10,6 +10,8 @@
 #include "MCTargetDesc/SystemZMCTargetDesc.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCELFObjectWriter.h"
 #include "llvm/MC/MCFixupKindInfo.h"
 #include "llvm/MC/MCInst.h"
@@ -21,7 +23,8 @@ using namespace llvm;
 // Value is a fully-resolved relocation value: Symbol + Addend [- Pivot].
 // Return the bits that should be installed in a relocation field for
 // fixup kind Kind.
-static uint64_t extractBitsForFixup(MCFixupKind Kind, uint64_t Value) {
+static uint64_t extractBitsForFixup(MCFixupKind Kind, uint64_t Value,
+                                    const MCFixup &Fixup, MCContext &Ctx) {
   if (Kind < FirstTargetFixupKind)
     return Value;
 
@@ -32,6 +35,24 @@ static uint64_t extractBitsForFixup(MCFixupKind Kind, uint64_t Value) {
   case SystemZ::FK_390_PC32DBL:
     return (int64_t)Value / 2;
 
+  case SystemZ::FK_390_12:
+    if (!isUInt<12>(Value)) {
+      Ctx.reportError(Fixup.getLoc(), "displacement exceeds uint12");
+      return 0;
+    }
+    return Value;
+
+  case SystemZ::FK_390_20: {
+    if (!isInt<20>(Value)) {
+      Ctx.reportError(Fixup.getLoc(), "displacement exceeds int20");
+      return 0;
+    }
+    // The high byte of a 20 bit displacement value comes first.
+    uint64_t DLo = Value & 0xfff;
+    uint64_t DHi = (Value >> 12) & 0xff;
+    return (DLo << 8) | DHi;
+  }
+
   case SystemZ::FK_390_TLS_CALL:
     return 0;
   }
@@ -95,7 +116,9 @@ SystemZMCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
     { "FK_390_PC16DBL",  0, 16, MCFixupKindInfo::FKF_IsPCRel },
     { "FK_390_PC24DBL",  0, 24, MCFixupKindInfo::FKF_IsPCRel },
     { "FK_390_PC32DBL",  0, 32, MCFixupKindInfo::FKF_IsPCRel },
-    { "FK_390_TLS_CALL", 0, 0, 0 }
+    { "FK_390_TLS_CALL", 0, 0, 0 },
+    { "FK_390_12",       4, 12, 0 },
+    { "FK_390_20",       4, 20, 0 }
   };
 
   // Fixup kinds from .reloc directive are like R_390_NONE. They
@@ -133,7 +156,7 @@ void SystemZMCAsmBackend::applyFixup(const MCAssembler &Asm,
   assert(Offset + Size <= Data.size() && "Invalid fixup offset!");
 
   // Big-endian insertion of Size bytes.
-  Value = extractBitsForFixup(Kind, Value);
+  Value = extractBitsForFixup(Kind, Value, Fixup, Asm.getContext());
   if (BitSize < 64)
     Value &= ((uint64_t)1 << BitSize) - 1;
   unsigned ShiftValue = (Size * 8) - 8;

diff  --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
index a5ccf4f68ffdf..e280e4aaf3d82 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp
@@ -12,6 +12,7 @@
 
 #include "MCTargetDesc/SystemZMCFixups.h"
 #include "MCTargetDesc/SystemZMCTargetDesc.h"
+#include "SystemZInstrInfo.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCContext.h"
@@ -60,6 +61,12 @@ class SystemZMCCodeEmitter : public MCCodeEmitter {
                              SmallVectorImpl<MCFixup> &Fixups,
                              const MCSubtargetInfo &STI) const;
 
+  // Return the displacement value for the OpNum operand. If it is a symbol,
+  // add a fixup for it and return 0.
+  uint64_t getDispOpValue(const MCInst &MI, unsigned OpNum,
+                          SmallVectorImpl<MCFixup> &Fixups,
+                          SystemZ::FixupKind Kind) const;
+
   // Called by the TableGen code to get the binary encoding of an address.
   // The index or length, if any, is encoded first, followed by the base,
   // followed by the displacement.  In a 20-bit displacement,
@@ -179,12 +186,30 @@ getMachineOpValue(const MCInst &MI, const MCOperand &MO,
   llvm_unreachable("Unexpected operand type!");
 }
 
+uint64_t SystemZMCCodeEmitter::
+getDispOpValue(const MCInst &MI, unsigned OpNum,
+               SmallVectorImpl<MCFixup> &Fixups,
+               SystemZ::FixupKind Kind) const {
+  const MCOperand &MO = MI.getOperand(OpNum);
+  if (MO.isImm())
+    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;
+    Fixups.push_back(MCFixup::create(ByteOffs, MO.getExpr(), (MCFixupKind)Kind));
+    assert(Fixups.size() <= 2 && "More than two memory operands in MI?");
+    return 0;
+  }
+  llvm_unreachable("Unexpected operand type!");
+}
+
 uint64_t SystemZMCCodeEmitter::
 getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
                     SmallVectorImpl<MCFixup> &Fixups,
                     const MCSubtargetInfo &STI) const {
   uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
-  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+  uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
   assert(isUInt<4>(Base) && isUInt<12>(Disp));
   return (Base << 12) | Disp;
 }
@@ -194,7 +219,7 @@ getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
                     SmallVectorImpl<MCFixup> &Fixups,
                     const MCSubtargetInfo &STI) const {
   uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
-  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+  uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_20);
   assert(isUInt<4>(Base) && isInt<20>(Disp));
   return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12);
 }
@@ -204,7 +229,7 @@ getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
                      SmallVectorImpl<MCFixup> &Fixups,
                      const MCSubtargetInfo &STI) const {
   uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
-  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+  uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
   uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
   assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index));
   return (Index << 16) | (Base << 12) | Disp;
@@ -215,7 +240,7 @@ getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
                      SmallVectorImpl<MCFixup> &Fixups,
                      const MCSubtargetInfo &STI) const {
   uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
-  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+  uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_20);
   uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
   assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index));
   return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8)
@@ -227,7 +252,7 @@ getBDLAddr12Len4Encoding(const MCInst &MI, unsigned OpNum,
                          SmallVectorImpl<MCFixup> &Fixups,
                          const MCSubtargetInfo &STI) const {
   uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
-  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+  uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
   uint64_t Len  = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
   assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
   return (Len << 16) | (Base << 12) | Disp;
@@ -238,7 +263,7 @@ getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
                          SmallVectorImpl<MCFixup> &Fixups,
                          const MCSubtargetInfo &STI) const {
   uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
-  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+  uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
   uint64_t Len  = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
   assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len));
   return (Len << 16) | (Base << 12) | Disp;
@@ -249,7 +274,7 @@ getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
                      SmallVectorImpl<MCFixup> &Fixups,
                      const MCSubtargetInfo &STI) const {
   uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
-  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+  uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
   uint64_t Len  = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
   assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
   return (Len << 16) | (Base << 12) | Disp;
@@ -260,7 +285,7 @@ getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
                      SmallVectorImpl<MCFixup> &Fixups,
                      const MCSubtargetInfo &STI) const {
   uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
-  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
+  uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
   uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
   assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<5>(Index));
   return (Index << 16) | (Base << 12) | Disp;

diff  --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h
index 14f6198183b97..1f62baabb9e7c 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h
@@ -20,6 +20,8 @@ enum FixupKind {
   FK_390_PC24DBL,
   FK_390_PC32DBL,
   FK_390_TLS_CALL,
+  FK_390_12,
+  FK_390_20,
 
   // Marker
   LastTargetFixupKind,

diff  --git a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
index 0b3e7b15df131..c23463ab9bde6 100644
--- a/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
+++ b/llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp
@@ -46,6 +46,8 @@ static unsigned getAbsoluteReloc(unsigned Kind) {
   case FK_Data_2: return ELF::R_390_16;
   case FK_Data_4: return ELF::R_390_32;
   case FK_Data_8: return ELF::R_390_64;
+  case SystemZ::FK_390_12: return ELF::R_390_12;
+  case SystemZ::FK_390_20: return ELF::R_390_20;
   }
   llvm_unreachable("Unsupported absolute address");
 }

diff  --git a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
index 2d09eed85694e..defab665f9249 100644
--- a/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
+++ b/llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp
@@ -775,9 +775,10 @@ bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
                                               unsigned OpNo,
                                               const char *ExtraCode,
                                               raw_ostream &OS) {
-  SystemZInstPrinter::printAddress(MAI, MI->getOperand(OpNo).getReg(),
-                                   MI->getOperand(OpNo + 1).getImm(),
-                                   MI->getOperand(OpNo + 2).getReg(), OS);
+  SystemZInstPrinter::
+    printAddress(MAI, MI->getOperand(OpNo).getReg(),
+                 MCOperand::createImm(MI->getOperand(OpNo + 1).getImm()),
+                 MI->getOperand(OpNo + 2).getReg(), OS);
   return false;
 }
 

diff  --git a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h
index 51943ad342cf8..3b796dea52c45 100644
--- a/llvm/lib/Target/SystemZ/SystemZInstrInfo.h
+++ b/llvm/lib/Target/SystemZ/SystemZInstrInfo.h
@@ -47,7 +47,8 @@ enum {
   CCMaskFirst            = (1 << 18),
   CCMaskLast             = (1 << 19),
   IsLogical              = (1 << 20),
-  CCIfNoSignedWrap       = (1 << 21)
+  CCIfNoSignedWrap       = (1 << 21),
+  MemMemOp               = (1 << 22)
 };
 
 static inline unsigned getAccessSize(unsigned int Flags) {

diff  --git a/llvm/test/MC/SystemZ/fixups-out-of-range.s b/llvm/test/MC/SystemZ/fixups-out-of-range.s
new file mode 100644
index 0000000000000..7715da2e4736d
--- /dev/null
+++ b/llvm/test/MC/SystemZ/fixups-out-of-range.s
@@ -0,0 +1,27 @@
+# RUN: not llvm-mc -triple s390x-unknown-unknown -filetype=obj %s 2>&1 | FileCheck %s
+
+	.text
+
+# CHECK: error: displacement exceeds uint12
+	la    %r1, b-a(%r1)
+
+# CHECK: error: displacement exceeds int20
+        lay   %r1, d-c(%r1)
+
+# CHECK-NOT: error
+        lay   %r1, b-a(%r1)
+
+	.type	a, at object
+	.local	a
+	.comm	a,4096
+	.type	b, at object
+	.local	b
+	.comm	b,4,4
+
+	.type	c, at object
+	.local	c
+	.comm	c,524288
+	.type	d, at object
+	.local	d
+	.comm	d,4,4
+

diff  --git a/llvm/test/MC/SystemZ/fixups.s b/llvm/test/MC/SystemZ/fixups.s
index fc8cf49c0d825..25202bb82c1c5 100644
--- a/llvm/test/MC/SystemZ/fixups.s
+++ b/llvm/test/MC/SystemZ/fixups.s
@@ -1,7 +1,7 @@
 
-# RUN: llvm-mc -triple s390x-unknown-unknown --show-encoding %s | FileCheck %s
+# RUN: llvm-mc -triple s390x-unknown-unknown -mcpu=z13 --show-encoding %s | FileCheck %s
 
-# RUN: llvm-mc -triple s390x-unknown-unknown -filetype=obj %s | \
+# RUN: llvm-mc -triple s390x-unknown-unknown -mcpu=z13 -filetype=obj %s | \
 # RUN: llvm-readobj -r - | FileCheck %s -check-prefix=CHECK-REL
 
 # CHECK: larl %r14, target                      # encoding: [0xc0,0xe0,A,A,A,A]
@@ -79,6 +79,215 @@
 	bras %r14, target at plt:tls_ldcall:sym
 
 
+# Symbolic displacements
+
+## BD12
+# CHECK: vl %v0, src                            # encoding: [0xe7,0x00,0b0000AAAA,A,0x00,0x06]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+        .align 16
+        vl %v0, src
+
+# CHECK: vl %v0, src(%r1)                       # encoding: [0xe7,0x00,0b0001AAAA,A,0x00,0x06]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+        .align 16
+        vl %v0, src(%r1)
+
+# CHECK: .insn vrx,253987186016262,%v0,src(%r1),3  # encoding: [0xe7,0x00,0b0001AAAA,A,0x30,0x06]
+# CHECK-NEXT:                                      # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                       0x{{[0-9A-F]*2}} R_390_12 src 0x0
+        .align 16
+        .insn vrx,0xe70000000006,%v0,src(%r1),3	   # vl
+
+## BD20
+# CHECK: lmg %r6, %r15, src                     # encoding: [0xeb,0x6f,0b0000AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_20
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_20 src 0x0
+	.align 16
+        lmg %r6, %r15, src
+
+# CHECK: lmg %r6, %r15, src(%r1)                # encoding: [0xeb,0x6f,0b0001AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_20
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_20 src 0x0
+	.align 16
+        lmg %r6, %r15, src(%r1)
+
+# CHECK: .insn siy,258385232527441,src(%r15),240  # encoding: [0xeb,0xf0,0b1111AAAA,A,A,0x51]
+# CHECK-NEXT:                                     # fixup A - offset: 2, value: src, kind: FK_390_20
+# CHECK-REL:                                      0x{{[0-9A-F]*2}} R_390_20 src 0x0
+	.align 16
+        .insn siy,0xeb0000000051,src(%r15),240	  # tmy
+
+## BDX12
+# CHECK: la %r14, src                           # encoding: [0x41,0xe0,0b0000AAAA,A]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+        .align 16
+        la %r14, src
+
+# CHECK: la %r14, src(%r1)                      # encoding: [0x41,0xe0,0b0001AAAA,A]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+        .align 16
+        la %r14, src(%r1)
+
+# CHECK: la %r14, src(%r1,%r2)                  # encoding: [0x41,0xe1,0b0010AAAA,A]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+        .align 16
+        la %r14, src(%r1, %r2)
+
+# CHECK: .insn vrx,253987186016262,%v2,src(%r2,%r3),3  # encoding: [0xe7,0x22,0b0011AAAA,A,0x30,0x06]
+# CHECK-NEXT:	                                       # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                           0x{{[0-9A-F]*2}} R_390_12 src 0x0
+        .align 16
+        .insn vrx,0xe70000000006,%v2,src(%r2, %r3),3   # vl
+
+##BDX20
+# CHECK: lg %r14, src                           # encoding: [0xe3,0xe0,0b0000AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_20
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_20 src 0x0
+	.align 16
+	lg %r14, src
+
+# CHECK: lg %r14, src(%r1)                      # encoding: [0xe3,0xe0,0b0001AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_20
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_20 src 0x0
+	.align 16
+	lg %r14, src(%r1)
+
+# CHECK: lg %r14, src(%r1,%r2)                  # encoding: [0xe3,0xe1,0b0010AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_20
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_20 src 0x0
+	.align 16
+	lg %r14, src(%r1, %r2)
+
+# CHECK:  .insn rxy,260584255783013,%f1,src(%r2,%r15)  # encoding: [0xed,0x12,0b1111AAAA,A,A,0x65]
+# CHECK-NEXT:                                          # fixup A - offset: 2, value: src, kind: FK_390_20
+# CHECK-REL:                                           0x{{[0-9A-F]*2}} R_390_20 src 0x0
+	.align 16
+	.insn rxy,0xed0000000065,%f1,src(%r2,%r15)     # ldy
+
+##BD12L4
+# CHECK: tp src(16)                             # encoding: [0xeb,0xf0,0b0000AAAA,A,0x00,0xc0]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+	.align 16
+        tp src(16)
+
+# CHECK: tp src(16,%r1)                         # encoding: [0xeb,0xf0,0b0001AAAA,A,0x00,0xc0]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+	.align 16
+        tp src(16, %r1)
+
+##BD12L8
+#SSa
+# CHECK: mvc dst(1,%r1), src(%r1)               # encoding: [0xd2,0x00,0b0001AAAA,A,0b0001BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: dst, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 dst 0x0
+# CHECK-REL:                                    0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+        mvc dst(1,%r1), src(%r1)
+
+#SSb
+# CHECK: mvo src(16,%r1), src(1,%r2)            # encoding: [0xf1,0xf0,0b0001AAAA,A,0b0010BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+# CHECK-REL:                                    0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+        mvo src(16,%r1), src(1,%r2)
+
+#SSc
+# CHECK: srp src(1,%r1), src(%r15), 0           # encoding: [0xf0,0x00,0b0001AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+# CHECK-REL:                                    0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+        srp src(1,%r1), src(%r15), 0
+
+##BDR12
+#SSd
+# CHECK: mvck dst(%r2,%r1), src, %r3            # encoding: [0xd9,0x23,0b0001AAAA,A,0b0000BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: dst, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 dst 0x0
+# CHECK-REL:                                    0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+	mvck dst(%r2,%r1), src, %r3
+
+# CHECK: .insn ss,238594023227392,dst(%r2,%r1),src,%r3  # encoding: [0xd9,0x23,0b0001AAAA,A,0b0000BBBB,B]
+# CHECK-NEXT:                                           # fixup A - offset: 2, value: dst, kind: FK_390_12
+# CHECK-NEXT:                                           # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                            0x{{[0-9A-F]*2}} R_390_12 dst 0x0
+# CHECK-REL:                                            0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+        .insn ss,0xd90000000000,dst(%r2,%r1),src,%r3	# mvck
+
+#SSe
+# CHECK: lmd %r2, %r4, src1(%r1), src2(%r1)     # encoding: [0xef,0x24,0b0001AAAA,A,0b0001BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src1, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: src2, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src1 0x0
+# CHECK-REL:                                    0x{{[0-9A-F]*4}} R_390_12 src2 0x0
+        .align 16
+        lmd %r2, %r4, src1(%r1), src2(%r1)
+
+#SSf
+# CHECK: pka dst(%r15), src(256,%r15)           # encoding: [0xe9,0xff,0b1111AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: dst, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 dst 0x0
+# CHECK-REL:                                    0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+	pka     dst(%r15), src(256,%r15)
+
+#SSE
+# CHECK: strag dst(%r1), src(%r15)              # encoding: [0xe5,0x02,0b0001AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: dst, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 dst 0x0
+# CHECK-REL:                                    0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+        strag dst(%r1), src(%r15)
+
+# CHECK: .insn sse,251796752695296,dst(%r1),src(%r15)  # encoding: [0xe5,0x02,0b0001AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                          # fixup A - offset: 2, value: dst, kind: FK_390_12
+# CHECK-NEXT:                                          # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                           0x{{[0-9A-F]*2}} R_390_12 dst 0x0
+# CHECK-REL:                                           0x{{[0-9A-F]*4}} R_390_12 src 0x0
+	.align 16
+	.insn sse,0xe50200000000,dst(%r1),src(%r15)    # strag
+
+#SSF
+# CHECK: ectg src, src(%r15), %r2               # encoding: [0xc8,0x21,0b0000AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+# CHECK-REL:                                    0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+        ectg src, src(%r15), %r2
+
+# CHECK: .insn ssf,219906620522496,src,src(%r15),%r2   # encoding: [0xc8,0x21,0b0000AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                          # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-NEXT:                                          # fixup B - offset: 4, value: src, kind: FK_390_12
+# CHECK-REL:                                           0x{{[0-9A-F]*2}} R_390_12 src 0x0
+# CHECK-REL:                                           0x{{[0-9A-F]*4}} R_390_12 src 0x0
+        .align 16
+        .insn ssf,0xc80100000000,src,src(%r15),%r2     # ectg
+
+##BDV12
+# CHECK: vgeg %v0, src(%v0,%r1), 0              # encoding: [0xe7,0x00,0b0001AAAA,A,0x00,0x12]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: src, kind: FK_390_12
+# CHECK-REL:                                    0x{{[0-9A-F]*2}} R_390_12 src 0x0
+        .align 16
+        vgeg %v0, src(%v0,%r1), 0
+
+
 # Data relocs
 # llvm-mc does not show any "encoding" string for data, so we just check the relocs
 

diff  --git a/llvm/test/MC/SystemZ/reloc-absolute.s b/llvm/test/MC/SystemZ/reloc-absolute.s
new file mode 100644
index 0000000000000..8b08af013e3d6
--- /dev/null
+++ b/llvm/test/MC/SystemZ/reloc-absolute.s
@@ -0,0 +1,213 @@
+# RUN: llvm-mc -triple s390x-unknown-unknown -mcpu=z13 --show-encoding %s | FileCheck %s
+
+# RUN: llvm-mc -triple s390x-unknown-unknown -filetype=obj -mcpu=z13 %s | \
+# RUN: llvm-objdump -d - --mcpu=z13 | FileCheck %s -check-prefix=CHECK-REL
+
+# Test relocations that can be lowered by the integrated assembler.
+
+	.text
+
+## BD12
+# CHECK: vl %v0, b-a                            # encoding: [0xe7,0x00,0b0000AAAA,A,0x00,0x06]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    e7 00 00 04 00 06    	vl	%v0, 4
+        .align 16
+        vl %v0, b-a
+
+# CHECK: vl %v0, b-a(%r1)                       # encoding: [0xe7,0x00,0b0001AAAA,A,0x00,0x06]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    e7 00 10 04 00 06    	vl	%v0, 4(%r1)
+        .align 16
+        vl %v0, b-a(%r1)
+
+# CHECK: .insn vrx,253987186016262,%v0,b-a(%r1),3  # encoding: [0xe7,0x00,0b0001AAAA,A,0x30,0x06]
+# CHECK-NEXT:                                      # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                       e7 00 10 04 30 06   	vl	%v0, 4(%r1), 3
+        .align 16
+        .insn vrx,0xe70000000006,%v0,b-a(%r1),3	   # vl
+
+## BD20
+# CHECK: lmg %r6, %r15, b-a                     # encoding: [0xeb,0x6f,0b0000AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_20
+# CHECK-REL:                                    eb 6f 00 04 00 04    	lmg	%r6, %r15, 4
+	.align 16
+        lmg %r6, %r15, b-a
+
+# CHECK: lmg %r6, %r15, b-a(%r1)                # encoding: [0xeb,0x6f,0b0001AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_20
+# CHECK-REL:                                    eb 6f 10 04 00 04    	lmg	%r6, %r15, 4(%r1)
+	.align 16
+        lmg %r6, %r15, b-a(%r1)
+
+# CHECK: .insn siy,258385232527441,b-a(%r15),240  # encoding: [0xeb,0xf0,0b1111AAAA,A,A,0x51]
+# CHECK-NEXT:                                     # fixup A - offset: 2, value: b-a, kind: FK_390_20
+# CHECK-REL:                                      eb f0 f0 04 00 51    	tmy	4(%r15), 240
+	.align 16
+        .insn siy,0xeb0000000051,b-a(%r15),240	  # tmy
+
+## BDX12
+# CHECK: la %r14, b-a                           # encoding: [0x41,0xe0,0b0000AAAA,A]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    41 e0 00 04  	la	%r14, 4
+        .align 16
+        la %r14, b-a
+
+# CHECK: la %r14, b-a(%r1)                      # encoding: [0x41,0xe0,0b0001AAAA,A]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    41 e0 10 04  	la	%r14, 4(%r1)
+        .align 16
+        la %r14, b-a(%r1)
+
+# CHECK: la %r14, b-a(%r1,%r2)                  # encoding: [0x41,0xe1,0b0010AAAA,A]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    41 e1 20 04  	la	%r14, 4(%r1,%r2)
+        .align 16
+        la %r14, b-a(%r1, %r2)
+
+# CHECK: .insn vrx,253987186016262,%v2,b-a(%r2,%r3),3  # encoding: [0xe7,0x22,0b0011AAAA,A,0x30,0x06]
+# CHECK-NEXT:	                                       # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                           e7 22 30 04 30 06    	vl	%v2, 4(%r2,%r3), 3
+        .align 16
+        .insn vrx,0xe70000000006,%v2,b-a(%r2, %r3),3   # vl
+
+##BDX20
+# CHECK: lg %r14, b-a                           # encoding: [0xe3,0xe0,0b0000AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_20
+# CHECK-REL:                                    e3 e0 00 04 00 04    	lg	%r14, 4
+	.align 16
+	lg %r14, b-a
+
+# CHECK: lg %r14, b-a(%r1)                      # encoding: [0xe3,0xe0,0b0001AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_20
+# CHECK-REL:                                    e3 e0 10 04 00 04    	lg	%r14, 4(%r1)
+	.align 16
+	lg %r14, b-a(%r1)
+
+# CHECK: lg %r14, b-a(%r1,%r2)                  # encoding: [0xe3,0xe1,0b0010AAAA,A,A,0x04]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_20
+# CHECK-REL:                                    e3 e1 20 04 00 04    	lg	%r14, 4(%r1,%r2)
+	.align 16
+	lg %r14, b-a(%r1, %r2)
+
+# CHECK:  .insn rxy,260584255783013,%f1,b-a(%r2,%r15)  # encoding: [0xed,0x12,0b1111AAAA,A,A,0x65]
+# CHECK-NEXT:                                          # fixup A - offset: 2, value: b-a, kind: FK_390_20
+# CHECK-REL:                                           ed 12 f0 04 00 65   	ldy	%f1, 4(%r2,%r15)
+	.align 16
+	.insn rxy,0xed0000000065,%f1,b-a(%r2,%r15)     # ldy
+
+##BD12L4
+# CHECK: tp b-a(16)                             # encoding: [0xeb,0xf0,0b0000AAAA,A,0x00,0xc0]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    eb f0 00 04 00 c0    	tp	4(16)
+	.align 16
+        tp b-a(16)
+
+# CHECK: tp b-a(16,%r1)                         # encoding: [0xeb,0xf0,0b0001AAAA,A,0x00,0xc0]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    eb f0 10 04 00 c0    	tp	4(16,%r1)
+	.align 16
+        tp b-a(16, %r1)
+
+##BD12L8
+#SSa
+# CHECK: mvc c-b(1,%r1), b-a(%r1)               # encoding: [0xd2,0x00,0b0001AAAA,A,0b0001BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: c-b, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    d2 00 10 08 10 04    	mvc	8(1,%r1), 4(%r1)
+        .align 16
+        mvc c-b(1,%r1), b-a(%r1)
+
+#SSb
+# CHECK: mvo c-b(16,%r1), b-a(1,%r2)            # encoding: [0xf1,0xf0,0b0001AAAA,A,0b0010BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: c-b, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    f1 f0 10 08 20 04    	mvo	8(16,%r1), 4(1,%r2)
+        .align 16
+        mvo c-b(16,%r1), b-a(1,%r2)
+
+#SSc
+# CHECK: srp b-a(1,%r1), b-a(%r15), 0           # encoding: [0xf0,0x00,0b0001AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    f0 00 10 04 f0 04    	srp	4(1,%r1), 4(%r15), 0
+        .align 16
+        srp b-a(1,%r1), b-a(%r15), 0
+
+##BDR12
+#SSd
+# CHECK: mvck c-b(%r2,%r1), b-a, %r3            # encoding: [0xd9,0x23,0b0001AAAA,A,0b0000BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: c-b, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    d9 23 10 08 00 04    	mvck	8(%r2,%r1), 4, %r3
+        .align 16
+	mvck c-b(%r2,%r1), b-a, %r3
+
+# CHECK: .insn ss,238594023227392,c-b(%r2,%r1),b-a,%r3  # encoding: [0xd9,0x23,0b0001AAAA,A,0b0000BBBB,B]
+# CHECK-NEXT:                                           # fixup A - offset: 2, value: c-b, kind: FK_390_12
+# CHECK-NEXT:                                           # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                            d9 23 10 08 00 04    	mvck	8(%r2,%r1), 4, %r3
+        .align 16
+        .insn ss,0xd90000000000,c-b(%r2,%r1),b-a,%r3	# mvck
+
+#SSe
+# CHECK: lmd %r2, %r4, b-a(%r1), c-b(%r1)       # encoding: [0xef,0x24,0b0001AAAA,A,0b0001BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: c-b, kind: FK_390_12
+# CHECK-REL:                                    ef 24 10 04 10 08    	lmd	%r2, %r4, 4(%r1), 8(%r1)
+        .align 16
+        lmd %r2, %r4, b-a(%r1), c-b(%r1)
+
+#SSf
+# CHECK: pka c-b(%r15), b-a(256,%r15)           # encoding: [0xe9,0xff,0b1111AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: c-b, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    e9 ff f0 08 f0 04    	pka	8(%r15), 4(256,%r15)
+        .align 16
+	pka     c-b(%r15), b-a(256,%r15)
+
+#SSE
+# CHECK: strag c-b(%r1), b-a(%r15)              # encoding: [0xe5,0x02,0b0001AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: c-b, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    e5 02 10 08 f0 04    	strag	8(%r1), 4(%r15)
+        .align 16
+        strag c-b(%r1), b-a(%r15)
+
+# CHECK: .insn sse,251796752695296,c-b(%r1),b-a(%r15)  # encoding: [0xe5,0x02,0b0001AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                          # fixup A - offset: 2, value: c-b, kind: FK_390_12
+# CHECK-NEXT:                                          # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                           e5 02 10 08 f0 04    	strag	8(%r1), 4(%r15)
+	.align 16
+	.insn sse,0xe50200000000,c-b(%r1),b-a(%r15)    # strag
+
+#SSF
+# CHECK: ectg b-a, b-a(%r15), %r2               # encoding: [0xc8,0x21,0b0000AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-NEXT:                                   # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    c8 21 00 04 f0 04    	ectg	4, 4(%r15), %r2
+        .align 16
+        ectg b-a, b-a(%r15), %r2
+
+# CHECK: .insn ssf,219906620522496,b-a,b-a(%r15),%r2   # encoding: [0xc8,0x21,0b0000AAAA,A,0b1111BBBB,B]
+# CHECK-NEXT:                                          # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-NEXT:                                          # fixup B - offset: 4, value: b-a, kind: FK_390_12
+# CHECK-REL:                                           c8 21 00 04 f0 04    	ectg	4, 4(%r15), %r2
+        .align 16
+        .insn ssf,0xc80100000000,b-a,b-a(%r15),%r2     # ectg
+
+##BDV12
+# CHECK: vgeg %v0, b-a(%v0,%r1), 0              # encoding: [0xe7,0x00,0b0001AAAA,A,0x00,0x12]
+# CHECK-NEXT:                                   # fixup A - offset: 2, value: b-a, kind: FK_390_12
+# CHECK-REL:                                    e7 00 10 04 00 12    	vgeg	%v0, 4(%v0,%r1), 0
+        .align 16
+        vgeg %v0, b-a(%v0,%r1), 0
+
+	.type	a, at object
+	.local	a
+	.comm	a,4,4
+	.type	b, at object
+	.local	b
+	.comm	b,8,4
+	.type	c, at object
+	.local	c
+	.comm	c,4,4

diff  --git a/llvm/test/MC/SystemZ/reloc-directive.s b/llvm/test/MC/SystemZ/reloc-directive.s
index 7a4b6daaa249f..abc6ca320642d 100644
--- a/llvm/test/MC/SystemZ/reloc-directive.s
+++ b/llvm/test/MC/SystemZ/reloc-directive.s
@@ -9,6 +9,8 @@
 # PRINT-NEXT: .reloc 0, R_390_64, .data+2
 # PRINT-NEXT: .reloc 0, R_390_GOTENT, foo+3
 # PRINT-NEXT: .reloc 0, R_390_PC32DBL, 6
+# PRINT-NEXT: .reloc 4, R_390_12, foo
+# PRINT-NEXT: .reloc 2, R_390_20, foo
 # PRINT:      .reloc 0, BFD_RELOC_NONE, 9
 # PRINT-NEXT: .reloc 0, BFD_RELOC_8, 9
 # PRINT-NEXT: .reloc 0, BFD_RELOC_16, 9
@@ -21,6 +23,8 @@
 # CHECK-NEXT: 0x0 R_390_64 .data 0x2
 # CHECK-NEXT: 0x0 R_390_GOTENT foo 0x3
 # CHECK-NEXT: 0x0 R_390_PC32DBL - 0x6
+# CHECK-NEXT: 0x4 R_390_12 foo 0x0
+# CHECK-NEXT: 0x2 R_390_20 foo 0x0
 # CHECK-NEXT: 0x0 R_390_NONE - 0x9
 # CHECK-NEXT: 0x0 R_390_8 - 0x9
 # CHECK-NEXT: 0x0 R_390_16 - 0x9
@@ -37,6 +41,8 @@
   .reloc 0, R_390_64, .data+2
   .reloc 0, R_390_GOTENT, foo+3
   .reloc 0, R_390_PC32DBL, 6
+  .reloc 4, R_390_12, foo
+  .reloc 2, R_390_20, foo
 
   .reloc 0, BFD_RELOC_NONE, 9
   .reloc 0, BFD_RELOC_8, 9


        


More information about the llvm-commits mailing list