SIInstrInfo.cpp revision ef8e66bc165ea2ef9987ab6406268ce195f74eb0
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 //XXX We need a better way of detecting end of program 110 case AMDIL::RETURN: return AMDIL::S_ENDPGM; 111 default: return AMDGPUInstrInfo::getISAOpcode(AMDILopcode); 112 } 113} 114 115MachineInstr * SIInstrInfo::convertABS_f32(MachineInstr & absInstr, 116 MachineFunction &MF, DebugLoc DL) const 117{ 118 MachineRegisterInfo &MRI = MF.getRegInfo(); 119 MachineOperand &dst = absInstr.getOperand(0); 120 121 /* Convert the desination register to the VReg_32 class */ 122 if (TargetRegisterInfo::isVirtualRegister(dst.getReg())) { 123 MRI.setRegClass(dst.getReg(), AMDIL::VReg_32RegisterClass); 124 } 125 126 return BuildMI(MF, DL, get(AMDIL::V_MOV_B32_e64)) 127 .addOperand(absInstr.getOperand(0)) 128 .addOperand(absInstr.getOperand(1)) 129 /* VSRC1-2 are unused, but we still need to fill all the 130 * operand slots, so we just reuse the VSRC0 operand */ 131 .addOperand(absInstr.getOperand(1)) 132 .addOperand(absInstr.getOperand(1)) 133 .addImm(1) // ABS 134 .addImm(0) // CLAMP 135 .addImm(0) // OMOD 136 .addImm(0); // NEG 137} 138 139MachineInstr * SIInstrInfo::convertCLAMP_f32(MachineInstr & clampInstr, 140 MachineFunction &MF, DebugLoc DL) const 141{ 142 MachineRegisterInfo &MRI = MF.getRegInfo(); 143 /* XXX: HACK assume that low == zero and high == one for now until 144 * we have a way to propogate the immediates. */ 145 146/* 147 uint32_t zero = (uint32_t)APFloat(0.0f).bitcastToAPInt().getZExtValue(); 148 uint32_t one = (uint32_t)APFloat(1.0f).bitcastToAPInt().getZExtValue(); 149 uint32_t low = clampInstr.getOperand(2).getImm(); 150 uint32_t high = clampInstr.getOperand(3).getImm(); 151*/ 152// if (low == zero && high == one) { 153 154 /* Convert the desination register to the VReg_32 class */ 155 if (TargetRegisterInfo::isVirtualRegister(clampInstr.getOperand(0).getReg())) { 156 MRI.setRegClass(clampInstr.getOperand(0).getReg(), 157 AMDIL::VReg_32RegisterClass); 158 } 159 return BuildMI(MF, DL, get(AMDIL::V_MOV_B32_e64)) 160 .addOperand(clampInstr.getOperand(0)) 161 .addOperand(clampInstr.getOperand(1)) 162 /* VSRC1-2 are unused, but we still need to fill all the 163 * operand slots, so we just reuse the VSRC0 operand */ 164 .addOperand(clampInstr.getOperand(1)) 165 .addOperand(clampInstr.getOperand(1)) 166 .addImm(0) // ABS 167 .addImm(1) // CLAMP 168 .addImm(0) // OMOD 169 .addImm(0); // NEG 170// } else { 171 /* XXX: Handle other cases */ 172// abort(); 173// } 174} 175