15f613dfdSUlrich Weigand //===-- SystemZMCCodeEmitter.cpp - Convert SystemZ code to machine code ---===//
25f613dfdSUlrich Weigand //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f613dfdSUlrich Weigand //
75f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
85f613dfdSUlrich Weigand //
95f613dfdSUlrich Weigand // This file implements the SystemZMCCodeEmitter class.
105f613dfdSUlrich Weigand //
115f613dfdSUlrich Weigand //===----------------------------------------------------------------------===//
125f613dfdSUlrich Weigand
135f613dfdSUlrich Weigand #include "MCTargetDesc/SystemZMCFixups.h"
143943d2b0SEugene Zelenko #include "MCTargetDesc/SystemZMCTargetDesc.h"
151c3ef9efSJonas Paulsson #include "SystemZInstrInfo.h"
163943d2b0SEugene Zelenko #include "llvm/ADT/SmallVector.h"
175f613dfdSUlrich Weigand #include "llvm/MC/MCCodeEmitter.h"
185f613dfdSUlrich Weigand #include "llvm/MC/MCContext.h"
195f613dfdSUlrich Weigand #include "llvm/MC/MCExpr.h"
203943d2b0SEugene Zelenko #include "llvm/MC/MCFixup.h"
213de83e40SPete Cooper #include "llvm/MC/MCInst.h"
225f613dfdSUlrich Weigand #include "llvm/MC/MCInstrInfo.h"
233de83e40SPete Cooper #include "llvm/MC/MCRegisterInfo.h"
243943d2b0SEugene Zelenko #include "llvm/MC/MCSubtargetInfo.h"
253943d2b0SEugene Zelenko #include "llvm/Support/ErrorHandling.h"
263943d2b0SEugene Zelenko #include "llvm/Support/raw_ostream.h"
273943d2b0SEugene Zelenko #include <cassert>
283943d2b0SEugene Zelenko #include <cstdint>
295f613dfdSUlrich Weigand
305f613dfdSUlrich Weigand using namespace llvm;
315f613dfdSUlrich Weigand
3284e68b29SChandler Carruth #define DEBUG_TYPE "mccodeemitter"
3384e68b29SChandler Carruth
345f613dfdSUlrich Weigand namespace {
353943d2b0SEugene Zelenko
365f613dfdSUlrich Weigand class SystemZMCCodeEmitter : public MCCodeEmitter {
375f613dfdSUlrich Weigand const MCInstrInfo &MCII;
385f613dfdSUlrich Weigand MCContext &Ctx;
395f613dfdSUlrich Weigand
40e547b04dSJonas Paulsson mutable unsigned MemOpsEmitted;
41e547b04dSJonas Paulsson
425f613dfdSUlrich Weigand public:
SystemZMCCodeEmitter(const MCInstrInfo & mcii,MCContext & ctx)435f613dfdSUlrich Weigand SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
445f613dfdSUlrich Weigand : MCII(mcii), Ctx(ctx) {
455f613dfdSUlrich Weigand }
465f613dfdSUlrich Weigand
473943d2b0SEugene Zelenko ~SystemZMCCodeEmitter() override = default;
485f613dfdSUlrich Weigand
495f613dfdSUlrich Weigand // OVerride MCCodeEmitter.
5091df21f7SJim Grosbach void encodeInstruction(const MCInst &MI, raw_ostream &OS,
519784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
5273156025SCraig Topper const MCSubtargetInfo &STI) const override;
535f613dfdSUlrich Weigand
545f613dfdSUlrich Weigand private:
555f613dfdSUlrich Weigand // Automatically generated by TableGen.
565f613dfdSUlrich Weigand uint64_t getBinaryCodeForInstr(const MCInst &MI,
573fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
583fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const;
595f613dfdSUlrich Weigand
605f613dfdSUlrich Weigand // Called by the TableGen code to get the binary encoding of operand
615f613dfdSUlrich Weigand // MO in MI. Fixups is the list of fixups against MI.
62d454ec0cSRichard Sandiford uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
633fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
643fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const;
65d454ec0cSRichard Sandiford
661c3ef9efSJonas Paulsson // Return the displacement value for the OpNum operand. If it is a symbol,
671c3ef9efSJonas Paulsson // add a fixup for it and return 0.
681c3ef9efSJonas Paulsson uint64_t getDispOpValue(const MCInst &MI, unsigned OpNum,
691c3ef9efSJonas Paulsson SmallVectorImpl<MCFixup> &Fixups,
701c3ef9efSJonas Paulsson SystemZ::FixupKind Kind) const;
711c3ef9efSJonas Paulsson
72d454ec0cSRichard Sandiford // Called by the TableGen code to get the binary encoding of an address.
731d959008SRichard Sandiford // The index or length, if any, is encoded first, followed by the base,
74d454ec0cSRichard Sandiford // followed by the displacement. In a 20-bit displacement,
75d454ec0cSRichard Sandiford // the low 12 bits are encoded before the high 8 bits.
76d454ec0cSRichard Sandiford uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
773fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
783fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const;
79d454ec0cSRichard Sandiford uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
803fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
813fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const;
82d454ec0cSRichard Sandiford uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
833fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
843fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const;
85d454ec0cSRichard Sandiford uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
863fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
873fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const;
88c7eb5a95SUlrich Weigand uint64_t getBDLAddr12Len4Encoding(const MCInst &MI, unsigned OpNum,
89c7eb5a95SUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
90c7eb5a95SUlrich Weigand const MCSubtargetInfo &STI) const;
911d959008SRichard Sandiford uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
923fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
933fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const;
94ec5d779eSUlrich Weigand uint64_t getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
95ec5d779eSUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
96ec5d779eSUlrich Weigand const MCSubtargetInfo &STI) const;
97a8b04e1cSUlrich Weigand uint64_t getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
98a8b04e1cSUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
99a8b04e1cSUlrich Weigand const MCSubtargetInfo &STI) const;
1005f613dfdSUlrich Weigand
1015f613dfdSUlrich Weigand // Operand OpNum of MI needs a PC-relative fixup of kind Kind at
1025f613dfdSUlrich Weigand // Offset bytes from the start of MI. Add the fixup to Fixups
1035f613dfdSUlrich Weigand // and return the in-place addend, which since we're a RELA target
1047bdd7c23SUlrich Weigand // is always 0. If AllowTLS is true and optional operand OpNum + 1
1057bdd7c23SUlrich Weigand // is present, also emit a TLS call fixup for it.
106d454ec0cSRichard Sandiford uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
1075f613dfdSUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
1087bdd7c23SUlrich Weigand unsigned Kind, int64_t Offset,
1097bdd7c23SUlrich Weigand bool AllowTLS) const;
1105f613dfdSUlrich Weigand
getPC16DBLEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const111d454ec0cSRichard Sandiford uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
1123fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
1133fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const {
1147bdd7c23SUlrich Weigand return getPCRelEncoding(MI, OpNum, Fixups,
1157bdd7c23SUlrich Weigand SystemZ::FK_390_PC16DBL, 2, false);
1165f613dfdSUlrich Weigand }
getPC32DBLEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const117d454ec0cSRichard Sandiford uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
1183fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
1193fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const {
1207bdd7c23SUlrich Weigand return getPCRelEncoding(MI, OpNum, Fixups,
1217bdd7c23SUlrich Weigand SystemZ::FK_390_PC32DBL, 2, false);
1227bdd7c23SUlrich Weigand }
getPC16DBLTLSEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1237bdd7c23SUlrich Weigand uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
1247bdd7c23SUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
1257bdd7c23SUlrich Weigand const MCSubtargetInfo &STI) const {
1267bdd7c23SUlrich Weigand return getPCRelEncoding(MI, OpNum, Fixups,
1277bdd7c23SUlrich Weigand SystemZ::FK_390_PC16DBL, 2, true);
1287bdd7c23SUlrich Weigand }
getPC32DBLTLSEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1297bdd7c23SUlrich Weigand uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
1307bdd7c23SUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
1317bdd7c23SUlrich Weigand const MCSubtargetInfo &STI) const {
1327bdd7c23SUlrich Weigand return getPCRelEncoding(MI, OpNum, Fixups,
1337bdd7c23SUlrich Weigand SystemZ::FK_390_PC32DBL, 2, true);
1345f613dfdSUlrich Weigand }
getPC12DBLBPPEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const13584404f30SUlrich Weigand uint64_t getPC12DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
13684404f30SUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
13784404f30SUlrich Weigand const MCSubtargetInfo &STI) const {
13884404f30SUlrich Weigand return getPCRelEncoding(MI, OpNum, Fixups,
13984404f30SUlrich Weigand SystemZ::FK_390_PC12DBL, 1, false);
14084404f30SUlrich Weigand }
getPC16DBLBPPEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const14184404f30SUlrich Weigand uint64_t getPC16DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
14284404f30SUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
14384404f30SUlrich Weigand const MCSubtargetInfo &STI) const {
14484404f30SUlrich Weigand return getPCRelEncoding(MI, OpNum, Fixups,
14584404f30SUlrich Weigand SystemZ::FK_390_PC16DBL, 4, false);
14684404f30SUlrich Weigand }
getPC24DBLBPPEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const14784404f30SUlrich Weigand uint64_t getPC24DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
14884404f30SUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
14984404f30SUlrich Weigand const MCSubtargetInfo &STI) const {
15084404f30SUlrich Weigand return getPCRelEncoding(MI, OpNum, Fixups,
15184404f30SUlrich Weigand SystemZ::FK_390_PC24DBL, 3, false);
15284404f30SUlrich Weigand }
1535f613dfdSUlrich Weigand };
1545f613dfdSUlrich Weigand
1553943d2b0SEugene Zelenko } // end anonymous namespace
1565f613dfdSUlrich Weigand
encodeInstruction(const MCInst & MI,raw_ostream & OS,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const157*3e0bf1c7SDavid Green void SystemZMCCodeEmitter::encodeInstruction(const MCInst &MI, raw_ostream &OS,
1589784cef3SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
1599784cef3SDavid Woodhouse const MCSubtargetInfo &STI) const {
160e547b04dSJonas Paulsson MemOpsEmitted = 0;
1613fa98a65SDavid Woodhouse uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
1625f613dfdSUlrich Weigand unsigned Size = MCII.get(MI.getOpcode()).getSize();
1635f613dfdSUlrich Weigand // Big-endian insertion of Size bytes.
1645f613dfdSUlrich Weigand unsigned ShiftValue = (Size * 8) - 8;
1655f613dfdSUlrich Weigand for (unsigned I = 0; I != Size; ++I) {
1665f613dfdSUlrich Weigand OS << uint8_t(Bits >> ShiftValue);
1675f613dfdSUlrich Weigand ShiftValue -= 8;
1685f613dfdSUlrich Weigand }
1695f613dfdSUlrich Weigand }
1705f613dfdSUlrich Weigand
171d454ec0cSRichard Sandiford uint64_t SystemZMCCodeEmitter::
getMachineOpValue(const MCInst & MI,const MCOperand & MO,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const1725f613dfdSUlrich Weigand getMachineOpValue(const MCInst &MI, const MCOperand &MO,
1733fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
1743fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const {
1755f613dfdSUlrich Weigand if (MO.isReg())
176bc07a890SBill Wendling return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
1775f613dfdSUlrich Weigand if (MO.isImm())
178d454ec0cSRichard Sandiford return static_cast<uint64_t>(MO.getImm());
1795f613dfdSUlrich Weigand llvm_unreachable("Unexpected operand type!");
1805f613dfdSUlrich Weigand }
1815f613dfdSUlrich Weigand
182d454ec0cSRichard Sandiford uint64_t SystemZMCCodeEmitter::
getDispOpValue(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,SystemZ::FixupKind Kind) const1831c3ef9efSJonas Paulsson getDispOpValue(const MCInst &MI, unsigned OpNum,
1841c3ef9efSJonas Paulsson SmallVectorImpl<MCFixup> &Fixups,
1851c3ef9efSJonas Paulsson SystemZ::FixupKind Kind) const {
1861c3ef9efSJonas Paulsson const MCOperand &MO = MI.getOperand(OpNum);
187e547b04dSJonas Paulsson if (MO.isImm()) {
188e547b04dSJonas Paulsson ++MemOpsEmitted;
1891c3ef9efSJonas Paulsson return static_cast<uint64_t>(MO.getImm());
190e547b04dSJonas Paulsson }
1911c3ef9efSJonas Paulsson if (MO.isExpr()) {
1921c3ef9efSJonas Paulsson // All instructions follow the pattern where the first displacement has a
1931c3ef9efSJonas Paulsson // 2 bytes offset, and the second one 4 bytes.
194e547b04dSJonas Paulsson unsigned ByteOffs = MemOpsEmitted++ == 0 ? 2 : 4;
1955bf4f2acSJonas Paulsson Fixups.push_back(MCFixup::create(ByteOffs, MO.getExpr(), (MCFixupKind)Kind,
1965bf4f2acSJonas Paulsson MI.getLoc()));
1971c3ef9efSJonas Paulsson assert(Fixups.size() <= 2 && "More than two memory operands in MI?");
1981c3ef9efSJonas Paulsson return 0;
1991c3ef9efSJonas Paulsson }
2001c3ef9efSJonas Paulsson llvm_unreachable("Unexpected operand type!");
2011c3ef9efSJonas Paulsson }
2021c3ef9efSJonas Paulsson
2031c3ef9efSJonas Paulsson uint64_t SystemZMCCodeEmitter::
getBDAddr12Encoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const204d454ec0cSRichard Sandiford getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
2053fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
2063fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const {
2073fa98a65SDavid Woodhouse uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
2081c3ef9efSJonas Paulsson uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
209d454ec0cSRichard Sandiford assert(isUInt<4>(Base) && isUInt<12>(Disp));
210d454ec0cSRichard Sandiford return (Base << 12) | Disp;
211d454ec0cSRichard Sandiford }
212d454ec0cSRichard Sandiford
213d454ec0cSRichard Sandiford uint64_t SystemZMCCodeEmitter::
getBDAddr20Encoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const214d454ec0cSRichard Sandiford getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
2153fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
2163fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const {
2173fa98a65SDavid Woodhouse uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
2181c3ef9efSJonas Paulsson uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_20);
219d454ec0cSRichard Sandiford assert(isUInt<4>(Base) && isInt<20>(Disp));
220d454ec0cSRichard Sandiford return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12);
221d454ec0cSRichard Sandiford }
222d454ec0cSRichard Sandiford
223d454ec0cSRichard Sandiford uint64_t SystemZMCCodeEmitter::
getBDXAddr12Encoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const224d454ec0cSRichard Sandiford getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
2253fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
2263fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const {
2273fa98a65SDavid Woodhouse uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
2281c3ef9efSJonas Paulsson uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
2293fa98a65SDavid Woodhouse uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
230d454ec0cSRichard Sandiford assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index));
231d454ec0cSRichard Sandiford return (Index << 16) | (Base << 12) | Disp;
232d454ec0cSRichard Sandiford }
233d454ec0cSRichard Sandiford
234d454ec0cSRichard Sandiford uint64_t SystemZMCCodeEmitter::
getBDXAddr20Encoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const235d454ec0cSRichard Sandiford getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
2363fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
2373fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const {
2383fa98a65SDavid Woodhouse uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
2391c3ef9efSJonas Paulsson uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_20);
2403fa98a65SDavid Woodhouse uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
241d454ec0cSRichard Sandiford assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index));
242d454ec0cSRichard Sandiford return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8)
243d454ec0cSRichard Sandiford | ((Disp & 0xff000) >> 12);
244d454ec0cSRichard Sandiford }
245d454ec0cSRichard Sandiford
2461d959008SRichard Sandiford uint64_t SystemZMCCodeEmitter::
getBDLAddr12Len4Encoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const247c7eb5a95SUlrich Weigand getBDLAddr12Len4Encoding(const MCInst &MI, unsigned OpNum,
248c7eb5a95SUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
249c7eb5a95SUlrich Weigand const MCSubtargetInfo &STI) const {
250c7eb5a95SUlrich Weigand uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
2511c3ef9efSJonas Paulsson uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
252c7eb5a95SUlrich Weigand uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
253c7eb5a95SUlrich Weigand assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
254c7eb5a95SUlrich Weigand return (Len << 16) | (Base << 12) | Disp;
255c7eb5a95SUlrich Weigand }
256c7eb5a95SUlrich Weigand
257c7eb5a95SUlrich Weigand uint64_t SystemZMCCodeEmitter::
getBDLAddr12Len8Encoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const2581d959008SRichard Sandiford getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
2593fa98a65SDavid Woodhouse SmallVectorImpl<MCFixup> &Fixups,
2603fa98a65SDavid Woodhouse const MCSubtargetInfo &STI) const {
2613fa98a65SDavid Woodhouse uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
2621c3ef9efSJonas Paulsson uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
2633fa98a65SDavid Woodhouse uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
2641d959008SRichard Sandiford assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len));
2651d959008SRichard Sandiford return (Len << 16) | (Base << 12) | Disp;
2661d959008SRichard Sandiford }
2671d959008SRichard Sandiford
268a8b04e1cSUlrich Weigand uint64_t SystemZMCCodeEmitter::
getBDRAddr12Encoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const269ec5d779eSUlrich Weigand getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
270ec5d779eSUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
271ec5d779eSUlrich Weigand const MCSubtargetInfo &STI) const {
272ec5d779eSUlrich Weigand uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
2731c3ef9efSJonas Paulsson uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
274ec5d779eSUlrich Weigand uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
275ec5d779eSUlrich Weigand assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
276ec5d779eSUlrich Weigand return (Len << 16) | (Base << 12) | Disp;
277ec5d779eSUlrich Weigand }
278ec5d779eSUlrich Weigand
279ec5d779eSUlrich Weigand uint64_t SystemZMCCodeEmitter::
getBDVAddr12Encoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,const MCSubtargetInfo & STI) const280a8b04e1cSUlrich Weigand getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
281a8b04e1cSUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
282a8b04e1cSUlrich Weigand const MCSubtargetInfo &STI) const {
283a8b04e1cSUlrich Weigand uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
2841c3ef9efSJonas Paulsson uint64_t Disp = getDispOpValue(MI, OpNum + 1, Fixups, SystemZ::FK_390_12);
285a8b04e1cSUlrich Weigand uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
286a8b04e1cSUlrich Weigand assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<5>(Index));
287a8b04e1cSUlrich Weigand return (Index << 16) | (Base << 12) | Disp;
288a8b04e1cSUlrich Weigand }
289a8b04e1cSUlrich Weigand
290d454ec0cSRichard Sandiford uint64_t
getPCRelEncoding(const MCInst & MI,unsigned OpNum,SmallVectorImpl<MCFixup> & Fixups,unsigned Kind,int64_t Offset,bool AllowTLS) const291d454ec0cSRichard Sandiford SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
2925f613dfdSUlrich Weigand SmallVectorImpl<MCFixup> &Fixups,
2937bdd7c23SUlrich Weigand unsigned Kind, int64_t Offset,
2947bdd7c23SUlrich Weigand bool AllowTLS) const {
2955bf4f2acSJonas Paulsson SMLoc Loc = MI.getLoc();
2965f613dfdSUlrich Weigand const MCOperand &MO = MI.getOperand(OpNum);
2971fb5883dSRichard Sandiford const MCExpr *Expr;
2985f613dfdSUlrich Weigand if (MO.isImm())
29913760bd1SJim Grosbach Expr = MCConstantExpr::create(MO.getImm() + Offset, Ctx);
3001fb5883dSRichard Sandiford else {
3011fb5883dSRichard Sandiford Expr = MO.getExpr();
3025f613dfdSUlrich Weigand if (Offset) {
3035f613dfdSUlrich Weigand // The operand value is relative to the start of MI, but the fixup
3045f613dfdSUlrich Weigand // is relative to the operand field itself, which is Offset bytes
3055f613dfdSUlrich Weigand // into MI. Add Offset to the relocation value to cancel out
3065f613dfdSUlrich Weigand // this difference.
30713760bd1SJim Grosbach const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
30813760bd1SJim Grosbach Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx);
3095f613dfdSUlrich Weigand }
3101fb5883dSRichard Sandiford }
3115bf4f2acSJonas Paulsson Fixups.push_back(MCFixup::create(Offset, Expr, (MCFixupKind)Kind, Loc));
3127bdd7c23SUlrich Weigand
3137bdd7c23SUlrich Weigand // Output the fixup for the TLS marker if present.
3147bdd7c23SUlrich Weigand if (AllowTLS && OpNum + 1 < MI.getNumOperands()) {
3157bdd7c23SUlrich Weigand const MCOperand &MOTLS = MI.getOperand(OpNum + 1);
3165bf4f2acSJonas Paulsson Fixups.push_back(MCFixup::create(
3175bf4f2acSJonas Paulsson 0, MOTLS.getExpr(), (MCFixupKind)SystemZ::FK_390_TLS_CALL, Loc));
3187bdd7c23SUlrich Weigand }
3195f613dfdSUlrich Weigand return 0;
3205f613dfdSUlrich Weigand }
3215f613dfdSUlrich Weigand
3225f613dfdSUlrich Weigand #include "SystemZGenMCCodeEmitter.inc"
3233943d2b0SEugene Zelenko
createSystemZMCCodeEmitter(const MCInstrInfo & MCII,MCContext & Ctx)3243943d2b0SEugene Zelenko MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII,
3253943d2b0SEugene Zelenko MCContext &Ctx) {
3263943d2b0SEugene Zelenko return new SystemZMCCodeEmitter(MCII, Ctx);
3273943d2b0SEugene Zelenko }
328