#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/raw_ostream.h"
-#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 {
/// \brief Encoding for when 4 consectuive registers are used
virtual unsigned GPR4AlignEncode(const MCInst &MI, unsigned OpNo,
SmallVectorImpl<MCFixup> &Fixup) const;
-
- /// \brief Post-Encoder method for VOP instructions
- virtual uint64_t VOPPostEncode(const MCInst &MI, uint64_t Value) const;
-
-private:
-
- /// \returns this SIInstrEncodingType for this instruction.
- unsigned getEncodingType(const MCInst &MI) const;
-
- /// \brief Get then size in bytes of this instructions encoding.
- unsigned getEncodingBytes(const MCInst &MI) const;
-
- /// \returns the hardware encoding for a register
- unsigned getRegBinaryCode(unsigned reg) const;
-
- /// \brief Generated function that returns the hardware encoding for
- /// a register
- unsigned getHWRegNum(unsigned reg) const;
-
};
} // End anonymous namespace
void SIMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups) const {
uint64_t Encoding = getBinaryCodeForInstr(MI, Fixups);
- unsigned bytes = getEncodingBytes(MI);
+ unsigned bytes = MCII.get(MI.getOpcode()).getSize();
for (unsigned i = 0; i < bytes; i++) {
OS.write((uint8_t) ((Encoding >> (8 * i)) & 0xff));
}
const MCOperand &MO,
SmallVectorImpl<MCFixup> &Fixups) const {
if (MO.isReg()) {
- return getRegBinaryCode(MO.getReg());
+ return MRI.getEncodingValue(MO.getReg());
} else if (MO.isImm()) {
return MO.getImm();
} else if (MO.isFPImm()) {
unsigned SIMCCodeEmitter::GPRAlign(const MCInst &MI, unsigned OpNo,
unsigned shift) const {
- unsigned regCode = getRegBinaryCode(MI.getOperand(OpNo).getReg());
- return regCode >> shift;
- return 0;
+ unsigned regCode = MRI.getEncodingValue(MI.getOperand(OpNo).getReg());
+ return (regCode & 0xff) >> shift;
}
unsigned SIMCCodeEmitter::GPR2AlignEncode(const MCInst &MI,
unsigned OpNo ,
SmallVectorImpl<MCFixup> &Fixup) const {
return GPRAlign(MI, OpNo, 2);
}
-
-//===----------------------------------------------------------------------===//
-// 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()) {
- union {
- float f;
- uint32_t i;
- } Imm;
- // XXX: Not all instructions can use inline literals
- // XXX: We should make sure this is a 32-bit constant
- Imm.f = MO.getFPImm();
- Value |= ((uint64_t)Imm.i) << 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 {
-
- // These instructions aren't real instructions with an encoding type, so
- // we need to manually specify their size.
- switch (MI.getOpcode()) {
- default: break;
- case AMDGPU::SI_LOAD_LITERAL_I32:
- case AMDGPU::SI_LOAD_LITERAL_F32:
- return 4;
- }
-
- 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;
- case AMDGPU::SI_LITERAL_CONSTANT: return 255;
- default: return MRI.getEncodingValue(reg);
- }
-}
-
class InstSI <dag outs, dag ins, string asm, list<dag> pattern> :
AMDGPUInst<outs, ins, asm, pattern> {
- field bits<4> EncodingType = 0;
field bits<1> VM_CNT = 0;
field bits<1> EXP_CNT = 0;
field bits<1> LGKM_CNT = 0;
- let TSFlags{3-0} = EncodingType;
- let TSFlags{4} = VM_CNT;
- let TSFlags{5} = EXP_CNT;
- let TSFlags{6} = LGKM_CNT;
+ let TSFlags{0} = VM_CNT;
+ let TSFlags{1} = EXP_CNT;
+ let TSFlags{2} = LGKM_CNT;
}
class Enc32 <dag outs, dag ins, string asm, list<dag> pattern> :
InstSI <outs, ins, asm, pattern> {
field bits<32> Inst;
+ let Size = 4;
}
class Enc64 <dag outs, dag ins, string asm, list<dag> pattern> :
InstSI <outs, ins, asm, pattern> {
field bits<64> Inst;
+ let Size = 8;
}
class SIOperand <ValueType vt, dag opInfo>: Operand <vt> {
let Inst{47-40} = VSRC1;
let Inst{55-48} = VSRC2;
let Inst{63-56} = VSRC3;
- let EncodingType = 0; //SIInstrEncodingType::EXP
let EXP_CNT = 1;
}
let Inst{47-40} = VDATA;
let Inst{52-48} = SRSRC;
let Inst{57-53} = SSAMP;
- let EncodingType = 2; //SIInstrEncodingType::MIMG
let VM_CNT = 1;
let EXP_CNT = 1;
let Inst{54} = SLC;
let Inst{55} = TFE;
let Inst{63-56} = SOFFSET;
- let EncodingType = 3; //SIInstrEncodingType::MTBUF
let VM_CNT = 1;
let EXP_CNT = 1;
let Inst{54} = SLC;
let Inst{55} = TFE;
let Inst{63-56} = SOFFSET;
- let EncodingType = 4; //SIInstrEncodingType::MUBUF
let VM_CNT = 1;
let EXP_CNT = 1;
let Inst{21-15} = SDST;
let Inst{26-22} = op;
let Inst{31-27} = 0x18; //encoding
- let EncodingType = 5; //SIInstrEncodingType::SMRD
let LGKM_CNT = 1;
}
let Inst{15-8} = op;
let Inst{22-16} = SDST;
let Inst{31-23} = 0x17d; //encoding;
- let EncodingType = 6; //SIInstrEncodingType::SOP1
let mayLoad = 0;
let mayStore = 0;
let Inst{22-16} = SDST;
let Inst{29-23} = op;
let Inst{31-30} = 0x2; // encoding
- let EncodingType = 7; // SIInstrEncodingType::SOP2
let mayLoad = 0;
let mayStore = 0;
let Inst{15-8} = SSRC1;
let Inst{22-16} = op;
let Inst{31-23} = 0x17e;
- let EncodingType = 8; // SIInstrEncodingType::SOPC
let DisableEncoding = "$dst";
let mayLoad = 0;
let Inst{22-16} = SDST;
let Inst{27-23} = op;
let Inst{31-28} = 0xb; //encoding
- let EncodingType = 9; // SIInstrEncodingType::SOPK
let mayLoad = 0;
let mayStore = 0;
let Inst{15-0} = SIMM16;
let Inst{22-16} = op;
let Inst{31-23} = 0x17f; // encoding
- let EncodingType = 10; // SIInstrEncodingType::SOPP
let mayLoad = 0;
let mayStore = 0;
let Inst{17-16} = op;
let Inst{25-18} = VDST;
let Inst{31-26} = 0x32; // encoding
- let EncodingType = 11; // SIInstrEncodingType::VINTRP
let neverHasSideEffects = 1;
let mayLoad = 1;
let Inst{24-17} = VDST;
let Inst{31-25} = 0x3f; //encoding
- let EncodingType = 12; // SIInstrEncodingType::VOP1
- let PostEncoderMethod = "VOPPostEncode";
-
let mayLoad = 0;
let mayStore = 0;
let hasSideEffects = 0;
let Inst{30-25} = op;
let Inst{31} = 0x0; //encoding
- let EncodingType = 13; // SIInstrEncodingType::VOP2
- let PostEncoderMethod = "VOPPostEncode";
-
let mayLoad = 0;
let mayStore = 0;
let hasSideEffects = 0;
let Inst{60-59} = OMOD;
let Inst{63-61} = NEG;
- let EncodingType = 14; // SIInstrEncodingType::VOP3
- let PostEncoderMethod = "VOPPostEncode";
-
let mayLoad = 0;
let mayStore = 0;
let hasSideEffects = 0;
let Inst{60-59} = OMOD;
let Inst{63-61} = NEG;
- let EncodingType = 14; // SIInstrEncodingType::VOP3
- let PostEncoderMethod = "VOPPostEncode";
-
let mayLoad = 0;
let mayStore = 0;
let hasSideEffects = 0;
let Inst{24-17} = op;
let Inst{31-25} = 0x3e;
- let EncodingType = 15; //SIInstrEncodingType::VOPC
- let PostEncoderMethod = "VOPPostEncode";
let DisableEncoding = "$dst";
let mayLoad = 0;
let mayStore = 0;