OSDN Git Service

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