SystemZMCCodeEmitter.cpp revision 285830
121308Sache//===-- SystemZMCCodeEmitter.cpp - Convert SystemZ code to machine code ---===// 221308Sache// 321308Sache// The LLVM Compiler Infrastructure 421308Sache// 521308Sache// This file is distributed under the University of Illinois Open Source 621308Sache// License. See LICENSE.TXT for details. 721308Sache// 821308Sache//===----------------------------------------------------------------------===// 921308Sache// 1021308Sache// This file implements the SystemZMCCodeEmitter class. 1121308Sache// 1221308Sache//===----------------------------------------------------------------------===// 1321308Sache 1421308Sache#define DEBUG_TYPE "mccodeemitter" 1521308Sache#include "MCTargetDesc/SystemZMCTargetDesc.h" 1621308Sache#include "MCTargetDesc/SystemZMCFixups.h" 1721308Sache#include "llvm/MC/MCCodeEmitter.h" 1821308Sache#include "llvm/MC/MCContext.h" 1921308Sache#include "llvm/MC/MCExpr.h" 2021308Sache#include "llvm/MC/MCInstrInfo.h" 2121308Sache 2221308Sacheusing namespace llvm; 2321308Sache 2421308Sachenamespace { 2521308Sacheclass SystemZMCCodeEmitter : public MCCodeEmitter { 2621308Sache const MCInstrInfo &MCII; 2721308Sache MCContext &Ctx; 2821308Sache 2921308Sachepublic: 3021308Sache SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx) 3121308Sache : MCII(mcii), Ctx(ctx) { 3221308Sache } 3321308Sache 3421308Sache ~SystemZMCCodeEmitter() {} 3521308Sache 3626497Sache // OVerride MCCodeEmitter. 3726497Sache virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 3826497Sache SmallVectorImpl<MCFixup> &Fixups) const 3926497Sache LLVM_OVERRIDE; 4026497Sache 4126497Sacheprivate: 4221308Sache // Automatically generated by TableGen. 4321308Sache uint64_t getBinaryCodeForInstr(const MCInst &MI, 4421308Sache SmallVectorImpl<MCFixup> &Fixups) const; 4521308Sache 4626497Sache // Called by the TableGen code to get the binary encoding of operand 4726497Sache // MO in MI. Fixups is the list of fixups against MI. 4826497Sache uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, 4926497Sache SmallVectorImpl<MCFixup> &Fixups) const; 5021308Sache 5121308Sache // Called by the TableGen code to get the binary encoding of an address. 5221308Sache // The index or length, if any, is encoded first, followed by the base, 5321308Sache // followed by the displacement. In a 20-bit displacement, 5421308Sache // the low 12 bits are encoded before the high 8 bits. 5521308Sache uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum, 5621308Sache SmallVectorImpl<MCFixup> &Fixups) const; 5721308Sache uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum, 5821308Sache SmallVectorImpl<MCFixup> &Fixups) const; 5921308Sache uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum, 6021308Sache SmallVectorImpl<MCFixup> &Fixups) const; 6121308Sache uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum, 6221308Sache SmallVectorImpl<MCFixup> &Fixups) const; 6321308Sache uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum, 6421308Sache SmallVectorImpl<MCFixup> &Fixups) const; 6521308Sache 6621308Sache // Operand OpNum of MI needs a PC-relative fixup of kind Kind at 6721308Sache // Offset bytes from the start of MI. Add the fixup to Fixups 6821308Sache // and return the in-place addend, which since we're a RELA target 6921308Sache // is always 0. 7021308Sache uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum, 7121308Sache SmallVectorImpl<MCFixup> &Fixups, 7221308Sache unsigned Kind, int64_t Offset) const; 7321308Sache 7421308Sache uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum, 7521308Sache SmallVectorImpl<MCFixup> &Fixups) const { 7621308Sache return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC16DBL, 2); 7721308Sache } 7821308Sache uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum, 7921308Sache SmallVectorImpl<MCFixup> &Fixups) const { 8021308Sache return getPCRelEncoding(MI, OpNum, Fixups, SystemZ::FK_390_PC32DBL, 2); 8121308Sache } 8221308Sache}; 8321308Sache} 8421308Sache 8521308SacheMCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII, 8621308Sache const MCRegisterInfo &MRI, 8721308Sache const MCSubtargetInfo &MCSTI, 8821308Sache MCContext &Ctx) { 8921308Sache return new SystemZMCCodeEmitter(MCII, Ctx); 9021308Sache} 9121308Sache 9221308Sachevoid SystemZMCCodeEmitter:: 9321308SacheEncodeInstruction(const MCInst &MI, raw_ostream &OS, 9421308Sache SmallVectorImpl<MCFixup> &Fixups) const { 9521308Sache uint64_t Bits = getBinaryCodeForInstr(MI, Fixups); 9621308Sache unsigned Size = MCII.get(MI.getOpcode()).getSize(); 9721308Sache // Big-endian insertion of Size bytes. 9821308Sache unsigned ShiftValue = (Size * 8) - 8; 9921308Sache for (unsigned I = 0; I != Size; ++I) { 10021308Sache OS << uint8_t(Bits >> ShiftValue); 10121308Sache ShiftValue -= 8; 10221308Sache } 10321308Sache} 10421308Sache 10521308Sacheuint64_t SystemZMCCodeEmitter:: 10621308SachegetMachineOpValue(const MCInst &MI, const MCOperand &MO, 10721308Sache SmallVectorImpl<MCFixup> &Fixups) const { 10821308Sache if (MO.isReg()) 10921308Sache return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()); 11021308Sache if (MO.isImm()) 11121308Sache return static_cast<uint64_t>(MO.getImm()); 11221308Sache llvm_unreachable("Unexpected operand type!"); 11321308Sache} 11421308Sache 11521308Sacheuint64_t SystemZMCCodeEmitter:: 11621308SachegetBDAddr12Encoding(const MCInst &MI, unsigned OpNum, 11721308Sache SmallVectorImpl<MCFixup> &Fixups) const { 11821308Sache uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups); 11921308Sache uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups); 12021308Sache assert(isUInt<4>(Base) && isUInt<12>(Disp)); 12121308Sache return (Base << 12) | Disp; 12221308Sache} 12321308Sache 12421308Sacheuint64_t SystemZMCCodeEmitter:: 12521308SachegetBDAddr20Encoding(const MCInst &MI, unsigned OpNum, 12621308Sache SmallVectorImpl<MCFixup> &Fixups) const { 12721308Sache uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups); 12821308Sache uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups); 12921308Sache assert(isUInt<4>(Base) && isInt<20>(Disp)); 13021308Sache return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12); 13121308Sache} 13221308Sache 13321308Sacheuint64_t SystemZMCCodeEmitter:: 13421308SachegetBDXAddr12Encoding(const MCInst &MI, unsigned OpNum, 13521308Sache SmallVectorImpl<MCFixup> &Fixups) const { 13621308Sache uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups); 13721308Sache uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups); 13821308Sache uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups); 13921308Sache assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index)); 14021308Sache return (Index << 16) | (Base << 12) | Disp; 14121308Sache} 14221308Sache 14321308Sacheuint64_t SystemZMCCodeEmitter:: 14421308SachegetBDXAddr20Encoding(const MCInst &MI, unsigned OpNum, 14521308Sache SmallVectorImpl<MCFixup> &Fixups) const { 14621308Sache uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups); 14721308Sache uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups); 14821308Sache uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups); 14921308Sache assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index)); 15021308Sache return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8) 15121308Sache | ((Disp & 0xff000) >> 12); 15221308Sache} 15321308Sache 15421308Sacheuint64_t SystemZMCCodeEmitter:: 15521308SachegetBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum, 15621308Sache SmallVectorImpl<MCFixup> &Fixups) const { 15721308Sache uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups); 15821308Sache uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups); 15921308Sache uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups) - 1; 16021308Sache assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len)); 16121308Sache return (Len << 16) | (Base << 12) | Disp; 16221308Sache} 16321308Sache 16421308Sacheuint64_t 16521308SacheSystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum, 16621308Sache SmallVectorImpl<MCFixup> &Fixups, 16721308Sache unsigned Kind, int64_t Offset) const { 16821308Sache const MCOperand &MO = MI.getOperand(OpNum); 16921308Sache const MCExpr *Expr; 17021308Sache if (MO.isImm()) 17121308Sache Expr = MCConstantExpr::Create(MO.getImm() + Offset, Ctx); 17221308Sache else { 17321308Sache Expr = MO.getExpr(); 17421308Sache if (Offset) { 17521308Sache // The operand value is relative to the start of MI, but the fixup 17621308Sache // is relative to the operand field itself, which is Offset bytes 17721308Sache // into MI. Add Offset to the relocation value to cancel out 17821308Sache // this difference. 17921308Sache const MCExpr *OffsetExpr = MCConstantExpr::Create(Offset, Ctx); 18021308Sache Expr = MCBinaryExpr::CreateAdd(Expr, OffsetExpr, Ctx); 18121308Sache } 18221308Sache } 18321308Sache Fixups.push_back(MCFixup::Create(Offset, Expr, (MCFixupKind)Kind)); 18421308Sache return 0; 18521308Sache} 18621308Sache 18721308Sache#include "SystemZGenMCCodeEmitter.inc" 18821308Sache