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 { 30e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 31e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig/// \brief Helper type used in encoding 32e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konigtypedef union { 33e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig int32_t I; 34e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig float F; 35e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig} IntFloatUnion; 36e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 37f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardclass SIMCCodeEmitter : public AMDGPUMCCodeEmitter { 38a39058aaed4540fc37681cad728b99546595b2e8David Blaikie SIMCCodeEmitter(const SIMCCodeEmitter &) LLVM_DELETED_FUNCTION; 39a39058aaed4540fc37681cad728b99546595b2e8David Blaikie void operator=(const SIMCCodeEmitter &) LLVM_DELETED_FUNCTION; 40f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCInstrInfo &MCII; 41f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCRegisterInfo &MRI; 42f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 43e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig /// \brief Can this operand also contain immediate values? 44e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig bool isSrcOperand(const MCInstrDesc &Desc, unsigned OpNo) const; 45e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 46e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig /// \brief Encode an fp or int literal 47e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig uint32_t getLitEncoding(const MCOperand &MO) const; 48e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 49f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardpublic: 50f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard SIMCCodeEmitter(const MCInstrInfo &mcii, const MCRegisterInfo &mri, 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCContext &ctx) 524d419bffb7ca0c04063afc0fd12ef7b7ced17658NAKAMURA Takumi : MCII(mcii), MRI(mri) { } 53f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 54f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard ~SIMCCodeEmitter() { } 55f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Encode the instruction and write it to the OS. 57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSubtargetInfo &STI) const override; 60f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 61f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard /// \returns the encoding for an MCOperand. 62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, 63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SmallVectorImpl<MCFixup> &Fixups, 64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSubtargetInfo &STI) const override; 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) { 7336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return new SIMCCodeEmitter(MCII, MRI, Ctx); 74f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 75f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 76e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konigbool SIMCCodeEmitter::isSrcOperand(const MCInstrDesc &Desc, 77e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig unsigned OpNo) const { 78e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 79e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig unsigned RegClass = Desc.OpInfo[OpNo].RegClass; 80e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return (AMDGPU::SSrc_32RegClassID == RegClass) || 81e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig (AMDGPU::SSrc_64RegClassID == RegClass) || 82e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig (AMDGPU::VSrc_32RegClassID == RegClass) || 83e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig (AMDGPU::VSrc_64RegClassID == RegClass); 84e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig} 85e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 86e25e490793241e471036c3e2f969ce6a068e5ce1Christian Koniguint32_t SIMCCodeEmitter::getLitEncoding(const MCOperand &MO) const { 87e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 88e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig IntFloatUnion Imm; 89e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (MO.isImm()) 90e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig Imm.I = MO.getImm(); 91e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig else if (MO.isFPImm()) 92e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig Imm.F = MO.getFPImm(); 93e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig else 94e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return ~0; 95e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 96e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.I >= 0 && Imm.I <= 64) 97e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 128 + Imm.I; 98e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 99e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.I >= -16 && Imm.I <= -1) 100e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 192 + abs(Imm.I); 101e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 102e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.F == 0.5f) 103e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 240; 104e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 105e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.F == -0.5f) 106e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 241; 107e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 108e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.F == 1.0f) 109e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 242; 110e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 111e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.F == -1.0f) 112e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 243; 113e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 114e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.F == 2.0f) 115e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 244; 116e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 117e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.F == -2.0f) 118e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 245; 119e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 120e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Imm.F == 4.0f) 121e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 246; 122e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 123a25b8d4c0b4f6422c58c0ca5c003757bfbf636acChristian Konig if (Imm.F == -4.0f) 124e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 247; 125e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 126e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return 255; 127e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig} 128e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 129f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellardvoid SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 132e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups, STI); 134e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 135e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig unsigned bytes = Desc.getSize(); 136e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 137f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard for (unsigned i = 0; i < bytes; i++) { 138f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard OS.write((uint8_t) ((Encoding >> (8 * i)) & 0xff)); 139f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 140e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 141e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (bytes > 4) 142e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return; 143e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 144e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig // Check for additional literals in SRC0/1/2 (Op 1/2/3) 145e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig for (unsigned i = 0, e = MI.getNumOperands(); i < e; ++i) { 146e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 147e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig // Check if this operand should be encoded as [SV]Src 148e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (!isSrcOperand(Desc, i)) 149e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig continue; 150e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 151e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig // Is this operand a literal immediate? 152e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig const MCOperand &Op = MI.getOperand(i); 153e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (getLitEncoding(Op) != 255) 154e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig continue; 155e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 156e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig // Yes! Encode it 157e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig IntFloatUnion Imm; 158e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Op.isImm()) 159e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig Imm.I = Op.getImm(); 160e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig else 161e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig Imm.F = Op.getFPImm(); 162e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 163e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig for (unsigned j = 0; j < 4; j++) { 164e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig OS.write((uint8_t) ((Imm.I >> (8 * j)) & 0xff)); 165e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig } 166e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 167e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig // Only one literal value allowed 168e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig break; 169e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig } 170f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 171f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 172f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellarduint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI, 173f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard const MCOperand &MO, 17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SmallVectorImpl<MCFixup> &Fixups, 17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSubtargetInfo &STI) const { 176e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (MO.isReg()) 177184f5c1545e06a99951f14d846a1d853ff19a2b8Tom Stellard return MRI.getEncodingValue(MO.getReg()); 178e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 179e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (MO.isExpr()) { 1803ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard const MCExpr *Expr = MO.getExpr(); 1813ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard MCFixupKind Kind = MCFixupKind(FK_PCRel_4); 1823ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard Fixups.push_back(MCFixup::Create(0, Expr, Kind, MI.getLoc())); 1833ee6391e0cddf8d94e2fa441d661c23e494a8489Tom Stellard return 0; 184f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard } 185e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 186e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig // Figure out the operand number, needed for isSrcOperand check 187e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig unsigned OpNo = 0; 188e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig for (unsigned e = MI.getNumOperands(); OpNo < e; ++OpNo) { 189e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (&MO == &MI.getOperand(OpNo)) 190e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig break; 191e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig } 192e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 193e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig const MCInstrDesc &Desc = MCII.get(MI.getOpcode()); 194e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (isSrcOperand(Desc, OpNo)) { 195e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig uint32_t Enc = getLitEncoding(MO); 196e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig if (Enc != ~0U && (Enc != 255 || Desc.getSize() == 4)) 197e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return Enc; 198e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 199e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig } else if (MO.isImm()) 200e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig return MO.getImm(); 201e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig 202e25e490793241e471036c3e2f969ce6a068e5ce1Christian Konig llvm_unreachable("Encoding of this operand type is not supported yet."); 203f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard return 0; 204f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard} 205f98f2ce29e6e2996fa58f38979143eceaa818335Tom Stellard 206