R600InstrInfo.cpp revision 040c2e04568e2fe9ec07167f5300a3dcdfebb04e
1//===-- R600InstrInfo.cpp - R600 Instruction Information ------------------===//
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// R600 Implementation of TargetInstrInfo.
11//
12//===----------------------------------------------------------------------===//
13
14#include "R600InstrInfo.h"
15#include "AMDGPUTargetMachine.h"
16#include "AMDGPUSubtarget.h"
17#include "R600RegisterInfo.h"
18#include "llvm/CodeGen/MachineInstrBuilder.h"
19
20#define GET_INSTRINFO_CTOR
21#include "AMDGPUGenDFAPacketizer.inc"
22
23using namespace llvm;
24
25R600InstrInfo::R600InstrInfo(AMDGPUTargetMachine &tm)
26  : AMDGPUInstrInfo(tm),
27    RI(tm, *this),
28    TM(tm)
29  { }
30
31const R600RegisterInfo &R600InstrInfo::getRegisterInfo() const
32{
33  return RI;
34}
35
36bool R600InstrInfo::isTrig(const MachineInstr &MI) const
37{
38  return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG;
39}
40
41bool R600InstrInfo::isVector(const MachineInstr &MI) const
42{
43  return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR;
44}
45
46void
47R600InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
48                           MachineBasicBlock::iterator MI, DebugLoc DL,
49                           unsigned DestReg, unsigned SrcReg,
50                           bool KillSrc) const
51{
52
53  unsigned subRegMap[4] = {AMDGPU::sel_x, AMDGPU::sel_y,
54                           AMDGPU::sel_z, AMDGPU::sel_w};
55
56  if (AMDGPU::R600_Reg128RegClass.contains(DestReg)
57      && AMDGPU::R600_Reg128RegClass.contains(SrcReg)) {
58    for (unsigned i = 0; i < 4; i++) {
59      BuildMI(MBB, MI, DL, get(AMDGPU::MOV))
60              .addReg(RI.getSubReg(DestReg, subRegMap[i]), RegState::Define)
61              .addReg(RI.getSubReg(SrcReg, subRegMap[i]))
62              .addReg(DestReg, RegState::Define | RegState::Implicit);
63    }
64  } else {
65
66    /* We can't copy vec4 registers */
67    assert(!AMDGPU::R600_Reg128RegClass.contains(DestReg)
68           && !AMDGPU::R600_Reg128RegClass.contains(SrcReg));
69
70    BuildMI(MBB, MI, DL, get(AMDGPU::MOV), DestReg)
71      .addReg(SrcReg, getKillRegState(KillSrc));
72  }
73}
74
75MachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF,
76                                             unsigned DstReg, int64_t Imm) const
77{
78  MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::MOV), DebugLoc());
79  MachineInstrBuilder(MI).addReg(DstReg, RegState::Define);
80  MachineInstrBuilder(MI).addReg(AMDGPU::ALU_LITERAL_X);
81  MachineInstrBuilder(MI).addImm(Imm);
82
83  return MI;
84}
85
86unsigned R600InstrInfo::getIEQOpcode() const
87{
88  return AMDGPU::SETE_INT;
89}
90
91bool R600InstrInfo::isMov(unsigned Opcode) const
92{
93  switch(Opcode) {
94  default: return false;
95  case AMDGPU::MOV:
96  case AMDGPU::MOV_IMM_F32:
97  case AMDGPU::MOV_IMM_I32:
98    return true;
99  }
100}
101
102// Some instructions act as place holders to emulate operations that the GPU
103// hardware does automatically. This function can be used to check if
104// an opcode falls into this category.
105bool R600InstrInfo::isPlaceHolderOpcode(unsigned opcode) const
106{
107  switch (opcode) {
108  default: return false;
109  case AMDGPU::RETURN:
110  case AMDGPU::LAST:
111  case AMDGPU::MASK_WRITE:
112  case AMDGPU::RESERVE_REG:
113    return true;
114  }
115}
116
117bool R600InstrInfo::isTexOp(unsigned opcode) const
118{
119  switch(opcode) {
120  default: return false;
121  case AMDGPU::TEX_LD:
122  case AMDGPU::TEX_GET_TEXTURE_RESINFO:
123  case AMDGPU::TEX_SAMPLE:
124  case AMDGPU::TEX_SAMPLE_C:
125  case AMDGPU::TEX_SAMPLE_L:
126  case AMDGPU::TEX_SAMPLE_C_L:
127  case AMDGPU::TEX_SAMPLE_LB:
128  case AMDGPU::TEX_SAMPLE_C_LB:
129  case AMDGPU::TEX_SAMPLE_G:
130  case AMDGPU::TEX_SAMPLE_C_G:
131  case AMDGPU::TEX_GET_GRADIENTS_H:
132  case AMDGPU::TEX_GET_GRADIENTS_V:
133  case AMDGPU::TEX_SET_GRADIENTS_H:
134  case AMDGPU::TEX_SET_GRADIENTS_V:
135    return true;
136  }
137}
138
139bool R600InstrInfo::isReductionOp(unsigned opcode) const
140{
141  switch(opcode) {
142    default: return false;
143    case AMDGPU::DOT4_r600:
144    case AMDGPU::DOT4_eg:
145      return true;
146  }
147}
148
149bool R600InstrInfo::isCubeOp(unsigned opcode) const
150{
151  switch(opcode) {
152    default: return false;
153    case AMDGPU::CUBE_r600:
154    case AMDGPU::CUBE_eg:
155      return true;
156  }
157}
158
159
160bool R600InstrInfo::isFCOp(unsigned opcode) const
161{
162  switch(opcode) {
163  default: return false;
164  case AMDGPU::BREAK_LOGICALZ_f32:
165  case AMDGPU::BREAK_LOGICALNZ_i32:
166  case AMDGPU::BREAK_LOGICALZ_i32:
167  case AMDGPU::BREAK_LOGICALNZ_f32:
168  case AMDGPU::CONTINUE_LOGICALNZ_f32:
169  case AMDGPU::IF_LOGICALNZ_i32:
170  case AMDGPU::IF_LOGICALZ_f32:
171  case AMDGPU::ELSE:
172  case AMDGPU::ENDIF:
173  case AMDGPU::ENDLOOP:
174  case AMDGPU::IF_LOGICALNZ_f32:
175  case AMDGPU::WHILELOOP:
176    return true;
177  }
178}
179
180DFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM,
181    const ScheduleDAG *DAG) const
182{
183  const InstrItineraryData *II = TM->getInstrItineraryData();
184  return TM->getSubtarget<AMDGPUSubtarget>().createDFAPacketizer(II);
185}
186