summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/radeon/R600ISelLowering.cpp
blob: f92fe2641a5f11a24e94779e68d0c1f7bfdacb50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//===-- R600ISelLowering.cpp - TODO: Add brief description -------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// TODO: Add full description
//
//===----------------------------------------------------------------------===//

#include "R600ISelLowering.h"
#include "R600InstrInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"

using namespace llvm;

R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
    AMDGPUTargetLowering(TM),
    TII(static_cast<const R600InstrInfo*>(TM.getInstrInfo()))
{
  setOperationAction(ISD::MUL, MVT::i64, Expand);
//  setSchedulingPreference(Sched::VLIW);
  addRegisterClass(MVT::v4f32, &AMDIL::R600_Reg128RegClass);
  addRegisterClass(MVT::f32, &AMDIL::R600_Reg32RegClass);

  setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal);
  setOperationAction(ISD::INSERT_VECTOR_ELT, MVT::v4f32, Legal);
}

MachineBasicBlock * R600TargetLowering::EmitInstrWithCustomInserter(
    MachineInstr * MI, MachineBasicBlock * BB) const
{
  MachineFunction * MF = BB->getParent();
  MachineRegisterInfo &MRI = MF->getRegInfo();

  switch (MI->getOpcode()) {
  default: return AMDGPUTargetLowering::EmitInstrWithCustomInserter(MI, BB);
  /* XXX: Use helper function from AMDGPULowerShaderInstructions here */
  case AMDIL::TGID_X:
    addLiveIn(MI, MF, MRI, TII, AMDIL::T1_X);
    break;
  case AMDIL::TGID_Y:
    addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Y);
    break;
  case AMDIL::TGID_Z:
    addLiveIn(MI, MF, MRI, TII, AMDIL::T1_Z);
    break;
  case AMDIL::TIDIG_X:
    addLiveIn(MI, MF, MRI, TII, AMDIL::T0_X);
    break;
  case AMDIL::TIDIG_Y:
    addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Y);
    break;
  case AMDIL::TIDIG_Z:
    addLiveIn(MI, MF, MRI, TII, AMDIL::T0_Z);
    break;
  case AMDIL::NGROUPS_X:
    lowerImplicitParameter(MI, *BB, MRI, 0);
    break;
  case AMDIL::NGROUPS_Y:
    lowerImplicitParameter(MI, *BB, MRI, 1);
    break;
  case AMDIL::NGROUPS_Z:
    lowerImplicitParameter(MI, *BB, MRI, 2);
    break;
  case AMDIL::GLOBAL_SIZE_X:
    lowerImplicitParameter(MI, *BB, MRI, 3);
    break;
  case AMDIL::GLOBAL_SIZE_Y:
    lowerImplicitParameter(MI, *BB, MRI, 4);
    break;
  case AMDIL::GLOBAL_SIZE_Z:
    lowerImplicitParameter(MI, *BB, MRI, 5);
    break;
  case AMDIL::LOCAL_SIZE_X:
    lowerImplicitParameter(MI, *BB, MRI, 6);
    break;
  case AMDIL::LOCAL_SIZE_Y:
    lowerImplicitParameter(MI, *BB, MRI, 7);
    break;
  case AMDIL::LOCAL_SIZE_Z:
    lowerImplicitParameter(MI, *BB, MRI, 8);
    break;
  }
  MI->eraseFromParent();
  return BB;
}

void R600TargetLowering::lowerImplicitParameter(MachineInstr *MI, MachineBasicBlock &BB,
    MachineRegisterInfo & MRI, unsigned dword_offset) const
{
  MachineBasicBlock::iterator I = *MI;
  unsigned offsetReg = MRI.createVirtualRegister(&AMDIL::R600_TReg32_XRegClass);
  MRI.setRegClass(MI->getOperand(0).getReg(), &AMDIL::R600_TReg32_XRegClass);

  BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::MOV), offsetReg)
          .addReg(AMDIL::ALU_LITERAL_X)
          .addImm(dword_offset * 4);

  BuildMI(BB, I, BB.findDebugLoc(I), TII->get(AMDIL::VTX_READ_eg))
          .addOperand(MI->getOperand(0))
          .addReg(offsetReg)
          .addImm(0);
}