Remove attribution from file headers, per discussion on llvmdev.
[oota-llvm.git] / lib / Target / CellSPU / SPUInstrInfo.cpp
1 //===- SPUInstrInfo.cpp - Cell SPU 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 // This file contains the Cell SPU implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SPURegisterNames.h"
15 #include "SPUInstrInfo.h"
16 #include "SPUTargetMachine.h"
17 #include "SPUGenInstrInfo.inc"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include <iostream>
20
21 using namespace llvm;
22
23 SPUInstrInfo::SPUInstrInfo(SPUTargetMachine &tm)
24   : TargetInstrInfo(SPUInsts, sizeof(SPUInsts)/sizeof(SPUInsts[0])),
25     TM(tm),
26     RI(*TM.getSubtargetImpl(), *this)
27 {
28   /* NOP */
29 }
30
31 /// getPointerRegClass - Return the register class to use to hold pointers.
32 /// This is used for addressing modes.
33 const TargetRegisterClass *
34 SPUInstrInfo::getPointerRegClass() const
35 {
36   return &SPU::R32CRegClass;
37 }
38
39 bool
40 SPUInstrInfo::isMoveInstr(const MachineInstr& MI,
41                           unsigned& sourceReg,
42                           unsigned& destReg) const {
43   // Primarily, ORI and OR are generated by copyRegToReg. But, there are other
44   // cases where we can safely say that what's being done is really a move
45   // (see how PowerPC does this -- it's the model for this code too.)
46   switch (MI.getOpcode()) {
47   default:
48     break;
49   case SPU::ORIv4i32:
50   case SPU::ORIr32:
51   case SPU::ORIr64:
52   case SPU::ORHIv8i16:
53   case SPU::ORHIr16:
54   case SPU::ORHI1To2:
55   case SPU::ORBIv16i8:
56   case SPU::ORBIr8:
57   case SPU::ORI2To4:
58   case SPU::ORI1To4:
59   case SPU::AHIvec:
60   case SPU::AHIr16:
61   case SPU::AIvec:
62     assert(MI.getNumOperands() == 3 &&
63            MI.getOperand(0).isRegister() &&
64            MI.getOperand(1).isRegister() &&
65            MI.getOperand(2).isImmediate() &&
66            "invalid SPU ORI/ORHI/ORBI/AHI/AI/SFI/SFHI instruction!");
67     if (MI.getOperand(2).getImmedValue() == 0) {
68       sourceReg = MI.getOperand(1).getReg();
69       destReg = MI.getOperand(0).getReg();
70       return true;
71     }
72     break;
73   case SPU::AIr32:
74     assert(MI.getNumOperands() == 3 &&
75            "wrong number of operands to AIr32");
76     if (MI.getOperand(0).isRegister() &&
77         (MI.getOperand(1).isRegister() ||
78          MI.getOperand(1).isFrameIndex()) &&
79         (MI.getOperand(2).isImmediate() &&
80          MI.getOperand(2).getImmedValue() == 0)) {
81       sourceReg = MI.getOperand(1).getReg();
82       destReg = MI.getOperand(0).getReg();
83       return true;
84     }
85     break;
86   case SPU::ORv16i8_i8:
87   case SPU::ORv8i16_i16:
88   case SPU::ORv4i32_i32:
89   case SPU::ORv2i64_i64:
90   case SPU::ORv4f32_f32:
91   case SPU::ORv2f64_f64:
92   case SPU::ORi8_v16i8:
93   case SPU::ORi16_v8i16:
94   case SPU::ORi32_v4i32:
95   case SPU::ORi64_v2i64:
96   case SPU::ORf32_v4f32:
97   case SPU::ORf64_v2f64:
98   case SPU::ORv16i8:
99   case SPU::ORv8i16:
100   case SPU::ORv4i32:
101   case SPU::ORr32:
102   case SPU::ORr64:
103   case SPU::ORf32:
104   case SPU::ORf64:
105   case SPU::ORgprc:
106     assert(MI.getNumOperands() == 3 &&
107            MI.getOperand(0).isRegister() &&
108            MI.getOperand(1).isRegister() &&
109            MI.getOperand(2).isRegister() &&
110            "invalid SPU OR(vec|r32|r64|gprc) instruction!");
111     if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
112       sourceReg = MI.getOperand(1).getReg();
113       destReg = MI.getOperand(0).getReg();
114       return true;
115     }
116     break;
117   }
118
119   return false;
120 }
121
122 unsigned
123 SPUInstrInfo::isLoadFromStackSlot(MachineInstr *MI, int &FrameIndex) const {
124   switch (MI->getOpcode()) {
125   default: break;
126   case SPU::LQDv16i8:
127   case SPU::LQDv8i16:
128   case SPU::LQDv4i32:
129   case SPU::LQDv4f32:
130   case SPU::LQDv2f64:
131   case SPU::LQDr128:
132   case SPU::LQDr64:
133   case SPU::LQDr32:
134   case SPU::LQDr16:
135   case SPU::LQXv4i32:
136   case SPU::LQXr128:
137   case SPU::LQXr64:
138   case SPU::LQXr32:
139   case SPU::LQXr16:
140     if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() &&
141         MI->getOperand(2).isFrameIndex()) {
142       FrameIndex = MI->getOperand(2).getFrameIndex();
143       return MI->getOperand(0).getReg();
144     }
145     break;
146   }
147   return 0;
148 }
149
150 unsigned
151 SPUInstrInfo::isStoreToStackSlot(MachineInstr *MI, int &FrameIndex) const {
152   switch (MI->getOpcode()) {
153   default: break;
154   case SPU::STQDv16i8:
155   case SPU::STQDv8i16:
156   case SPU::STQDv4i32:
157   case SPU::STQDv4f32:
158   case SPU::STQDv2f64:
159   case SPU::STQDr128:
160   case SPU::STQDr64:
161   case SPU::STQDr32:
162   case SPU::STQDr16:
163     // case SPU::STQDr8:
164   case SPU::STQXv16i8:
165   case SPU::STQXv8i16:
166   case SPU::STQXv4i32:
167   case SPU::STQXv4f32:
168   case SPU::STQXv2f64:
169   case SPU::STQXr128:
170   case SPU::STQXr64:
171   case SPU::STQXr32:
172   case SPU::STQXr16:
173     // case SPU::STQXr8:
174     if (MI->getOperand(1).isImmediate() && !MI->getOperand(1).getImmedValue() &&
175         MI->getOperand(2).isFrameIndex()) {
176       FrameIndex = MI->getOperand(2).getFrameIndex();
177       return MI->getOperand(0).getReg();
178     }
179     break;
180   }
181   return 0;
182 }