11d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===-- SystemZMCCodeEmitter.cpp - Convert SystemZ code to machine code ---===//
21d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//
31d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//                     The LLVM Compiler Infrastructure
41d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//
51d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file is distributed under the University of Illinois Open Source
61d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// License. See LICENSE.TXT for details.
71d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//
81d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===//
91d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//
101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand// This file implements the SystemZMCCodeEmitter class.
111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//
121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand//===----------------------------------------------------------------------===//
131d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#define DEBUG_TYPE "mccodeemitter"
151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "MCTargetDesc/SystemZMCTargetDesc.h"
161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "MCTargetDesc/SystemZMCFixups.h"
171d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCCodeEmitter.h"
181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCContext.h"
191d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCExpr.h"
201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "llvm/MC/MCInstrInfo.h"
211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandusing namespace llvm;
231d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
241d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandnamespace {
251d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandclass SystemZMCCodeEmitter : public MCCodeEmitter {
261d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  const MCInstrInfo &MCII;
271d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  MCContext &Ctx;
281d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
291d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandpublic:
301d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
311d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    : MCII(mcii), Ctx(ctx) {
321d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
331d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
341d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  ~SystemZMCCodeEmitter() {}
351d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
361d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // OVerride MCCodeEmitter.
371d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
381d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                                 SmallVectorImpl<MCFixup> &Fixups) const
391d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    LLVM_OVERRIDE;
401d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
411d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandprivate:
421d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // Automatically generated by TableGen.
431d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  uint64_t getBinaryCodeForInstr(const MCInst &MI,
441d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                                 SmallVectorImpl<MCFixup> &Fixups) const;
451d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
461d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // Called by the TableGen code to get the binary encoding of operand
471d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // MO in MI.  Fixups is the list of fixups against MI.
48055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
491d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                             SmallVectorImpl<MCFixup> &Fixups) const;
501d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
51055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  // Called by the TableGen code to get the binary encoding of an address.
529188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford  // The index or length, if any, is encoded first, followed by the base,
53055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  // followed by the displacement.  In a 20-bit displacement,
54055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  // the low 12 bits are encoded before the high 8 bits.
55055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
56055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford                               SmallVectorImpl<MCFixup> &Fixups) const;
57055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
58055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford                               SmallVectorImpl<MCFixup> &Fixups) const;
59055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
60055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford                                SmallVectorImpl<MCFixup> &Fixups) const;
61055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
62055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford                                SmallVectorImpl<MCFixup> &Fixups) const;
639188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford  uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
649188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford                                    SmallVectorImpl<MCFixup> &Fixups) const;
65055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford
661d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // Operand OpNum of MI needs a PC-relative fixup of kind Kind at
671d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // Offset bytes from the start of MI.  Add the fixup to Fixups
681d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // and return the in-place addend, which since we're a RELA target
691d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // is always 0.
70055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
711d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                            SmallVectorImpl<MCFixup> &Fixups,
721d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                            unsigned Kind, int64_t Offset) const;
731d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
74055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                              SmallVectorImpl<MCFixup> &Fixups) const {
761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC16DBL, 2);
771d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
78055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
791d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                              SmallVectorImpl<MCFixup> &Fixups) const {
801d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC32DBL, 2);
811d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
82055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getPLT16DBLEncoding(const MCInst &MI, unsigned OpNum,
831d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                               SmallVectorImpl<MCFixup> &Fixups) const {
841d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PLT16DBL, 2);
851d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
86055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t getPLT32DBLEncoding(const MCInst &MI, unsigned OpNum,
871d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                               SmallVectorImpl<MCFixup> &Fixups) const {
881d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PLT32DBL, 2);
891d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand};
911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandMCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII,
941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                                                const MCRegisterInfo &MRI,
951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                                                const MCSubtargetInfo &MCSTI,
961d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                                                MCContext &Ctx) {
971d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  return new SystemZMCCodeEmitter(MCII, Ctx);
981d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
991d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
1001d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigandvoid SystemZMCCodeEmitter::
1011d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandEncodeInstruction(const MCInst &MI, raw_ostream &OS,
1021d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                  SmallVectorImpl<MCFixup> &Fixups) const {
1031d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  uint64_t Bits = getBinaryCodeForInstr(MI, Fixups);
1041d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  unsigned Size = MCII.get(MI.getOpcode()).getSize();
1051d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  // Big-endian insertion of Size bytes.
1061d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  unsigned ShiftValue = (Size * 8) - 8;
1071d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  for (unsigned I = 0; I != Size; ++I) {
1081d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    OS << uint8_t(Bits >> ShiftValue);
1091d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand    ShiftValue -= 8;
1101d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
1111d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
1121d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
113055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiforduint64_t SystemZMCCodeEmitter::
1141d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich WeigandgetMachineOpValue(const MCInst &MI, const MCOperand &MO,
1151d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                  SmallVectorImpl<MCFixup> &Fixups) const {
1161d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  if (MO.isReg())
11799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
1181d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  if (MO.isImm())
119055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford    return static_cast<uint64_t>(MO.getImm());
1201d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  llvm_unreachable("Unexpected operand type!");
1211d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
1221d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
123055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiforduint64_t SystemZMCCodeEmitter::
124055ac429cc995c78be4aee552ea51be7b32efbf1Richard SandifordgetBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
125055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford                    SmallVectorImpl<MCFixup> &Fixups) const {
126055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
127055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
128055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  assert(isUInt<4>(Base) && isUInt<12>(Disp));
129055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  return (Base << 12) | Disp;
130055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford}
131055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford
132055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiforduint64_t SystemZMCCodeEmitter::
133055ac429cc995c78be4aee552ea51be7b32efbf1Richard SandifordgetBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
134055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford                    SmallVectorImpl<MCFixup> &Fixups) const {
135055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
136055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
137055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  assert(isUInt<4>(Base) && isInt<20>(Disp));
138055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12);
139055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford}
140055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford
141055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiforduint64_t SystemZMCCodeEmitter::
142055ac429cc995c78be4aee552ea51be7b32efbf1Richard SandifordgetBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
143055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford                     SmallVectorImpl<MCFixup> &Fixups) const {
144055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
145055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
146055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups);
147055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index));
148055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  return (Index << 16) | (Base << 12) | Disp;
149055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford}
150055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford
151055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiforduint64_t SystemZMCCodeEmitter::
152055ac429cc995c78be4aee552ea51be7b32efbf1Richard SandifordgetBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
153055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford                     SmallVectorImpl<MCFixup> &Fixups) const {
154055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
155055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
156055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups);
157055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index));
158055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford  return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8)
159055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford    | ((Disp & 0xff000) >> 12);
160055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford}
161055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiford
1629188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiforduint64_t SystemZMCCodeEmitter::
1639188443a2d35352c4e8a2cffd1b4d31d47843b26Richard SandifordgetBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
1649188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford                         SmallVectorImpl<MCFixup> &Fixups) const {
1659188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups);
1669188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups);
1679188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford  uint64_t Len  = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups) - 1;
1689188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford  assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len));
1699188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford  return (Len << 16) | (Base << 12) | Disp;
1709188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford}
1719188443a2d35352c4e8a2cffd1b4d31d47843b26Richard Sandiford
172055ac429cc995c78be4aee552ea51be7b32efbf1Richard Sandiforduint64_t
173055ac429cc995c78be4aee552ea51be7b32efbf1Richard SandifordSystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
1741d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                                       SmallVectorImpl<MCFixup> &Fixups,
1751d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand                                       unsigned Kind, int64_t Offset) const {
1761d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  const MCOperand &MO = MI.getOperand(OpNum);
177b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford  const MCExpr *Expr;
1781d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  if (MO.isImm())
179b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford    Expr = MCConstantExpr::Create(MO.getImm() + Offset, Ctx);
180b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford  else {
181b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford    Expr = MO.getExpr();
182b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford    if (Offset) {
183b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford      // The operand value is relative to the start of MI, but the fixup
184b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford      // is relative to the operand field itself, which is Offset bytes
185b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford      // into MI.  Add Offset to the relocation value to cancel out
186b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford      // this difference.
187b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford      const MCExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx);
188b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford      Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx);
189b594c4c873bd3e2ee560cc83bd50282ec56b01e9Richard Sandiford    }
1901d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  }
1911d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  Fixups.push_back(MCFixup::Create(Offset, Expr, (MCFixupKind)Kind));
1921d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand  return 0;
1931d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand}
1941d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand
1951d09d56fe1e3f3faadd4bf4ccf3e585ddb3c3b07Ulrich Weigand#include "SystemZGenMCCodeEmitter.inc"
196