Index: llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp =================================================================== --- llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ 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(Expr)) { int64_t Value = CE->getValue(); return Value >= MinValue && Value <= MaxValue; } - return false; + return AllowSymbol; } namespace { @@ -265,10 +267,10 @@ 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); Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h +++ llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.h @@ -33,8 +33,9 @@ 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, Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp +++ llvm/lib/Target/SystemZ/MCTargetDesc/SystemZInstPrinter.cpp @@ -24,9 +24,9 @@ #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::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::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::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); } Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCAsmBackend.cpp +++ 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 @@ // 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,20 @@ 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; + } + return Value; + case SystemZ::FK_390_TLS_CALL: return 0; } @@ -95,7 +112,9 @@ { "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,9 +152,15 @@ 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; + if (Kind == (MCFixupKind)SystemZ::FK_390_20) { + // The high byte of a 20 bit displacement value comes first. + uint64_t DLo = Value & 0xfff; + uint64_t DHi = (Value >> 12) & 0xff; + Value = (DLo << 8) | DHi; + } unsigned ShiftValue = (Size * 8) - 8; for (unsigned I = 0; I != Size; ++I) { Data[Offset + I] |= uint8_t(Value >> ShiftValue); Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCCodeEmitter.cpp +++ 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 @@ SmallVectorImpl &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 &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 @@ llvm_unreachable("Unexpected operand type!"); } +uint64_t SystemZMCCodeEmitter:: +getDispOpValue(const MCInst &MI, unsigned OpNum, + SmallVectorImpl &Fixups, + SystemZ::FixupKind Kind) const { + const MCOperand &MO = MI.getOperand(OpNum); + if (MO.isImm()) + return static_cast(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 &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 @@ SmallVectorImpl &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 @@ SmallVectorImpl &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 @@ SmallVectorImpl &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 @@ SmallVectorImpl &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 @@ SmallVectorImpl &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 @@ SmallVectorImpl &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 @@ SmallVectorImpl &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; Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h +++ llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCFixups.h @@ -20,6 +20,8 @@ FK_390_PC24DBL, FK_390_PC32DBL, FK_390_TLS_CALL, + FK_390_12, + FK_390_20, // Marker LastTargetFixupKind, Index: llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp =================================================================== --- llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp +++ llvm/lib/Target/SystemZ/MCTargetDesc/SystemZMCObjectWriter.cpp @@ -46,6 +46,8 @@ 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"); } Index: llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp +++ llvm/lib/Target/SystemZ/SystemZAsmPrinter.cpp @@ -775,9 +775,10 @@ 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; } Index: llvm/lib/Target/SystemZ/SystemZInstrInfo.h =================================================================== --- llvm/lib/Target/SystemZ/SystemZInstrInfo.h +++ llvm/lib/Target/SystemZ/SystemZInstrInfo.h @@ -47,7 +47,8 @@ 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) { Index: llvm/test/MC/SystemZ/fixups-out-of-range.s =================================================================== --- /dev/null +++ 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,@object + .local a + .comm a,4096 + .type b,@object + .local b + .comm b,4,4 + + .type c,@object + .local c + .comm c,524288 + .type d,@object + .local d + .comm d,4,4 + Index: llvm/test/MC/SystemZ/fixups.s =================================================================== --- llvm/test/MC/SystemZ/fixups.s +++ 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@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 Index: llvm/test/MC/SystemZ/reloc-absolute.s =================================================================== --- /dev/null +++ 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,@object + .local a + .comm a,4,4 + .type b,@object + .local b + .comm b,8,4 + .type c,@object + .local c + .comm c,4,4 Index: llvm/test/MC/SystemZ/reloc-directive.s =================================================================== --- llvm/test/MC/SystemZ/reloc-directive.s +++ 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