radeon/llvm: add support for v4i32
[mesa.git] / src / gallium / drivers / radeon / R600ISelLowering.cpp
1 //===-- R600ISelLowering.cpp - TODO: Add brief description -------===//
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 // TODO: Add full description
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "R600ISelLowering.h"
15 #include "R600InstrInfo.h"
16 #include "llvm/CodeGen/MachineRegisterInfo.h"
17
18 using namespace llvm;
19
20 R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
21 AMDGPUTargetLowering(TM),
22 TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo()))
23 {
24 setOperationAction(ISD::MUL, MVT::i64, Expand);
25 // setSchedulingPreference(Sched::VLIW);
26 addRegisterClass(MVT::v4f32, &AMDIL::R600_Reg128RegClass);
27 addRegisterClass(MVT::f32, &AMDIL::R600_Reg32RegClass);
28 addRegisterClass(MVT::v4i32, &AMDIL::R600_Reg128RegClass);
29 addRegisterClass(MVT::i32, &AMDIL::R600_Reg32RegClass);
30
31 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal);
32 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal);
33 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4i32, Legal);
34 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4i32, Legal);
35 }
36
37 MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
38 MachineInstr * MI, MachineBasicBlock * BB) const
39 {
40 MachineFunction * MF = BB->getParent();
41 MachineRegisterInfo &MRI = MF->getRegInfo();
42
43 switch (MI->getOpcode()) {
44 default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
45 /* XXX: Use helper function from AMDGPULowerShaderInstructions here */
46 case AMDIL::TGID_X:
47 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_X);
48 break;
49 case AMDIL::TGID_Y:
50 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Y);
51 break;
52 case AMDIL::TGID_Z:
53 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Z);
54 break;
55 case AMDIL::TIDIG_X:
56 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_X);
57 break;
58 case AMDIL::TIDIG_Y:
59 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Y);
60 break;
61 case AMDIL::TIDIG_Z:
62 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Z);
63 break;
64 case AMDIL::NGROUPS_X:
65 lowerImplicitParameter(MI, *BB, MRI, 0);
66 break;
67 case AMDIL::NGROUPS_Y:
68 lowerImplicitParameter(MI, *BB, MRI, 1);
69 break;
70 case AMDIL::NGROUPS_Z:
71 lowerImplicitParameter(MI, *BB, MRI, 2);
72 break;
73 case AMDIL::GLOBAL_SIZE_X:
74 lowerImplicitParameter(MI, *BB, MRI, 3);
75 break;
76 case AMDIL::GLOBAL_SIZE_Y:
77 lowerImplicitParameter(MI, *BB, MRI, 4);
78 break;
79 case AMDIL::GLOBAL_SIZE_Z:
80 lowerImplicitParameter(MI, *BB, MRI, 5);
81 break;
82 case AMDIL::LOCAL_SIZE_X:
83 lowerImplicitParameter(MI, *BB, MRI, 6);
84 break;
85 case AMDIL::LOCAL_SIZE_Y:
86 lowerImplicitParameter(MI, *BB, MRI, 7);
87 break;
88 case AMDIL::LOCAL_SIZE_Z:
89 lowerImplicitParameter(MI, *BB, MRI, 8);
90 break;
91 }
92 MI->eraseFromParent();
93 return BB;
94 }
95
96 void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBlock &BB,
97 MachineRegisterInfo & MRI, unsigned dword_offset) const
98 {
99 MachineBasicBlock::iterator I = *MI;
100 unsigned offsetReg = MRI.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass);
101 MRI.setRegClass(MI->getOperand(0).getReg(), &AMDIL::R600_TReg32_XRegClass);
102
103 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::MOV), offsetReg)
104 .addReg(AMDIL::ALU_LITERAL_X)
105 .addImm(dword_offset * 4);
106
107 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::VTX_READ_eg))
108 .addOperand(MI->getOperand(0))
109 .addReg(offsetReg)
110 .addImm(0);
111 }