r600g/llvm: Let ISel handle lowering to {INSERT,EXTRACT}_SUBREG
[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
29 setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal);
30 setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal);
31 }
32
33 MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
34 MachineInstr * MI, MachineBasicBlock * BB) const
35 {
36 MachineFunction * MF = BB->getParent();
37 MachineRegisterInfo &MRI = MF->getRegInfo();
38
39 switch (MI->getOpcode()) {
40 default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
41 /* XXX: Use helper function from AMDGPULowerShaderInstructions here */
42 case AMDIL::TGID_X:
43 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_X);
44 break;
45 case AMDIL::TGID_Y:
46 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Y);
47 break;
48 case AMDIL::TGID_Z:
49 addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Z);
50 break;
51 case AMDIL::TIDIG_X:
52 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_X);
53 break;
54 case AMDIL::TIDIG_Y:
55 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Y);
56 break;
57 case AMDIL::TIDIG_Z:
58 addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Z);
59 break;
60 case AMDIL::NGROUPS_X:
61 lowerImplicitParameter(MI, *BB, MRI, 0);
62 break;
63 case AMDIL::NGROUPS_Y:
64 lowerImplicitParameter(MI, *BB, MRI, 1);
65 break;
66 case AMDIL::NGROUPS_Z:
67 lowerImplicitParameter(MI, *BB, MRI, 2);
68 break;
69 case AMDIL::GLOBAL_SIZE_X:
70 lowerImplicitParameter(MI, *BB, MRI, 3);
71 break;
72 case AMDIL::GLOBAL_SIZE_Y:
73 lowerImplicitParameter(MI, *BB, MRI, 4);
74 break;
75 case AMDIL::GLOBAL_SIZE_Z:
76 lowerImplicitParameter(MI, *BB, MRI, 5);
77 break;
78 case AMDIL::LOCAL_SIZE_X:
79 lowerImplicitParameter(MI, *BB, MRI, 6);
80 break;
81 case AMDIL::LOCAL_SIZE_Y:
82 lowerImplicitParameter(MI, *BB, MRI, 7);
83 break;
84 case AMDIL::LOCAL_SIZE_Z:
85 lowerImplicitParameter(MI, *BB, MRI, 8);
86 break;
87 }
88 MI->eraseFromParent();
89 return BB;
90 }
91
92 void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBlock &BB,
93 MachineRegisterInfo & MRI, unsigned dword_offset) const
94 {
95 MachineBasicBlock::iterator I = *MI;
96 unsigned offsetReg = MRI.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass);
97 MRI.setRegClass(MI->getOperand(0).getReg(), &AMDIL::R600_TReg32_XRegClass);
98
99 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::MOV), offsetReg)
100 .addReg(AMDIL::ALU_LITERAL_X)
101 .addImm(dword_offset * 4);
102
103 BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::VTX_READ_eg))
104 .addOperand(MI->getOperand(0))
105 .addReg(offsetReg)
106 .addImm(0);
107 }