1235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===-- SIMCCodeEmitter.cpp - SI Code Emitter -------------------------------===// 2235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// 3235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// The LLVM Compiler Infrastructure 4235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// 5235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// This file is distributed under the University of Illinois Open Source 6235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// License. See LICENSE.TXT for details. 7235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// 8235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===----------------------------------------------------------------------===// 9235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// 10235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// The SI code emitter produces machine code that can be executed directly on 11235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// the GPU device. 12235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// 13235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===----------------------------------------------------------------------===// 14235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 15228a6641ccddaf24a993f827af1e97379785985aTom Stellard#include "MCTargetDesc/AMDGPUMCTargetDesc.h" 16235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "MCTargetDesc/AMDGPUMCCodeEmitter.h" 17235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "llvm/MC/MCCodeEmitter.h" 18235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "llvm/MC/MCContext.h" 19235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "llvm/MC/MCInst.h" 20235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "llvm/MC/MCInstrInfo.h" 21235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "llvm/MC/MCRegisterInfo.h" 22235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "llvm/MC/MCSubtargetInfo.h" 23235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "llvm/Support/raw_ostream.h" 24235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 25235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#define LITERAL_REG 255 26235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#define VGPR_BIT(src_idx) (1ULL << (9 * src_idx - 1)) 27235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#define SI_INSTR_FLAGS_ENCODING_MASK 0xf 28235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 29235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 30235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// These must be kept in sync with SIInstructions.td and also the 31235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// InstrEncodingInfo array in SIInstrInfo.cpp. 32235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// 33235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// NOTE: This enum is only used to identify the encoding type within LLVM, 34235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// the actual encoding type that is part of the instruction format is different 35235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardnamespace SIInstrEncodingType { 36235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard enum Encoding { 37235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard EXP = 0, 38235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard LDS = 1, 39235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard MIMG = 2, 40235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard MTBUF = 3, 41235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard MUBUF = 4, 42235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SMRD = 5, 43235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SOP1 = 6, 44235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SOP2 = 7, 45235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SOPC = 8, 46235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SOPK = 9, 47235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SOPP = 10, 48235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard VINTRP = 11, 49235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard VOP1 = 12, 50235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard VOP2 = 13, 51235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard VOP3 = 14, 52235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard VOPC = 15 53235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard }; 54235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 55235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 56235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardusing namespace llvm; 57235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 58235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardnamespace { 59235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardclass SIMCCodeEmitter : public AMDGPUMCCodeEmitter { 60235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SIMCCodeEmitter(const SIMCCodeEmitter &); // DO NOT IMPLEMENT 61235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard void operator=(const SIMCCodeEmitter &); // DO NOT IMPLEMENT 62235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard const MCInstrInfo &MCII; 63235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard const MCSubtargetInfo &STI; 64235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard MCContext &Ctx; 65235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 66235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardpublic: 67235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SIMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti, 68235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard MCContext &ctx) 69235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard : MCII(mcii), STI(sti), Ctx(ctx) { } 70235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 71235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard ~SIMCCodeEmitter() { } 72235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 73235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// EncodeInstruction - Encode the instruction and write it to the OS. 74235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS, 75235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixups) const; 76235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 77235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// getMachineOpValue - Reutrn the encoding for an MCOperand. 78235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO, 79235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixups) const; 80235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 81235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardpublic: 82235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 83235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// GPRAlign - Encode a sequence of registers with the correct alignment. 84235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned GPRAlign(const MCInst &MI, unsigned OpNo, unsigned shift) const; 85235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 86235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// GPR2AlignEncode - Encoding for when 2 consecutive registers are used 87235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard virtual unsigned GPR2AlignEncode(const MCInst &MI, unsigned OpNo, 88235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixup) const; 89235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 90235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// GPR4AlignEncode - Encoding for when 4 consectuive registers are used 91235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard virtual unsigned GPR4AlignEncode(const MCInst &MI, unsigned OpNo, 92235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixup) const; 93235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 94235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// i32LiteralEncode - Encode an i32 literal this is used as an operand 95235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// for an instruction in place of a register. 96235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard virtual uint64_t i32LiteralEncode(const MCInst &MI, unsigned OpNo, 97235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixup) const; 98235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 99235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// SMRDmemriEncode - Encoding for SMRD indexed loads 100235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard virtual uint32_t SMRDmemriEncode(const MCInst &MI, unsigned OpNo, 101235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixup) const; 102235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 103235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// VOPPostEncode - Post-Encoder method for VOP instructions 104235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard virtual uint64_t VOPPostEncode(const MCInst &MI, uint64_t Value) const; 105235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 106235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardprivate: 107235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 108235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard ///getEncodingType = Return this SIInstrEncodingType for this instruction. 109235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned getEncodingType(const MCInst &MI) const; 110235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 111235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard ///getEncodingBytes - Get then size in bytes of this instructions encoding. 112235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned getEncodingBytes(const MCInst &MI) const; 113235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 114235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// getRegBinaryCode - Returns the hardware encoding for a register 115235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned getRegBinaryCode(unsigned reg) const; 116235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 117235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// getHWRegNum - Generated function that returns the hardware encoding for 118235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard /// a register 119235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned getHWRegNum(unsigned reg) const; 120235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 121235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard}; 122235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 123235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} // End anonymous namespace 124235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 12590bd1d52bbf95947955a66ec67f5f6c7dc87119aTom StellardMCCodeEmitter *llvm::createSIMCCodeEmitter(const MCInstrInfo &MCII, 12690bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard const MCSubtargetInfo &STI, 12790bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard MCContext &Ctx) { 12890bd1d52bbf95947955a66ec67f5f6c7dc87119aTom Stellard return new SIMCCodeEmitter(MCII, STI, Ctx); 129235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 130235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 131235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardvoid SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, 132235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixups) const { 133235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups); 134235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned bytes = getEncodingBytes(MI); 135235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard for (unsigned i = 0; i < bytes; i++) { 136235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard OS.write((uint8_t) ((Encoding >> (8 * i)) & 0xff)); 137235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 138235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 139235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 140235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellarduint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI, 141235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard const MCOperand &MO, 142235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixups) const { 143235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard if (MO.isReg()) { 144235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return getRegBinaryCode(MO.getReg()); 145235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } else if (MO.isImm()) { 146235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return MO.getImm(); 147235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } else if (MO.isFPImm()) { 148235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard // XXX: Not all instructions can use inline literals 149235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard // XXX: We should make sure this is a 32-bit constant 150235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return LITERAL_REG; 151235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } else{ 152235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard llvm_unreachable("Encoding of this operand type is not supported yet."); 153235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 154235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return 0; 155235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 156235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 157235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===----------------------------------------------------------------------===// 158235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// Custom Operand Encodings 159235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===----------------------------------------------------------------------===// 160235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 161235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardunsigned SIMCCodeEmitter::GPRAlign(const MCInst &MI, unsigned OpNo, 162235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned shift) const { 163235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned regCode = getRegBinaryCode(MI.getOperand(OpNo).getReg()); 164235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return regCode >> shift; 165235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return 0; 166235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 167235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardunsigned SIMCCodeEmitter::GPR2AlignEncode(const MCInst &MI, 168235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned OpNo , 169235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixup) const { 170235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return GPRAlign(MI, OpNo, 1); 171235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 172235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 173235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardunsigned SIMCCodeEmitter::GPR4AlignEncode(const MCInst &MI, 174235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned OpNo, 175235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixup) const { 176235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return GPRAlign(MI, OpNo, 2); 177235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 178235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 179235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellarduint64_t SIMCCodeEmitter::i32LiteralEncode(const MCInst &MI, 180235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned OpNo, 181235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixup) const { 182235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return LITERAL_REG | (MI.getOperand(OpNo).getImm() << 32); 183235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 184235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 185235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#define SMRD_OFFSET_MASK 0xff 186235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#define SMRD_IMM_SHIFT 8 187235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#define SMRD_SBASE_MASK 0x3f 188235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#define SMRD_SBASE_SHIFT 9 189235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// SMRDmemriEncode - This function is responsibe for encoding the offset 190235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// and the base ptr for SMRD instructions it should return a bit string in 191235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// this format: 192235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// 193235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// OFFSET = bits{7-0} 194235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// IMM = bits{8} 195235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// SBASE = bits{14-9} 196235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard/// 197235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellarduint32_t SIMCCodeEmitter::SMRDmemriEncode(const MCInst &MI, unsigned OpNo, 198235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard SmallVectorImpl<MCFixup> &Fixup) const { 199235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard uint32_t Encoding; 200235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 201235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard const MCOperand &OffsetOp = MI.getOperand(OpNo + 1); 202235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 203235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard //XXX: Use this function for SMRD loads with register offsets 204235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard assert(OffsetOp.isImm()); 205235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 206235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard Encoding = 207235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard (getMachineOpValue(MI, OffsetOp, Fixup) & SMRD_OFFSET_MASK) 208235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard | (1 << SMRD_IMM_SHIFT) //XXX If the Offset is a register we shouldn't set this bit 209235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard | ((GPR2AlignEncode(MI, OpNo, Fixup) & SMRD_SBASE_MASK) << SMRD_SBASE_SHIFT) 210235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard ; 211235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 212235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return Encoding; 213235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 214235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 215235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===----------------------------------------------------------------------===// 216235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// Post Encoder Callbacks 217235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===----------------------------------------------------------------------===// 218235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 219235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellarduint64_t SIMCCodeEmitter::VOPPostEncode(const MCInst &MI, uint64_t Value) const{ 220235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned encodingType = getEncodingType(MI); 221235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned numSrcOps; 222235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned vgprBitOffset; 223235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 224235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard if (encodingType == SIInstrEncodingType::VOP3) { 225235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard numSrcOps = 3; 226235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard vgprBitOffset = 32; 227235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } else { 228235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard numSrcOps = 1; 229235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard vgprBitOffset = 0; 230235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 231235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 232235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard // Add one to skip over the destination reg operand. 233235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard for (unsigned opIdx = 1; opIdx < numSrcOps + 1; opIdx++) { 234235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard const MCOperand &MO = MI.getOperand(opIdx); 235235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard if (MO.isReg()) { 236235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned reg = MI.getOperand(opIdx).getReg(); 237235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard if (AMDGPUMCRegisterClasses[AMDGPU::VReg_32RegClassID].contains(reg) || 238235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard AMDGPUMCRegisterClasses[AMDGPU::VReg_64RegClassID].contains(reg)) { 239235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard Value |= (VGPR_BIT(opIdx)) << vgprBitOffset; 240235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 241235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } else if (MO.isFPImm()) { 2422809ae3d445bc10a79f119946439431ba73bb069Tom Stellard union { 2432809ae3d445bc10a79f119946439431ba73bb069Tom Stellard float f; 2442809ae3d445bc10a79f119946439431ba73bb069Tom Stellard uint32_t i; 2452809ae3d445bc10a79f119946439431ba73bb069Tom Stellard } Imm; 246235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard // XXX: Not all instructions can use inline literals 247235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard // XXX: We should make sure this is a 32-bit constant 2482809ae3d445bc10a79f119946439431ba73bb069Tom Stellard Imm.f = MO.getFPImm(); 2492809ae3d445bc10a79f119946439431ba73bb069Tom Stellard Value |= ((uint64_t)Imm.i) << 32; 250235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 251235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 252235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return Value; 253235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 254235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 255235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===----------------------------------------------------------------------===// 256235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard// Encoding helper functions 257235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard//===----------------------------------------------------------------------===// 258235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 259235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardunsigned SIMCCodeEmitter::getEncodingType(const MCInst &MI) const { 260235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return MCII.get(MI.getOpcode()).TSFlags & SI_INSTR_FLAGS_ENCODING_MASK; 261235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 262235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 263235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardunsigned SIMCCodeEmitter::getEncodingBytes(const MCInst &MI) const { 264235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 265235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard // Instructions with literal constants are expanded to 64-bits, and 266235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard // the constant is stored in bits [63:32] 267235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard for (unsigned i = 0; i < MI.getNumOperands(); i++) { 268235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard if (MI.getOperand(i).isFPImm()) { 269235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return 8; 270235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 271235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 272235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 273235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard // This instruction always has a literal 274235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard if (MI.getOpcode() == AMDGPU::S_MOV_IMM_I32) { 275235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return 8; 276235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 277235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 278235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard unsigned encoding_type = getEncodingType(MI); 279235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard switch (encoding_type) { 280235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard case SIInstrEncodingType::EXP: 281235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard case SIInstrEncodingType::LDS: 282235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard case SIInstrEncodingType::MUBUF: 283235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard case SIInstrEncodingType::MTBUF: 284235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard case SIInstrEncodingType::MIMG: 285235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard case SIInstrEncodingType::VOP3: 286235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return 8; 287235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard default: 288235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard return 4; 289235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 290235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 291235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 292235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 293235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellardunsigned SIMCCodeEmitter::getRegBinaryCode(unsigned reg) const { 294235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard switch (reg) { 295235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard case AMDGPU::M0: return 124; 296235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard case AMDGPU::SREG_LIT_0: return 128; 297235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard default: return getHWRegNum(reg); 298235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard } 299235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard} 300235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard 301235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#define SIRegisterInfo SIMCCodeEmitter 302235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#include "SIRegisterGetHWRegNum.inc" 303235318a578b3d7772a60590c7e76791ed6d1a78eTom Stellard#undef SIRegisterInfo 304