1 //===-- R600LowerShaderInstructions.cpp - TODO: Add brief description -------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // TODO: Add full description
12 //===----------------------------------------------------------------------===//
15 #include "AMDGPULowerShaderInstructions.h"
17 #include "AMDILInstrInfo.h"
18 #include "llvm/CodeGen/MachineFunctionPass.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
25 class R600LowerShaderInstructionsPass
: public MachineFunctionPass
,
26 public AMDGPULowerShaderInstructionsPass
{
32 void lowerEXPORT_REG_FAKE(MachineInstr
&MI
, MachineBasicBlock
&MBB
,
33 MachineBasicBlock::iterator I
);
34 void lowerLOAD_INPUT(MachineInstr
& MI
);
35 bool lowerSTORE_OUTPUT(MachineInstr
& MI
, MachineBasicBlock
&MBB
,
36 MachineBasicBlock::iterator I
);
39 R600LowerShaderInstructionsPass(TargetMachine
&tm
) :
40 MachineFunctionPass(ID
), TM(tm
) { }
42 bool runOnMachineFunction(MachineFunction
&MF
);
44 const char *getPassName() const { return "R600 Lower Shader Instructions"; }
46 } /* End anonymous namespace */
48 char R600LowerShaderInstructionsPass::ID
= 0;
50 FunctionPass
*llvm::createR600LowerShaderInstructionsPass(TargetMachine
&tm
) {
51 return new R600LowerShaderInstructionsPass(tm
);
54 #define INSTR_CASE_FLOAT_V(inst) \
55 case AMDIL:: inst##_v4f32: \
57 #define INSTR_CASE_FLOAT_S(inst) \
58 case AMDIL:: inst##_f32:
60 #define INSTR_CASE_FLOAT(inst) \
61 INSTR_CASE_FLOAT_V(inst) \
62 INSTR_CASE_FLOAT_S(inst)
63 bool R600LowerShaderInstructionsPass::runOnMachineFunction(MachineFunction
&MF
)
65 MRI
= &MF
.getRegInfo();
68 for (MachineFunction::iterator BB
= MF
.begin(), BB_E
= MF
.end();
70 MachineBasicBlock
&MBB
= *BB
;
71 for (MachineBasicBlock::iterator I
= MBB
.begin(); I
!= MBB
.end();) {
72 MachineInstr
&MI
= *I
;
73 bool deleteInstr
= false;
74 switch (MI
.getOpcode()) {
78 case AMDIL::RESERVE_REG
:
79 case AMDIL::EXPORT_REG
:
83 case AMDIL::LOAD_INPUT
:
88 case AMDIL::STORE_OUTPUT
:
89 deleteInstr
= lowerSTORE_OUTPUT(MI
, MBB
, I
);
105 /* The goal of this function is to replace the virutal destination register of
106 * a LOAD_INPUT instruction with the correct physical register that will.
108 * XXX: I don't think this is the right way things assign physical registers,
109 * but I'm not sure of another way to do this.
111 void R600LowerShaderInstructionsPass::lowerLOAD_INPUT(MachineInstr
&MI
)
113 MachineOperand
&dst
= MI
.getOperand(0);
114 MachineOperand
&arg
= MI
.getOperand(1);
115 int64_t inputIndex
= arg
.getImm();
116 const TargetRegisterClass
* inputClass
= TM
.getRegisterInfo()->getRegClass(AMDIL::R600_TReg32RegClassID
);
117 unsigned newRegister
= inputClass
->getRegister(inputIndex
);
118 unsigned dstReg
= dst
.getReg();
120 preloadRegister(MI
.getParent()->getParent(), TM
.getInstrInfo(), newRegister
,
124 bool R600LowerShaderInstructionsPass::lowerSTORE_OUTPUT(MachineInstr
&MI
,
125 MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
)
127 MachineOperand
&valueOp
= MI
.getOperand(1);
128 MachineOperand
&indexOp
= MI
.getOperand(2);
129 unsigned valueReg
= valueOp
.getReg();
130 int64_t outputIndex
= indexOp
.getImm();
131 const TargetRegisterClass
* outputClass
= TM
.getRegisterInfo()->getRegClass(AMDIL::R600_TReg32RegClassID
);
132 unsigned newRegister
= outputClass
->getRegister(outputIndex
);
134 BuildMI(MBB
, I
, MBB
.findDebugLoc(I
), TM
.getInstrInfo()->get(AMDIL::COPY
),
138 if (!MRI
->isLiveOut(newRegister
))
139 MRI
->addLiveOut(newRegister
);