llvm.org GIT mirror llvm / 564427e
Main CellSPU backend files checked in. Intrinsics and autoconf files remain. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44595 91177308-0d34-0410-b5e6-96231b3b80d8 Scott Michel 12 years ago
13 changed file(s) with 2697 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===-- SPUMachineFunctionInfo.h - Private data used for CellSPU --*- C++ -*-=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file declares the IBM Cell SPU specific subclass of MachineFunctionInfo.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef SPU_MACHINE_FUNCTION_INFO_H
16 #define SPU_MACHINE_FUNCTION_INFO_H
17
18 #include "llvm/CodeGen/MachineFunction.h"
19
20 namespace llvm {
21
22 /// SPUFunctionInfo - Cell SPU target-specific information for each
23 /// MachineFunction
24 class SPUFunctionInfo : public MachineFunctionInfo {
25 private:
26 /// UsesLR - Indicates whether LR is used in the current function.
27 ///
28 bool UsesLR;
29
30 public:
31 SPUFunctionInfo(MachineFunction& MF)
32 : UsesLR(false)
33 {}
34
35 void setUsesLR(bool U) { UsesLR = U; }
36 bool usesLR() { return UsesLR; }
37
38 };
39
40 } // end of namespace llvm
41
42
43 #endif
44
0 //=- SPUNodes.h - Specialized SelectionDAG nodes used for CellSPU -*- C++ -*-=//
1 //
2 // This file was developed by a team from the Computer Systems Research
3 // Department at The Aerospace Corporation.
4 //
5 // See README.txt for details.
6 //===----------------------------------------------------------------------===//
7 //
8 // Type profiles and SelectionDAG nodes used by CellSPU
9 //
10 //===----------------------------------------------------------------------===//
11
12 // Type profile for a call sequence
13 def SDT_SPUCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
14
15 // SPU_GenControl: Type profile for generating control words for insertions
16 def SPU_GenControl : SDTypeProfile<1, 1, []>;
17 def SPUvecinsmask : SDNode<"SPUISD::INSERT_MASK", SPU_GenControl, []>;
18
19 def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_SPUCallSeq,
20 [SDNPHasChain, SDNPOutFlag]>;
21 def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_SPUCallSeq,
22 [SDNPHasChain, SDNPOutFlag]>;
23 //===----------------------------------------------------------------------===//
24 // Operand constraints:
25 //===----------------------------------------------------------------------===//
26
27 def SDT_SPUCall : SDTypeProfile<0, -1, [SDTCisInt<0>]>;
28 def SPUcall : SDNode<"SPUISD::CALL", SDT_SPUCall,
29 [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>;
30
31 // Operand type constraints for vector shuffle/permute operations
32 def SDT_SPUshuffle : SDTypeProfile<1, 3, [
33 SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>
34 ]>;
35
36 // Unary, binary v16i8 operator type constraints:
37 def SPUv16i8_unop: SDTypeProfile<1, 1, [
38 SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>]>;
39
40 def SPUv16i8_binop: SDTypeProfile<1, 2, [
41 SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>;
42
43 // Binary v8i16 operator type constraints:
44 def SPUv8i16_unop: SDTypeProfile<1, 1, [
45 SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>]>;
46
47 def SPUv8i16_binop: SDTypeProfile<1, 2, [
48 SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>;
49
50 // Binary v4i32 operator type constraints:
51 def SPUv4i32_unop: SDTypeProfile<1, 1, [
52 SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>]>;
53
54 def SPUv4i32_binop: SDTypeProfile<1, 2, [
55 SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>]>;
56
57 // FSMBI type constraints: There are several variations for the various
58 // vector types (this avoids having to bit_convert all over the place.)
59 def SPUfsmbi_type_v16i8: SDTypeProfile<1, 1, [
60 SDTCisVT<0, v16i8>, SDTCisVT<1, i32>]>;
61
62 def SPUfsmbi_type_v8i16: SDTypeProfile<1, 1, [
63 SDTCisVT<0, v8i16>, SDTCisVT<1, i32>]>;
64
65 def SPUfsmbi_type_v4i32: SDTypeProfile<1, 1, [
66 SDTCisVT<0, v4i32>, SDTCisVT<1, i32>]>;
67
68 // SELB type constraints:
69 def SPUselb_type_v16i8: SDTypeProfile<1, 3, [
70 SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
71 SDTCisSameAs<0, 3> ]>;
72
73 def SPUselb_type_v8i16: SDTypeProfile<1, 3, [
74 SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
75 SDTCisSameAs<0, 3> ]>;
76
77 def SPUselb_type_v4i32: SDTypeProfile<1, 3, [
78 SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>,
79 SDTCisSameAs<0, 3> ]>;
80
81 // SPU Vector shift pseudo-instruction type constraints
82 def SPUvecshift_type_v16i8: SDTypeProfile<1, 2, [
83 SDTCisVT<0, v16i8>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
84
85 def SPUvecshift_type_v8i16: SDTypeProfile<1, 2, [
86 SDTCisVT<0, v8i16>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
87
88 def SPUvecshift_type_v4i32: SDTypeProfile<1, 2, [
89 SDTCisVT<0, v4i32>, SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
90
91 //===----------------------------------------------------------------------===//
92 // Synthetic/pseudo-instructions
93 //===----------------------------------------------------------------------===//
94
95 // SPU CNTB:
96 def SPUcntb_v16i8: SDNode<"SPUISD::CNTB", SPUv16i8_unop, []>;
97 def SPUcntb_v8i16: SDNode<"SPUISD::CNTB", SPUv8i16_unop, []>;
98 def SPUcntb_v4i32: SDNode<"SPUISD::CNTB", SPUv4i32_unop, []>;
99
100 // SPU vector shuffle node, matched by the SPUISD::SHUFB enum (see
101 // SPUISelLowering.h):
102 def SPUshuffle: SDNode<"SPUISD::SHUFB", SDT_SPUshuffle, []>;
103
104 // SPU 16-bit multiply
105 def SPUmpy_v16i8: SDNode<"SPUISD::MPY", SPUv16i8_binop, []>;
106 def SPUmpy_v8i16: SDNode<"SPUISD::MPY", SPUv8i16_binop, []>;
107 def SPUmpy_v4i32: SDNode<"SPUISD::MPY", SPUv4i32_binop, []>;
108
109 // SPU multiply unsigned, used in instruction lowering for v4i32
110 // multiplies:
111 def SPUmpyu_v4i32: SDNode<"SPUISD::MPYU", SPUv4i32_binop, []>;
112 def SPUmpyu_i32: SDNode<"SPUISD::MPYU", SDTIntBinOp, []>;
113
114 // SPU 16-bit multiply high x low, shift result 16-bits
115 // Used to compute intermediate products for 32-bit multiplies
116 def SPUmpyh_v4i32: SDNode<"SPUISD::MPYH", SPUv4i32_binop, []>;
117 def SPUmpyh_i32: SDNode<"SPUISD::MPYH", SDTIntBinOp, []>;
118
119 // SPU 16-bit multiply high x high, 32-bit product
120 // Used to compute intermediate products for 16-bit multiplies
121 def SPUmpyhh_v8i16: SDNode<"SPUISD::MPYHH", SPUv8i16_binop, []>;
122
123 // Vector shifts (ISD::SHL,SRL,SRA are for _integers_ only):
124 def SPUvec_shl_v8i16: SDNode<"SPUISD::VEC_SHL", SPUvecshift_type_v8i16, []>;
125 def SPUvec_srl_v8i16: SDNode<"SPUISD::VEC_SRL", SPUvecshift_type_v8i16, []>;
126 def SPUvec_sra_v8i16: SDNode<"SPUISD::VEC_SRA", SPUvecshift_type_v8i16, []>;
127
128 def SPUvec_shl_v4i32: SDNode<"SPUISD::VEC_SHL", SPUvecshift_type_v4i32, []>;
129 def SPUvec_srl_v4i32: SDNode<"SPUISD::VEC_SRL", SPUvecshift_type_v4i32, []>;
130 def SPUvec_sra_v4i32: SDNode<"SPUISD::VEC_SRA", SPUvecshift_type_v4i32, []>;
131
132 def SPUvec_rotl_v8i16: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type_v8i16, []>;
133 def SPUvec_rotl_v4i32: SDNode<"SPUISD::VEC_ROTL", SPUvecshift_type_v4i32, []>;
134
135 def SPUvec_rotr_v8i16: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v8i16, []>;
136 def SPUvec_rotr_v4i32: SDNode<"SPUISD::VEC_ROTR", SPUvecshift_type_v4i32, []>;
137
138 def SPUrotbytes_right_zfill: SDNode<"SPUISD::ROTBYTES_RIGHT_Z",
139 SPUvecshift_type_v16i8, []>;
140 def SPUrotbytes_right_sfill: SDNode<"SPUISD::ROTBYTES_RIGHT_S",
141 SPUvecshift_type_v16i8, []>;
142 def SPUrotbytes_left: SDNode<"SPUISD::ROTBYTES_LEFT",
143 SPUvecshift_type_v16i8, []>;
144
145 def SPUrotbytes_left_chained : SDNode<"SPUISD::ROTBYTES_LEFT_CHAINED",
146 SPUvecshift_type_v16i8, [SDNPHasChain]>;
147
148 // SPU form select mask for bytes, immediate
149 def SPUfsmbi_v16i8: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v16i8, []>;
150 def SPUfsmbi_v8i16: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v8i16, []>;
151 def SPUfsmbi_v4i32: SDNode<"SPUISD::FSMBI", SPUfsmbi_type_v4i32, []>;
152
153 // SPU select bits instruction
154 def SPUselb_v16i8: SDNode<"SPUISD::SELB", SPUselb_type_v16i8, []>;
155 def SPUselb_v8i16: SDNode<"SPUISD::SELB", SPUselb_type_v8i16, []>;
156 def SPUselb_v4i32: SDNode<"SPUISD::SELB", SPUselb_type_v4i32, []>;
157
158 // SPU single precision floating point constant load
159 def SPUFPconstant: SDNode<"SPUISD::SFPConstant", SDTFPUnaryOp, []>;
160
161 // SPU floating point interpolate
162 def SPUinterpolate : SDNode<"SPUISD::FPInterp", SDTFPBinOp, []>;
163
164 // SPU floating point reciprocal estimate (used for fdiv)
165 def SPUreciprocalEst: SDNode<"SPUISD::FPRecipEst", SDTFPUnaryOp, []>;
166
167 def SDT_vec_promote : SDTypeProfile<1, 1, []>;
168 def SPUpromote_scalar: SDNode<"SPUISD::PROMOTE_SCALAR", SDT_vec_promote, []>;
169
170 def SPU_vec_demote : SDTypeProfile<1, 1, []>;
171 def SPUextract_elt0: SDNode<"SPUISD::EXTRACT_ELT0", SPU_vec_demote, []>;
172 def SPU_vec_demote_chained : SDTypeProfile<1, 2, []>;
173 def SPUextract_elt0_chained: SDNode<"SPUISD::EXTRACT_ELT0_CHAINED",
174 SPU_vec_demote_chained, [SDNPHasChain]>;
175 def SPUextract_i1_sext: SDNode<"SPUISD::EXTRACT_I1_SEXT", SPU_vec_demote, []>;
176 def SPUextract_i1_zext: SDNode<"SPUISD::EXTRACT_I1_ZEXT", SPU_vec_demote, []>;
177 def SPUextract_i8_sext: SDNode<"SPUISD::EXTRACT_I8_SEXT", SPU_vec_demote, []>;
178 def SPUextract_i8_zext: SDNode<"SPUISD::EXTRACT_I8_ZEXT", SPU_vec_demote, []>;
179
180 // Address high and low components, used for [r+r] type addressing
181 def SPUhi : SDNode<"SPUISD::Hi", SDTIntBinOp, []>;
182 def SPUlo : SDNode<"SPUISD::Lo", SDTIntBinOp, []>;
183
184 // PC-relative address
185 def SPUpcrel : SDNode<"SPUISD::PCRelAddr", SDTIntBinOp, []>;
186
187 // D-Form "imm($reg)" addresses
188 def SPUdform : SDNode<"SPUISD::DFormAddr", SDTIntBinOp, []>;
189
190 // SPU 32-bit sign-extension to 64-bits
191 def SPUsext32_to_64: SDNode<"SPUISD::SEXT32TO64", SDTIntExtendOp, []>;
192
193 // Branches:
194
195 def SPUbrnz : SDNode<"SPUISD::BR_NOTZERO", SDTBrcond, [SDNPHasChain]>;
196 def SPUbrz : SDNode<"SPUISD::BR_ZERO", SDTBrcond, [SDNPHasChain]>;
197 /* def SPUbinz : SDNode<"SPUISD::BR_NOTZERO", SDTBrind, [SDNPHasChain]>;
198 def SPUbiz : SDNode<"SPUISD::BR_ZERO", SPUBrind, [SDNPHasChain]>; */
199
200 //===----------------------------------------------------------------------===//
201 // Constraints: (taken from PPCInstrInfo.td)
202 //===----------------------------------------------------------------------===//
203
204 class RegConstraint {
205 string Constraints = C;
206 }
207
208 class NoEncode {
209 string DisableEncoding = E;
210 }
211
212 //===----------------------------------------------------------------------===//
213 // Return (flag isn't quite what it means: the operations are flagged so that
214 // instruction scheduling doesn't disassociate them.)
215 //===----------------------------------------------------------------------===//
216
217 def retflag : SDNode<"SPUISD::RET_FLAG", SDTRet,
218 [SDNPHasChain, SDNPOptInFlag]>;
0 //===- SPUOperands.td - Cell SPU Instruction Operands ------*- tablegen -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by The Aerospace Corporation.
5 //
6 //===----------------------------------------------------------------------===//
7 // Cell SPU Instruction Operands:
8 //===----------------------------------------------------------------------===//
9
10 def LO16 : SDNodeXForm
11 unsigned val = N->getValue();
12 // Transformation function: get the low 16 bits.
13 return getI32Imm(val & 0xffff);
14 }]>;
15
16 def LO16_vec : SDNodeXForm
17 SDOperand OpVal(0, 0);
18
19 // Transformation function: get the low 16 bit immediate from a build_vector
20 // node.
21 assert(N->getOpcode() == ISD::BUILD_VECTOR
22 && "LO16_vec got something other than a BUILD_VECTOR");
23
24 // Get first constant operand...
25 for (unsigned i = 0, e = N->getNumOperands(); OpVal.Val == 0 && i != e; ++i) {
26 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
27 if (OpVal.Val == 0)
28 OpVal = N->getOperand(i);
29 }
30
31 assert(OpVal.Val != 0 && "LO16_vec did not locate a node");
32 ConstantSDNode *CN = dyn_cast(OpVal);
33 return getI32Imm((unsigned)CN->getValue() & 0xffff);
34 }]>;
35
36 // Transform an immediate, returning the high 16 bits shifted down:
37 def HI16 : SDNodeXForm
38 return getI32Imm((unsigned)N->getValue() >> 16);
39 }]>;
40
41 // Transformation function: shift the high 16 bit immediate from a build_vector
42 // node into the low 16 bits, and return a 16-bit constant.
43 def HI16_vec : SDNodeXForm
44 SDOperand OpVal(0, 0);
45
46 assert(N->getOpcode() == ISD::BUILD_VECTOR
47 && "HI16_vec got something other than a BUILD_VECTOR");
48
49 // Get first constant operand...
50 for (unsigned i = 0, e = N->getNumOperands(); OpVal.Val == 0 && i != e; ++i) {
51 if (N->getOperand(i).getOpcode() == ISD::UNDEF) continue;
52 if (OpVal.Val == 0)
53 OpVal = N->getOperand(i);
54 }
55
56 assert(OpVal.Val != 0 && "HI16_vec did not locate a node");
57 ConstantSDNode *CN = dyn_cast(OpVal);
58 return getI32Imm((unsigned)CN->getValue() >> 16);
59 }]>;
60
61 // simm7 predicate - True if the immediate fits in an 7-bit signed
62 // field.
63 def simm7: PatLeaf<(imm), [{
64 int sextVal = ((((int) N->getValue()) << 25) >> 25);
65 return (sextVal >= -64 && sextVal <= 63);
66 }]>;
67
68 // uimm7 predicate - True if the immediate fits in an 7-bit unsigned
69 // field.
70 def uimm7: PatLeaf<(imm), [{
71 return (N->getValue() <= 0x7f);
72 }]>;
73
74 // immSExt8 predicate - True if the immediate fits in an 8-bit sign extended
75 // field.
76 def immSExt8 : PatLeaf<(imm), [{
77 int Value = (int) N->getValue();
78 int Value8 = (Value << 24) >> 24;
79 return (Value < 0xff && (Value8 >= -128 && Value8 < 127));
80 }]>;
81
82 // immU8: immediate, unsigned 8-bit quantity
83 def immU8 : PatLeaf<(imm), [{
84 return (N->getValue() <= 0xff);
85 }]>;
86
87 // i64ImmSExt10 predicate - True if the i64 immediate fits in a 10-bit sign
88 // extended field. Used by RI10Form instructions like 'ldq'.
89 def i64ImmSExt10 : PatLeaf<(imm), [{
90 return isI64IntS10Immediate(N);
91 }]>;
92
93 // i32ImmSExt10 predicate - True if the i32 immediate fits in a 10-bit sign
94 // extended field. Used by RI10Form instructions like 'ldq'.
95 def i32ImmSExt10 : PatLeaf<(imm), [{
96 return isI32IntS10Immediate(N);
97 }]>;
98
99 // i16ImmSExt10 predicate - True if the i32 immediate fits in a 10-bit sign
100 // extended field. Used by RI10Form instructions like 'ldq'.
101 def i16ImmSExt10 : PatLeaf<(imm), [{
102 return isI16IntS10Immediate(N);
103 }]>;
104
105 def immSExt16 : PatLeaf<(imm), [{
106 // immSExt16 predicate - True if the immediate fits in a 16-bit sign extended
107 // field.
108 short Ignored;
109 return isIntS16Immediate(N, Ignored);
110 }]>;
111
112 def immZExt16 : PatLeaf<(imm), [{
113 // immZExt16 predicate - True if the immediate fits in a 16-bit zero extended
114 // field.
115 return (uint64_t)N->getValue() == (unsigned short)N->getValue();
116 }], LO16>;
117
118 def immU16 : PatLeaf<(imm), [{
119 // immU16 predicate- True if the immediate fits into a 16-bit unsigned field.
120 return (uint64_t)N->getValue() == (N->getValue() & 0xffff);
121 }]>;
122
123 def imm18 : PatLeaf<(imm), [{
124 // imm18 predicate: True if the immediate fits into an 18-bit unsigned field.
125 int Value = (int) N->getValue();
126 return ((Value & ((1 << 19) - 1)) == Value);
127 }]>;
128
129 def hi16 : PatLeaf<(imm), [{
130 // hi16 predicate - returns true if the immediate has all zeros in the
131 // low order bits and is a 32-bit constant:
132 if (N->getValueType(0) == MVT::i32) {
133 uint32_t val = N->getValue();
134 return ((val & 0xffff0000) == val);
135 }
136
137 return false;
138 }], HI16>;
139
140 //===----------------------------------------------------------------------===//
141 // Floating point operands:
142 //===----------------------------------------------------------------------===//
143
144 // Transform a float, returning the high 16 bits shifted down, as if
145 // the float was really an unsigned integer:
146 def HI16_f32 : SDNodeXForm
147 const APFloat &apf = N->getValueAPF();
148 float fval = apf.convertToFloat();
149 unsigned val = *((unsigned *) &fval);
150 return getI32Imm(val >> 16);
151 }]>;
152
153 // Transformation function on floats: get the low 16 bits as if the float was
154 // an unsigned integer.
155 def LO16_f32 : SDNodeXForm
156 const APFloat &apf = N->getValueAPF();
157 float fval = apf.convertToFloat();
158 unsigned val = *((unsigned *) &fval);
159 return getI32Imm(val & 0xffff);
160 }]>;
161
162 def FPimm_sext16 : SDNodeXForm
163 const APFloat &apf = N->getValueAPF();
164 float fval = apf.convertToFloat();
165 unsigned val = *((unsigned *) &fval);
166 return getI32Imm((int) ((val << 16) >> 16));
167 }]>;
168
169 def FPimm_u18 : SDNodeXForm
170 const APFloat &apf = N->getValueAPF();
171 float fval = apf.convertToFloat();
172 unsigned val = *((unsigned *) &fval);
173 return getI32Imm(val & ((1 << 19) - 1));
174 }]>;
175
176 def fpimmSExt16 : PatLeaf<(fpimm), [{
177 short Ignored;
178 return isFPS16Immediate(N, Ignored);
179 }], FPimm_sext16>;
180
181 // Does the SFP constant only have upp 16 bits set?
182 def hi16_f32 : PatLeaf<(fpimm), [{
183 if (N->getValueType(0) == MVT::f32) {
184 const APFloat &apf = N->getValueAPF();
185 float fval = apf.convertToFloat();
186 uint32_t val = *((unsigned *) &fval);
187 return ((val & 0xffff0000) == val);
188 }
189
190 return false;
191 }], HI16_f32>;
192
193 // Does the SFP constant fit into 18 bits?
194 def fpimm18 : PatLeaf<(fpimm), [{
195 if (N->getValueType(0) == MVT::f32) {
196 const APFloat &apf = N->getValueAPF();
197 float fval = apf.convertToFloat();
198 uint32_t Value = *((uint32_t *) &fval);
199 return ((Value & ((1 << 19) - 1)) == Value);
200 }
201
202 return false;
203 }], FPimm_u18>;
204
205 //===----------------------------------------------------------------------===//
206 // 64-bit operands:
207 //===----------------------------------------------------------------------===//
208
209 //===----------------------------------------------------------------------===//
210 // build_vector operands:
211 //===----------------------------------------------------------------------===//
212
213 // v16i8SExt8Imm_xform function: convert build_vector to 8-bit sign extended
214 // immediate constant load for v16i8 vectors. N.B.: The incoming constant has
215 // to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
216 def v16i8SExt8Imm_xform: SDNodeXForm
217 return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
218 }]>;
219
220 // v16i8SExt8Imm: Predicate test for 8-bit sign extended immediate constant
221 // load, works in conjunction with its transform function. N.B.: This relies the
222 // incoming constant being a 16-bit quantity, where the upper and lower bytes
223 // are EXACTLY the same (e.g., 0x2a2a)
224 def v16i8SExt8Imm: PatLeaf<(build_vector), [{
225 return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).Val != 0;
226 }], v16i8SExt8Imm_xform>;
227
228 // v16i8U8Imm_xform function: convert build_vector to unsigned 8-bit
229 // immediate constant load for v16i8 vectors. N.B.: The incoming constant has
230 // to be a 16-bit quantity with the upper and lower bytes equal (e.g., 0x2a2a).
231 def v16i8U8Imm_xform: SDNodeXForm
232 return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8);
233 }]>;
234
235 // v16i8U8Imm: Predicate test for unsigned 8-bit immediate constant
236 // load, works in conjunction with its transform function. N.B.: This relies the
237 // incoming constant being a 16-bit quantity, where the upper and lower bytes
238 // are EXACTLY the same (e.g., 0x2a2a)
239 def v16i8U8Imm: PatLeaf<(build_vector), [{
240 return SPU::get_vec_i8imm(N, *CurDAG, MVT::i8).Val != 0;
241 }], v16i8U8Imm_xform>;
242
243 // v8i16SExt8Imm_xform function: convert build_vector to 8-bit sign extended
244 // immediate constant load for v8i16 vectors.
245 def v8i16SExt8Imm_xform: SDNodeXForm
246 return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16);
247 }]>;
248
249 // v8i16SExt8Imm: Predicate test for 8-bit sign extended immediate constant
250 // load, works in conjunction with its transform function.
251 def v8i16SExt8Imm: PatLeaf<(build_vector), [{
252 return SPU::get_vec_i8imm(N, *CurDAG, MVT::i16).Val != 0;
253 }], v8i16SExt8Imm_xform>;
254
255 // v8i16SExt10Imm_xform function: convert build_vector to 16-bit sign extended
256 // immediate constant load for v8i16 vectors.
257 def v8i16SExt10Imm_xform: SDNodeXForm
258 return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16);
259 }]>;
260
261 // v8i16SExt10Imm: Predicate test for 16-bit sign extended immediate constant
262 // load, works in conjunction with its transform function.
263 def v8i16SExt10Imm: PatLeaf<(build_vector), [{
264 return SPU::get_vec_i10imm(N, *CurDAG, MVT::i16).Val != 0;
265 }], v8i16SExt10Imm_xform>;
266
267 // v8i16SExt16Imm_xform function: convert build_vector to 16-bit sign extended
268 // immediate constant load for v8i16 vectors.
269 def v8i16SExt16Imm_xform: SDNodeXForm
270 return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16);
271 }]>;
272
273 // v8i16SExt16Imm: Predicate test for 16-bit sign extended immediate constant
274 // load, works in conjunction with its transform function.
275 def v8i16SExt16Imm: PatLeaf<(build_vector), [{
276 return SPU::get_vec_i16imm(N, *CurDAG, MVT::i16).Val != 0;
277 }], v8i16SExt16Imm_xform>;
278
279 // v4i32SExt10Imm_xform function: convert build_vector to 10-bit sign extended
280 // immediate constant load for v4i32 vectors.
281 def v4i32SExt10Imm_xform: SDNodeXForm
282 return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32);
283 }]>;
284
285 // v4i32SExt10Imm: Predicate test for 10-bit sign extended immediate constant
286 // load, works in conjunction with its transform function.
287 def v4i32SExt10Imm: PatLeaf<(build_vector), [{
288 return SPU::get_vec_i10imm(N, *CurDAG, MVT::i32).Val != 0;
289 }], v4i32SExt10Imm_xform>;
290
291 // v4i32SExt16Imm_xform function: convert build_vector to 16-bit sign extended
292 // immediate constant load for v4i32 vectors.
293 def v4i32SExt16Imm_xform: SDNodeXForm
294 return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32);
295 }]>;
296
297 // v4i32SExt16Imm: Predicate test for 16-bit sign extended immediate constant
298 // load, works in conjunction with its transform function.
299 def v4i32SExt16Imm: PatLeaf<(build_vector), [{
300 return SPU::get_vec_i16imm(N, *CurDAG, MVT::i32).Val != 0;
301 }], v4i32SExt16Imm_xform>;
302
303 // v4i32Uns18Imm_xform function: convert build_vector to 18-bit unsigned
304 // immediate constant load for v4i32 vectors.
305 def v4i32Uns18Imm_xform: SDNodeXForm
306 return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32);
307 }]>;
308
309 // v4i32Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
310 // works in conjunction with its transform function.
311 def v4i32Uns18Imm: PatLeaf<(build_vector), [{
312 return SPU::get_vec_u18imm(N, *CurDAG, MVT::i32).Val != 0;
313 }], v4i32Uns18Imm_xform>;
314
315 // ILHUvec_get_imm xform function: convert build_vector to ILHUvec imm constant
316 // load.
317 def ILHUvec_get_imm: SDNodeXForm
318 return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32);
319 }]>;
320
321 /// immILHUvec: Predicate test for a ILHU constant vector.
322 def immILHUvec: PatLeaf<(build_vector), [{
323 return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i32).Val != 0;
324 }], ILHUvec_get_imm>;
325
326 // Catch-all for any other i32 vector constants
327 def v4i32_get_imm: SDNodeXForm
328 return SPU::get_v4i32_imm(N, *CurDAG);
329 }]>;
330
331 def v4i32Imm: PatLeaf<(build_vector), [{
332 return SPU::get_v4i32_imm(N, *CurDAG).Val != 0;
333 }], v4i32_get_imm>;
334
335 // v2i64SExt10Imm_xform function: convert build_vector to 10-bit sign extended
336 // immediate constant load for v2i64 vectors.
337 def v2i64SExt10Imm_xform: SDNodeXForm
338 return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64);
339 }]>;
340
341 // v2i64SExt10Imm: Predicate test for 10-bit sign extended immediate constant
342 // load, works in conjunction with its transform function.
343 def v2i64SExt10Imm: PatLeaf<(build_vector), [{
344 return SPU::get_vec_i10imm(N, *CurDAG, MVT::i64).Val != 0;
345 }], v2i64SExt10Imm_xform>;
346
347 // v2i64SExt16Imm_xform function: convert build_vector to 16-bit sign extended
348 // immediate constant load for v2i64 vectors.
349 def v2i64SExt16Imm_xform: SDNodeXForm
350 return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64);
351 }]>;
352
353 // v2i64SExt16Imm: Predicate test for 16-bit sign extended immediate constant
354 // load, works in conjunction with its transform function.
355 def v2i64SExt16Imm: PatLeaf<(build_vector), [{
356 return SPU::get_vec_i16imm(N, *CurDAG, MVT::i64).Val != 0;
357 }], v2i64SExt16Imm_xform>;
358
359 // v2i64Uns18Imm_xform function: convert build_vector to 18-bit unsigned
360 // immediate constant load for v2i64 vectors.
361 def v2i64Uns18Imm_xform: SDNodeXForm
362 return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64);
363 }]>;
364
365 // v2i64Uns18Imm: Predicate test for 18-bit unsigned immediate constant load,
366 // works in conjunction with its transform function.
367 def v2i64Uns18Imm: PatLeaf<(build_vector), [{
368 return SPU::get_vec_u18imm(N, *CurDAG, MVT::i64).Val != 0;
369 }], v2i64Uns18Imm_xform>;
370
371 /// immILHUvec: Predicate test for a ILHU constant vector.
372 def immILHUvec_i64: PatLeaf<(build_vector), [{
373 return SPU::get_ILHUvec_imm(N, *CurDAG, MVT::i64).Val != 0;
374 }], ILHUvec_get_imm>;
375
376 // Catch-all for any other i32 vector constants
377 def v2i64_get_imm: SDNodeXForm
378 return SPU::get_v2i64_imm(N, *CurDAG);
379 }]>;
380
381 def v2i64Imm: PatLeaf<(build_vector), [{
382 return SPU::get_v2i64_imm(N, *CurDAG).Val != 0;
383 }], v2i64_get_imm>;
384
385 //===----------------------------------------------------------------------===//
386 // Operand Definitions.
387
388 def s7imm: Operand {
389 let PrintMethod = "printS7ImmOperand";
390 }
391
392 def u7imm: Operand {
393 let PrintMethod = "printU7ImmOperand";
394 }
395
396 def u7imm_i32: Operand {
397 let PrintMethod = "printU7ImmOperand";
398 }
399
400 // Halfword, signed 10-bit constant
401 def s10imm : Operand {
402 let PrintMethod = "printS10ImmOperand";
403 }
404
405 def s10imm_i32: Operand {
406 let PrintMethod = "printS10ImmOperand";
407 }
408
409 def s10imm_i64: Operand {
410 let PrintMethod = "printS10ImmOperand";
411 }
412
413 // Unsigned 10-bit integers:
414 def u10imm: Operand {
415 let PrintMethod = "printU10ImmOperand";
416 }
417
418 def u10imm_i32: Operand {
419 let PrintMethod = "printU10ImmOperand";
420 }
421
422 def s16imm : Operand {
423 let PrintMethod = "printS16ImmOperand";
424 }
425
426 def s16imm_i32: Operand {
427 let PrintMethod = "printS16ImmOperand";
428 }
429
430 def s16imm_i64: Operand {
431 let PrintMethod = "printS16ImmOperand";
432 }
433
434 def s16imm_f32: Operand {
435 let PrintMethod = "printS16ImmOperand";
436 }
437
438 def s16imm_f64: Operand {
439 let PrintMethod = "printS16ImmOperand";
440 }
441
442 def u16imm : Operand {
443 let PrintMethod = "printU16ImmOperand";
444 }
445
446 def f16imm : Operand {
447 let PrintMethod = "printU16ImmOperand";
448 }
449
450 def s18imm : Operand {
451 let PrintMethod = "printS18ImmOperand";
452 }
453
454 def u18imm : Operand {
455 let PrintMethod = "printU18ImmOperand";
456 }
457
458 def u18imm_i64 : Operand {
459 let PrintMethod = "printU18ImmOperand";
460 }
461
462 def f18imm : Operand {
463 let PrintMethod = "printU18ImmOperand";
464 }
465
466 def f18imm_f64 : Operand {
467 let PrintMethod = "printU18ImmOperand";
468 }
469
470 // Negated 7-bit halfword rotate immediate operands
471 def rothNeg7imm : Operand {
472 let PrintMethod = "printROTHNeg7Imm";
473 }
474
475 def rothNeg7imm_i16 : Operand {
476 let PrintMethod = "printROTHNeg7Imm";
477 }
478
479 // Negated 7-bit word rotate immediate operands
480 def rotNeg7imm : Operand {
481 let PrintMethod = "printROTNeg7Imm";
482 }
483
484 def rotNeg7imm_i16 : Operand {
485 let PrintMethod = "printROTNeg7Imm";
486 }
487
488 // Floating point immediate operands
489 def f32imm : Operand;
490
491 def target : Operand {
492 let PrintMethod = "printBranchOperand";
493 }
494
495 // Absolute address call target
496 def calltarget : Operand {
497 let PrintMethod = "printCallOperand";
498 let MIOperandInfo = (ops u18imm:$calldest);
499 }
500
501 // Relative call target
502 def relcalltarget : Operand {
503 let PrintMethod = "printPCRelativeOperand";
504 let MIOperandInfo = (ops s16imm:$calldest);
505 }
506
507 // Branch targets:
508 def brtarget : Operand {
509 let PrintMethod = "printPCRelativeOperand";
510 }
511
512 // Indirect call target
513 def indcalltarget : Operand {
514 let PrintMethod = "printCallOperand";
515 let MIOperandInfo = (ops ptr_rc:$calldest);
516 }
517
518 def symbolHi: Operand {
519 let PrintMethod = "printSymbolHi";
520 }
521
522 def symbolLo: Operand {
523 let PrintMethod = "printSymbolLo";
524 }
525
526 def symbolLSA: Operand {
527 let PrintMethod = "printSymbolLSA";
528 }
529
530 // memory s7imm(reg) operaand
531 def memri7 : Operand {
532 let PrintMethod = "printMemRegImmS7";
533 let MIOperandInfo = (ops s7imm:$imm, ptr_rc:$reg);
534 }
535
536 // memory s10imm(reg) operand
537 def memri10 : Operand {
538 let PrintMethod = "printMemRegImmS10";
539 let MIOperandInfo = (ops s10imm:$imm, ptr_rc:$reg);
540 }
541
542 // 256K local store address
543 // N.B.: The tblgen code generator expects to have two operands, an offset
544 // and a pointer. Of these, only the immediate is actually used.
545 def addr256k : Operand {
546 let PrintMethod = "printAddr256K";
547 let MIOperandInfo = (ops s16imm:$imm, ptr_rc:$reg);
548 }
549
550 // memory s18imm(reg) operand
551 def memri18 : Operand {
552 let PrintMethod = "printMemRegImmS18";
553 let MIOperandInfo = (ops s18imm:$imm, ptr_rc:$reg);
554 }
555
556 // memory register + register operand
557 def memrr : Operand {
558 let PrintMethod = "printMemRegReg";
559 let MIOperandInfo = (ops ptr_rc:$reg_a, ptr_rc:$reg_b);
560 }
561
562 // Define SPU-specific addressing modes: These come in three basic
563 // flavors:
564 //
565 // D-form : [r+I10] (10-bit signed offset + reg)
566 // X-form : [r+r] (reg+reg)
567 // A-form : abs (256K LSA offset)
568 // D-form(2): [r+I7] (7-bit signed offset + reg)
569
570 def dform_addr : ComplexPattern;
571 def xform_addr : ComplexPattern;
572 def aform_addr : ComplexPattern;
573 def dform2_addr : ComplexPattern;
0 //===- SPURegisterInfo.cpp - Cell SPU Register Information ------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file contains the PowerPC implementation of the MRegisterInfo class.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "reginfo"
16 #include "SPU.h"
17 #include "SPURegisterInfo.h"
18 #include "SPURegisterNames.h"
19 #include "SPUInstrBuilder.h"
20 #include "SPUSubtarget.h"
21 #include "SPUMachineFunction.h"
22 #include "SPUFrameInfo.h"
23 #include "llvm/Constants.h"
24 #include "llvm/Type.h"
25 #include "llvm/CodeGen/ValueTypes.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/CodeGen/MachineModuleInfo.h"
28 #include "llvm/CodeGen/MachineFunction.h"
29 #include "llvm/CodeGen/MachineFrameInfo.h"
30 #include "llvm/CodeGen/MachineLocation.h"
31 #include "llvm/CodeGen/SelectionDAGNodes.h"
32 #include "llvm/CodeGen/ValueTypes.h"
33 #include "llvm/Target/TargetFrameInfo.h"
34 #include "llvm/Target/TargetInstrInfo.h"
35 #include "llvm/Target/TargetMachine.h"
36 #include "llvm/Target/TargetOptions.h"
37 #include "llvm/Support/CommandLine.h"
38 #include "llvm/Support/Debug.h"
39 #include "llvm/Support/MathExtras.h"
40 #include "llvm/ADT/BitVector.h"
41 #include "llvm/ADT/STLExtras.h"
42 #include
43 #include
44
45 using namespace llvm;
46
47 /// getRegisterNumbering - Given the enum value for some register, e.g.
48 /// PPC::F14, return the number that it corresponds to (e.g. 14).
49 unsigned SPURegisterInfo::getRegisterNumbering(unsigned RegEnum) {
50 using namespace SPU;
51 switch (RegEnum) {
52 case SPU::R0: return 0;
53 case SPU::R1: return 1;
54 case SPU::R2: return 2;
55 case SPU::R3: return 3;
56 case SPU::R4: return 4;
57 case SPU::R5: return 5;
58 case SPU::R6: return 6;
59 case SPU::R7: return 7;
60 case SPU::R8: return 8;
61 case SPU::R9: return 9;
62 case SPU::R10: return 10;
63 case SPU::R11: return 11;
64 case SPU::R12: return 12;
65 case SPU::R13: return 13;
66 case SPU::R14: return 14;
67 case SPU::R15: return 15;
68 case SPU::R16: return 16;
69 case SPU::R17: return 17;
70 case SPU::R18: return 18;
71 case SPU::R19: return 19;
72 case SPU::R20: return 20;
73 case SPU::R21: return 21;
74 case SPU::R22: return 22;
75 case SPU::R23: return 23;
76 case SPU::R24: return 24;
77 case SPU::R25: return 25;
78 case SPU::R26: return 26;
79 case SPU::R27: return 27;
80 case SPU::R28: return 28;
81 case SPU::R29: return 29;
82 case SPU::R30: return 30;
83 case SPU::R31: return 31;
84 case SPU::R32: return 32;
85 case SPU::R33: return 33;
86 case SPU::R34: return 34;
87 case SPU::R35: return 35;
88 case SPU::R36: return 36;
89 case SPU::R37: return 37;
90 case SPU::R38: return 38;
91 case SPU::R39: return 39;
92 case SPU::R40: return 40;
93 case SPU::R41: return 41;
94 case SPU::R42: return 42;
95 case SPU::R43: return 43;
96 case SPU::R44: return 44;
97 case SPU::R45: return 45;
98 case SPU::R46: return 46;
99 case SPU::R47: return 47;
100 case SPU::R48: return 48;
101 case SPU::R49: return 49;
102 case SPU::R50: return 50;
103 case SPU::R51: return 51;
104 case SPU::R52: return 52;
105 case SPU::R53: return 53;
106 case SPU::R54: return 54;
107 case SPU::R55: return 55;
108 case SPU::R56: return 56;
109 case SPU::R57: return 57;
110 case SPU::R58: return 58;
111 case SPU::R59: return 59;
112 case SPU::R60: return 60;
113 case SPU::R61: return 61;
114 case SPU::R62: return 62;
115 case SPU::R63: return 63;
116 case SPU::R64: return 64;
117 case SPU::R65: return 65;
118 case SPU::R66: return 66;
119 case SPU::R67: return 67;
120 case SPU::R68: return 68;
121 case SPU::R69: return 69;
122 case SPU::R70: return 70;
123 case SPU::R71: return 71;
124 case SPU::R72: return 72;
125 case SPU::R73: return 73;
126 case SPU::R74: return 74;
127 case SPU::R75: return 75;
128 case SPU::R76: return 76;
129 case SPU::R77: return 77;
130 case SPU::R78: return 78;
131 case SPU::R79: return 79;
132 case SPU::R80: return 80;
133 case SPU::R81: return 81;
134 case SPU::R82: return 82;
135 case SPU::R83: return 83;
136 case SPU::R84: return 84;
137 case SPU::R85: return 85;
138 case SPU::R86: return 86;
139 case SPU::R87: return 87;
140 case SPU::R88: return 88;
141 case SPU::R89: return 89;
142 case SPU::R90: return 90;
143 case SPU::R91: return 91;
144 case SPU::R92: return 92;
145 case SPU::R93: return 93;
146 case SPU::R94: return 94;
147 case SPU::R95: return 95;
148 case SPU::R96: return 96;
149 case SPU::R97: return 97;
150 case SPU::R98: return 98;
151 case SPU::R99: return 99;
152 case SPU::R100: return 100;
153 case SPU::R101: return 101;
154 case SPU::R102: return 102;
155 case SPU::R103: return 103;
156 case SPU::R104: return 104;
157 case SPU::R105: return 105;
158 case SPU::R106: return 106;
159 case SPU::R107: return 107;
160 case SPU::R108: return 108;
161 case SPU::R109: return 109;
162 case SPU::R110: return 110;
163 case SPU::R111: return 111;
164 case SPU::R112: return 112;
165 case SPU::R113: return 113;
166 case SPU::R114: return 114;
167 case SPU::R115: return 115;
168 case SPU::R116: return 116;
169 case SPU::R117: return 117;
170 case SPU::R118: return 118;
171 case SPU::R119: return 119;
172 case SPU::R120: return 120;
173 case SPU::R121: return 121;
174 case SPU::R122: return 122;
175 case SPU::R123: return 123;
176 case SPU::R124: return 124;
177 case SPU::R125: return 125;
178 case SPU::R126: return 126;
179 case SPU::R127: return 127;
180 default:
181 std::cerr << "Unhandled reg in SPURegisterInfo::getRegisterNumbering!\n";
182 abort();
183 }
184 }
185
186 SPURegisterInfo::SPURegisterInfo(const SPUSubtarget &subtarget,
187 const TargetInstrInfo &tii) :
188 SPUGenRegisterInfo(SPU::ADJCALLSTACKDOWN, SPU::ADJCALLSTACKUP),
189 Subtarget(subtarget),
190 TII(tii)
191 {
192 }
193
194 void
195 SPURegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
196 MachineBasicBlock::iterator MI,
197 unsigned SrcReg, int FrameIdx,
198 const TargetRegisterClass *RC) const
199 {
200 MachineOpCode opc;
201 if (RC == SPU::GPRCRegisterClass) {
202 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
203 ? SPU::STQDr128
204 : SPU::STQXr128;
205 } else if (RC == SPU::R64CRegisterClass) {
206 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
207 ? SPU::STQDr64
208 : SPU::STQXr64;
209 } else if (RC == SPU::R64FPRegisterClass) {
210 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
211 ? SPU::STQDr64
212 : SPU::STQXr64;
213 } else if (RC == SPU::R32CRegisterClass) {
214 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
215 ? SPU::STQDr32
216 : SPU::STQXr32;
217 } else if (RC == SPU::R32FPRegisterClass) {
218 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
219 ? SPU::STQDr32
220 : SPU::STQXr32;
221 } else if (RC == SPU::R16CRegisterClass) {
222 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset()) ?
223 SPU::STQDr16
224 : SPU::STQXr16;
225 } else {
226 assert(0 && "Unknown regclass!");
227 abort();
228 }
229
230 addFrameReference(BuildMI(MBB, MI, TII.get(opc)).addReg(SrcReg), FrameIdx);
231 }
232
233 void SPURegisterInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
234 SmallVectorImpl &Addr,
235 const TargetRegisterClass *RC,
236 SmallVectorImpl &NewMIs) const {
237 cerr << "storeRegToAddr() invoked!\n";
238 abort();
239
240 if (Addr[0].isFrameIndex()) {
241 /* do what storeRegToStackSlot does here */
242 } else {
243 unsigned Opc = 0;
244 if (RC == SPU::GPRCRegisterClass) {
245 /* Opc = PPC::STW; */
246 } else if (RC == SPU::R16CRegisterClass) {
247 /* Opc = PPC::STD; */
248 } else if (RC == SPU::R32CRegisterClass) {
249 /* Opc = PPC::STFD; */
250 } else if (RC == SPU::R32FPRegisterClass) {
251 /* Opc = PPC::STFD; */
252 } else if (RC == SPU::R64FPRegisterClass) {
253 /* Opc = PPC::STFS; */
254 } else if (RC == SPU::VECREGRegisterClass) {
255 /* Opc = PPC::STVX; */
256 } else {
257 assert(0 && "Unknown regclass!");
258 abort();
259 }
260 MachineInstrBuilder MIB = BuildMI(TII.get(Opc))
261 .addReg(SrcReg, false, false, true);
262 for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
263 MachineOperand &MO = Addr[i];
264 if (MO.isRegister())
265 MIB.addReg(MO.getReg());
266 else if (MO.isImmediate())
267 MIB.addImm(MO.getImmedValue());
268 else
269 MIB.addFrameIndex(MO.getFrameIndex());
270 }
271 NewMIs.push_back(MIB);
272 }
273 }
274
275 void
276 SPURegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
277 MachineBasicBlock::iterator MI,
278 unsigned DestReg, int FrameIdx,
279 const TargetRegisterClass *RC) const
280 {
281 MachineOpCode opc;
282 if (RC == SPU::GPRCRegisterClass) {
283 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
284 ? SPU::LQDr128
285 : SPU::LQXr128;
286 } else if (RC == SPU::R64CRegisterClass) {
287 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
288 ? SPU::LQDr64
289 : SPU::LQXr64;
290 } else if (RC == SPU::R64FPRegisterClass) {
291 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
292 ? SPU::LQDr64
293 : SPU::LQXr64;
294 } else if (RC == SPU::R32CRegisterClass) {
295 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
296 ? SPU::LQDr32
297 : SPU::LQXr32;
298 } else if (RC == SPU::R32FPRegisterClass) {
299 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
300 ? SPU::LQDr32
301 : SPU::LQXr32;
302 } else if (RC == SPU::R16CRegisterClass) {
303 opc = (FrameIdx < SPUFrameInfo::maxFrameOffset())
304 ? SPU::LQDr16
305 : SPU::LQXr16;
306 } else {
307 assert(0 && "Unknown regclass in loadRegFromStackSlot!");
308 abort();
309 }
310
311 addFrameReference(BuildMI(MBB, MI, TII.get(opc)).addReg(DestReg), FrameIdx);
312 }
313
314 /*!
315 \note We are really pessimistic here about what kind of a load we're doing.
316 */
317 void SPURegisterInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
318 SmallVectorImpl &Addr,
319 const TargetRegisterClass *RC,
320 SmallVectorImpl &NewMIs)
321 const {
322 cerr << "loadRegToAddr() invoked!\n";
323 abort();
324
325 if (Addr[0].isFrameIndex()) {
326 /* do what loadRegFromStackSlot does here... */
327 } else {
328 unsigned Opc = 0;
329 if (RC == SPU::R16CRegisterClass) {
330 /* Opc = PPC::LWZ; */
331 } else if (RC == SPU::R32CRegisterClass) {
332 /* Opc = PPC::LD; */
333 } else if (RC == SPU::R32FPRegisterClass) {
334 /* Opc = PPC::LFD; */
335 } else if (RC == SPU::R64FPRegisterClass) {
336 /* Opc = PPC::LFS; */
337 } else if (RC == SPU::VECREGRegisterClass) {
338 /* Opc = PPC::LVX; */
339 } else if (RC == SPU::GPRCRegisterClass) {
340 /* Opc = something else! */
341 } else {
342 assert(0 && "Unknown regclass!");
343 abort();
344 }
345 MachineInstrBuilder MIB = BuildMI(TII.get(Opc), DestReg);
346 for (unsigned i = 0, e = Addr.size(); i != e; ++i) {
347 MachineOperand &MO = Addr[i];
348 if (MO.isRegister())
349 MIB.addReg(MO.getReg());
350 else if (MO.isImmediate())
351 MIB.addImm(MO.getImmedValue());
352 else
353 MIB.addFrameIndex(MO.getFrameIndex());
354 }
355 NewMIs.push_back(MIB);
356 }
357 }
358
359 void SPURegisterInfo::copyRegToReg(MachineBasicBlock &MBB,
360 MachineBasicBlock::iterator MI,
361 unsigned DestReg, unsigned SrcReg,
362 const TargetRegisterClass *DestRC,
363 const TargetRegisterClass *SrcRC) const
364 {
365 if (DestRC != SrcRC) {
366 cerr << "SPURegisterInfo::copyRegToReg(): DestRC != SrcRC not supported!\n";
367 abort();
368 }
369
370 /* if (DestRC == SPU::R8CRegisterClass) {
371 BuildMI(MBB, MI, TII.get(SPU::ORBIr8), DestReg).addReg(SrcReg).addImm(0);
372 } else */
373 if (DestRC == SPU::R16CRegisterClass) {
374 BuildMI(MBB, MI, TII.get(SPU::ORHIr16), DestReg).addReg(SrcReg).addImm(0);
375 } else if (DestRC == SPU::R32CRegisterClass) {
376 BuildMI(MBB, MI, TII.get(SPU::ORIr32), DestReg).addReg(SrcReg).addImm(0);
377 } else if (DestRC == SPU::R32FPRegisterClass) {
378 BuildMI(MBB, MI, TII.get(SPU::ORIf32), DestReg).addReg(SrcReg).addImm(0);
379 } else if (DestRC == SPU::R64CRegisterClass) {
380 BuildMI(MBB, MI, TII.get(SPU::ORIr64), DestReg).addReg(SrcReg).addImm(0);
381 } else if (DestRC == SPU::R64FPRegisterClass) {
382 BuildMI(MBB, MI, TII.get(SPU::ORIf64), DestReg).addReg(SrcReg).addImm(0);
383 } else if (DestRC == SPU::GPRCRegisterClass) {
384 BuildMI(MBB, MI, TII.get(SPU::ORgprc), DestReg).addReg(SrcReg)
385 .addReg(SrcReg);
386 } else if (DestRC == SPU::VECREGRegisterClass) {
387 BuildMI(MBB, MI, TII.get(SPU::ORv4i32), DestReg).addReg(SrcReg)
388 .addReg(SrcReg);
389 } else {
390 std::cerr << "Attempt to copy unknown/unsupported register class!\n";
391 abort();
392 }
393 }
394
395 void SPURegisterInfo::reMaterialize(MachineBasicBlock &MBB,
396 MachineBasicBlock::iterator I,
397 unsigned DestReg,
398 const MachineInstr *Orig) const {
399 MachineInstr *MI = Orig->clone();
400 MI->getOperand(0).setReg(DestReg);
401 MBB.insert(I, MI);
402 }
403
404 // SPU's 128-bit registers used for argument passing:
405 static const unsigned SPU_ArgRegs[] = {
406 SPU::R3, SPU::R4, SPU::R5, SPU::R6, SPU::R7, SPU::R8, SPU::R9,
407 SPU::R10, SPU::R11, SPU::R12, SPU::R13, SPU::R14, SPU::R15, SPU::R16,
408 SPU::R17, SPU::R18, SPU::R19, SPU::R20, SPU::R21, SPU::R22, SPU::R23,
409 SPU::R24, SPU::R25, SPU::R26, SPU::R27, SPU::R28, SPU::R29, SPU::R30,
410 SPU::R31, SPU::R32, SPU::R33, SPU::R34, SPU::R35, SPU::R36, SPU::R37,
411 SPU::R38, SPU::R39, SPU::R40, SPU::R41, SPU::R42, SPU::R43, SPU::R44,
412 SPU::R45, SPU::R46, SPU::R47, SPU::R48, SPU::R49, SPU::R50, SPU::R51,
413 SPU::R52, SPU::R53, SPU::R54, SPU::R55, SPU::R56, SPU::R57, SPU::R58,
414 SPU::R59, SPU::R60, SPU::R61, SPU::R62, SPU::R63, SPU::R64, SPU::R65,
415 SPU::R66, SPU::R67, SPU::R68, SPU::R69, SPU::R70, SPU::R71, SPU::R72,
416 SPU::R73, SPU::R74, SPU::R75, SPU::R76, SPU::R77, SPU::R78, SPU::R79
417 };
418
419 const unsigned *
420 SPURegisterInfo::getArgRegs()
421 {
422 return SPU_ArgRegs;
423 }
424
425 const unsigned
426 SPURegisterInfo::getNumArgRegs()
427 {
428 return sizeof(SPU_ArgRegs) / sizeof(SPU_ArgRegs[0]);
429 }
430
431 const unsigned *
432 SPURegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const
433 {
434 // Cell ABI calling convention
435 static const unsigned SPU_CalleeSaveRegs[] = {
436 SPU::R80, SPU::R81, SPU::R82, SPU::R83,
437 SPU::R84, SPU::R85, SPU::R86, SPU::R87,
438 SPU::R88, SPU::R89, SPU::R90, SPU::R91,
439 SPU::R92, SPU::R93, SPU::R94, SPU::R95,
440 SPU::R96, SPU::R97, SPU::R98, SPU::R99,
441 SPU::R100, SPU::R101, SPU::R102, SPU::R103,
442 SPU::R104, SPU::R105, SPU::R106, SPU::R107,
443 SPU::R108, SPU::R109, SPU::R110, SPU::R111,
444 SPU::R112, SPU::R113, SPU::R114, SPU::R115,
445 SPU::R116, SPU::R117, SPU::R118, SPU::R119,
446 SPU::R120, SPU::R121, SPU::R122, SPU::R123,
447 SPU::R124, SPU::R125, SPU::R126, SPU::R127,
448 SPU::R2, /* environment pointer */
449 SPU::R1, /* stack pointer */
450 SPU::R0, /* link register */
451 0 /* end */
452 };
453
454 return SPU_CalleeSaveRegs;
455 }
456
457 const TargetRegisterClass* const*
458 SPURegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const
459 {
460 // Cell ABI Calling Convention
461 static const TargetRegisterClass * const SPU_CalleeSaveRegClasses[] = {
462 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
463 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
464 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
465 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
466 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
467 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
468 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
469 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
470 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
471 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
472 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
473 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
474 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
475 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
476 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
477 &SPU::GPRCRegClass, &SPU::GPRCRegClass, &SPU::GPRCRegClass,
478 &SPU::GPRCRegClass, /* environment pointer */
479 &SPU::GPRCRegClass, /* stack pointer */
480 &SPU::GPRCRegClass, /* link register */
481 0 /* end */
482 };
483
484 return SPU_CalleeSaveRegClasses;
485 }
486
487 /*!
488 R0 (link register), R1 (stack pointer) and R2 (environment pointer -- this is
489 generally unused) are the Cell's reserved registers
490 */
491 BitVector SPURegisterInfo::getReservedRegs(const MachineFunction &MF) const {
492 BitVector Reserved(getNumRegs());
493 Reserved.set(SPU::R0); // LR
494 Reserved.set(SPU::R1); // SP
495 Reserved.set(SPU::R2); // environment pointer
496 return Reserved;
497 }
498
499 /// foldMemoryOperand - SPU, like PPC, can only fold spills into
500 /// copy instructions, turning them into load/store instructions.
501 MachineInstr *
502 SPURegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum,
503 int FrameIndex) const
504 {
505 #if SOMEDAY_SCOTT_LOOKS_AT_ME_AGAIN
506 unsigned Opc = MI->getOpcode();
507 MachineInstr *NewMI = 0;
508
509 if ((Opc == SPU::ORr32
510 || Opc == SPU::ORv4i32)
511 && MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) {
512 if (OpNum == 0) { // move -> store
513 unsigned InReg = MI->getOperand(1).getReg();
514 if (FrameIndex < SPUFrameInfo::maxFrameOffset()) {
515 NewMI = addFrameReference(BuildMI(TII.get(SPU::STQDr32)).addReg(InReg),
516 FrameIndex);
517 }
518 } else { // move -> load
519 unsigned OutReg = MI->getOperand(0).getReg();
520 Opc = (FrameIndex < SPUFrameInfo::maxFrameOffset()) ? SPU::STQDr32 : SPU::STQXr32;
521 NewMI = addFrameReference(BuildMI(TII.get(Opc), OutReg), FrameIndex);
522 }
523 }
524
525 if (NewMI)
526 NewMI->copyKillDeadInfo(MI);
527
528 return NewMI;
529 #else
530 return 0;
531 #endif
532 }
533
534 /// General-purpose load/store fold to operand code
535 MachineInstr *
536 SPURegisterInfo::foldMemoryOperand(MachineInstr *MI, unsigned OpNum,
537 MachineInstr *LoadMI) const
538 {
539 return 0;
540 }
541
542 //===----------------------------------------------------------------------===//
543 // Stack Frame Processing methods
544 //===----------------------------------------------------------------------===//
545
546 // needsFP - Return true if the specified function should have a dedicated frame
547 // pointer register. This is true if the function has variable sized allocas or
548 // if frame pointer elimination is disabled.
549 //
550 static bool needsFP(const MachineFunction &MF) {
551 const MachineFrameInfo *MFI = MF.getFrameInfo();
552 return NoFramePointerElim || MFI->hasVarSizedObjects();
553 }
554
555 //--------------------------------------------------------------------------
556 // hasFP - Return true if the specified function actually has a dedicated frame
557 // pointer register. This is true if the function needs a frame pointer and has
558 // a non-zero stack size.
559 bool
560 SPURegisterInfo::hasFP(const MachineFunction &MF) const {
561 const MachineFrameInfo *MFI = MF.getFrameInfo();
562 return MFI->getStackSize() && needsFP(MF);
563 }
564
565 //--------------------------------------------------------------------------
566 void
567 SPURegisterInfo::eliminateCallFramePseudoInstr(MachineFunction &MF,
568 MachineBasicBlock &MBB,
569 MachineBasicBlock::iterator I)
570 const
571 {
572 // Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
573 MBB.erase(I);
574 }
575
576 void
577 SPURegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj,
578 RegScavenger *RS) const
579 {
580 assert(SPAdj == 0 && "Unexpected SP adjacency == 0");
581
582 unsigned i = 0;
583 MachineInstr &MI = *II;
584 MachineBasicBlock &MBB = *MI.getParent();
585 MachineFunction &MF = *MBB.getParent();
586 MachineFrameInfo *MFI = MF.getFrameInfo();
587
588 while (!MI.getOperand(i).isFrameIndex()) {
589 ++i;
590 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!");
591 }
592
593 MachineOperand &SPOp = MI.getOperand(i);
594 int FrameIndex = SPOp.getFrameIndex();
595
596 // Now add the frame object offset to the offset from r1.
597 int Offset = MFI->getObjectOffset(FrameIndex);
598
599 // Most instructions, except for generated FrameIndex additions using AIr32,
600 // have the immediate in operand 1. AIr32, in this case, has the immediate
601 // in operand 2.
602 unsigned OpNo = (MI.getOpcode() != SPU::AIr32 ? 1 : 2);
603 MachineOperand &MO = MI.getOperand(OpNo);
604
605 // Offset is biased by $lr's slot at the bottom.
606 Offset += MO.getImmedValue() + MFI->getStackSize()
607 + SPUFrameInfo::minStackSize();
608 assert((Offset & 0xf) == 0
609 && "16-byte alignment violated in SPURegisterInfo::eliminateFrameIndex");
610
611 // Replace the FrameIndex with base register with $sp (aka $r1)
612 SPOp.ChangeToRegister(SPU::R1, false);
613 if (Offset > SPUFrameInfo::maxFrameOffset()
614 || Offset < SPUFrameInfo::minFrameOffset()) {
615 cerr << "Large stack adjustment ("
616 << Offset
617 << ") in SPURegisterInfo::eliminateFrameIndex.";
618 } else {
619 MO.ChangeToImmediate(Offset);
620 }
621 }
622
623 /// determineFrameLayout - Determine the size of the frame and maximum call
624 /// frame size.
625 void
626 SPURegisterInfo::determineFrameLayout(MachineFunction &MF) const
627 {
628 MachineFrameInfo *MFI = MF.getFrameInfo();
629
630 // Get the number of bytes to allocate from the FrameInfo
631 unsigned FrameSize = MFI->getStackSize();
632
633 // Get the alignments provided by the target, and the maximum alignment
634 // (if any) of the fixed frame objects.
635 unsigned TargetAlign = MF.getTarget().getFrameInfo()->getStackAlignment();
636 unsigned Align = std::max(TargetAlign, MFI->getMaxAlignment());
637 assert(isPowerOf2_32(Align) && "Alignment is not power of 2");
638 unsigned AlignMask = Align - 1;
639
640 // Get the maximum call frame size of all the calls.
641 unsigned maxCallFrameSize = MFI->getMaxCallFrameSize();
642
643 // If we have dynamic alloca then maxCallFrameSize needs to be aligned so
644 // that allocations will be aligned.
645 if (MFI->hasVarSizedObjects())
646 maxCallFrameSize = (maxCallFrameSize + AlignMask) & ~AlignMask;
647
648 // Update maximum call frame size.
649 MFI->setMaxCallFrameSize(maxCallFrameSize);
650
651 // Include call frame size in total.
652 FrameSize += maxCallFrameSize;
653
654 // Make sure the frame is aligned.
655 FrameSize = (FrameSize + AlignMask) & ~AlignMask;
656
657 // Update frame info.
658 MFI->setStackSize(FrameSize);
659 }
660
661 void SPURegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
662 RegScavenger *RS)
663 const {
664 #if 0
665 // Save and clear the LR state.
666 SPUFunctionInfo *FI = MF.getInfo();
667 FI->setUsesLR(MF.isPhysRegUsed(LR));
668 #endif
669 // Mark LR and SP unused, since the prolog spills them to stack and
670 // we don't want anyone else to spill them for us.
671 //
672 // Also, unless R2 is really used someday, don't spill it automatically.
673 MF.setPhysRegUnused(SPU::R0);
674 MF.setPhysRegUnused(SPU::R1);
675 MF.setPhysRegUnused(SPU::R2);
676 }
677
678 void SPURegisterInfo::emitPrologue(MachineFunction &MF) const
679 {
680 MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB
681 MachineBasicBlock::iterator MBBI = MBB.begin();
682 MachineFrameInfo *MFI = MF.getFrameInfo();
683 MachineModuleInfo *MMI = MFI->getMachineModuleInfo();
684
685 // Prepare for debug frame info.
686 bool hasDebugInfo = MMI && MMI->hasDebugInfo();
687 unsigned FrameLabelId = 0;
688
689 // Move MBBI back to the beginning of the function.
690 MBBI = MBB.begin();
691
692 // Work out frame sizes.
693 determineFrameLayout(MF);
694 int FrameSize = MFI->getStackSize();
695
696 assert((FrameSize & 0xf) == 0
697 && "SPURegisterInfo::emitPrologue: FrameSize not aligned");
698
699 if (FrameSize > 0) {
700 FrameSize = -(FrameSize + SPUFrameInfo::minStackSize());
701 if (hasDebugInfo) {
702 // Mark effective beginning of when frame pointer becomes valid.
703 FrameLabelId = MMI->NextLabelID();
704 BuildMI(MBB, MBBI, TII.get(ISD::LABEL)).addImm(FrameLabelId);
705 }
706
707 // Adjust stack pointer, spilling $lr -> 16($sp) and $sp -> -FrameSize($sp)
708 // for the ABI
709 BuildMI(MBB, MBBI, TII.get(SPU::STQDr32), SPU::R0).addImm(16)
710 .addReg(SPU::R1);
711 if (isS10Constant(FrameSize)) {
712 // Spill $sp to adjusted $sp
713 BuildMI(MBB, MBBI, TII.get(SPU::STQDr32), SPU::R1).addImm(FrameSize)
714 .addReg(SPU::R1);
715 // Adjust $sp by required amout
716 BuildMI(MBB, MBBI, TII.get(SPU::AIr32), SPU::R1).addReg(SPU::R1)
717 .addImm(FrameSize);
718 } else if (FrameSize <= (1 << 16) - 1 && FrameSize >= -(1 << 16)) {
719 // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use
720 // $r2 to adjust $sp:
721 BuildMI(MBB, MBBI, TII.get(SPU::STQDr128), SPU::R2)
722 .addImm(-16)
723 .addReg(SPU::R1);
724 BuildMI(MBB, MBBI, TII.get(SPU::ILr32), SPU::R2)
725 .addImm(FrameSize);
726 BuildMI(MBB, MBBI, TII.get(SPU::STQDr32), SPU::R1)
727 .addReg(SPU::R2)
728 .addReg(SPU::R1);
729 BuildMI(MBB, MBBI, TII.get(SPU::Ar32), SPU::R1)
730 .addReg(SPU::R1)
731 .addReg(SPU::R2);
732 BuildMI(MBB, MBBI, TII.get(SPU::SFIr32), SPU::R2)
733 .addReg(SPU::R2)
734 .addImm(16);
735 BuildMI(MBB, MBBI, TII.get(SPU::LQXr128), SPU::R2)
736 .addReg(SPU::R2)
737 .addReg(SPU::R1);
738 } else {
739 cerr << "Unhandled frame size: " << FrameSize << "\n";
740 abort();
741 }
742
743 if (hasDebugInfo) {
744 std::vector &Moves = MMI->getFrameMoves();
745
746 // Show update of SP.
747 MachineLocation SPDst(MachineLocation::VirtualFP);
748 MachineLocation SPSrc(MachineLocation::VirtualFP, -FrameSize);
749 Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc));
750
751 // Add callee saved registers to move list.
752 const std::vector &CSI = MFI->getCalleeSavedInfo();
753 for (unsigned I = 0, E = CSI.size(); I != E; ++I) {
754 int Offset = MFI->getObjectOffset(CSI[I].getFrameIdx());
755 unsigned Reg = CSI[I].getReg();
756 if (Reg == SPU::R0) continue;
757 MachineLocation CSDst(MachineLocation::VirtualFP, Offset);
758 MachineLocation CSSrc(Reg);
759 Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc));
760 }
761
762 // Mark effective beginning of when frame pointer is ready.
763 unsigned ReadyLabelId = MMI->NextLabelID();
764 BuildMI(MBB, MBBI, TII.get(ISD::LABEL)).addImm(ReadyLabelId);
765
766 MachineLocation FPDst(SPU::R1);
767 MachineLocation FPSrc(MachineLocation::VirtualFP);
768 Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc));
769 }
770 } else {
771 // This is a leaf function -- insert a branch hint iff there are
772 // sufficient number instructions in the basic block. Note that
773 // this is just a best guess based on the basic block's size.
774 if (MBB.size() >= (unsigned) SPUFrameInfo::branchHintPenalty()) {
775 MachineBasicBlock::iterator MBBI = prior(MBB.end());
776 // Insert terminator label
777 unsigned BranchLabelId = MMI->NextLabelID();
778 BuildMI(MBB, MBBI, TII.get(SPU::LABEL)).addImm(BranchLabelId);
779 }
780 }
781 }
782
783 void
784 SPURegisterInfo::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const
785 {
786 MachineBasicBlock::iterator MBBI = prior(MBB.end());
787 const MachineFrameInfo *MFI = MF.getFrameInfo();
788 int FrameSize = MFI->getStackSize();
789 int LinkSlotOffset = SPUFrameInfo::stackSlotSize();
790
791 assert(MBBI->getOpcode() == SPU::RET &&
792 "Can only insert epilog into returning blocks");
793 assert((FrameSize & 0xf) == 0
794 && "SPURegisterInfo::emitEpilogue: FrameSize not aligned");
795 if (FrameSize > 0) {
796 FrameSize = FrameSize + SPUFrameInfo::minStackSize();
797 if (isS10Constant(FrameSize + LinkSlotOffset)) {
798 // Reload $lr, adjust $sp by required amount
799 // Note: We do this to slightly improve dual issue -- not by much, but it
800 // is an opportunity for dual issue.
801 BuildMI(MBB, MBBI, TII.get(SPU::LQDr128), SPU::R0)
802 .addImm(FrameSize + LinkSlotOffset)
803 .addReg(SPU::R1);
804 BuildMI(MBB, MBBI, TII.get(SPU::AIr32), SPU::R1)
805 .addReg(SPU::R1)
806 .addImm(FrameSize);
807 } else if (FrameSize <= (1 << 16) - 1 && FrameSize >= -(1 << 16)) {
808 // Frame size can be loaded into ILr32n, so temporarily spill $r2 and use
809 // $r2 to adjust $sp:
810 BuildMI(MBB, MBBI, TII.get(SPU::STQDr128), SPU::R2)
811 .addImm(16)
812 .addReg(SPU::R1);
813 BuildMI(MBB, MBBI, TII.get(SPU::ILr32), SPU::R2)
814 .addImm(FrameSize);
815 BuildMI(MBB, MBBI, TII.get(SPU::Ar32), SPU::R1)
816 .addReg(SPU::R1)
817 .addReg(SPU::R2);
818 BuildMI(MBB, MBBI, TII.get(SPU::LQDr128), SPU::R0)
819 .addImm(16)
820 .addReg(SPU::R2);
821 BuildMI(MBB, MBBI, TII.get(SPU::SFIr32), SPU::R2).
822 addReg(SPU::R2)
823 .addImm(16);
824 BuildMI(MBB, MBBI, TII.get(SPU::LQXr128), SPU::R2)
825 .addReg(SPU::R2)
826 .addReg(SPU::R1);
827 } else {
828 cerr << "Unhandled frame size: " << FrameSize << "\n";
829 abort();
830 }
831 }
832 }
833
834 unsigned
835 SPURegisterInfo::getRARegister() const
836 {
837 return SPU::R0;
838 }
839
840 unsigned
841 SPURegisterInfo::getFrameRegister(MachineFunction &MF) const
842 {
843 return SPU::R1;
844 }
845
846 void
847 SPURegisterInfo::getInitialFrameState(std::vector &Moves) const
848 {
849 // Initial state of the frame pointer is R1.
850 MachineLocation Dst(MachineLocation::VirtualFP);
851 MachineLocation Src(SPU::R1, 0);
852 Moves.push_back(MachineMove(0, Dst, Src));
853 }
854
855
856 int
857 SPURegisterInfo::getDwarfRegNum(unsigned RegNum, bool isEH) const {
858 // FIXME: Most probably dwarf numbers differs for Linux and Darwin
859 return SPUGenRegisterInfo::getDwarfRegNumFull(RegNum, 0);
860 }
861
862 #include "SPUGenRegisterInfo.inc"
0 //===- SPURegisterInfo.h - Cell SPU Register Information Impl ----*- C++ -*-==//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by The Aerospace Corporation.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file contains the Cell SPU implementation of the MRegisterInfo class.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #ifndef SPU_REGISTERINFO_H
13 #define SPU_REGISTERINFO_H
14
15 #include "SPU.h"
16 #include "SPUGenRegisterInfo.h.inc"
17
18 namespace llvm {
19 class SPUSubtarget;
20 class TargetInstrInfo;
21 class Type;
22
23 class SPURegisterInfo : public SPUGenRegisterInfo {
24 private:
25 const SPUSubtarget &Subtarget;
26 const TargetInstrInfo &TII;
27
28 //! Predicate: Does the machine function use the link register?
29 bool usesLR(MachineFunction &MF) const;
30
31 public:
32 SPURegisterInfo(const SPUSubtarget &subtarget, const TargetInstrInfo &tii);
33
34 //! Translate a register's enum value to a register number
35 /*!
36 This method translates a register's enum value to it's regiser number,
37 e.g. SPU::R14 -> 14.
38 */
39 static unsigned getRegisterNumbering(unsigned RegEnum);
40
41 //! Store a register to a stack slot, based on its register class.
42 void storeRegToStackSlot(MachineBasicBlock &MBB,
43 MachineBasicBlock::iterator MBBI,
44 unsigned SrcReg, int FrameIndex,
45 const TargetRegisterClass *RC) const;
46
47 //! Store a register to an address, based on its register class
48 void storeRegToAddr(MachineFunction &MF, unsigned SrcReg,
49 SmallVectorImpl &Addr,
50 const TargetRegisterClass *RC,
51 SmallVectorImpl &NewMIs) const;
52
53 //! Load a register from a stack slot, based on its register class.
54 void loadRegFromStackSlot(MachineBasicBlock &MBB,
55 MachineBasicBlock::iterator MBBI,
56 unsigned DestReg, int FrameIndex,
57 const TargetRegisterClass *RC) const;
58
59 //! Loqad a register from an address, based on its register class
60 virtual void loadRegFromAddr(MachineFunction &MF, unsigned DestReg,
61 SmallVectorImpl &Addr,
62 const TargetRegisterClass *RC,
63 SmallVectorImpl &NewMIs) const;
64
65 //! Copy a register to another
66 void copyRegToReg(MachineBasicBlock &MBB,
67 MachineBasicBlock::iterator MI,
68 unsigned DestReg, unsigned SrcReg,
69 const TargetRegisterClass *DestRC,
70 const TargetRegisterClass *SrcRC) const;
71
72 void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
73 unsigned DestReg, const MachineInstr *Orig) const;
74
75 //! Fold spills into load/store instructions
76 virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
77 int FrameIndex) const;
78
79 //! Fold any load/store to an operand
80 virtual MachineInstr* foldMemoryOperand(MachineInstr* MI, unsigned OpNum,
81 MachineInstr* LoadMI) const;
82
83 //! Return the array of callee-saved registers
84 virtual const unsigned* getCalleeSavedRegs(const MachineFunction *MF) const;
85
86 //! Return the register class array of the callee-saved registers
87 virtual const TargetRegisterClass* const *
88 getCalleeSavedRegClasses(const MachineFunction *MF) const;
89
90 //! Return the reserved registers
91 BitVector getReservedRegs(const MachineFunction &MF) const;
92
93 //! Prediate: Target has dedicated frame pointer
94 bool hasFP(const MachineFunction &MF) const;
95 //! Eliminate the call frame setup pseudo-instructions
96 void eliminateCallFramePseudoInstr(MachineFunction &MF,
97 MachineBasicBlock &MBB,
98 MachineBasicBlock::iterator I) const;
99 //! Convert frame indicies into machine operands
100 void eliminateFrameIndex(MachineBasicBlock::iterator II, int,
101 RegScavenger *RS) const;
102 //! Determine the frame's layour
103 void determineFrameLayout(MachineFunction &MF) const;
104
105 void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
106 RegScavenger *RS = NULL) const;
107 //! Emit the function prologue
108 void emitPrologue(MachineFunction &MF) const;
109 //! Emit the function epilogue
110 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
111 //! Get return address register (LR, aka R0)
112 unsigned getRARegister() const;
113 //! Get the stack frame register (SP, aka R1)
114 unsigned getFrameRegister(MachineFunction &MF) const;
115 //! Perform target-specific stack frame setup.
116 void getInitialFrameState(std::vector &Moves) const;
117
118 //------------------------------------------------------------------------
119 // New methods added:
120 //------------------------------------------------------------------------
121
122 //! Return the array of argument passing registers
123 /*!
124 \note The size of this array is returned by getArgRegsSize().
125 */
126 static const unsigned *getArgRegs();
127
128 //! Return the size of the argument passing register array
129 static const unsigned getNumArgRegs();
130
131 //! Get DWARF debugging register number
132 int getDwarfRegNum(unsigned RegNum, bool isEH) const;
133 };
134 } // end namespace llvm
135
136 #endif
0 //===- SPURegisterInfo.td - The Cell SPU Register File -----*- tablegen -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by The Aerospace Corporation. No distribution rights
5 // yet determined...
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11
12 class SPUReg : Register {
13 let Namespace = "SPU";
14 }
15
16 // The SPU's register are all 128-bits wide, which makes specifying the
17 // registers relatively easy, if relatively mundane:
18
19 class SPUVecReg num, string n> : SPUReg {
20 field bits<7> Num = num;
21 }
22
23 def R0 : SPUVecReg<0, "$lr">, DwarfRegNum<[0]>;
24 def R1 : SPUVecReg<1, "$sp">, DwarfRegNum<[1]>;
25 def R2 : SPUVecReg<2, "$2">, DwarfRegNum<[2]>;
26 def R3 : SPUVecReg<3, "$3">, DwarfRegNum<[3]>;
27 def R4 : SPUVecReg<4, "$4">, DwarfRegNum<[4]>;
28 def R5 : SPUVecReg<5, "$5">, DwarfRegNum<[5]>;
29 def R6 : SPUVecReg<6, "$6">, DwarfRegNum<[6]>;
30 def R7 : SPUVecReg<7, "$7">, DwarfRegNum<[7]>;
31 def R8 : SPUVecReg<8, "$8">, DwarfRegNum<[8]>;
32 def R9 : SPUVecReg<9, "$9">, DwarfRegNum<[9]>;
33 def R10 : SPUVecReg<10, "$10">, DwarfRegNum<[10]>;
34 def R11 : SPUVecReg<11, "$11">, DwarfRegNum<[11]>;
35 def R12 : SPUVecReg<12, "$12">, DwarfRegNum<[12]>;
36 def R13 : SPUVecReg<13, "$13">, DwarfRegNum<[13]>;
37 def R14 : SPUVecReg<14, "$14">, DwarfRegNum<[14]>;
38 def R15 : SPUVecReg<15, "$15">, DwarfRegNum<[15]>;
39 def R16 : SPUVecReg<16, "$16">, DwarfRegNum<[16]>;
40 def R17 : SPUVecReg<17, "$17">, DwarfRegNum<[17]>;
41 def R18 : SPUVecReg<18, "$18">, DwarfRegNum<[18]>;
42 def R19 : SPUVecReg<19, "$19">, DwarfRegNum<[19]>;
43 def R20 : SPUVecReg<20, "$20">, DwarfRegNum<[20]>;
44 def R21 : SPUVecReg<21, "$21">, DwarfRegNum<[21]>;
45 def R22 : SPUVecReg<22, "$22">, DwarfRegNum<[22]>;
46 def R23 : SPUVecReg<23, "$23">, DwarfRegNum<[23]>;
47 def R24 : SPUVecReg<24, "$24">, DwarfRegNum<[24]>;
48 def R25 : SPUVecReg<25, "$25">, DwarfRegNum<[25]>;
49 def R26 : SPUVecReg<26, "$26">, DwarfRegNum<[26]>;
50 def R27 : SPUVecReg<27, "$27">, DwarfRegNum<[27]>;
51 def R28 : SPUVecReg<28, "$28">, DwarfRegNum<[28]>;
52 def R29 : SPUVecReg<29, "$29">, DwarfRegNum<[29]>;
53 def R30 : SPUVecReg<30, "$30">, DwarfRegNum<[30]>;
54 def R31 : SPUVecReg<31, "$31">, DwarfRegNum<[31]>;
55 def R32 : SPUVecReg<32, "$32">, DwarfRegNum<[32]>;
56 def R33 : SPUVecReg<33, "$33">, DwarfRegNum<[33]>;
57 def R34 : SPUVecReg<34, "$34">, DwarfRegNum<[34]>;
58 def R35 : SPUVecReg<35, "$35">, DwarfRegNum<[35]>;
59 def R36 : SPUVecReg<36, "$36">, DwarfRegNum<[36]>;
60 def R37 : SPUVecReg<37, "$37">, DwarfRegNum<[37]>;
61 def R38 : SPUVecReg<38, "$38">, DwarfRegNum<[38]>;
62 def R39 : SPUVecReg<39, "$39">, DwarfRegNum<[39]>;
63 def R40 : SPUVecReg<40, "$40">, DwarfRegNum<[40]>;
64 def R41 : SPUVecReg<41, "$41">, DwarfRegNum<[41]>;
65 def R42 : SPUVecReg<42, "$42">, DwarfRegNum<[42]>;
66 def R43 : SPUVecReg<43, "$43">, DwarfRegNum<[43]>;
67 def R44 : SPUVecReg<44, "$44">, DwarfRegNum<[44]>;
68 def R45 : SPUVecReg<45, "$45">, DwarfRegNum<[45]>;
69 def R46 : SPUVecReg<46, "$46">, DwarfRegNum<[46]>;
70 def R47 : SPUVecReg<47, "$47">, DwarfRegNum<[47]>;
71 def R48 : SPUVecReg<48, "$48">, DwarfRegNum<[48]>;
72 def R49 : SPUVecReg<49, "$49">, DwarfRegNum<[49]>;
73 def R50 : SPUVecReg<50, "$50">, DwarfRegNum<[50]>;
74 def R51 : SPUVecReg<51, "$51">, DwarfRegNum<[51]>;
75 def R52 : SPUVecReg<52, "$52">, DwarfRegNum<[52]>;
76 def R53 : SPUVecReg<53, "$53">, DwarfRegNum<[53]>;
77 def R54 : SPUVecReg<54, "$54">, DwarfRegNum<[54]>;
78 def R55 : SPUVecReg<55, "$55">, DwarfRegNum<[55]>;
79 def R56 : SPUVecReg<56, "$56">, DwarfRegNum<[56]>;
80 def R57 : SPUVecReg<57, "$57">, DwarfRegNum<[57]>;
81 def R58 : SPUVecReg<58, "$58">, DwarfRegNum<[58]>;
82 def R59 : SPUVecReg<59, "$59">, DwarfRegNum<[59]>;
83 def R60 : SPUVecReg<60, "$60">, DwarfRegNum<[60]>;
84 def R61 : SPUVecReg<61, "$61">, DwarfRegNum<[61]>;
85 def R62 : SPUVecReg<62, "$62">, DwarfRegNum<[62]>;
86 def R63 : SPUVecReg<63, "$63">, DwarfRegNum<[63]>;
87 def R64 : SPUVecReg<64, "$64">, DwarfRegNum<[64]>;
88 def R65 : SPUVecReg<65, "$65">, DwarfRegNum<[65]>;
89 def R66 : SPUVecReg<66, "$66">, DwarfRegNum<[66]>;
90 def R67 : SPUVecReg<67, "$67">, DwarfRegNum<[67]>;
91 def R68 : SPUVecReg<68, "$68">, DwarfRegNum<[68]>;
92 def R69 : SPUVecReg<69, "$69">, DwarfRegNum<[69]>;
93 def R70 : SPUVecReg<70, "$70">, DwarfRegNum<[70]>;
94 def R71 : SPUVecReg<71, "$71">, DwarfRegNum<[71]>;
95 def R72 : SPUVecReg<72, "$72">, DwarfRegNum<[72]>;
96 def R73 : SPUVecReg<73, "$73">, DwarfRegNum<[73]>;
97 def R74 : SPUVecReg<74, "$74">, DwarfRegNum<[74]>;
98 def R75 : SPUVecReg<75, "$75">, DwarfRegNum<[75]>;
99 def R76 : SPUVecReg<76, "$76">, DwarfRegNum<[76]>;
100 def R77 : SPUVecReg<77, "$77">, DwarfRegNum<[77]>;
101 def R78 : SPUVecReg<78, "$78">, DwarfRegNum<[78]>;
102 def R79 : SPUVecReg<79, "$79">, DwarfRegNum<[79]>;
103 def R80 : SPUVecReg<80, "$80">, DwarfRegNum<[80]>;
104 def R81 : SPUVecReg<81, "$81">, DwarfRegNum<[81]>;
105 def R82 : SPUVecReg<82, "$82">, DwarfRegNum<[82]>;
106 def R83 : SPUVecReg<83, "$83">, DwarfRegNum<[83]>;
107 def R84 : SPUVecReg<84, "$84">, DwarfRegNum<[84]>;
108 def R85 : SPUVecReg<85, "$85">, DwarfRegNum<[85]>;
109 def R86 : SPUVecReg<86, "$86">, DwarfRegNum<[86]>;
110 def R87 : SPUVecReg<87, "$87">, DwarfRegNum<[87]>;
111 def R88 : SPUVecReg<88, "$88">, DwarfRegNum<[88]>;
112 def R89 : SPUVecReg<89, "$89">, DwarfRegNum<[89]>;
113 def R90 : SPUVecReg<90, "$90">, DwarfRegNum<[90]>;
114 def R91 : SPUVecReg<91, "$91">, DwarfRegNum<[91]>;
115 def R92 : SPUVecReg<92, "$92">, DwarfRegNum<[92]>;
116 def R93 : SPUVecReg<93, "$93">, DwarfRegNum<[93]>;
117 def R94 : SPUVecReg<94, "$94">, DwarfRegNum<[94]>;
118 def R95 : SPUVecReg<95, "$95">, DwarfRegNum<[95]>;
119 def R96 : SPUVecReg<96, "$96">, DwarfRegNum<[96]>;
120 def R97 : SPUVecReg<97, "$97">, DwarfRegNum<[97]>;
121 def R98 : SPUVecReg<98, "$98">, DwarfRegNum<[98]>;
122 def R99 : SPUVecReg<99, "$99">, DwarfRegNum<[99]>;
123 def R100 : SPUVecReg<100, "$100">, DwarfRegNum<[100]>;
124 def R101 : SPUVecReg<101, "$101">, DwarfRegNum<[101]>;
125 def R102 : SPUVecReg<102, "$102">, DwarfRegNum<[102]>;
126 def R103 : SPUVecReg<103, "$103">, DwarfRegNum<[103]>;
127 def R104 : SPUVecReg<104, "$104">, DwarfRegNum<[104]>;
128 def R105 : SPUVecReg<105, "$105">, DwarfRegNum<[105]>;
129 def R106 : SPUVecReg<106, "$106">, DwarfRegNum<[106]>;
130 def R107 : SPUVecReg<107, "$107">, DwarfRegNum<[107]>;
131 def R108 : SPUVecReg<108, "$108">, DwarfRegNum<[108]>;
132 def R109 : SPUVecReg<109, "$109">, DwarfRegNum<[109]>;
133 def R110 : SPUVecReg<110, "$110">, DwarfRegNum<[110]>;
134 def R111 : SPUVecReg<111, "$111">, DwarfRegNum<[111]>;
135 def R112 : SPUVecReg<112, "$112">, DwarfRegNum<[112]>;
136 def R113 : SPUVecReg<113, "$113">, DwarfRegNum<[113]>;
137 def R114 : SPUVecReg<114, "$114">, DwarfRegNum<[114]>;
138 def R115 : SPUVecReg<115, "$115">, DwarfRegNum<[115]>;
139 def R116 : SPUVecReg<116, "$116">, DwarfRegNum<[116]>;
140 def R117 : SPUVecReg<117, "$117">, DwarfRegNum<[117]>;
141 def R118 : SPUVecReg<118, "$118">, DwarfRegNum<[118]>;
142 def R119 : SPUVecReg<119, "$119">, DwarfRegNum<[119]>;
143 def R120 : SPUVecReg<120, "$120">, DwarfRegNum<[120]>;
144 def R121 : SPUVecReg<121, "$121">, DwarfRegNum<[121]>;
145 def R122 : SPUVecReg<122, "$122">, DwarfRegNum<[122]>;
146 def R123 : SPUVecReg<123, "$123">, DwarfRegNum<[123]>;
147 def R124 : SPUVecReg<124, "$124">, DwarfRegNum<[124]>;
148 def R125 : SPUVecReg<125, "$125">, DwarfRegNum<[125]>;
149 def R126 : SPUVecReg<126, "$126">, DwarfRegNum<[126]>;
150 def R127 : SPUVecReg<127, "$127">, DwarfRegNum<[127]>;
151
152 /* Need floating point status register here: */
153 /* def FPCSR : ... */
154
155 // The SPU's registers as 128-bit wide entities, and can function as general
156 // purpose registers, where the operands are in the "preferred slot":
157 def GPRC : RegisterClass<"SPU", [i128], 128,
158 [
159 /* volatile register */
160 R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
161 R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
162 R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
163 R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
164 R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
165 R77, R78, R79,
166 /* non-volatile register: take hint from PPC and allocate in reverse order */
167 R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
168 R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
169 R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
170 R86, R85, R84, R83, R82, R81, R80,
171 /* environment ptr, SP, LR */
172 R2, R1, R0 ]>
173 {
174 let MethodProtos = [{
175 iterator allocation_order_begin(const MachineFunction &MF) const;
176 iterator allocation_order_end(const MachineFunction &MF) const;
177 }];
178 let MethodBodies = [{
179 GPRCClass::iterator
180 GPRCClass::allocation_order_begin(const MachineFunction &MF) const {
181 return begin();
182 }
183 GPRCClass::iterator
184 GPRCClass::allocation_order_end(const MachineFunction &MF) const {
185 return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr)
186 }
187 }];
188 }
189
190 // The SPU's registers as 64-bit wide (double word integer) "preferred slot":
191 def R64C : RegisterClass<"SPU", [i64], 128,
192 [
193 /* volatile register */
194 R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
195 R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
196 R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
197 R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
198 R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
199 R77, R78, R79,
200 /* non-volatile register: take hint from PPC and allocate in reverse order */
201 R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
202 R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
203 R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
204 R86, R85, R84, R83, R82, R81, R80,
205 /* environment ptr, SP, LR */
206 R2, R1, R0 ]>
207 {
208 let MethodProtos = [{
209 iterator allocation_order_begin(const MachineFunction &MF) const;
210 iterator allocation_order_end(const MachineFunction &MF) const;
211 }];
212 let MethodBodies = [{
213 R64CClass::iterator
214 R64CClass::allocation_order_begin(const MachineFunction &MF) const {
215 return begin();
216 }
217 R64CClass::iterator
218 R64CClass::allocation_order_end(const MachineFunction &MF) const {
219 return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr)
220 }
221 }];
222 }
223
224 // The SPU's registers as 64-bit wide (double word) FP "preferred slot":
225 def R64FP : RegisterClass<"SPU", [f64], 128,
226 [
227 /* volatile register */
228 R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
229 R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
230 R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
231 R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
232 R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
233 R77, R78, R79,
234 /* non-volatile register: take hint from PPC and allocate in reverse order */
235 R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
236 R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
237 R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
238 R86, R85, R84, R83, R82, R81, R80,
239 /* environment ptr, SP, LR */
240 R2, R1, R0 ]>
241 {
242 let MethodProtos = [{
243 iterator allocation_order_begin(const MachineFunction &MF) const;
244 iterator allocation_order_end(const MachineFunction &MF) const;
245 }];
246 let MethodBodies = [{
247 R64FPClass::iterator
248 R64FPClass::allocation_order_begin(const MachineFunction &MF) const {
249 return begin();
250 }
251 R64FPClass::iterator
252 R64FPClass::allocation_order_end(const MachineFunction &MF) const {
253 return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr)
254 }
255 }];
256 }
257
258 // The SPU's registers as 32-bit wide (word) "preferred slot":
259 def R32C : RegisterClass<"SPU", [i32], 128,
260 [
261 /* volatile register */
262 R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
263 R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
264 R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
265 R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
266 R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
267 R77, R78, R79,
268 /* non-volatile register: take hint from PPC and allocate in reverse order */
269 R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
270 R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
271 R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
272 R86, R85, R84, R83, R82, R81, R80,
273 /* environment ptr, SP, LR */
274 R2, R1, R0 ]>
275 {
276 let MethodProtos = [{
277 iterator allocation_order_begin(const MachineFunction &MF) const;
278 iterator allocation_order_end(const MachineFunction &MF) const;
279 }];
280 let MethodBodies = [{
281 R32CClass::iterator
282 R32CClass::allocation_order_begin(const MachineFunction &MF) const {
283 return begin();
284 }
285 R32CClass::iterator
286 R32CClass::allocation_order_end(const MachineFunction &MF) const {
287 return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr)
288 }
289 }];
290 }
291
292 // The SPU's registers as single precision floating point "preferred slot":
293 def R32FP : RegisterClass<"SPU", [f32], 128,
294 [
295 /* volatile register */
296 R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
297 R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
298 R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
299 R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
300 R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
301 R77, R78, R79,
302 /* non-volatile register: take hint from PPC and allocate in reverse order */
303 R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
304 R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
305 R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
306 R86, R85, R84, R83, R82, R81, R80,
307 /* environment ptr, SP, LR */
308 R2, R1, R0 ]>
309 {
310 let MethodProtos = [{
311 iterator allocation_order_begin(const MachineFunction &MF) const;
312 iterator allocation_order_end(const MachineFunction &MF) const;
313 }];
314 let MethodBodies = [{
315 R32FPClass::iterator
316 R32FPClass::allocation_order_begin(const MachineFunction &MF) const {
317 return begin();
318 }
319 R32FPClass::iterator
320 R32FPClass::allocation_order_end(const MachineFunction &MF) const {
321 return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr)
322 }
323 }];
324 }
325
326 // The SPU's registers as 16-bit wide (halfword) "preferred slot":
327 def R16C : RegisterClass<"SPU", [i16], 128,
328 [
329 /* volatile register */
330 R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
331 R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
332 R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
333 R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
334 R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
335 R77, R78, R79,
336 /* non-volatile register: take hint from PPC and allocate in reverse order */
337 R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
338 R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
339 R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
340 R86, R85, R84, R83, R82, R81, R80,
341 /* environment ptr, SP, LR */
342 R2, R1, R0 ]>
343 {
344 let MethodProtos = [{
345 iterator allocation_order_begin(const MachineFunction &MF) const;
346 iterator allocation_order_end(const MachineFunction &MF) const;
347 }];
348 let MethodBodies = [{
349 R16CClass::iterator
350 R16CClass::allocation_order_begin(const MachineFunction &MF) const {
351 return begin();
352 }
353 R16CClass::iterator
354 R16CClass::allocation_order_end(const MachineFunction &MF) const {
355 return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr)
356 }
357 }];
358 }
359
360 // The SPU's registers as vector registers:
361 def VECREG : RegisterClass<"SPU", [v16i8,v8i16,v4i32,v4f32,v2i64,v2f64], 128,
362 [
363 /* volatile register */
364 R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
365 R17, R18, R19, R20, R21, R22, R23, R24, R25, R26, R27, R28, R29, R30, R31,
366 R32, R33, R34, R35, R36, R37, R38, R39, R40, R41, R42, R43, R44, R45, R46,
367 R47, R48, R49, R50, R51, R52, R53, R54, R55, R56, R57, R58, R59, R60, R61,
368 R62, R63, R64, R65, R66, R67, R68, R69, R70, R71, R72, R73, R74, R75, R76,
369 R77, R78, R79,
370 /* non-volatile register: take hint from PPC and allocate in reverse order */
371 R127, R126, R125, R124, R123, R122, R121, R120, R119, R118, R117, R116, R115,
372 R114, R113, R112, R111, R110, R109, R108, R107, R106, R105, R104, R103, R102,
373 R101, R100, R99, R98, R97, R96, R95, R94, R93, R92, R91, R90, R89, R88, R87,
374 R86, R85, R84, R83, R82, R81, R80,
375 /* environment ptr, SP, LR */
376 R2, R1, R0 ]>
377 {
378 let MethodProtos = [{
379 iterator allocation_order_begin(const MachineFunction &MF) const;
380 iterator allocation_order_end(const MachineFunction &MF) const;
381 }];
382 let MethodBodies = [{
383 VECREGClass::iterator
384 VECREGClass::allocation_order_begin(const MachineFunction &MF) const {
385 return begin();
386 }
387 VECREGClass::iterator
388 VECREGClass::allocation_order_end(const MachineFunction &MF) const {
389 return end()-3; // don't allocate R2, R1, or R0 (envp, sp, lr)
390 }
391 }];
392 }
0 //===- SPUSchedule.td - Cell Scheduling Definitions --------*- tablegen -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10
11 //===----------------------------------------------------------------------===//
12 // Even pipeline:
13
14 def EVEN_UNIT : FuncUnit; // Even execution unit: (PC & 0x7 == 000)
15 def ODD_UNIT : FuncUnit; // Odd execution unit: (PC & 0x7 == 100)
16
17 //===----------------------------------------------------------------------===//
18 // Instruction Itinerary classes used for Cell SPU
19 //===----------------------------------------------------------------------===//
20
21 def LoadStore : InstrItinClass; // ODD_UNIT
22 def BranchHints : InstrItinClass; // ODD_UNIT
23 def BranchResolv : InstrItinClass; // ODD_UNIT
24 def ChanOpSPR : InstrItinClass; // ODD_UNIT
25 def ShuffleOp : InstrItinClass; // ODD_UNIT
26 def SelectOp : InstrItinClass; // ODD_UNIT
27 def GatherOp : InstrItinClass; // ODD_UNIT
28 def LoadNOP : InstrItinClass; // ODD_UNIT
29 def ExecNOP : InstrItinClass; // EVEN_UNIT
30 def SPrecFP : InstrItinClass; // EVEN_UNIT
31 def DPrecFP : InstrItinClass; // EVEN_UNIT
32 def FPInt : InstrItinClass; // EVEN_UNIT (FP<->integer)
33 def ByteOp : InstrItinClass; // EVEN_UNIT
34 def IntegerOp : InstrItinClass; // EVEN_UNIT
35 def IntegerMulDiv: InstrItinClass; // EVEN_UNIT
36 def RotateShift : InstrItinClass; // EVEN_UNIT
37 def ImmLoad : InstrItinClass; // EVEN_UNIT
38
39 /* Note: The itinerary for the Cell SPU is somewhat contrived... */
40 def SPUItineraries : ProcessorItineraries<[
41 InstrItinData]>,
42 InstrItinData]>,
43 InstrItinData]>,
44 InstrItinData]>,
45 InstrItinData]>,
46 InstrItinData]>,
47 InstrItinData]>,
48 InstrItinData]>,
49 InstrItinData]>,
50 InstrItinData]>,
51 InstrItinData]>,
52 InstrItinData]>,
53 InstrItinData]>,
54 InstrItinData]>,
55 InstrItinData]>,
56 InstrItinData]>,
57 InstrItinData]>
58 ]>;
0 //===- SPUSubtarget.cpp - STI Cell SPU Subtarget Information --------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file implements the CellSPU-specific subclass of TargetSubtarget.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "SPUSubtarget.h"
16 #include "SPU.h"
17 #include "llvm/Module.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "SPUGenSubtarget.inc"
20
21 using namespace llvm;
22
23 SPUSubtarget::SPUSubtarget(const TargetMachine &tm, const Module &M,
24 const std::string &FS) :
25 TM(tm),
26 StackAlignment(16),
27 ProcDirective(SPU::DEFAULT_PROC),
28 UseLargeMem(false)
29 {
30 // Should be the target SPU processor type. For now, since there's only
31 // one, simply default to the current "v0" default:
32 std::string default_cpu("v0");
33
34 // Parse features string.
35 ParseSubtargetFeatures(FS, default_cpu);
36 }
37
38 /// SetJITMode - This is called to inform the subtarget info that we are
39 /// producing code for the JIT.
40 void SPUSubtarget::SetJITMode() {
41 }
0 //=====-- SPUSubtarget.h - Define Subtarget for the Cell SPU -----*- C++ -*--=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file declares the Cell SPU-specific subclass of TargetSubtarget.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef POWERPCSUBTARGET_H
16 #define POWERPCSUBTARGET_H
17
18 #include "llvm/Target/TargetInstrItineraries.h"
19 #include "llvm/Target/TargetSubtarget.h"
20
21 #include
22
23 namespace llvm {
24 class Module;
25 class GlobalValue;
26 class TargetMachine;
27
28 namespace SPU {
29 enum {
30 DEFAULT_PROC
31 };
32 }
33
34 class SPUSubtarget : public TargetSubtarget {
35 protected:
36 const TargetMachine &TM;
37
38 /// stackAlignment - The minimum alignment known to hold of the stack frame
39 /// on entry to the function and which must be maintained by every function.
40 unsigned StackAlignment;
41
42 /// Selected instruction itineraries (one entry per itinerary class.)
43 InstrItineraryData InstrItins;
44
45 /// Which SPU processor (this isn't really used, but it's there to keep
46 /// the C compiler happy)
47 unsigned ProcDirective;
48
49 /// Use (assume) large memory -- effectively disables the LQA/STQA
50 /// instructions that assume 259K local store.
51 bool UseLargeMem;
52
53 public:
54 /// This constructor initializes the data members to match that
55 /// of the specified module.
56 ///
57 SPUSubtarget(const TargetMachine &TM, const Module &M,
58 const std::string &FS);
59
60 /// ParseSubtargetFeatures - Parses features string setting specified
61 /// subtarget options. Definition of function is auto generated by tblgen.
62 void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
63
64 /// SetJITMode - This is called to inform the subtarget info that we are
65 /// producing code for the JIT.
66 void SetJITMode();
67
68 /// getStackAlignment - Returns the minimum alignment known to hold of the
69 /// stack frame on entry to the function and which must be maintained by
70 /// every function for this subtarget.
71 unsigned getStackAlignment() const { return StackAlignment; }
72
73 /// getInstrItins - Return the instruction itineraies based on subtarget
74 /// selection.
75 const InstrItineraryData &getInstrItineraryData() const {
76 return InstrItins;
77 }
78
79 /// Use large memory addressing predicate
80 bool usingLargeMem() const {
81 return UseLargeMem;
82 }
83
84 /// getTargetDataString - Return the pointer size and type alignment
85 /// properties of this subtarget.
86 const char *getTargetDataString() const {
87 return "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128"
88 "-i16:16:128-i8:8:128-i1:8:128-a:0:128-v128:128:128"
89 "-s:128:128";
90 }
91 };
92 } // End llvm namespace
93
94 #endif
0 //===-- SPUTargetAsmInfo.cpp - Cell SPU asm properties ----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file contains the declarations of the SPUTargetAsmInfo properties.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "SPUTargetAsmInfo.h"
16 #include "SPUTargetMachine.h"
17 #include "llvm/Function.h"
18 using namespace llvm;
19
20 SPUTargetAsmInfo::SPUTargetAsmInfo(const SPUTargetMachine &TM) {
21 CommentString = "#";
22 GlobalPrefix = "";
23 PrivateGlobalPrefix = ".L";
24 ZeroDirective = "\t.space\t";
25 SetDirective = "\t.set";
26 Data64bitsDirective = "\t.quad\t";
27 AlignmentIsInBytes = false;
28 SwitchToSectionDirective = "\t.section\t";
29 ConstantPoolSection = "\t.const\t";
30 JumpTableDataSection = ".const";
31 CStringSection = "\t.cstring";
32 LCOMMDirective = "\t.lcomm\t";
33 StaticCtorsSection = ".mod_init_func";
34 StaticDtorsSection = ".mod_term_func";
35 FourByteConstantSection = ".const";
36 SixteenByteConstantSection = "\t.section\t.rodata.cst16,\"aM\",@progbits,16";
37 UsedDirective = "\t.no_dead_strip\t";
38 WeakRefDirective = "\t.weak_reference\t";
39 InlineAsmStart = "# InlineAsm Start";
40 InlineAsmEnd = "# InlineAsm End";
41
42 NeedsSet = true;
43 /* FIXME: Need actual assembler syntax for DWARF info: */
44 DwarfAbbrevSection = ".section __DWARF,__debug_abbrev,regular,debug";
45 DwarfInfoSection = ".section __DWARF,__debug_info,regular,debug";
46 DwarfLineSection = ".section __DWARF,__debug_line,regular,debug";
47 DwarfFrameSection = ".section __DWARF,__debug_frame,regular,debug";
48 DwarfPubNamesSection = ".section __DWARF,__debug_pubnames,regular,debug";
49 DwarfPubTypesSection = ".section __DWARF,__debug_pubtypes,regular,debug";
50 DwarfStrSection = ".section __DWARF,__debug_str,regular,debug";
51 DwarfLocSection = ".section __DWARF,__debug_loc,regular,debug";
52 DwarfARangesSection = ".section __DWARF,__debug_aranges,regular,debug";
53 DwarfRangesSection = ".section __DWARF,__debug_ranges,regular,debug";
54 DwarfMacInfoSection = ".section __DWARF,__debug_macinfo,regular,debug";
55 }
0 //=====-- SPUTargetAsmInfo.h - Cell SPU asm properties --------*- C++ -*--====//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file contains the declaration of the SPUTargetAsmInfo class.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef PPCTARGETASMINFO_H
16 #define PPCTARGETASMINFO_H
17
18 #include "llvm/Target/TargetAsmInfo.h"
19
20 namespace llvm {
21
22 // Forward declaration.
23 class SPUTargetMachine;
24
25 struct SPUTargetAsmInfo : public TargetAsmInfo {
26 SPUTargetAsmInfo(const SPUTargetMachine &TM);
27 };
28
29 } // namespace llvm
30
31 #endif
0 //===-- SPUTargetMachine.cpp - Define TargetMachine for Cell SPU ----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // Top-level implementation for the Cell SPU target.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "SPU.h"
16 #include "SPURegisterNames.h"
17 #include "SPUTargetAsmInfo.h"
18 #include "SPUTargetMachine.h"
19 #include "llvm/Module.h"
20 #include "llvm/PassManager.h"
21 #include "llvm/Target/TargetMachineRegistry.h"
22
23 using namespace llvm;
24
25 namespace {
26 // Register the targets
27 RegisterTarget
28 CELLSPU("cellspu", " STI CBEA Cell SPU");
29 }
30
31 const std::pair *
32 SPUFrameInfo::getCalleeSaveSpillSlots(unsigned &NumEntries) const {
33 NumEntries = 1;
34 return &LR[0];
35 }
36
37 const TargetAsmInfo *
38 SPUTargetMachine::createTargetAsmInfo() const
39 {
40 return new SPUTargetAsmInfo(*this);
41 }
42
43 unsigned
44 SPUTargetMachine::getModuleMatchQuality(const Module &M)
45 {
46 // We strongly match "spu-*" or "cellspu-*".
47 std::string TT = M.getTargetTriple();
48 if ((TT.size() == 3 && std::string(TT.begin(), TT.begin()+3) == "spu")
49 || (TT.size() == 7 && std::string(TT.begin(), TT.begin()+7) == "cellspu")
50 || (TT.size() >= 4 && std::string(TT.begin(), TT.begin()+4) == "spu-")
51 || (TT.size() >= 8 && std::string(TT.begin(), TT.begin()+8) == "cellspu-"))
52 return 20;
53
54 return 0; // No match at all...
55 }
56
57 SPUTargetMachine::SPUTargetMachine(const Module &M, const std::string &FS)
58 : Subtarget(*this, M, FS),
59 DataLayout(Subtarget.getTargetDataString()),
60 InstrInfo(*this),
61 FrameInfo(*this),
62 TLInfo(*this),
63 InstrItins(Subtarget.getInstrItineraryData())
64 {
65 // For the time being, use static relocations, since there's really no
66 // support for PIC yet.
67 setRelocationModel(Reloc::Static);
68 }
69
70 //===----------------------------------------------------------------------===//
71 // Pass Pipeline Configuration
72 //===----------------------------------------------------------------------===//
73
74 bool
75 SPUTargetMachine::addInstSelector(FunctionPassManager &PM, bool Fast)
76 {
77 // Install an instruction selector.
78 PM.add(createSPUISelDag(*this));
79 return false;
80 }
81
82 bool SPUTargetMachine::addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
83 std::ostream &Out) {
84 PM.add(createSPUAsmPrinterPass(Out, *this));
85 return false;
86 }
0 //===-- SPUTargetMachine.h - Define TargetMachine for Cell SPU ----*- C++ -*-=//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file was developed by a team from the Computer Systems Research
5 // Department at The Aerospace Corporation.
6 //
7 // See README.txt for details.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file declares the CellSPU-specific subclass of TargetMachine.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef SPU_TARGETMACHINE_H
16 #define SPU_TARGETMACHINE_H
17
18 #include "SPUSubtarget.h"
19 #include "SPUInstrInfo.h"
20 #include "SPUISelLowering.h"
21 #include "SPUFrameInfo.h"
22 #include "llvm/Target/TargetMachine.h"
23 #include "llvm/Target/TargetData.h"
24
25 namespace llvm {
26 class PassManager;
27 class GlobalValue;
28 class TargetFrameInfo;
29
30 /// SPUTargetMachine
31 ///
32 class SPUTargetMachine : public LLVMTargetMachine {
33 SPUSubtarget Subtarget;
34 const TargetData DataLayout;
35 SPUInstrInfo InstrInfo;
36 SPUFrameInfo FrameInfo;
37 SPUTargetLowering TLInfo;
38 InstrItineraryData InstrItins;
39
40 protected:
41 virtual const TargetAsmInfo *createTargetAsmInfo() const;
42
43 public:
44 SPUTargetMachine(const Module &M, const std::string &FS);
45
46 /// Return the subtarget implementation object
47 virtual const SPUSubtarget *getSubtargetImpl() const {
48 return &Subtarget;
49 }
50 virtual const SPUInstrInfo *getInstrInfo() const {
51 return &InstrInfo;
52 }
53 virtual const TargetFrameInfo *getFrameInfo() const {
54 return &FrameInfo;
55 }
56 /*!
57 \note Cell SPU does not support JIT today. It could support JIT at some
58 point.
59 */
60 virtual TargetJITInfo *getJITInfo() {
61 return NULL;
62 }
63
64 //! Module match function
65 /*!
66 Module matching function called by TargetMachineRegistry().
67 */
68 static unsigned getModuleMatchQuality(const Module &M);
69
70 virtual SPUTargetLowering *getTargetLowering() const {
71 return const_cast(&TLInfo);
72 }
73
74 virtual const MRegisterInfo *getRegisterInfo() const {
75 return &InstrInfo.getRegisterInfo();
76 }
77
78 virtual const TargetData *getTargetData() const {
79 return &DataLayout;
80 }
81
82 virtual const InstrItineraryData getInstrItineraryData() const {
83 return InstrItins;
84 }
85
86 // Pass Pipeline Configuration
87 virtual bool addInstSelector(FunctionPassManager &PM, bool Fast);
88 virtual bool addAssemblyEmitter(FunctionPassManager &PM, bool Fast,
89 std::ostream &Out);
90 };
91
92 } // end namespace llvm
93
94 #endif