Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 1 | //===-- SystemZMCCodeEmitter.cpp - Convert SystemZ code to machine code ---===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file implements the SystemZMCCodeEmitter class. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 14 | #include "MCTargetDesc/SystemZMCTargetDesc.h" |
| 15 | #include "MCTargetDesc/SystemZMCFixups.h" |
| 16 | #include "llvm/MC/MCCodeEmitter.h" |
| 17 | #include "llvm/MC/MCContext.h" |
| 18 | #include "llvm/MC/MCExpr.h" |
Pete Cooper | 3de83e4 | 2015-05-15 21:58:42 +0000 | [diff] [blame] | 19 | #include "llvm/MC/MCInst.h" |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 20 | #include "llvm/MC/MCInstrInfo.h" |
Pete Cooper | 3de83e4 | 2015-05-15 21:58:42 +0000 | [diff] [blame] | 21 | #include "llvm/MC/MCRegisterInfo.h" |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 22 | |
| 23 | using namespace llvm; |
| 24 | |
Chandler Carruth | 84e68b2 | 2014-04-22 02:41:26 +0000 | [diff] [blame] | 25 | #define DEBUG_TYPE "mccodeemitter" |
| 26 | |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 27 | namespace { |
| 28 | class SystemZMCCodeEmitter : public MCCodeEmitter { |
| 29 | const MCInstrInfo &MCII; |
| 30 | MCContext &Ctx; |
| 31 | |
| 32 | public: |
| 33 | SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) |
| 34 | : MCII(mcii), Ctx(ctx) { |
| 35 | } |
| 36 | |
Alexander Kornienko | f817c1c | 2015-04-11 02:11:45 +0000 | [diff] [blame] | 37 | ~SystemZMCCodeEmitter() override {} |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 38 | |
| 39 | // OVerride MCCodeEmitter. |
Jim Grosbach | 91df21f | 2015-05-15 19:13:16 +0000 | [diff] [blame] | 40 | void encodeInstruction(const MCInst &MI, raw_ostream &OS, |
Richard Sandiford | b4d67b5 | 2014-03-06 12:03:36 +0000 | [diff] [blame] | 41 | SmallVectorImpl<MCFixup> &Fixups, |
| 42 | const MCSubtargetInfo &STI) const override; |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 43 | |
| 44 | private: |
| 45 | // Automatically generated by TableGen. |
| 46 | uint64_t getBinaryCodeForInstr(const MCInst &MI, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 47 | SmallVectorImpl<MCFixup> &Fixups, |
| 48 | const MCSubtargetInfo &STI) const; |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 49 | |
| 50 | // Called by the TableGen code to get the binary encoding of operand |
| 51 | // MO in MI. Fixups is the list of fixups against MI. |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 52 | uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 53 | SmallVectorImpl<MCFixup> &Fixups, |
| 54 | const MCSubtargetInfo &STI) const; |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 55 | |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 56 | // Called by the TableGen code to get the binary encoding of an address. |
Richard Sandiford | 1d95900 | 2013-07-02 14:56:45 +0000 | [diff] [blame] | 57 | // The index or length, if any, is encoded first, followed by the base, |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 58 | // followed by the displacement. In a 20-bit displacement, |
| 59 | // the low 12 bits are encoded before the high 8 bits. |
| 60 | uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 61 | SmallVectorImpl<MCFixup> &Fixups, |
| 62 | const MCSubtargetInfo &STI) const; |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 63 | uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 64 | SmallVectorImpl<MCFixup> &Fixups, |
| 65 | const MCSubtargetInfo &STI) const; |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 66 | uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 67 | SmallVectorImpl<MCFixup> &Fixups, |
| 68 | const MCSubtargetInfo &STI) const; |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 69 | uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 70 | SmallVectorImpl<MCFixup> &Fixups, |
| 71 | const MCSubtargetInfo &STI) const; |
Richard Sandiford | 1d95900 | 2013-07-02 14:56:45 +0000 | [diff] [blame] | 72 | uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 73 | SmallVectorImpl<MCFixup> &Fixups, |
| 74 | const MCSubtargetInfo &STI) const; |
Ulrich Weigand | ec5d779 | 2016-10-31 14:21:36 +0000 | [diff] [blame] | 75 | uint64_t getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum, |
| 76 | SmallVectorImpl<MCFixup> &Fixups, |
| 77 | const MCSubtargetInfo &STI) const; |
Ulrich Weigand | a8b04e1 | 2015-05-05 19:23:40 +0000 | [diff] [blame] | 78 | uint64_t getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum, |
| 79 | SmallVectorImpl<MCFixup> &Fixups, |
| 80 | const MCSubtargetInfo &STI) const; |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 81 | |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 82 | // Operand OpNum of MI needs a PC-relative fixup of kind Kind at |
| 83 | // Offset bytes from the start of MI. Add the fixup to Fixups |
| 84 | // and return the in-place addend, which since we're a RELA target |
Ulrich Weigand | 7bdd7c2 | 2015-02-18 09:11:36 +0000 | [diff] [blame] | 85 | // is always 0. If AllowTLS is true and optional operand OpNum + 1 |
| 86 | // is present, also emit a TLS call fixup for it. |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 87 | uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum, |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 88 | SmallVectorImpl<MCFixup> &Fixups, |
Ulrich Weigand | 7bdd7c2 | 2015-02-18 09:11:36 +0000 | [diff] [blame] | 89 | unsigned Kind, int64_t Offset, |
| 90 | bool AllowTLS) const; |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 91 | |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 92 | uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 93 | SmallVectorImpl<MCFixup> &Fixups, |
| 94 | const MCSubtargetInfo &STI) const { |
Ulrich Weigand | 7bdd7c2 | 2015-02-18 09:11:36 +0000 | [diff] [blame] | 95 | return getPCRelEncoding(MI, OpNum, Fixups, |
| 96 | SystemZ::FK_390_PC16DBL, 2, false); |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 97 | } |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 98 | uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 99 | SmallVectorImpl<MCFixup> &Fixups, |
| 100 | const MCSubtargetInfo &STI) const { |
Ulrich Weigand | 7bdd7c2 | 2015-02-18 09:11:36 +0000 | [diff] [blame] | 101 | return getPCRelEncoding(MI, OpNum, Fixups, |
| 102 | SystemZ::FK_390_PC32DBL, 2, false); |
| 103 | } |
| 104 | uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum, |
| 105 | SmallVectorImpl<MCFixup> &Fixups, |
| 106 | const MCSubtargetInfo &STI) const { |
| 107 | return getPCRelEncoding(MI, OpNum, Fixups, |
| 108 | SystemZ::FK_390_PC16DBL, 2, true); |
| 109 | } |
| 110 | uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum, |
| 111 | SmallVectorImpl<MCFixup> &Fixups, |
| 112 | const MCSubtargetInfo &STI) const { |
| 113 | return getPCRelEncoding(MI, OpNum, Fixups, |
| 114 | SystemZ::FK_390_PC32DBL, 2, true); |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 115 | } |
Ulrich Weigand | 84404f3 | 2016-11-28 14:01:51 +0000 | [diff] [blame] | 116 | uint64_t getPC12DBLBPPEncoding(const MCInst &MI, unsigned OpNum, |
| 117 | SmallVectorImpl<MCFixup> &Fixups, |
| 118 | const MCSubtargetInfo &STI) const { |
| 119 | return getPCRelEncoding(MI, OpNum, Fixups, |
| 120 | SystemZ::FK_390_PC12DBL, 1, false); |
| 121 | } |
| 122 | uint64_t getPC16DBLBPPEncoding(const MCInst &MI, unsigned OpNum, |
| 123 | SmallVectorImpl<MCFixup> &Fixups, |
| 124 | const MCSubtargetInfo &STI) const { |
| 125 | return getPCRelEncoding(MI, OpNum, Fixups, |
| 126 | SystemZ::FK_390_PC16DBL, 4, false); |
| 127 | } |
| 128 | uint64_t getPC24DBLBPPEncoding(const MCInst &MI, unsigned OpNum, |
| 129 | SmallVectorImpl<MCFixup> &Fixups, |
| 130 | const MCSubtargetInfo &STI) const { |
| 131 | return getPCRelEncoding(MI, OpNum, Fixups, |
| 132 | SystemZ::FK_390_PC24DBL, 3, false); |
| 133 | } |
Daniel Sanders | 72db2a3 | 2016-11-19 13:05:44 +0000 | [diff] [blame] | 134 | |
| 135 | private: |
| 136 | uint64_t computeAvailableFeatures(const FeatureBitset &FB) const; |
| 137 | void verifyInstructionPredicates(const MCInst &MI, |
| 138 | uint64_t AvailableFeatures) const; |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 139 | }; |
Richard Sandiford | c231269 | 2014-03-06 10:38:30 +0000 | [diff] [blame] | 140 | } // end anonymous namespace |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 141 | |
| 142 | MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII, |
| 143 | const MCRegisterInfo &MRI, |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 144 | MCContext &Ctx) { |
| 145 | return new SystemZMCCodeEmitter(MCII, Ctx); |
| 146 | } |
| 147 | |
| 148 | void SystemZMCCodeEmitter:: |
Jim Grosbach | 91df21f | 2015-05-15 19:13:16 +0000 | [diff] [blame] | 149 | encodeInstruction(const MCInst &MI, raw_ostream &OS, |
David Woodhouse | 9784cef | 2014-01-28 23:13:07 +0000 | [diff] [blame] | 150 | SmallVectorImpl<MCFixup> &Fixups, |
| 151 | const MCSubtargetInfo &STI) const { |
Daniel Sanders | 72db2a3 | 2016-11-19 13:05:44 +0000 | [diff] [blame] | 152 | verifyInstructionPredicates(MI, |
| 153 | computeAvailableFeatures(STI.getFeatureBits())); |
| 154 | |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 155 | uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI); |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 156 | unsigned Size = MCII.get(MI.getOpcode()).getSize(); |
| 157 | // Big-endian insertion of Size bytes. |
| 158 | unsigned ShiftValue = (Size * 8) - 8; |
| 159 | for (unsigned I = 0; I != Size; ++I) { |
| 160 | OS << uint8_t(Bits >> ShiftValue); |
| 161 | ShiftValue -= 8; |
| 162 | } |
| 163 | } |
| 164 | |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 165 | uint64_t SystemZMCCodeEmitter:: |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 166 | getMachineOpValue(const MCInst &MI, const MCOperand &MO, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 167 | SmallVectorImpl<MCFixup> &Fixups, |
| 168 | const MCSubtargetInfo &STI) const { |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 169 | if (MO.isReg()) |
Bill Wendling | bc07a89 | 2013-06-18 07:20:20 +0000 | [diff] [blame] | 170 | return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 171 | if (MO.isImm()) |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 172 | return static_cast<uint64_t>(MO.getImm()); |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 173 | llvm_unreachable("Unexpected operand type!"); |
| 174 | } |
| 175 | |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 176 | uint64_t SystemZMCCodeEmitter:: |
| 177 | getBDAddr12Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 178 | SmallVectorImpl<MCFixup> &Fixups, |
| 179 | const MCSubtargetInfo &STI) const { |
| 180 | uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI); |
| 181 | uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI); |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 182 | assert(isUInt<4>(Base) && isUInt<12>(Disp)); |
| 183 | return (Base << 12) | Disp; |
| 184 | } |
| 185 | |
| 186 | uint64_t SystemZMCCodeEmitter:: |
| 187 | getBDAddr20Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 188 | SmallVectorImpl<MCFixup> &Fixups, |
| 189 | const MCSubtargetInfo &STI) const { |
| 190 | uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI); |
| 191 | uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI); |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 192 | assert(isUInt<4>(Base) && isInt<20>(Disp)); |
| 193 | return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12); |
| 194 | } |
| 195 | |
| 196 | uint64_t SystemZMCCodeEmitter:: |
| 197 | getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 198 | SmallVectorImpl<MCFixup> &Fixups, |
| 199 | const MCSubtargetInfo &STI) const { |
| 200 | uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI); |
| 201 | uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI); |
| 202 | uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI); |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 203 | assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index)); |
| 204 | return (Index << 16) | (Base << 12) | Disp; |
| 205 | } |
| 206 | |
| 207 | uint64_t SystemZMCCodeEmitter:: |
| 208 | getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 209 | SmallVectorImpl<MCFixup> &Fixups, |
| 210 | const MCSubtargetInfo &STI) const { |
| 211 | uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI); |
| 212 | uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI); |
| 213 | uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI); |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 214 | assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index)); |
| 215 | return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8) |
| 216 | | ((Disp & 0xff000) >> 12); |
| 217 | } |
| 218 | |
Richard Sandiford | 1d95900 | 2013-07-02 14:56:45 +0000 | [diff] [blame] | 219 | uint64_t SystemZMCCodeEmitter:: |
| 220 | getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum, |
David Woodhouse | 3fa98a6 | 2014-01-28 23:13:18 +0000 | [diff] [blame] | 221 | SmallVectorImpl<MCFixup> &Fixups, |
| 222 | const MCSubtargetInfo &STI) const { |
| 223 | uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI); |
| 224 | uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI); |
| 225 | uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1; |
Richard Sandiford | 1d95900 | 2013-07-02 14:56:45 +0000 | [diff] [blame] | 226 | assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len)); |
| 227 | return (Len << 16) | (Base << 12) | Disp; |
| 228 | } |
| 229 | |
Ulrich Weigand | a8b04e1 | 2015-05-05 19:23:40 +0000 | [diff] [blame] | 230 | uint64_t SystemZMCCodeEmitter:: |
Ulrich Weigand | ec5d779 | 2016-10-31 14:21:36 +0000 | [diff] [blame] | 231 | getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum, |
| 232 | SmallVectorImpl<MCFixup> &Fixups, |
| 233 | const MCSubtargetInfo &STI) const { |
| 234 | uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI); |
| 235 | uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI); |
| 236 | uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI); |
| 237 | assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len)); |
| 238 | return (Len << 16) | (Base << 12) | Disp; |
| 239 | } |
| 240 | |
| 241 | uint64_t SystemZMCCodeEmitter:: |
Ulrich Weigand | a8b04e1 | 2015-05-05 19:23:40 +0000 | [diff] [blame] | 242 | getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum, |
| 243 | SmallVectorImpl<MCFixup> &Fixups, |
| 244 | const MCSubtargetInfo &STI) const { |
| 245 | uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI); |
| 246 | uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI); |
| 247 | uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI); |
| 248 | assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<5>(Index)); |
| 249 | return (Index << 16) | (Base << 12) | Disp; |
| 250 | } |
| 251 | |
Richard Sandiford | d454ec0 | 2013-05-14 09:28:21 +0000 | [diff] [blame] | 252 | uint64_t |
| 253 | SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum, |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 254 | SmallVectorImpl<MCFixup> &Fixups, |
Ulrich Weigand | 7bdd7c2 | 2015-02-18 09:11:36 +0000 | [diff] [blame] | 255 | unsigned Kind, int64_t Offset, |
| 256 | bool AllowTLS) const { |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 257 | const MCOperand &MO = MI.getOperand(OpNum); |
Richard Sandiford | 1fb5883 | 2013-05-14 09:47:26 +0000 | [diff] [blame] | 258 | const MCExpr *Expr; |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 259 | if (MO.isImm()) |
Jim Grosbach | 13760bd | 2015-05-30 01:25:56 +0000 | [diff] [blame] | 260 | Expr = MCConstantExpr::create(MO.getImm() + Offset, Ctx); |
Richard Sandiford | 1fb5883 | 2013-05-14 09:47:26 +0000 | [diff] [blame] | 261 | else { |
| 262 | Expr = MO.getExpr(); |
| 263 | if (Offset) { |
| 264 | // The operand value is relative to the start of MI, but the fixup |
| 265 | // is relative to the operand field itself, which is Offset bytes |
| 266 | // into MI. Add Offset to the relocation value to cancel out |
| 267 | // this difference. |
Jim Grosbach | 13760bd | 2015-05-30 01:25:56 +0000 | [diff] [blame] | 268 | const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx); |
| 269 | Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx); |
Richard Sandiford | 1fb5883 | 2013-05-14 09:47:26 +0000 | [diff] [blame] | 270 | } |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 271 | } |
Jim Grosbach | 63661f8 | 2015-05-15 19:13:05 +0000 | [diff] [blame] | 272 | Fixups.push_back(MCFixup::create(Offset, Expr, (MCFixupKind)Kind)); |
Ulrich Weigand | 7bdd7c2 | 2015-02-18 09:11:36 +0000 | [diff] [blame] | 273 | |
| 274 | // Output the fixup for the TLS marker if present. |
| 275 | if (AllowTLS && OpNum + 1 < MI.getNumOperands()) { |
| 276 | const MCOperand &MOTLS = MI.getOperand(OpNum + 1); |
Jim Grosbach | 63661f8 | 2015-05-15 19:13:05 +0000 | [diff] [blame] | 277 | Fixups.push_back(MCFixup::create(0, MOTLS.getExpr(), |
Ulrich Weigand | 7bdd7c2 | 2015-02-18 09:11:36 +0000 | [diff] [blame] | 278 | (MCFixupKind)SystemZ::FK_390_TLS_CALL)); |
| 279 | } |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 280 | return 0; |
| 281 | } |
| 282 | |
Daniel Sanders | 72db2a3 | 2016-11-19 13:05:44 +0000 | [diff] [blame] | 283 | #define ENABLE_INSTR_PREDICATE_VERIFIER |
Ulrich Weigand | 5f613df | 2013-05-06 16:15:19 +0000 | [diff] [blame] | 284 | #include "SystemZGenMCCodeEmitter.inc" |