diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2012-07-16 18:19:53 +0000 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2012-07-16 18:19:53 +0000 |
commit | 1be1aa84ecd5cb975535097a7ad653d4ac8fd17a (patch) | |
tree | 3a700e4e9168be657b0bf48b34786de85de7e2d0 /llvm/lib/Target/AMDGPU/SICodeEmitter.cpp | |
parent | adf452260ffaba71892c2e78db06da8e0a2b57d4 (diff) | |
download | bcm5719-llvm-1be1aa84ecd5cb975535097a7ad653d4ac8fd17a.tar.gz bcm5719-llvm-1be1aa84ecd5cb975535097a7ad653d4ac8fd17a.zip |
Revert "AMDGPU: Add core backend files for R600/SI codegen v6"
This reverts commit 4ea70107c5e51230e9e60f0bf58a0f74aa4885ea.
llvm-svn: 160303
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SICodeEmitter.cpp')
-rw-r--r-- | llvm/lib/Target/AMDGPU/SICodeEmitter.cpp | 321 |
1 files changed, 0 insertions, 321 deletions
diff --git a/llvm/lib/Target/AMDGPU/SICodeEmitter.cpp b/llvm/lib/Target/AMDGPU/SICodeEmitter.cpp deleted file mode 100644 index f169287f038..00000000000 --- a/llvm/lib/Target/AMDGPU/SICodeEmitter.cpp +++ /dev/null @@ -1,321 +0,0 @@ -//===-- SICodeEmitter.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 "AMDGPU.h" -#include "AMDGPUUtil.h" -#include "AMDILCodeEmitter.h" -#include "SIInstrInfo.h" -#include "SIMachineFunctionInfo.h" -#include "llvm/CodeGen/MachineFunctionPass.h" -#include "llvm/CodeGen/MachineInstr.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Target/TargetMachine.h" - -#include <stdio.h> - -#define LITERAL_REG 255 -#define VGPR_BIT(src_idx) (1ULL << (9 * src_idx - 1)) -using namespace llvm; - -namespace { - - class SICodeEmitter : public MachineFunctionPass, public AMDILCodeEmitter { - - private: - static char ID; - formatted_raw_ostream &_OS; - const TargetMachine *TM; - void emitState(MachineFunction & MF); - void emitInstr(MachineInstr &MI); - - void outputBytes(uint64_t value, unsigned bytes); - unsigned GPRAlign(const MachineInstr &MI, unsigned OpNo, unsigned shift) - const; - - public: - SICodeEmitter(formatted_raw_ostream &OS) : MachineFunctionPass(ID), - _OS(OS), TM(NULL) { } - const char *getPassName() const { return "SI Code Emitter"; } - bool runOnMachineFunction(MachineFunction &MF); - - /// getMachineOpValue - Return the encoding for MO - virtual uint64_t getMachineOpValue(const MachineInstr &MI, - const MachineOperand &MO) const; - - /// GPR4AlignEncode - Encoding for when 4 consectuive registers are used - virtual unsigned GPR4AlignEncode(const MachineInstr &MI, unsigned OpNo) - const; - - /// GPR2AlignEncode - Encoding for when 2 consecutive registers are used - virtual unsigned GPR2AlignEncode(const MachineInstr &MI, unsigned OpNo) - 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 MachineInstr &MI, unsigned OpNo) - const; - /// SMRDmemriEncode - Encoding for SMRD indexed loads - virtual uint32_t SMRDmemriEncode(const MachineInstr &MI, unsigned OpNo) - const; - - /// VOPPostEncode - Post-Encoder method for VOP instructions - virtual uint64_t VOPPostEncode(const MachineInstr &MI, - uint64_t Value) const; - }; -} - -char SICodeEmitter::ID = 0; - -FunctionPass *llvm::createSICodeEmitterPass(formatted_raw_ostream &OS) { - return new SICodeEmitter(OS); -} - -void SICodeEmitter::emitState(MachineFunction & MF) -{ - unsigned maxSGPR = 0; - unsigned maxVGPR = 0; - bool VCCUsed = false; - const SIRegisterInfo * RI = - static_cast<const SIRegisterInfo*>(TM->getRegisterInfo()); - SIMachineFunctionInfo * MFI = MF.getInfo<SIMachineFunctionInfo>(); - - for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); - BB != BB_E; ++BB) { - MachineBasicBlock &MBB = *BB; - for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); - I != E; ++I) { - MachineInstr &MI = *I; - unsigned numOperands = MI.getNumOperands(); - for (unsigned op_idx = 0; op_idx < numOperands; op_idx++) { - MachineOperand & MO = MI.getOperand(op_idx); - unsigned maxUsed; - unsigned width = 0; - bool isSGPR = false; - unsigned reg; - unsigned hwReg; - if (!MO.isReg()) { - continue; - } - reg = MO.getReg(); - if (reg == AMDGPU::VCC) { - VCCUsed = true; - continue; - } - if (AMDGPU::SReg_32RegClass.contains(reg)) { - isSGPR = true; - width = 1; - } else if (AMDGPU::VReg_32RegClass.contains(reg)) { - isSGPR = false; - width = 1; - } else if (AMDGPU::SReg_64RegClass.contains(reg)) { - isSGPR = true; - width = 2; - } else if (AMDGPU::VReg_64RegClass.contains(reg)) { - isSGPR = false; - width = 2; - } else if (AMDGPU::SReg_128RegClass.contains(reg)) { - isSGPR = true; - width = 4; - } else if (AMDGPU::VReg_128RegClass.contains(reg)) { - isSGPR = false; - width = 4; - } else if (AMDGPU::SReg_256RegClass.contains(reg)) { - isSGPR = true; - width = 8; - } else { - assert("!Unknown register class"); - } - hwReg = RI->getEncodingValue(reg); - maxUsed = ((hwReg + 1) * width) - 1; - if (isSGPR) { - maxSGPR = maxUsed > maxSGPR ? maxUsed : maxSGPR; - } else { - maxVGPR = maxUsed > maxVGPR ? maxUsed : maxVGPR; - } - } - } - } - if (VCCUsed) { - maxSGPR += 2; - } - outputBytes(maxSGPR + 1, 4); - outputBytes(maxVGPR + 1, 4); - outputBytes(MFI->spi_ps_input_addr, 4); -} - -bool SICodeEmitter::runOnMachineFunction(MachineFunction &MF) -{ - TM = &MF.getTarget(); - const AMDILSubtarget &STM = TM->getSubtarget<AMDILSubtarget>(); - - if (STM.dumpCode()) { - MF.dump(); - } - - emitState(MF); - - for (MachineFunction::iterator BB = MF.begin(), BB_E = MF.end(); - BB != BB_E; ++BB) { - MachineBasicBlock &MBB = *BB; - for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); - I != E; ++I) { - MachineInstr &MI = *I; - if (MI.getOpcode() != AMDGPU::KILL && MI.getOpcode() != AMDGPU::RETURN) { - emitInstr(MI); - } - } - } - // Emit S_END_PGM - MachineInstr * End = BuildMI(MF, DebugLoc(), - TM->getInstrInfo()->get(AMDGPU::S_ENDPGM)); - emitInstr(*End); - return false; -} - -void SICodeEmitter::emitInstr(MachineInstr &MI) -{ - const SIInstrInfo * SII = static_cast<const SIInstrInfo*>(TM->getInstrInfo()); - - uint64_t hwInst = getBinaryCodeForInstr(MI); - - if ((hwInst & 0xffffffff) == 0xffffffff) { - fprintf(stderr, "Unsupported Instruction: \n"); - MI.dump(); - abort(); - } - - unsigned bytes = SII->getEncodingBytes(MI); - outputBytes(hwInst, bytes); -} - -uint64_t SICodeEmitter::getMachineOpValue(const MachineInstr &MI, - const MachineOperand &MO) const -{ - const SIRegisterInfo * RI = - static_cast<const SIRegisterInfo*>(TM->getRegisterInfo()); - - switch(MO.getType()) { - case MachineOperand::MO_Register: - return RI->getEncodingValue(MO.getReg()); - - case MachineOperand::MO_Immediate: - return MO.getImm(); - - case MachineOperand::MO_FPImmediate: - // XXX: Not all instructions can use inline literals - // XXX: We should make sure this is a 32-bit constant - return LITERAL_REG | (MO.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue() << 32); - default: - llvm_unreachable("Encoding of this operand type is not supported yet."); - break; - } -} - -unsigned SICodeEmitter::GPRAlign(const MachineInstr &MI, unsigned OpNo, - unsigned shift) const -{ - const SIRegisterInfo * RI = - static_cast<const SIRegisterInfo*>(TM->getRegisterInfo()); - unsigned regCode = RI->getEncodingValue(MI.getOperand(OpNo).getReg()); - return regCode >> shift; -} - -unsigned SICodeEmitter::GPR4AlignEncode(const MachineInstr &MI, - unsigned OpNo) const -{ - return GPRAlign(MI, OpNo, 2); -} - -unsigned SICodeEmitter::GPR2AlignEncode(const MachineInstr &MI, - unsigned OpNo) const -{ - return GPRAlign(MI, OpNo, 1); -} - -uint64_t SICodeEmitter::i32LiteralEncode(const MachineInstr &MI, - unsigned OpNo) 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 SICodeEmitter::SMRDmemriEncode(const MachineInstr &MI, - unsigned OpNo) const -{ - uint32_t encoding; - - const MachineOperand &OffsetOp = MI.getOperand(OpNo + 1); - - //XXX: Use this function for SMRD loads with register offsets - assert(OffsetOp.isImm()); - - encoding = - (getMachineOpValue(MI, OffsetOp) & SMRD_OFFSET_MASK) - | (1 << SMRD_IMM_SHIFT) //XXX If the Offset is a register we shouldn't set this bit - | ((GPR2AlignEncode(MI, OpNo) & SMRD_SBASE_MASK) << SMRD_SBASE_SHIFT) - ; - - return encoding; -} - -/// Set the "VGPR" bit for VOP args that can take either a VGPR or a SGPR. -/// XXX: It would be nice if we could handle this without a PostEncode function. -uint64_t SICodeEmitter::VOPPostEncode(const MachineInstr &MI, - uint64_t Value) const -{ - const SIInstrInfo * SII = static_cast<const SIInstrInfo*>(TM->getInstrInfo()); - unsigned encodingType = SII->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++) { - if (!MI.getOperand(opIdx).isReg()) { - continue; - } - unsigned reg = MI.getOperand(opIdx).getReg(); - if (AMDGPU::VReg_32RegClass.contains(reg) - || AMDGPU::VReg_64RegClass.contains(reg)) { - Value |= (VGPR_BIT(opIdx)) << vgprBitOffset; - } - } - return Value; -} - - -void SICodeEmitter::outputBytes(uint64_t value, unsigned bytes) -{ - for (unsigned i = 0; i < bytes; i++) { - _OS.write((uint8_t) ((value >> (8 * i)) & 0xff)); - } -} |