summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon/MCTargetDesc
diff options
context:
space:
mode:
authorTom Stellard <[email protected]>2012-08-17 19:42:11 +0000
committerTom Stellard <[email protected]>2012-08-23 15:00:48 +0000
commit235318a578b3d7772a60590c7e76791ed6d1a78e (patch)
tree91891bdde0a4a16ed4ce49d711c86ec6ffc04233 /src/gallium/drivers/radeon/MCTargetDesc
parent2de24024c1ca5366e76f449b115392a97808ef2d (diff)
radeon/llvm: Use the MCCodeEmitter for SI
Diffstat (limited to 'src/gallium/drivers/radeon/MCTargetDesc')
-rw-r--r--src/gallium/drivers/radeon/MCTargetDesc/AMDGPUAsmBackend.cpp80
-rw-r--r--src/gallium/drivers/radeon/MCTargetDesc/AMDGPUMCCodeEmitter.h59
-rw-r--r--src/gallium/drivers/radeon/MCTargetDesc/AMDILMCAsmInfo.cpp8
-rw-r--r--src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.cpp16
-rw-r--r--src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.h12
-rw-r--r--src/gallium/drivers/radeon/MCTargetDesc/SIMCCodeEmitter.cpp309
6 files changed, 478 insertions, 6 deletions
diff --git a/src/gallium/drivers/radeon/MCTargetDesc/AMDGPUAsmBackend.cpp b/src/gallium/drivers/radeon/MCTargetDesc/AMDGPUAsmBackend.cpp
new file mode 100644
index 00000000000..10bf5a39366
--- /dev/null
+++ b/src/gallium/drivers/radeon/MCTargetDesc/AMDGPUAsmBackend.cpp
@@ -0,0 +1,80 @@
+//===-- AMDGPUAsmBackend.cpp - AMDGPU Assembler Backend -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/AMDILMCTargetDesc.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/MC/MCAsmBackend.h"
+#include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCObjectWriter.h"
+#include "llvm/MC/MCValue.h"
+#include "llvm/Support/TargetRegistry.h"
+
+using namespace llvm;
+
+namespace {
+
+class AMDGPUMCObjectWriter : public MCObjectWriter {
+public:
+ AMDGPUMCObjectWriter(raw_ostream &OS) : MCObjectWriter(OS, true) { }
+ virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ //XXX: Implement if necessary.
+ }
+ virtual void RecordRelocation(const MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCFragment *Fragment,
+ const MCFixup &Fixup,
+ MCValue Target, uint64_t &FixedValue) {
+ assert(!"Not implemented");
+ }
+
+ virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout);
+
+};
+
+class AMDGPUAsmBackend : public MCAsmBackend {
+public:
+ AMDGPUAsmBackend(const Target &T)
+ : MCAsmBackend() {}
+
+ virtual AMDGPUMCObjectWriter *createObjectWriter(raw_ostream &OS) const;
+ virtual unsigned getNumFixupKinds() const { return 0; };
+ virtual void applyFixup(const MCFixup &Fixup, char *Data, unsigned DataSize,
+ uint64_t Value) const { assert(!"Not implemented"); }
+ virtual bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
+ const MCInstFragment *DF,
+ const MCAsmLayout &Layout) const {
+ return false;
+ }
+ virtual void relaxInstruction(const MCInst &Inst, MCInst &Res) const {
+ assert(!"Not implemented");
+ }
+ virtual bool mayNeedRelaxation(const MCInst &Inst) const { return false; }
+ virtual bool writeNopData(uint64_t Count, MCObjectWriter *OW) const {
+ return true;
+ }
+};
+
+} //End anonymous namespace
+
+void AMDGPUMCObjectWriter::WriteObject(MCAssembler &Asm,
+ const MCAsmLayout &Layout) {
+ for (MCAssembler::iterator I = Asm.begin(), E = Asm.end(); I != E; ++I) {
+ Asm.writeSectionData(I, Layout);
+ }
+}
+
+MCAsmBackend *llvm::createAMDGPUAsmBackend(const Target &T, StringRef TT) {
+ return new AMDGPUAsmBackend(T);
+}
+
+AMDGPUMCObjectWriter * AMDGPUAsmBackend::createObjectWriter(
+ raw_ostream &OS) const {
+ return new AMDGPUMCObjectWriter(OS);
+}
diff --git a/src/gallium/drivers/radeon/MCTargetDesc/AMDGPUMCCodeEmitter.h b/src/gallium/drivers/radeon/MCTargetDesc/AMDGPUMCCodeEmitter.h
new file mode 100644
index 00000000000..a75a8414e6c
--- /dev/null
+++ b/src/gallium/drivers/radeon/MCTargetDesc/AMDGPUMCCodeEmitter.h
@@ -0,0 +1,59 @@
+//===-- AMDGPUCodeEmitter.h - AMDGPU Code Emitter interface -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// CodeEmitter interface for R600 and SI codegen.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef AMDGPUCODEEMITTER_H
+#define AMDGPUCODEEMITTER_H
+
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+
+ class MCInst;
+ class MCOperand;
+
+ class AMDGPUMCCodeEmitter : public MCCodeEmitter {
+ public:
+
+ uint64_t getBinaryCodeForInstr(const MCInst &MI,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
+ virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ return 0;
+ }
+
+ virtual unsigned GPR4AlignEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ return 0;
+ }
+ virtual unsigned GPR2AlignEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ return 0;
+ }
+ virtual uint64_t VOPPostEncode(const MCInst &MI, uint64_t Value) const {
+ return Value;
+ }
+ virtual uint64_t i32LiteralEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ return 0;
+ }
+ virtual uint32_t SMRDmemriEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ return 0;
+ }
+ };
+
+} // End namespace llvm
+
+#endif // AMDGPUCODEEMITTER_H
diff --git a/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCAsmInfo.cpp b/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCAsmInfo.cpp
index 5b62311c6e6..1f3e4e7c0d4 100644
--- a/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCAsmInfo.cpp
+++ b/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCAsmInfo.cpp
@@ -19,6 +19,8 @@
using namespace llvm;
AMDILMCAsmInfo::AMDILMCAsmInfo(const Target &T, StringRef &TT) : MCAsmInfo()
{
+ HasSingleParameterDotFile = false;
+ WeakDefDirective = NULL;
//===------------------------------------------------------------------===//
HasSubsectionsViaSymbols = true;
HasMachoZeroFillDirective = false;
@@ -67,16 +69,10 @@ AMDILMCAsmInfo::AMDILMCAsmInfo(const Target &T, StringRef &TT) : MCAsmInfo()
LCOMMDirectiveType = LCOMM::None;
COMMDirectiveAlignmentIsInBytes = false;
HasDotTypeDotSizeDirective = false;
- HasSingleParameterDotFile = true;
HasNoDeadStrip = true;
HasSymbolResolver = false;
WeakRefDirective = ".weakref\t";
- WeakDefDirective = ".weakdef\t";
LinkOnceDirective = NULL;
- HiddenVisibilityAttr = MCSA_Hidden;
- HiddenDeclarationVisibilityAttr = MCSA_Hidden;
- ProtectedVisibilityAttr = MCSA_Protected;
-
//===--- Dwarf Emission Directives -----------------------------------===//
HasLEB128 = true;
SupportsDebugInformation = true;
diff --git a/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.cpp b/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.cpp
index 24cfb1f5355..6da38a67305 100644
--- a/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.cpp
+++ b/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.cpp
@@ -5,6 +5,7 @@
#include "llvm/MC/MCCodeGenInfo.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TargetRegistry.h"
@@ -56,6 +57,15 @@ static MCInstPrinter *createAMDGPUMCInstPrinter(const Target &T,
return new AMDGPUInstPrinter(MAI, MII, MRI);
}
+static MCStreamer *createMCStreamer(const Target &T, StringRef TT,
+ MCContext &Ctx, MCAsmBackend &MAB,
+ raw_ostream &_OS,
+ MCCodeEmitter *_Emitter,
+ bool RelaxAll,
+ bool NoExecStack) {
+ return createPureStreamer(Ctx, MAB, _OS, _Emitter);
+}
+
extern "C" void LLVMInitializeAMDGPUTargetMC() {
RegisterMCAsmInfo<AMDILMCAsmInfo> Y(TheAMDGPUTarget);
@@ -69,4 +79,10 @@ extern "C" void LLVMInitializeAMDGPUTargetMC() {
TargetRegistry::RegisterMCSubtargetInfo(TheAMDGPUTarget, createAMDGPUMCSubtargetInfo);
TargetRegistry::RegisterMCInstPrinter(TheAMDGPUTarget, createAMDGPUMCInstPrinter);
+
+ TargetRegistry::RegisterMCCodeEmitter(TheAMDGPUTarget, createAMDGPUMCCodeEmitter);
+
+ TargetRegistry::RegisterMCAsmBackend(TheAMDGPUTarget, createAMDGPUAsmBackend);
+
+ TargetRegistry::RegisterMCObjectStreamer(TheAMDGPUTarget, createMCStreamer);
}
diff --git a/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.h b/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.h
index 2eab136e67a..d693ecc7069 100644
--- a/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.h
+++ b/src/gallium/drivers/radeon/MCTargetDesc/AMDILMCTargetDesc.h
@@ -15,12 +15,24 @@
#ifndef AMDILMCTARGETDESC_H
#define AMDILMCTARGETDESC_H
+#include "llvm/ADT/StringRef.h"
+
namespace llvm {
+class MCAsmBackend;
+class MCCodeEmitter;
+class MCContext;
+class MCInstrInfo;
+class MCRegisterInfo;
class MCSubtargetInfo;
class Target;
extern Target TheAMDGPUTarget;
+MCCodeEmitter *createAMDGPUMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx);
+
+MCAsmBackend *createAMDGPUAsmBackend(const Target &T, StringRef TT);
} // End llvm namespace
#define GET_REGINFO_ENUM
diff --git a/src/gallium/drivers/radeon/MCTargetDesc/SIMCCodeEmitter.cpp b/src/gallium/drivers/radeon/MCTargetDesc/SIMCCodeEmitter.cpp
new file mode 100644
index 00000000000..1d7e84fdc5c
--- /dev/null
+++ b/src/gallium/drivers/radeon/MCTargetDesc/SIMCCodeEmitter.cpp
@@ -0,0 +1,309 @@
+//===-- SIMCCodeEmitter.cpp - SI Code Emitter -------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The SI code emitter produces machine code that can be executed directly on
+// the GPU device.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCTargetDesc/AMDILMCTargetDesc.h"
+#include "MCTargetDesc/AMDGPUMCCodeEmitter.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/raw_ostream.h"
+
+#define LITERAL_REG 255
+#define VGPR_BIT(src_idx) (1ULL << (9 * src_idx - 1))
+#define SI_INSTR_FLAGS_ENCODING_MASK 0xf
+
+
+// These must be kept in sync with SIInstructions.td and also the
+// InstrEncodingInfo array in SIInstrInfo.cpp.
+//
+// NOTE: This enum is only used to identify the encoding type within LLVM,
+// the actual encoding type that is part of the instruction format is different
+namespace SIInstrEncodingType {
+ enum Encoding {
+ EXP = 0,
+ LDS = 1,
+ MIMG = 2,
+ MTBUF = 3,
+ MUBUF = 4,
+ SMRD = 5,
+ SOP1 = 6,
+ SOP2 = 7,
+ SOPC = 8,
+ SOPK = 9,
+ SOPP = 10,
+ VINTRP = 11,
+ VOP1 = 12,
+ VOP2 = 13,
+ VOP3 = 14,
+ VOPC = 15
+ };
+}
+
+using namespace llvm;
+
+namespace {
+class SIMCCodeEmitter : public AMDGPUMCCodeEmitter {
+ SIMCCodeEmitter(const SIMCCodeEmitter &); // DO NOT IMPLEMENT
+ void operator=(const SIMCCodeEmitter &); // DO NOT IMPLEMENT
+ const MCInstrInfo &MCII;
+ const MCSubtargetInfo &STI;
+ MCContext &Ctx;
+
+public:
+ SIMCCodeEmitter(const MCInstrInfo &mcii, const MCSubtargetInfo &sti,
+ MCContext &ctx)
+ : MCII(mcii), STI(sti), Ctx(ctx) { }
+
+ ~SIMCCodeEmitter() { }
+
+ /// getBinaryCodeForInstr - Function generated by tablegen for encoding
+ /// instructions based on the *.td files.
+// virtual uint64_t getBinaryCodeForInstr(const MCInst &MI,
+// SmallVectorImpl<MCFixup> &Fixups) const;
+
+ /// EncodeInstruction - Encode the instruction and write it to the OS.
+ virtual void EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
+ /// getMachineOpValue - Reutrn the encoding for an MCOperand.
+ virtual uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
+ SmallVectorImpl<MCFixup> &Fixups) const;
+
+public:
+
+ /// GPRAlign - Encode a sequence of registers with the correct alignment.
+ unsigned GPRAlign(const MCInst &MI, unsigned OpNo, unsigned shift) const;
+
+ /// GPR2AlignEncode - Encoding for when 2 consecutive registers are used
+ virtual unsigned GPR2AlignEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixup) const;
+
+ /// GPR4AlignEncode - Encoding for when 4 consectuive registers are used
+ virtual unsigned GPR4AlignEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixup) const;
+
+ /// i32LiteralEncode - Encode an i32 literal this is used as an operand
+ /// for an instruction in place of a register.
+ virtual uint64_t i32LiteralEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixup) const;
+
+ /// SMRDmemriEncode - Encoding for SMRD indexed loads
+ virtual uint32_t SMRDmemriEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixup) const;
+
+ /// VOPPostEncode - Post-Encoder method for VOP instructions
+ virtual uint64_t VOPPostEncode(const MCInst &MI, uint64_t Value) const;
+
+private:
+
+ ///getEncodingType = Return this SIInstrEncodingType for this instruction.
+ unsigned getEncodingType(const MCInst &MI) const;
+
+ ///getEncodingBytes - Get then size in bytes of this instructions encoding.
+ unsigned getEncodingBytes(const MCInst &MI) const;
+
+ /// getRegBinaryCode - Returns the hardware encoding for a register
+ unsigned getRegBinaryCode(unsigned reg) const;
+
+ /// getHWRegNum - Generated function that returns the hardware encoding for
+ /// a register
+ unsigned getHWRegNum(unsigned reg) const;
+
+};
+
+} // End anonymous namespace
+
+MCCodeEmitter *llvm::createAMDGPUMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCSubtargetInfo &STI,
+ MCContext &Ctx) {
+ if (STI.getFeatureBits() & AMDGPU::Feature64BitPtr) {
+ return new SIMCCodeEmitter(MCII, STI, Ctx);
+ } else {
+ return NULL;
+ }
+}
+
+void SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups);
+ unsigned bytes = getEncodingBytes(MI);
+ for (unsigned i = 0; i < bytes; i++) {
+ OS.write((uint8_t) ((Encoding >> (8 * i)) & 0xff));
+ }
+}
+
+uint64_t SIMCCodeEmitter::getMachineOpValue(const MCInst &MI,
+ const MCOperand &MO,
+ SmallVectorImpl<MCFixup> &Fixups) const {
+ if (MO.isReg()) {
+ return getRegBinaryCode(MO.getReg());
+ } else if (MO.isImm()) {
+ return MO.getImm();
+ } else if (MO.isFPImm()) {
+ // XXX: Not all instructions can use inline literals
+ // XXX: We should make sure this is a 32-bit constant
+ return LITERAL_REG;
+ } else{
+ llvm_unreachable("Encoding of this operand type is not supported yet.");
+ }
+ return 0;
+}
+
+//===----------------------------------------------------------------------===//
+// Custom Operand Encodings
+//===----------------------------------------------------------------------===//
+
+unsigned SIMCCodeEmitter::GPRAlign(const MCInst &MI, unsigned OpNo,
+ unsigned shift) const {
+ unsigned regCode = getRegBinaryCode(MI.getOperand(OpNo).getReg());
+ return regCode >> shift;
+ return 0;
+}
+unsigned SIMCCodeEmitter::GPR2AlignEncode(const MCInst &MI,
+ unsigned OpNo ,
+ SmallVectorImpl<MCFixup> &Fixup) const {
+ return GPRAlign(MI, OpNo, 1);
+}
+
+unsigned SIMCCodeEmitter::GPR4AlignEncode(const MCInst &MI,
+ unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixup) const {
+ return GPRAlign(MI, OpNo, 2);
+}
+
+uint64_t SIMCCodeEmitter::i32LiteralEncode(const MCInst &MI,
+ unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixup) const {
+ return LITERAL_REG | (MI.getOperand(OpNo).getImm() << 32);
+}
+
+#define SMRD_OFFSET_MASK 0xff
+#define SMRD_IMM_SHIFT 8
+#define SMRD_SBASE_MASK 0x3f
+#define SMRD_SBASE_SHIFT 9
+/// SMRDmemriEncode - This function is responsibe for encoding the offset
+/// and the base ptr for SMRD instructions it should return a bit string in
+/// this format:
+///
+/// OFFSET = bits{7-0}
+/// IMM = bits{8}
+/// SBASE = bits{14-9}
+///
+uint32_t SIMCCodeEmitter::SMRDmemriEncode(const MCInst &MI, unsigned OpNo,
+ SmallVectorImpl<MCFixup> &Fixup) const {
+ uint32_t Encoding;
+
+ const MCOperand &OffsetOp = MI.getOperand(OpNo + 1);
+
+ //XXX: Use this function for SMRD loads with register offsets
+ assert(OffsetOp.isImm());
+
+ Encoding =
+ (getMachineOpValue(MI, OffsetOp, Fixup) & SMRD_OFFSET_MASK)
+ | (1 << SMRD_IMM_SHIFT) //XXX If the Offset is a register we shouldn't set this bit
+ | ((GPR2AlignEncode(MI, OpNo, Fixup) & SMRD_SBASE_MASK) << SMRD_SBASE_SHIFT)
+ ;
+
+ return Encoding;
+}
+
+//===----------------------------------------------------------------------===//
+// Post Encoder Callbacks
+//===----------------------------------------------------------------------===//
+
+uint64_t SIMCCodeEmitter::VOPPostEncode(const MCInst &MI, uint64_t Value) const{
+ unsigned encodingType = getEncodingType(MI);
+ unsigned numSrcOps;
+ unsigned vgprBitOffset;
+
+ if (encodingType == SIInstrEncodingType::VOP3) {
+ numSrcOps = 3;
+ vgprBitOffset = 32;
+ } else {
+ numSrcOps = 1;
+ vgprBitOffset = 0;
+ }
+
+ // Add one to skip over the destination reg operand.
+ for (unsigned opIdx = 1; opIdx < numSrcOps + 1; opIdx++) {
+ const MCOperand &MO = MI.getOperand(opIdx);
+ if (MO.isReg()) {
+ unsigned reg = MI.getOperand(opIdx).getReg();
+ if (AMDGPUMCRegisterClasses[AMDGPU::VReg_32RegClassID].contains(reg) ||
+ AMDGPUMCRegisterClasses[AMDGPU::VReg_64RegClassID].contains(reg)) {
+ Value |= (VGPR_BIT(opIdx)) << vgprBitOffset;
+ }
+ } else if (MO.isFPImm()) {
+ // XXX: Not all instructions can use inline literals
+ // XXX: We should make sure this is a 32-bit constant
+ Value |= ((uint64_t)MO.getFPImm()) << 32;
+ }
+ }
+ return Value;
+}
+
+//===----------------------------------------------------------------------===//
+// Encoding helper functions
+//===----------------------------------------------------------------------===//
+
+unsigned SIMCCodeEmitter::getEncodingType(const MCInst &MI) const {
+ return MCII.get(MI.getOpcode()).TSFlags & SI_INSTR_FLAGS_ENCODING_MASK;
+}
+
+unsigned SIMCCodeEmitter::getEncodingBytes(const MCInst &MI) const {
+
+ // Instructions with literal constants are expanded to 64-bits, and
+ // the constant is stored in bits [63:32]
+ for (unsigned i = 0; i < MI.getNumOperands(); i++) {
+ if (MI.getOperand(i).isFPImm()) {
+ return 8;
+ }
+ }
+
+ // This instruction always has a literal
+ if (MI.getOpcode() == AMDGPU::S_MOV_IMM_I32) {
+ return 8;
+ }
+
+ unsigned encoding_type = getEncodingType(MI);
+ switch (encoding_type) {
+ case SIInstrEncodingType::EXP:
+ case SIInstrEncodingType::LDS:
+ case SIInstrEncodingType::MUBUF:
+ case SIInstrEncodingType::MTBUF:
+ case SIInstrEncodingType::MIMG:
+ case SIInstrEncodingType::VOP3:
+ return 8;
+ default:
+ return 4;
+ }
+}
+
+
+unsigned SIMCCodeEmitter::getRegBinaryCode(unsigned reg) const {
+ switch (reg) {
+ case AMDGPU::M0: return 124;
+ case AMDGPU::SREG_LIT_0: return 128;
+ default: return getHWRegNum(reg);
+ }
+}
+
+#define SIRegisterInfo SIMCCodeEmitter
+#include "SIRegisterGetHWRegNum.inc"
+#undef SIRegisterInfo
+
+#include "AMDGPUGenMCCodeEmitter.inc"