r600g/llvm: Remove unnecessary dynamic casts
[mesa.git] / src / gallium / drivers / radeon / AMDGPUInstrInfo.cpp
1 //===-- AMDGPUInstrInfo.cpp - Base class for AMD GPU InstrInfo ------------===//
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 // This file contains the implementation of the TargetInstrInfo class that is
11 // common to all AMD GPUs.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "AMDGPUInstrInfo.h"
16 #include "AMDGPURegisterInfo.h"
17 #include "AMDGPUTargetMachine.h"
18 #include "AMDIL.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20
21 using namespace llvm;
22
23 AMDGPUInstrInfo::AMDGPUInstrInfo(AMDGPUTargetMachine &tm)
24 : AMDILInstrInfo(tm), TM(tm)
25 {
26 const AMDILDevice * dev = TM.getSubtarget<AMDILSubtarget>().device();
27 for (unsigned i = 0; i < AMDIL::INSTRUCTION_LIST_END; i++) {
28 const MCInstrDesc & instDesc = get(i);
29 uint32_t instGen = (instDesc.TSFlags >> 40) & 0x7;
30 uint32_t inst = (instDesc.TSFlags >> 48) & 0xffff;
31 if (inst == 0) {
32 continue;
33 }
34 switch (instGen) {
35 case AMDGPUInstrInfo::R600_CAYMAN:
36 if (dev->getGeneration() > AMDILDeviceInfo::HD6XXX) {
37 continue;
38 }
39 break;
40 case AMDGPUInstrInfo::R600:
41 if (dev->getGeneration() != AMDILDeviceInfo::HD4XXX) {
42 continue;
43 }
44 break;
45 case AMDGPUInstrInfo::EG_CAYMAN:
46 if (dev->getGeneration() < AMDILDeviceInfo::HD5XXX
47 || dev->getGeneration() > AMDILDeviceInfo::HD6XXX) {
48 continue;
49 }
50 break;
51 case AMDGPUInstrInfo::CAYMAN:
52 if (dev->getDeviceFlag() != OCL_DEVICE_CAYMAN) {
53 continue;
54 }
55 break;
56 case AMDGPUInstrInfo::SI:
57 if (dev->getGeneration() != AMDILDeviceInfo::HD7XXX) {
58 continue;
59 }
60 break;
61 default:
62 abort();
63 break;
64 }
65
66 unsigned amdilOpcode = GetRealAMDILOpcode(inst);
67 amdilToISA[amdilOpcode] = instDesc.Opcode;
68 }
69 }
70
71 MachineInstr * AMDGPUInstrInfo::convertToISA(MachineInstr & MI, MachineFunction &MF,
72 DebugLoc DL) const
73 {
74 MachineInstrBuilder newInstr;
75 MachineRegisterInfo &MRI = MF.getRegInfo();
76 const AMDGPURegisterInfo & RI = getRegisterInfo();
77 unsigned ISAOpcode = getISAOpcode(MI.getOpcode());
78
79 /* Create the new instruction */
80 newInstr = BuildMI(MF, DL, TM.getInstrInfo()->get(ISAOpcode));
81
82 for (unsigned i = 0; i < MI.getNumOperands(); i++) {
83 MachineOperand &MO = MI.getOperand(i);
84 /* Convert dst regclass to one that is supported by the ISA */
85 if (MO.isReg() && MO.isDef()) {
86 if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
87 const TargetRegisterClass * oldRegClass = MRI.getRegClass(MO.getReg());
88 const TargetRegisterClass * newRegClass = RI.getISARegClass(oldRegClass);
89
90 assert(newRegClass);
91
92 MRI.setRegClass(MO.getReg(), newRegClass);
93 }
94 }
95 /* Add the operand to the new instruction */
96 newInstr.addOperand(MO);
97 }
98
99 return newInstr;
100 }
101
102 unsigned AMDGPUInstrInfo::getISAOpcode(unsigned opcode) const
103 {
104 if (amdilToISA.count(opcode) == 0) {
105 return opcode;
106 } else {
107 return amdilToISA.find(opcode)->second;
108 }
109 }
110
111 bool AMDGPUInstrInfo::isRegPreload(const MachineInstr &MI) const
112 {
113 return (get(MI.getOpcode()).TSFlags >> AMDGPU_TFLAG_SHIFTS::PRELOAD_REG) & 0x1;
114 }
115
116 #include "AMDGPUInstrEnums.include"