SIInstrInfo.cpp revision f8e9c29020289387f0f429ac6d3c28e73e5847a3
1//===-- SIInstrInfo.cpp - SI Instruction Information ---------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// SI Implementation of TargetInstrInfo. 11// 12//===----------------------------------------------------------------------===// 13 14 15#include "SIInstrInfo.h" 16#include "AMDGPUTargetMachine.h" 17#include "llvm/CodeGen/MachineRegisterInfo.h" 18#include "llvm/MC/MCInstrDesc.h" 19 20#include <stdio.h> 21 22using namespace llvm; 23 24SIInstrInfo::SIInstrInfo(AMDGPUTargetMachine &tm) 25 : AMDGPUInstrInfo(tm), 26 RI(tm, *this), 27 TM(tm) 28 { } 29 30const SIRegisterInfo &SIInstrInfo::getRegisterInfo() const 31{ 32 return RI; 33} 34 35void 36SIInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 37 MachineBasicBlock::iterator MI, DebugLoc DL, 38 unsigned DestReg, unsigned SrcReg, 39 bool KillSrc) const 40{ 41 BuildMI(MBB, MI, DL, get(AMDIL::V_MOV_B32_e32), DestReg) 42 .addReg(SrcReg, getKillRegState(KillSrc)); 43} 44 45unsigned SIInstrInfo::getEncodingType(const MachineInstr &MI) const 46{ 47 return get(MI.getOpcode()).TSFlags & SI_INSTR_FLAGS_ENCODING_MASK; 48} 49 50unsigned SIInstrInfo::getEncodingBytes(const MachineInstr &MI) const 51{ 52 53 /* Instructions with literal constants are expanded to 64-bits, and 54 * the constant is stored in bits [63:32] */ 55 for (unsigned i = 0; i < MI.getNumOperands(); i++) { 56 if (MI.getOperand(i).getType() == MachineOperand::MO_FPImmediate) { 57 return 8; 58 } 59 } 60 61 /* This instruction always has a literal */ 62 if (MI.getOpcode() == AMDIL::S_MOV_IMM_I32) { 63 return 8; 64 } 65 66 unsigned encoding_type = getEncodingType(MI); 67 switch (encoding_type) { 68 case SIInstrEncodingType::EXP: 69 case SIInstrEncodingType::LDS: 70 case SIInstrEncodingType::MUBUF: 71 case SIInstrEncodingType::MTBUF: 72 case SIInstrEncodingType::MIMG: 73 case SIInstrEncodingType::VOP3: 74 return 8; 75 default: 76 return 4; 77 } 78} 79 80MachineInstr * SIInstrInfo::convertToISA(MachineInstr & MI, MachineFunction &MF, 81 DebugLoc DL) const 82{ 83 84 switch (MI.getOpcode()) { 85 default: break; 86 case AMDIL::ABS_f32: return convertABS_f32(MI, MF, DL); 87 case AMDIL::CLAMP_f32: return convertCLAMP_f32(MI, MF, DL); 88 } 89 90 MachineInstr * newMI = AMDGPUInstrInfo::convertToISA(MI, MF, DL); 91 const MCInstrDesc &newDesc = get(newMI->getOpcode()); 92 93 /* If this instruction was converted to a VOP3, we need to add the extra 94 * operands for abs, clamp, omod, and negate. */ 95 if (getEncodingType(*newMI) == SIInstrEncodingType::VOP3 96 && newMI->getNumOperands() < newDesc.getNumOperands()) { 97 MachineInstrBuilder builder(newMI); 98 for (unsigned op_idx = newMI->getNumOperands(); 99 op_idx < newDesc.getNumOperands(); op_idx++) { 100 builder.addImm(0); 101 } 102 } 103 return newMI; 104} 105 106unsigned SIInstrInfo::getISAOpcode(unsigned AMDILopcode) const 107{ 108 switch (AMDILopcode) { 109 case AMDIL::MAD_f32: return AMDIL::V_MAD_LEGACY_F32; 110 //XXX We need a better way of detecting end of program 111 case AMDIL::RETURN: return AMDIL::S_ENDPGM; 112 default: return AMDGPUInstrInfo::getISAOpcode(AMDILopcode); 113 } 114} 115 116MachineInstr * SIInstrInfo::convertABS_f32(MachineInstr & absInstr, 117 MachineFunction &MF, DebugLoc DL) const 118{ 119 MachineRegisterInfo &MRI = MF.getRegInfo(); 120 MachineOperand &dst = absInstr.getOperand(0); 121 122 /* Convert the desination register to the VReg_32 class */ 123 if (TargetRegisterInfo::isVirtualRegister(dst.getReg())) { 124 MRI.setRegClass(dst.getReg(), AMDIL::VReg_32RegisterClass); 125 } 126 127 return BuildMI(MF, DL, get(AMDIL::V_MOV_B32_e64)) 128 .addOperand(absInstr.getOperand(0)) 129 .addOperand(absInstr.getOperand(1)) 130 /* VSRC1-2 are unused, but we still need to fill all the 131 * operand slots, so we just reuse the VSRC0 operand */ 132 .addOperand(absInstr.getOperand(1)) 133 .addOperand(absInstr.getOperand(1)) 134 .addImm(1) // ABS 135 .addImm(0) // CLAMP 136 .addImm(0) // OMOD 137 .addImm(0); // NEG 138} 139 140MachineInstr * SIInstrInfo::convertCLAMP_f32(MachineInstr & clampInstr, 141 MachineFunction &MF, DebugLoc DL) const 142{ 143 MachineRegisterInfo &MRI = MF.getRegInfo(); 144 /* XXX: HACK assume that low == zero and high == one for now until 145 * we have a way to propogate the immediates. */ 146 147/* 148 uint32_t zero = (uint32_t)APFloat(0.0f).bitcastToAPInt().getZExtValue(); 149 uint32_t one = (uint32_t)APFloat(1.0f).bitcastToAPInt().getZExtValue(); 150 uint32_t low = clampInstr.getOperand(2).getImm(); 151 uint32_t high = clampInstr.getOperand(3).getImm(); 152*/ 153// if (low == zero && high == one) { 154 155 /* Convert the desination register to the VReg_32 class */ 156 if (TargetRegisterInfo::isVirtualRegister(clampInstr.getOperand(0).getReg())) { 157 MRI.setRegClass(clampInstr.getOperand(0).getReg(), 158 AMDIL::VReg_32RegisterClass); 159 } 160 return BuildMI(MF, DL, get(AMDIL::V_MOV_B32_e64)) 161 .addOperand(clampInstr.getOperand(0)) 162 .addOperand(clampInstr.getOperand(1)) 163 /* VSRC1-2 are unused, but we still need to fill all the 164 * operand slots, so we just reuse the VSRC0 operand */ 165 .addOperand(clampInstr.getOperand(1)) 166 .addOperand(clampInstr.getOperand(1)) 167 .addImm(0) // ABS 168 .addImm(1) // CLAMP 169 .addImm(0) // OMOD 170 .addImm(0); // NEG 171// } else { 172 /* XXX: Handle other cases */ 173// abort(); 174// } 175} 176