blob: 179888d783579f411d12b9a831b2adca5b3d8998 [file] [log] [blame]
Chris Lattnera5a91b12005-08-17 19:33:03 +00001//===-- PPC32ISelDAGToDAG.cpp - PPC32 pattern matching inst selector ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by Chris Lattner and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a pattern matching instruction selector for 32 bit PowerPC,
11// converting from a legalized dag to a PPC dag.
12//
13//===----------------------------------------------------------------------===//
14
15#include "PowerPC.h"
16#include "PPC32TargetMachine.h"
17#include "PPC32ISelLowering.h"
18#include "llvm/CodeGen/SelectionDAG.h"
19#include "llvm/CodeGen/SelectionDAGISel.h"
20#include "llvm/Target/TargetOptions.h"
21#include "llvm/ADT/Statistic.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/MathExtras.h"
24using namespace llvm;
25
26namespace {
27 Statistic<> Recorded("ppc-codegen", "Number of recording ops emitted");
28 Statistic<> FusedFP ("ppc-codegen", "Number of fused fp operations");
29 Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed");
30
31 //===--------------------------------------------------------------------===//
32 /// PPC32DAGToDAGISel - PPC32 specific code to select PPC32 machine
33 /// instructions for SelectionDAG operations.
34 ///
35 class PPC32DAGToDAGISel : public SelectionDAGISel {
36 PPC32TargetLowering PPC32Lowering;
37
38 unsigned GlobalBaseReg;
39 bool GlobalBaseInitialized;
40 public:
41 PPC32DAGToDAGISel(TargetMachine &TM)
42 : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) {}
43
44 /// runOnFunction - Override this function in order to reset our
45 /// per-function variables.
46 virtual bool runOnFunction(Function &Fn) {
47 // Make sure we re-emit a set of the global base reg if necessary
48 GlobalBaseInitialized = false;
49 return SelectionDAGISel::runOnFunction(Fn);
50 }
51
52 /// getI32Imm - Return a target constant with the specified value, of type
53 /// i32.
54 inline SDOperand getI32Imm(unsigned Imm) {
55 return CurDAG->getTargetConstant(Imm, MVT::i32);
56 }
57
58 // Select - Convert the specified operand from a target-independent to a
59 // target-specific node if it hasn't already been changed.
60 SDOperand Select(SDOperand Op);
61
62 SDNode *SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS,
63 unsigned OCHi, unsigned OCLo,
64 bool IsArithmetic = false,
65 bool Negate = false);
66
67 /// InstructionSelectBasicBlock - This callback is invoked by
68 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
69 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
70 DEBUG(BB->dump());
71 // Codegen the basic block.
72 Select(DAG.getRoot());
73 DAG.RemoveDeadNodes();
74 DAG.viewGraph();
75 }
76
77 virtual const char *getPassName() const {
78 return "PowerPC DAG->DAG Pattern Instruction Selection";
79 }
80 };
81}
82
Nate Begeman0f3257a2005-08-18 05:00:13 +000083// isIntImmediate - This method tests to see if a constant operand.
84// If so Imm will receive the 32 bit value.
85static bool isIntImmediate(SDNode *N, unsigned& Imm) {
86 if (N->getOpcode() == ISD::Constant) {
87 Imm = cast<ConstantSDNode>(N)->getValue();
88 return true;
89 }
90 return false;
91}
92
93// isOpcWithIntImmediate - This method tests to see if the node is a specific
94// opcode and that it has a immediate integer right operand.
95// If so Imm will receive the 32 bit value.
96static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) {
97 return N->getOpcode() == Opc && isIntImmediate(N->getOperand(1).Val, Imm);
98}
99
100// isOprNot - Returns true if the specified operand is an xor with immediate -1.
101static bool isOprNot(SDNode *N) {
102 unsigned Imm;
103 return isOpcWithIntImmediate(N, ISD::XOR, Imm) && (signed)Imm == -1;
104}
105
Chris Lattnera5a91b12005-08-17 19:33:03 +0000106// Immediate constant composers.
107// Lo16 - grabs the lo 16 bits from a 32 bit constant.
108// Hi16 - grabs the hi 16 bits from a 32 bit constant.
109// HA16 - computes the hi bits required if the lo bits are add/subtracted in
110// arithmethically.
111static unsigned Lo16(unsigned x) { return x & 0x0000FFFF; }
112static unsigned Hi16(unsigned x) { return Lo16(x >> 16); }
113static unsigned HA16(unsigned x) { return Hi16((signed)x - (signed short)x); }
114
115// isIntImmediate - This method tests to see if a constant operand.
116// If so Imm will receive the 32 bit value.
117static bool isIntImmediate(SDOperand N, unsigned& Imm) {
118 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) {
119 Imm = (unsigned)CN->getSignExtended();
120 return true;
121 }
122 return false;
123}
124
125// SelectIntImmediateExpr - Choose code for integer operations with an immediate
126// operand.
127SDNode *PPC32DAGToDAGISel::SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS,
128 unsigned OCHi, unsigned OCLo,
129 bool IsArithmetic,
130 bool Negate) {
131 // Check to make sure this is a constant.
132 ConstantSDNode *CN = dyn_cast<ConstantSDNode>(RHS);
133 // Exit if not a constant.
134 if (!CN) return 0;
135 // Extract immediate.
136 unsigned C = (unsigned)CN->getValue();
137 // Negate if required (ISD::SUB).
138 if (Negate) C = -C;
139 // Get the hi and lo portions of constant.
140 unsigned Hi = IsArithmetic ? HA16(C) : Hi16(C);
141 unsigned Lo = Lo16(C);
142
143 // If two instructions are needed and usage indicates it would be better to
144 // load immediate into a register, bail out.
145 if (Hi && Lo && CN->use_size() > 2) return false;
146
147 // Select the first operand.
148 SDOperand Opr0 = Select(LHS);
149
150 if (Lo) // Add in the lo-part.
151 Opr0 = CurDAG->getTargetNode(OCLo, MVT::i32, Opr0, getI32Imm(Lo));
152 if (Hi) // Add in the hi-part.
153 Opr0 = CurDAG->getTargetNode(OCHi, MVT::i32, Opr0, getI32Imm(Hi));
154 return Opr0.Val;
155}
156
157
158// Select - Convert the specified operand from a target-independent to a
159// target-specific node if it hasn't already been changed.
160SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
161 SDNode *N = Op.Val;
162 if (N->getOpcode() >= ISD::BUILTIN_OP_END)
163 return Op; // Already selected.
164
165 switch (N->getOpcode()) {
166 default:
167 std::cerr << "Cannot yet select: ";
168 N->dump();
169 std::cerr << "\n";
170 abort();
171 case ISD::EntryToken: // These leaves remain the same.
172 case ISD::UNDEF:
173 return Op;
174 case ISD::TokenFactor: {
175 SDOperand New;
176 if (N->getNumOperands() == 2) {
177 SDOperand Op0 = Select(N->getOperand(0));
178 SDOperand Op1 = Select(N->getOperand(1));
179 New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);
180 } else {
181 std::vector<SDOperand> Ops;
182 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
183 Ops.push_back(Select(N->getOperand(0)));
184 New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops);
185 }
186
187 if (New.Val != N) {
188 CurDAG->ReplaceAllUsesWith(N, New.Val);
189 N = New.Val;
190 }
191 break;
192 }
193 case ISD::CopyFromReg: {
194 SDOperand Chain = Select(N->getOperand(0));
195 if (Chain == N->getOperand(0)) return Op; // No change
196 SDOperand New = CurDAG->getCopyFromReg(Chain,
197 cast<RegisterSDNode>(N->getOperand(1))->getReg(), N->getValueType(0));
198 return New.getValue(Op.ResNo);
199 }
200 case ISD::CopyToReg: {
201 SDOperand Chain = Select(N->getOperand(0));
202 SDOperand Reg = N->getOperand(1);
203 SDOperand Val = Select(N->getOperand(2));
204 if (Chain != N->getOperand(0) || Val != N->getOperand(2)) {
205 SDOperand New = CurDAG->getNode(ISD::CopyToReg, MVT::Other,
206 Chain, Reg, Val);
207 CurDAG->ReplaceAllUsesWith(N, New.Val);
208 N = New.Val;
209 }
210 break;
211 }
212 case ISD::Constant: {
213 assert(N->getValueType(0) == MVT::i32);
214 unsigned v = (unsigned)cast<ConstantSDNode>(N)->getValue();
215 if ((unsigned)(short)v == v) {
216 CurDAG->SelectNodeTo(N, MVT::i32, PPC::LI, getI32Imm(v));
217 break;
218 } else {
219 SDOperand Top = CurDAG->getTargetNode(PPC::LIS, MVT::i32,
220 getI32Imm(unsigned(v) >> 16));
221 CurDAG->SelectNodeTo(N, MVT::i32, PPC::ORI, Top, getI32Imm(v & 0xFFFF));
222 break;
223 }
224 }
Nate Begeman305a1c72005-08-18 03:04:18 +0000225 case ISD::SIGN_EXTEND_INREG:
226 switch(cast<VTSDNode>(N->getOperand(1))->getVT()) {
227 default: assert(0 && "Illegal type in SIGN_EXTEND_INREG"); break;
228 case MVT::i16:
229 CurDAG->SelectNodeTo(N, MVT::i32, PPC::EXTSH, Select(N->getOperand(0)));
230 break;
231 case MVT::i8:
232 CurDAG->SelectNodeTo(N, MVT::i32, PPC::EXTSB, Select(N->getOperand(0)));
233 break;
Nate Begeman305a1c72005-08-18 03:04:18 +0000234 }
235 break;
236 case ISD::CTLZ:
237 assert(N->getValueType(0) == MVT::i32);
238 CurDAG->SelectNodeTo(N, MVT::i32, PPC::CNTLZW, Select(N->getOperand(0)));
239 break;
Chris Lattnera5a91b12005-08-17 19:33:03 +0000240 case ISD::ADD: {
241 MVT::ValueType Ty = N->getValueType(0);
242 if (Ty == MVT::i32) {
243 if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1),
244 PPC::ADDIS, PPC::ADDI, true)) {
245 CurDAG->ReplaceAllUsesWith(N, I);
246 N = I;
247 } else {
248 CurDAG->SelectNodeTo(N, Ty, PPC::ADD, Select(N->getOperand(0)),
249 Select(N->getOperand(1)));
250 }
251 break;
252 }
253
254 if (!NoExcessFPPrecision) { // Match FMA ops
255 if (N->getOperand(0).getOpcode() == ISD::MUL &&
256 N->getOperand(0).Val->hasOneUse()) {
257 ++FusedFP; // Statistic
258 CurDAG->SelectNodeTo(N, Ty, Ty == MVT::f64 ? PPC::FMADD : PPC::FMADDS,
259 Select(N->getOperand(0).getOperand(0)),
260 Select(N->getOperand(0).getOperand(1)),
261 Select(N->getOperand(1)));
262 break;
263 } else if (N->getOperand(1).getOpcode() == ISD::MUL &&
264 N->getOperand(1).hasOneUse()) {
265 ++FusedFP; // Statistic
266 CurDAG->SelectNodeTo(N, Ty, Ty == MVT::f64 ? PPC::FMADD : PPC::FMADDS,
267 Select(N->getOperand(1).getOperand(0)),
268 Select(N->getOperand(1).getOperand(1)),
269 Select(N->getOperand(0)));
270 break;
271 }
272 }
273
274 CurDAG->SelectNodeTo(N, Ty, Ty == MVT::f64 ? PPC::FADD : PPC::FADDS,
275 Select(N->getOperand(0)), Select(N->getOperand(1)));
276 break;
277 }
278 case ISD::SUB: {
279 MVT::ValueType Ty = N->getValueType(0);
280 if (Ty == MVT::i32) {
281 unsigned Imm;
282 if (isIntImmediate(N->getOperand(0), Imm) && isInt16(Imm)) {
283 CurDAG->SelectNodeTo(N, Ty, PPC::SUBFIC, Select(N->getOperand(1)),
284 getI32Imm(Lo16(Imm)));
285 break;
286 }
287 if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), N->getOperand(1),
288 PPC::ADDIS, PPC::ADDI, true, true)) {
289 CurDAG->ReplaceAllUsesWith(N, I);
290 N = I;
291 } else {
292 CurDAG->SelectNodeTo(N, Ty, PPC::SUBF, Select(N->getOperand(1)),
293 Select(N->getOperand(0)));
294 }
295 break;
296 }
297
298 if (!NoExcessFPPrecision) { // Match FMA ops
299 if (N->getOperand(0).getOpcode() == ISD::MUL &&
300 N->getOperand(0).Val->hasOneUse()) {
301 ++FusedFP; // Statistic
302 CurDAG->SelectNodeTo(N, Ty, Ty == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS,
303 Select(N->getOperand(0).getOperand(0)),
304 Select(N->getOperand(0).getOperand(1)),
305 Select(N->getOperand(1)));
306 break;
307 } else if (N->getOperand(1).getOpcode() == ISD::MUL &&
308 N->getOperand(1).Val->hasOneUse()) {
309 ++FusedFP; // Statistic
310 CurDAG->SelectNodeTo(N, Ty, Ty == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS,
311 Select(N->getOperand(1).getOperand(0)),
312 Select(N->getOperand(1).getOperand(1)),
313 Select(N->getOperand(0)));
314 break;
315 }
316 }
317 CurDAG->SelectNodeTo(N, Ty, Ty == MVT::f64 ? PPC::FSUB : PPC::FSUBS,
318 Select(N->getOperand(0)),
319 Select(N->getOperand(1)));
320 break;
Nate Begeman26653502005-08-17 23:46:35 +0000321 }
Nate Begemanb5a06682005-08-18 00:21:41 +0000322 case ISD::MUL: {
323 unsigned Imm, Opc;
324 if (isIntImmediate(N->getOperand(1), Imm) && isInt16(Imm)) {
325 CurDAG->SelectNodeTo(N, N->getValueType(0), PPC::MULLI,
326 Select(N->getOperand(0)), getI32Imm(Lo16(Imm)));
327 break;
328 }
329 switch (N->getValueType(0)) {
330 default: assert(0 && "Unhandled multiply type!");
331 case MVT::i32: Opc = PPC::MULLW; break;
332 case MVT::f32: Opc = PPC::FMULS; break;
333 case MVT::f64: Opc = PPC::FMUL; break;
334 }
335 CurDAG->SelectNodeTo(N, N->getValueType(0), Opc, Select(N->getOperand(0)),
336 Select(N->getOperand(1)));
337 break;
338 }
Nate Begeman305a1c72005-08-18 03:04:18 +0000339 case ISD::MULHS:
Nate Begemanb5a06682005-08-18 00:21:41 +0000340 assert(N->getValueType(0) == MVT::i32);
Nate Begeman305a1c72005-08-18 03:04:18 +0000341 CurDAG->SelectNodeTo(N, MVT::i32, PPC::MULHW, Select(N->getOperand(0)),
342 Select(N->getOperand(1)));
Nate Begemanb5a06682005-08-18 00:21:41 +0000343 break;
Nate Begeman305a1c72005-08-18 03:04:18 +0000344 case ISD::MULHU:
Nate Begemanb5a06682005-08-18 00:21:41 +0000345 assert(N->getValueType(0) == MVT::i32);
Nate Begeman305a1c72005-08-18 03:04:18 +0000346 CurDAG->SelectNodeTo(N, MVT::i32, PPC::MULHWU, Select(N->getOperand(0)),
347 Select(N->getOperand(1)));
Nate Begemanb5a06682005-08-18 00:21:41 +0000348 break;
Nate Begeman0f3257a2005-08-18 05:00:13 +0000349 case ISD::XOR:
350 // Check whether or not this node is a logical 'not'. This is represented
351 // by llvm as a xor with the constant value -1 (all bits set). If this is a
352 // 'not', then fold 'or' into 'nor', and so forth for the supported ops.
353 if (isOprNot(N)) {
354 unsigned Opc;
355 switch(N->getOperand(0).getOpcode()) {
356 default: Opc = 0; break;
357 case ISD::OR: Opc = PPC::NOR; break;
358 case ISD::AND: Opc = PPC::NAND; break;
359 case ISD::XOR: Opc = PPC::EQV; break;
360 }
361 if (Opc)
362 CurDAG->SelectNodeTo(N, MVT::i32, Opc,
363 Select(N->getOperand(0).getOperand(0)),
364 Select(N->getOperand(0).getOperand(1)));
365 else
366 CurDAG->SelectNodeTo(N, MVT::i32, PPC::NOR, Select(N->getOperand(0)),
367 Select(N->getOperand(0)));
368 break;
369 }
370 // If this is a xor with an immediate other than -1, then codegen it as high
371 // and low 16 bit immediate xors.
372 if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0),
373 N->getOperand(1),
374 PPC::XORIS, PPC::XORI)) {
375 CurDAG->ReplaceAllUsesWith(N, I);
376 N = I;
377 break;
378 }
379 // Finally, check for the case where we are being asked to select
380 // xor (not(a), b) which is equivalent to not(xor a, b), which is eqv
381 if (isOprNot(N->getOperand(0).Val))
382 CurDAG->SelectNodeTo(N, MVT::i32, PPC::EQV,
383 Select(N->getOperand(0).getOperand(0)),
384 Select(N->getOperand(1)));
385 else
386 CurDAG->SelectNodeTo(N, MVT::i32, PPC::XOR, Select(N->getOperand(0)),
387 Select(N->getOperand(1)));
388 break;
Nate Begeman305a1c72005-08-18 03:04:18 +0000389 case ISD::FABS:
Nate Begeman6a7d6112005-08-18 00:53:47 +0000390 CurDAG->SelectNodeTo(N, N->getValueType(0), PPC::FABS,
391 Select(N->getOperand(0)));
392 break;
Nate Begeman305a1c72005-08-18 03:04:18 +0000393 case ISD::FP_EXTEND:
394 assert(MVT::f64 == N->getValueType(0) &&
395 MVT::f32 == N->getOperand(0).getValueType() && "Illegal FP_EXTEND");
396 CurDAG->SelectNodeTo(N, MVT::f64, PPC::FMR, Select(N->getOperand(0)));
397 break;
398 case ISD::FP_ROUND:
399 assert(MVT::f32 == N->getValueType(0) &&
400 MVT::f64 == N->getOperand(0).getValueType() && "Illegal FP_ROUND");
401 CurDAG->SelectNodeTo(N, MVT::f32, PPC::FRSP, Select(N->getOperand(0)));
402 break;
Nate Begeman26653502005-08-17 23:46:35 +0000403 case ISD::FNEG: {
404 SDOperand Val = Select(N->getOperand(0));
405 MVT::ValueType Ty = N->getValueType(0);
406 if (Val.Val->hasOneUse()) {
407 unsigned Opc;
408 switch (Val.getTargetOpcode()) {
409 default: Opc = 0; break;
410 case PPC::FABS: Opc = PPC::FNABS; break;
411 case PPC::FMADD: Opc = PPC::FNMADD; break;
412 case PPC::FMADDS: Opc = PPC::FNMADDS; break;
413 case PPC::FMSUB: Opc = PPC::FNMSUB; break;
414 case PPC::FMSUBS: Opc = PPC::FNMSUBS; break;
415 }
416 // If we inverted the opcode, then emit the new instruction with the
417 // inverted opcode and the original instruction's operands. Otherwise,
418 // fall through and generate a fneg instruction.
419 if (Opc) {
420 if (PPC::FNABS == Opc)
421 CurDAG->SelectNodeTo(N, Ty, Opc, Val.getOperand(0));
422 else
423 CurDAG->SelectNodeTo(N, Ty, Opc, Val.getOperand(0),
424 Val.getOperand(1), Val.getOperand(2));
425 break;
426 }
427 }
428 CurDAG->SelectNodeTo(N, Ty, PPC::FNEG, Val);
429 break;
430 }
Nate Begeman6a7d6112005-08-18 00:53:47 +0000431 case ISD::FSQRT: {
432 MVT::ValueType Ty = N->getValueType(0);
433 CurDAG->SelectNodeTo(N, Ty, Ty == MVT::f64 ? PPC::FSQRT : PPC::FSQRTS,
434 Select(N->getOperand(0)));
435 break;
436 }
Chris Lattnera5a91b12005-08-17 19:33:03 +0000437 case ISD::RET: {
438 SDOperand Chain = Select(N->getOperand(0)); // Token chain.
439
440 if (N->getNumOperands() > 1) {
441 SDOperand Val = Select(N->getOperand(1));
442 switch (N->getOperand(1).getValueType()) {
443 default: assert(0 && "Unknown return type!");
444 case MVT::f64:
445 case MVT::f32:
446 Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val);
447 break;
448 case MVT::i32:
449 Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val);
450 break;
451 }
452
453 if (N->getNumOperands() > 2) {
454 assert(N->getOperand(1).getValueType() == MVT::i32 &&
455 N->getOperand(2).getValueType() == MVT::i32 &&
456 N->getNumOperands() == 2 && "Unknown two-register ret value!");
457 Val = Select(N->getOperand(2));
458 Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Val);
459 }
460 }
461
462 // Finally, select this to a blr (return) instruction.
463 CurDAG->SelectNodeTo(N, MVT::Other, PPC::BLR, Chain);
464 break;
465 }
466 }
467 return SDOperand(N, 0);
468}
469
470
471/// createPPC32ISelDag - This pass converts a legalized DAG into a
472/// PowerPC-specific DAG, ready for instruction scheduling.
473///
474FunctionPass *llvm::createPPC32ISelDag(TargetMachine &TM) {
475 return new PPC32DAGToDAGISel(TM);
476}
477