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