//===-- R600InstrInfo.cpp - R600 Instruction Information ------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // R600 Implementation of TargetInstrInfo. // //===----------------------------------------------------------------------===// #include "R600InstrInfo.h" #include "AMDGPUTargetMachine.h" #include "R600RegisterInfo.h" using namespace llvm; R600InstrInfo::R600InstrInfo(AMDGPUTargetMachine &tm) : AMDGPUInstrInfo(tm), RI(tm, *this), TM(tm) { } const R600RegisterInfo &R600InstrInfo::getRegisterInfo() const { return RI; } bool R600InstrInfo::isTrig(const MachineInstr &MI) const { return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG; } void R600InstrInfo::copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, DebugLoc DL, unsigned DestReg, unsigned SrcReg, bool KillSrc) const { unsigned subRegMap[4] = {AMDIL::sel_x, AMDIL::sel_y, AMDIL::sel_z, AMDIL::sel_w}; if (AMDIL::R600_Reg128RegClass.contains(DestReg) && AMDIL::R600_Reg128RegClass.contains(SrcReg)) { for (unsigned i = 0; i < 4; i++) { BuildMI(MBB, MI, DL, get(AMDIL::MOV)) .addReg(RI.getSubReg(DestReg, subRegMap[i]), RegState::Define) .addReg(RI.getSubReg(SrcReg, subRegMap[i])) .addReg(DestReg, RegState::Define | RegState::Implicit); } } else { /* We can't copy vec4 registers */ assert(!AMDIL::R600_Reg128RegClass.contains(DestReg) && !AMDIL::R600_Reg128RegClass.contains(SrcReg)); BuildMI(MBB, MI, DL, get(AMDIL::MOV), DestReg) .addReg(SrcReg, getKillRegState(KillSrc)); } } unsigned R600InstrInfo::getISAOpcode(unsigned opcode) const { switch (opcode) { default: return AMDGPUInstrInfo::getISAOpcode(opcode); case AMDIL::CUSTOM_ADD_i32: return AMDIL::ADD_INT; case AMDIL::IEQ: return AMDIL::SETE_INT; case AMDIL::INE: return AMDIL::SETNE_INT; case AMDIL::IGE: return AMDIL::SETGE_INT; case AMDIL::MOVE_f32: case AMDIL::MOVE_i32: return AMDIL::MOV; case AMDIL::SHR_i32: return getASHRop(); case AMDIL::UGE: return AMDIL::SETGE_UINT; case AMDIL::UGT: return AMDIL::SETGT_UINT; case AMDIL::USHR_i32: return getLSHRop(); } } unsigned R600InstrInfo::getASHRop() const { unsigned gen = TM.getSubtarget().device()->getGeneration(); if (gen < AMDILDeviceInfo::HD5XXX) { return AMDIL::ASHR_r600; } else { return AMDIL::ASHR_eg; } } unsigned R600InstrInfo::getLSHRop() const { unsigned gen = TM.getSubtarget().device()->getGeneration(); if (gen < AMDILDeviceInfo::HD5XXX) { return AMDIL::LSHR_r600; } else { return AMDIL::LSHR_eg; } } unsigned R600InstrInfo::getMULHI_UINT() const { unsigned gen = TM.getSubtarget().device()->getGeneration(); if (gen < AMDILDeviceInfo::HD5XXX) { return AMDIL::MULHI_UINT_r600; } else { return AMDIL::MULHI_UINT_eg; } } unsigned R600InstrInfo::getMULLO_UINT() const { unsigned gen = TM.getSubtarget().device()->getGeneration(); if (gen < AMDILDeviceInfo::HD5XXX) { return AMDIL::MULLO_UINT_r600; } else { return AMDIL::MULLO_UINT_eg; } } unsigned R600InstrInfo::getRECIP_UINT() const { const AMDILDevice * dev = TM.getSubtarget().device(); if (dev->getGeneration() < AMDILDeviceInfo::HD5XXX) { return AMDIL::RECIP_UINT_r600; } else if (dev->getDeviceFlag() != OCL_DEVICE_CAYMAN) { return AMDIL::RECIP_UINT_eg; } else { return AMDIL::RECIP_UINT_cm; } }