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 @@ -32,6 +32,10 @@ case SystemZ::FK_390_PC32DBL: return (int64_t)Value / 2; + case SystemZ::FK_390_12: + case SystemZ::FK_390_20: + return Value; + case SystemZ::FK_390_TLS_CALL: return 0; } @@ -95,7 +99,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 @@ -136,6 +142,12 @@ Value = extractBitsForFixup(Kind, Value); 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,48 @@ llvm_unreachable("Unexpected operand type!"); } +uint64_t SystemZMCCodeEmitter:: +getDispOpValue(const MCInst &MI, unsigned OpNum, + SmallVectorImpl &Fixups, + SystemZ::FixupKind Kind) const { + const MCInstrDesc &MCID = MCII.get(MI.getOpcode()); + auto isDispOp = [&MCID](unsigned OpIdx) -> bool { + return OpIdx > 0 && + MCID.OpInfo[OpIdx].OperandType == MCOI::OPERAND_MEMORY && + MCID.OpInfo[OpIdx].RegClass == -1 && + MCID.OpInfo[OpIdx - 1].OperandType == MCOI::OPERAND_MEMORY && + MCID.OpInfo[OpIdx - 1].RegClass != -1; + }; + assert(isDispOp(OpNum) && "Expected a displacement op after base reg op."); + + const MCOperand &MO = MI.getOperand(OpNum); + if (MO.isImm()) + return static_cast(MO.getImm()); + if (MO.isExpr()) { + unsigned ByteOffs = 2; + if (MCID.TSFlags & SystemZII::MemMemOp) { + unsigned DisplacementOps[2]; + unsigned D = 0; + for (unsigned Idx = 1, e = MCID.getNumOperands(); Idx != e; ++Idx) + if (isDispOp(Idx)) + DisplacementOps[D++] = Idx; + assert(D == 2 && "Expected exactly two memory operands."); + // The second MemMem displacement starts with a byte offset of 4. + if (OpNum == DisplacementOps[1]) + ByteOffs = 4; + } + Fixups.push_back(MCFixup::create(ByteOffs, MO.getExpr(), (MCFixupKind)Kind)); + 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 +237,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 +247,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 +258,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 +270,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 +281,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 +292,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 +303,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/SystemZInstrFormats.td =================================================================== --- llvm/lib/Target/SystemZ/SystemZInstrFormats.td +++ llvm/lib/Target/SystemZ/SystemZInstrFormats.td @@ -98,6 +98,9 @@ // result against zero, but only if the 'nsw' flag is set. bit CCIfNoSignedWrap = 0; + // True for a mem-mem operation like MVC that has a second memory operand. + bit MemMemOp = 0; + let TSFlags{0} = SimpleBDXLoad; let TSFlags{1} = SimpleBDXStore; let TSFlags{2} = Has20BitOffset; @@ -110,6 +113,7 @@ let TSFlags{19} = CCMaskLast; let TSFlags{20} = IsLogical; let TSFlags{21} = CCIfNoSignedWrap; + let TSFlags{22} = MemMemOp; } //===----------------------------------------------------------------------===// @@ -879,6 +883,7 @@ let Inst{15-0} = RI2; } +let MemMemOp = 1 in { class InstSSa op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<6, outs, ins, asmstr, pattern> { field bits<48> Inst; @@ -998,6 +1003,7 @@ let Inst{31-16} = BD1; let Inst{15-0} = BD2; } +} // MemMemOp class InstS op, dag outs, dag ins, string asmstr, list pattern> : InstSystemZ<4, outs, ins, asmstr, pattern> { 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.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,48 @@ bras %r14, target@plt:tls_ldcall:sym +# Symbolic displacements +# 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: 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: lay %r14, src(%r1,%r2) # encoding: [0xe3,0xe1,0b0010AAAA,A,A,0x71] +# 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 + lay %r14, src(%r1, %r2) + +# 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) + +# 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) + +# 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 + + # 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,24 @@ + +# RUN: llvm-mc -triple s390x-unknown-unknown --show-encoding %s | FileCheck %s + +# RUN: llvm-mc -triple s390x-unknown-unknown -filetype=obj %s | \ +# RUN: llvm-objdump -d - | FileCheck %s -check-prefix=CHECK-REL + + .text + +# CHECK: la %r1, b-a(%r1) # encoding: [0x41,0x10,0b0001AAAA,A] +# CHECK-NEXT: # fixup A - offset: 2, value: b-a, kind: FK_390_12 +# CHECK-REL: 0: 41 10 10 04 la %r1, 4(%r1) + la %r1, b-a(%r1) + +# CHECK: lay %r1, b-a(%r1) # encoding: [0xe3,0x10,0b0001AAAA,A,A,0x71] +# CHECK-NEXT: # fixup A - offset: 2, value: b-a, kind: FK_390_20 +# CHECK-REL: 4: e3 10 10 04 00 71 lay %r1, 4(%r1) + lay %r1, b-a(%r1) + + .type a,@object + .local a + .comm a,4,4 + .type b,@object + .local b + .comm b,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