SIMCCodeEmitter.cpp revision 184f5c1545e06a99951f14d846a1d853ff19a2b8
1f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===-- SIMCCodeEmitter.cpp - SI Code Emitter -------------------------------===// 2f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 3f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// The LLVM Compiler Infrastructure 4f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 5f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// This file is distributed under the University of Illinois Open Source 6f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// License. See LICENSE.TXT for details. 7f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 8f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 9f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 10f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \file 11f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// \brief The SI code emitter produces machine code that can be executed 12f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard/// directly on the GPU device. 13f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// 14f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 15f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 16f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "MCTargetDesc/AMDGPUMCTargetDesc.h" 17f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "MCTargetDesc/AMDGPUMCCodeEmitter.h" 18f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCCodeEmitter.h" 19f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCContext.h" 2058a2cbef4aac9ee7d530dfb690c78d6fc11a2371Chandler Carruth#include "llvm/MC/MCFixup.h" 21f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCInst.h" 22f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCInstrInfo.h" 23f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCRegisterInfo.h" 24f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/MC/MCSubtargetInfo.h" 25f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard#include "llvm/Support/raw_ostream.h" 26f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 27f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardusing namespace llvm; 28f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 29f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardnamespace { 30f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardclass SIMCCodeEmitter : public AMDGPUMCCodeEmitter { 31f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SIMCCodeEmitter(const SIMCCodeEmitter &); // DO NOT IMPLEMENT 32f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard void operator=(const SIMCCodeEmitter &); // DO NOT IMPLEMENT 33f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCInstrInfo &MCII; 34f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCRegisterInfo &MRI; 35f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCSubtargetInfo &STI; 36f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MCContext &Ctx; 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 38f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardpublic: 39f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SIMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri, 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCSubtargetInfo &sti, MCContext &ctx) 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard : MCII(mcii), MRI(mri), STI(sti), Ctx(ctx) { } 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 43f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ~SIMCCodeEmitter() { } 44f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 45f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard /// \breif Encode the instruction and write it to the OS. 46f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 47f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MCFixup> &Fixups) const; 48f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard /// \returns the encoding for an MCOperand. 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, 51f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MCFixup> &Fixups) const; 52f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardpublic: 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard /// \brief Encode a sequence of registers with the correct alignment. 56f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned GPRAlign(const MCInst &MI, unsigned OpNo, unsigned shift) const; 57f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 58f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard /// \brief Encoding for when 2 consecutive registers are used 59f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual unsigned GPR2AlignEncode(const MCInst &MI, unsigned OpNo, 60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MCFixup> &Fixup) const; 61f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 62f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard /// \brief Encoding for when 4 consectuive registers are used 63f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard virtual unsigned GPR4AlignEncode(const MCInst &MI, unsigned OpNo, 64f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MCFixup> &Fixup) const; 65f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard}; 66f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 67f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} // End anonymous namespace 68f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 69f98f2ce29e6e2996fa58f38979143eceaa818335Tom StellardMCCodeEmitter *llvm::createSIMCCodeEmitter(const MCInstrInfo &MCII, 70f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCRegisterInfo &MRI, 71f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCSubtargetInfo &STI, 72f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard MCContext &Ctx) { 73f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return new SIMCCodeEmitter(MCII, MRI, STI, Ctx); 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 75f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 76f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, 77f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MCFixup> &Fixups) const { 78f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups); 79184f5c1545e06a99951f14d846a1d853ff19a2b8Tom Stellard unsigned bytes = MCII.get(MI.getOpcode()).getSize(); 80f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned i = 0; i < bytes; i++) { 81f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OS.write((uint8_t) ((Encoding >> (8 * i)) & 0xff)); 82f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 83f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 84f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 85f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellarduint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI, 86f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCOperand &MO, 87f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MCFixup> &Fixups) const { 88f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard if (MO.isReg()) { 89184f5c1545e06a99951f14d846a1d853ff19a2b8Tom Stellard return MRI.getEncodingValue(MO.getReg()); 90f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (MO.isImm()) { 91f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return MO.getImm(); 92f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else if (MO.isFPImm()) { 93f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: Not all instructions can use inline literals 94f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard // XXX: We should make sure this is a 32-bit constant 95f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard union { 96f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard float F; 97f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard uint32_t I; 98f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } Imm; 99f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard Imm.F = MO.getFPImm(); 100f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return Imm.I; 1013ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard } else if (MO.isExpr()) { 1023ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard const MCExpr *Expr = MO.getExpr(); 1033ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard MCFixupKind Kind = MCFixupKind(FK_PCRel_4); 1043ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 1053ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard return 0; 106f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } else{ 107f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard llvm_unreachable("Encoding of this operand type is not supported yet."); 108f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 109f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 110f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 111f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 112f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 113f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard// Custom Operand Encodings 114f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard//===----------------------------------------------------------------------===// 115f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 116f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned SIMCCodeEmitter::GPRAlign(const MCInst &MI, unsigned OpNo, 117f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned shift) const { 118184f5c1545e06a99951f14d846a1d853ff19a2b8Tom Stellard unsigned regCode = MRI.getEncodingValue(MI.getOperand(OpNo).getReg()); 119184f5c1545e06a99951f14d846a1d853ff19a2b8Tom Stellard return (regCode & 0xff) >> shift; 120f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 121f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned SIMCCodeEmitter::GPR2AlignEncode(const MCInst &MI, 122f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned OpNo , 123f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MCFixup> &Fixup) const { 124f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return GPRAlign(MI, OpNo, 1); 125f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 126f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 127f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardunsigned SIMCCodeEmitter::GPR4AlignEncode(const MCInst &MI, 128f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard unsigned OpNo, 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SmallVectorImpl<MCFixup> &Fixup) const { 130f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return GPRAlign(MI, OpNo, 2); 131f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 132