R600InstrInfo.cpp revision 76b44034b9b234d3db4012342f0fae677d4f10f6
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 "AMDILSubtarget.h"
17#include "R600RegisterInfo.h"
18
19#define GET_INSTRINFO_CTOR
20#include "AMDGPUGenDFAPacketizer.inc"
21
22using namespace llvm;
23
24R600InstrInfo::R600InstrInfo(AMDGPUTargetMachine &tm)
25  : AMDGPUInstrInfo(tm),
26    RI(tm, *this),
27    TM(tm)
28  { }
29
30const R600RegisterInfo &R600InstrInfo::getRegisterInfo() const
31{
32  return RI;
33}
34
35bool R600InstrInfo::isTrig(const MachineInstr &MI) const
36{
37  return get(MI.getOpcode()).TSFlags & R600_InstFlag::TRIG;
38}
39
40bool R600InstrInfo::isVector(const MachineInstr &MI) const
41{
42  return get(MI.getOpcode()).TSFlags & R600_InstFlag::VECTOR;
43}
44
45void
46R600InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
47                           MachineBasicBlock::iterator MI, DebugLoc DL,
48                           unsigned DestReg, unsigned SrcReg,
49                           bool KillSrc) const
50{
51
52  unsigned subRegMap[4] = {AMDGPU::sel_x, AMDGPU::sel_y,
53                           AMDGPU::sel_z, AMDGPU::sel_w};
54
55  if (AMDGPU::R600_Reg128RegClass.contains(DestReg)
56      && AMDGPU::R600_Reg128RegClass.contains(SrcReg)) {
57    for (unsigned i = 0; i < 4; i++) {
58      BuildMI(MBB, MI, DL, get(AMDGPU::MOV))
59              .addReg(RI.getSubReg(DestReg, subRegMap[i]), RegState::Define)
60              .addReg(RI.getSubReg(SrcReg, subRegMap[i]))
61              .addReg(DestReg, RegState::Define | RegState::Implicit);
62    }
63  } else {
64
65    /* We can't copy vec4 registers */
66    assert(!AMDGPU::R600_Reg128RegClass.contains(DestReg)
67           && !AMDGPU::R600_Reg128RegClass.contains(SrcReg));
68
69    BuildMI(MBB, MI, DL, get(AMDGPU::MOV), DestReg)
70      .addReg(SrcReg, getKillRegState(KillSrc));
71  }
72}
73
74MachineInstr * R600InstrInfo::getMovImmInstr(MachineFunction *MF,
75                                             unsigned DstReg, int64_t Imm) const
76{
77  MachineInstr * MI = MF->CreateMachineInstr(get(AMDGPU::MOV), DebugLoc());
78  MachineInstrBuilder(MI).addReg(DstReg, RegState::Define);
79  MachineInstrBuilder(MI).addReg(AMDGPU::ALU_LITERAL_X);
80  MachineInstrBuilder(MI).addImm(Imm);
81
82  return MI;
83}
84
85unsigned R600InstrInfo::getIEQOpcode() const
86{
87  return AMDGPU::SETE_INT;
88}
89
90bool R600InstrInfo::isMov(unsigned Opcode) const
91{
92  switch(Opcode) {
93  default: return false;
94  case AMDGPU::MOV:
95  case AMDGPU::MOV_IMM_F32:
96  case AMDGPU::MOV_IMM_I32:
97    return true;
98  }
99}
100
101DFAPacketizer *R600InstrInfo::CreateTargetScheduleState(const TargetMachine *TM,
102    const ScheduleDAG *DAG) const
103{
104  const InstrItineraryData *II = TM->getInstrItineraryData();
105  return TM->getSubtarget<AMDILSubtarget>().createDFAPacketizer(II);
106}
107