blob: 603cfecb5944c1812cf8570a311518ecf4fc6c9d [file] [log] [blame]
Anton Korobeynikov4403b932009-07-16 13:27:25 +00001//==-- SystemZISelDAGToDAG.cpp - A dag to dag inst selector for SystemZ ---===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines an instruction selector for the SystemZ target.
11//
12//===----------------------------------------------------------------------===//
13
14#include "SystemZ.h"
15#include "SystemZISelLowering.h"
16#include "SystemZTargetMachine.h"
17#include "llvm/DerivedTypes.h"
18#include "llvm/Function.h"
19#include "llvm/Intrinsics.h"
20#include "llvm/CallingConv.h"
21#include "llvm/Constants.h"
22#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineInstrBuilder.h"
25#include "llvm/CodeGen/MachineRegisterInfo.h"
26#include "llvm/CodeGen/SelectionDAG.h"
27#include "llvm/CodeGen/SelectionDAGISel.h"
28#include "llvm/Target/TargetLowering.h"
29#include "llvm/Support/Compiler.h"
30#include "llvm/Support/Debug.h"
31using namespace llvm;
32
Anton Korobeynikov3360da92009-07-16 13:44:00 +000033namespace {
34 /// SystemZRRIAddressMode - This corresponds to rriaddr, but uses SDValue's
35 /// instead of register numbers for the leaves of the matched tree.
36 struct SystemZRRIAddressMode {
37 enum {
38 RegBase,
39 FrameIndexBase
40 } BaseType;
41
42 struct { // This is really a union, discriminated by BaseType!
43 SDValue Reg;
44 int FrameIndex;
45 } Base;
46
47 SDValue IndexReg;
Anton Korobeynikov32407402009-07-16 13:48:23 +000048 int64_t Disp;
Anton Korobeynikov3360da92009-07-16 13:44:00 +000049
50 SystemZRRIAddressMode()
51 : BaseType(RegBase), IndexReg(), Disp(0) {
52 }
53
54 void dump() {
Anton Korobeynikov961bb6f2009-07-16 13:45:00 +000055 cerr << "SystemZRRIAddressMode " << this << '\n';
Anton Korobeynikov3360da92009-07-16 13:44:00 +000056 if (BaseType == RegBase) {
57 cerr << "Base.Reg ";
58 if (Base.Reg.getNode() != 0) Base.Reg.getNode()->dump();
59 else cerr << "nul";
Anton Korobeynikov961bb6f2009-07-16 13:45:00 +000060 cerr << '\n';
Anton Korobeynikov3360da92009-07-16 13:44:00 +000061 } else {
Anton Korobeynikov961bb6f2009-07-16 13:45:00 +000062 cerr << " Base.FrameIndex " << Base.FrameIndex << '\n';
Anton Korobeynikov3360da92009-07-16 13:44:00 +000063 }
64 cerr << "IndexReg ";
65 if (IndexReg.getNode() != 0) IndexReg.getNode()->dump();
66 else cerr << "nul";
Anton Korobeynikov961bb6f2009-07-16 13:45:00 +000067 cerr << " Disp " << Disp << '\n';
Anton Korobeynikov3360da92009-07-16 13:44:00 +000068 }
69 };
70}
71
Anton Korobeynikov4403b932009-07-16 13:27:25 +000072/// SystemZDAGToDAGISel - SystemZ specific code to select SystemZ machine
73/// instructions for SelectionDAG operations.
74///
75namespace {
76 class SystemZDAGToDAGISel : public SelectionDAGISel {
77 SystemZTargetLowering &Lowering;
78 const SystemZSubtarget &Subtarget;
79
80 public:
81 SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel)
82 : SelectionDAGISel(TM, OptLevel),
83 Lowering(*TM.getTargetLowering()),
84 Subtarget(*TM.getSubtargetImpl()) { }
85
86 virtual void InstructionSelect();
87
88 virtual const char *getPassName() const {
89 return "SystemZ DAG->DAG Pattern Instruction Selection";
90 }
91
Anton Korobeynikov89edcd02009-07-16 13:33:57 +000092 /// getI16Imm - Return a target constant with the specified value, of type
93 /// i16.
94 inline SDValue getI16Imm(uint64_t Imm) {
95 return CurDAG->getTargetConstant(Imm, MVT::i16);
96 }
97
Anton Korobeynikovda308c92009-07-16 13:34:50 +000098 /// getI32Imm - Return a target constant with the specified value, of type
99 /// i32.
100 inline SDValue getI32Imm(uint64_t Imm) {
101 return CurDAG->getTargetConstant(Imm, MVT::i32);
102 }
103
Anton Korobeynikov4403b932009-07-16 13:27:25 +0000104 // Include the pieces autogenerated from the target description.
Anton Korobeynikov89edcd02009-07-16 13:33:57 +0000105 #include "SystemZGenDAGISel.inc"
Anton Korobeynikov4403b932009-07-16 13:27:25 +0000106
107 private:
Anton Korobeynikov3166a9a2009-07-16 14:03:41 +0000108 bool SelectAddrRI32(const SDValue& Op, SDValue& Addr,
109 SDValue &Base, SDValue &Disp);
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000110 bool SelectAddrRI(const SDValue& Op, SDValue& Addr,
111 SDValue &Base, SDValue &Disp);
Anton Korobeynikovc4368a12009-07-16 13:48:42 +0000112 bool SelectAddrRRI(SDValue Op, SDValue Addr,
113 SDValue &Base, SDValue &Disp, SDValue &Index);
114 bool SelectLAAddr(SDValue Op, SDValue Addr,
115 SDValue &Base, SDValue &Disp, SDValue &Index);
116
117 SDNode *Select(SDValue Op);
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000118 bool MatchAddress(SDValue N, SystemZRRIAddressMode &AM, unsigned Depth = 0);
119 bool MatchAddressBase(SDValue N, SystemZRRIAddressMode &AM);
Anton Korobeynikov4403b932009-07-16 13:27:25 +0000120
121 #ifndef NDEBUG
122 unsigned Indent;
123 #endif
124 };
125} // end anonymous namespace
126
127/// createSystemZISelDag - This pass converts a legalized DAG into a
128/// SystemZ-specific DAG, ready for instruction scheduling.
129///
130FunctionPass *llvm::createSystemZISelDag(SystemZTargetMachine &TM,
131 CodeGenOpt::Level OptLevel) {
132 return new SystemZDAGToDAGISel(TM, OptLevel);
133}
134
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000135/// isImmSExt20 - This method tests to see if the node is either a 32-bit
136/// or 64-bit immediate, and if the value can be accurately represented as a
137/// sign extension from a 20-bit value. If so, this returns true and the
138/// immediate.
Anton Korobeynikov32407402009-07-16 13:48:23 +0000139static bool isImmSExt20(int64_t Val, int64_t &Imm) {
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000140 if (Val >= -524288 && Val <= 524287) {
Anton Korobeynikov32407402009-07-16 13:48:23 +0000141 Imm = Val;
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000142 return true;
143 }
144 return false;
145}
146
Anton Korobeynikov32407402009-07-16 13:48:23 +0000147static bool isImmSExt20(SDNode *N, int64_t &Imm) {
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000148 if (N->getOpcode() != ISD::Constant)
149 return false;
150
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000151 return isImmSExt20(cast<ConstantSDNode>(N)->getSExtValue(), Imm);
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000152}
153
Anton Korobeynikov32407402009-07-16 13:48:23 +0000154static bool isImmSExt20(SDValue Op, int64_t &Imm) {
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000155 return isImmSExt20(Op.getNode(), Imm);
156}
157
Anton Korobeynikov3166a9a2009-07-16 14:03:41 +0000158/// isImmSExt12 - This method tests to see if the node is either a 32-bit
159/// or 64-bit immediate, and if the value can be accurately represented as a
160/// zero extension from a 12-bit value. If so, this returns true and the
161/// immediate.
162static bool isImmZExt12(SDNode *N, uint64_t &Imm) {
163 if (N->getOpcode() != ISD::Constant)
164 return false;
165
166 uint64_t Val = cast<ConstantSDNode>(N)->getZExtValue();
167 if (Val <= 0xFFF) {
168 Imm = Val;
169 return true;
170 }
171
172 return false;
173}
174
175static bool isImmZExt12(SDValue Op, uint64_t &Imm) {
176 return isImmZExt12(Op.getNode(), Imm);
177}
178
179/// Returns true if the address can be represented by a base register plus
180/// an unsigned 12-bit displacement [r+imm].
181bool SystemZDAGToDAGISel::SelectAddrRI32(const SDValue& Op, SDValue& Addr,
182 SDValue &Base, SDValue &Disp) {
183 // FIXME dl should come from parent load or store, not from address
184 DebugLoc dl = Addr.getDebugLoc();
185 MVT VT = Addr.getValueType();
186
187 if (Addr.getOpcode() == ISD::ADD) {
188 uint64_t Imm = 0;
189 if (isImmZExt12(Addr.getOperand(1), Imm)) {
190 Disp = CurDAG->getTargetConstant(Imm, MVT::i64);
191 if (FrameIndexSDNode *FI =
192 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
193 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), VT);
194 } else {
195 Base = Addr.getOperand(0);
196 }
197 return true; // [r+i]
198 }
199 } else if (Addr.getOpcode() == ISD::OR) {
200 uint64_t Imm = 0;
201 if (isImmZExt12(Addr.getOperand(1), Imm)) {
202 // If this is an or of disjoint bitfields, we can codegen this as an add
203 // (for better address arithmetic) if the LHS and RHS of the OR are
204 // provably disjoint.
205 APInt LHSKnownZero, LHSKnownOne;
206 CurDAG->ComputeMaskedBits(Addr.getOperand(0),
207 APInt::getAllOnesValue(Addr.getOperand(0)
208 .getValueSizeInBits()),
209 LHSKnownZero, LHSKnownOne);
210
211 if ((LHSKnownZero.getZExtValue()|~(uint64_t)Imm) == ~0ULL) {
212 // If all of the bits are known zero on the LHS or RHS, the add won't
213 // carry.
214 Base = Addr.getOperand(0);
215 Disp = CurDAG->getTargetConstant(Imm, MVT::i64);
216 return true;
217 }
218 }
219 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr)) {
220 // Loading from a constant address.
221
222 // If this address fits entirely in a 12-bit zext immediate field, codegen
223 // this as "d(r0)"
224 uint64_t Imm;
225 if (isImmZExt12(CN, Imm)) {
226 Disp = CurDAG->getTargetConstant(Imm, MVT::i64);
227 Base = CurDAG->getRegister(0, VT);
228 return true;
229 }
230 }
231
232 Disp = CurDAG->getTargetConstant(0, MVT::i64);
233 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Addr))
234 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), VT);
235 else
236 Base = Addr;
237 return true; // [r+0]
238}
239
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000240/// Returns true if the address can be represented by a base register plus
241/// a signed 20-bit displacement [r+imm].
242bool SystemZDAGToDAGISel::SelectAddrRI(const SDValue& Op, SDValue& Addr,
243 SDValue &Base, SDValue &Disp) {
244 // FIXME dl should come from parent load or store, not from address
245 DebugLoc dl = Addr.getDebugLoc();
246 MVT VT = Addr.getValueType();
247
248 if (Addr.getOpcode() == ISD::ADD) {
Anton Korobeynikov32407402009-07-16 13:48:23 +0000249 int64_t Imm = 0;
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000250 if (isImmSExt20(Addr.getOperand(1), Imm)) {
Anton Korobeynikov32407402009-07-16 13:48:23 +0000251 Disp = CurDAG->getTargetConstant(Imm, MVT::i64);
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000252 if (FrameIndexSDNode *FI =
253 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
254 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), VT);
255 } else {
256 Base = Addr.getOperand(0);
257 }
258 return true; // [r+i]
259 }
260 } else if (Addr.getOpcode() == ISD::OR) {
Anton Korobeynikov32407402009-07-16 13:48:23 +0000261 int64_t Imm = 0;
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000262 if (isImmSExt20(Addr.getOperand(1), Imm)) {
263 // If this is an or of disjoint bitfields, we can codegen this as an add
264 // (for better address arithmetic) if the LHS and RHS of the OR are
265 // provably disjoint.
266 APInt LHSKnownZero, LHSKnownOne;
267 CurDAG->ComputeMaskedBits(Addr.getOperand(0),
268 APInt::getAllOnesValue(Addr.getOperand(0)
269 .getValueSizeInBits()),
270 LHSKnownZero, LHSKnownOne);
271
272 if ((LHSKnownZero.getZExtValue()|~(uint64_t)Imm) == ~0ULL) {
273 // If all of the bits are known zero on the LHS or RHS, the add won't
274 // carry.
275 Base = Addr.getOperand(0);
Anton Korobeynikov32407402009-07-16 13:48:23 +0000276 Disp = CurDAG->getTargetConstant(Imm, MVT::i64);
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000277 return true;
278 }
279 }
280 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr)) {
281 // Loading from a constant address.
282
283 // If this address fits entirely in a 20-bit sext immediate field, codegen
284 // this as "d(r0)"
Anton Korobeynikov32407402009-07-16 13:48:23 +0000285 int64_t Imm;
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000286 if (isImmSExt20(CN, Imm)) {
Anton Korobeynikov32407402009-07-16 13:48:23 +0000287 Disp = CurDAG->getTargetConstant(Imm, MVT::i64);
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000288 Base = CurDAG->getRegister(0, VT);
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000289 return true;
290 }
291 }
292
Anton Korobeynikov32407402009-07-16 13:48:23 +0000293 Disp = CurDAG->getTargetConstant(0, MVT::i64);
Anton Korobeynikov9e4816e2009-07-16 13:43:18 +0000294 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Addr))
295 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), VT);
296 else
297 Base = Addr;
298 return true; // [r+0]
299}
300
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000301/// MatchAddress - Add the specified node to the specified addressing mode,
302/// returning true if it cannot be done. This just pattern matches for the
303/// addressing mode.
304bool SystemZDAGToDAGISel::MatchAddress(SDValue N, SystemZRRIAddressMode &AM,
305 unsigned Depth) {
306 DebugLoc dl = N.getDebugLoc();
307 DOUT << "MatchAddress: "; DEBUG(AM.dump());
308 // Limit recursion.
309 if (Depth > 5)
310 return MatchAddressBase(N, AM);
311
Anton Korobeynikovdc289552009-07-16 13:44:30 +0000312 // FIXME: We can perform better here. If we have something like
313 // (shift (add A, imm), N), we can try to reassociate stuff and fold shift of
314 // imm into addressing mode.
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000315 switch (N.getOpcode()) {
316 default: break;
317 case ISD::Constant: {
Anton Korobeynikov32407402009-07-16 13:48:23 +0000318 int64_t Val = cast<ConstantSDNode>(N)->getSExtValue();
319 int64_t Imm;
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000320 if (isImmSExt20(AM.Disp + Val, Imm)) {
321 AM.Disp = Imm;
322 return false;
323 }
324 break;
325 }
326
327 case ISD::FrameIndex:
328 if (AM.BaseType == SystemZRRIAddressMode::RegBase
329 && AM.Base.Reg.getNode() == 0) {
330 AM.BaseType = SystemZRRIAddressMode::FrameIndexBase;
331 AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex();
332 return false;
333 }
334 break;
335
336 case ISD::SUB: {
337 // Given A-B, if A can be completely folded into the address and
338 // the index field with the index field unused, use -B as the index.
339 // This is a win if a has multiple parts that can be folded into
340 // the address. Also, this saves a mov if the base register has
341 // other uses, since it avoids a two-address sub instruction, however
342 // it costs an additional mov if the index register has other uses.
343
344 // Test if the LHS of the sub can be folded.
345 SystemZRRIAddressMode Backup = AM;
346 if (MatchAddress(N.getNode()->getOperand(0), AM, Depth+1)) {
347 AM = Backup;
348 break;
349 }
350 // Test if the index field is free for use.
351 if (AM.IndexReg.getNode()) {
352 AM = Backup;
353 break;
354 }
355
356 // If the base is a register with multiple uses, this transformation may
357 // save a mov. Otherwise it's probably better not to do it.
358 if (AM.BaseType == SystemZRRIAddressMode::RegBase &&
359 (!AM.Base.Reg.getNode() || AM.Base.Reg.getNode()->hasOneUse())) {
360 AM = Backup;
361 break;
362 }
363
364 // Ok, the transformation is legal and appears profitable. Go for it.
365 SDValue RHS = N.getNode()->getOperand(1);
366 SDValue Zero = CurDAG->getConstant(0, N.getValueType());
367 SDValue Neg = CurDAG->getNode(ISD::SUB, dl, N.getValueType(), Zero, RHS);
368 AM.IndexReg = Neg;
369
370 // Insert the new nodes into the topological ordering.
371 if (Zero.getNode()->getNodeId() == -1 ||
372 Zero.getNode()->getNodeId() > N.getNode()->getNodeId()) {
373 CurDAG->RepositionNode(N.getNode(), Zero.getNode());
374 Zero.getNode()->setNodeId(N.getNode()->getNodeId());
375 }
376 if (Neg.getNode()->getNodeId() == -1 ||
377 Neg.getNode()->getNodeId() > N.getNode()->getNodeId()) {
378 CurDAG->RepositionNode(N.getNode(), Neg.getNode());
379 Neg.getNode()->setNodeId(N.getNode()->getNodeId());
380 }
381 return false;
382 }
383
384 case ISD::ADD: {
385 SystemZRRIAddressMode Backup = AM;
386 if (!MatchAddress(N.getNode()->getOperand(0), AM, Depth+1) &&
387 !MatchAddress(N.getNode()->getOperand(1), AM, Depth+1))
388 return false;
389 AM = Backup;
390 if (!MatchAddress(N.getNode()->getOperand(1), AM, Depth+1) &&
391 !MatchAddress(N.getNode()->getOperand(0), AM, Depth+1))
392 return false;
393 AM = Backup;
394
395 // If we couldn't fold both operands into the address at the same time,
396 // see if we can just put each operand into a register and fold at least
397 // the add.
398 if (AM.BaseType == SystemZRRIAddressMode::RegBase &&
399 !AM.Base.Reg.getNode() && !AM.IndexReg.getNode()) {
400 AM.Base.Reg = N.getNode()->getOperand(0);
401 AM.IndexReg = N.getNode()->getOperand(1);
402 return false;
403 }
404 break;
405 }
406
407 case ISD::OR:
408 // Handle "X | C" as "X + C" iff X is known to have C bits clear.
409 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
410 SystemZRRIAddressMode Backup = AM;
Anton Korobeynikov32407402009-07-16 13:48:23 +0000411 int64_t Offset = CN->getSExtValue();
412 int64_t Imm;
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000413 // Start with the LHS as an addr mode.
414 if (!MatchAddress(N.getOperand(0), AM, Depth+1) &&
415 // The resultant disp must fit in 20-bits.
416 isImmSExt20(AM.Disp + Offset, Imm) &&
417 // Check to see if the LHS & C is zero.
418 CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) {
419 AM.Disp = Imm;
420 return false;
421 }
422 AM = Backup;
423 }
424 break;
425 }
426
427 return MatchAddressBase(N, AM);
428}
429
430/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the
431/// specified addressing mode without any further recursion.
432bool SystemZDAGToDAGISel::MatchAddressBase(SDValue N,
433 SystemZRRIAddressMode &AM) {
434 // Is the base register already occupied?
435 if (AM.BaseType != SystemZRRIAddressMode::RegBase || AM.Base.Reg.getNode()) {
436 // If so, check to see if the scale index register is set.
437 if (AM.IndexReg.getNode() == 0) {
438 AM.IndexReg = N;
439 return false;
440 }
441
442 // Otherwise, we cannot select it.
443 return true;
444 }
445
446 // Default, generate it as a register.
447 AM.BaseType = SystemZRRIAddressMode::RegBase;
448 AM.Base.Reg = N;
449 return false;
450}
451
452/// Returns true if the address can be represented by a base register plus
453/// index register plus a signed 20-bit displacement [base + idx + imm].
454bool SystemZDAGToDAGISel::SelectAddrRRI(SDValue Op, SDValue Addr,
Anton Korobeynikovc4368a12009-07-16 13:48:42 +0000455 SDValue &Base, SDValue &Disp, SDValue &Index) {
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000456 SystemZRRIAddressMode AM;
457 bool Done = false;
458
Anton Korobeynikov711d5b62009-07-16 13:47:59 +0000459 if (!Addr.hasOneUse()) {
460 unsigned Opcode = Addr.getOpcode();
461 if (Opcode != ISD::Constant && Opcode != ISD::FrameIndex) {
462 // If we are able to fold N into addressing mode, then we'll allow it even
463 // if N has multiple uses. In general, addressing computation is used as
464 // addresses by all of its uses. But watch out for CopyToReg uses, that
465 // means the address computation is liveout. It will be computed by a LA
466 // so we want to avoid computing the address twice.
467 for (SDNode::use_iterator UI = Addr.getNode()->use_begin(),
468 UE = Addr.getNode()->use_end(); UI != UE; ++UI) {
469 if (UI->getOpcode() == ISD::CopyToReg) {
470 MatchAddressBase(Addr, AM);
471 Done = true;
472 break;
473 }
474 }
475 }
476 }
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000477 if (!Done && MatchAddress(Addr, AM))
478 return false;
479
Anton Korobeynikov32407402009-07-16 13:48:23 +0000480 DOUT << "MatchAddress (final): "; DEBUG(AM.dump());
481
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000482 MVT VT = Addr.getValueType();
483 if (AM.BaseType == SystemZRRIAddressMode::RegBase) {
484 if (!AM.Base.Reg.getNode())
485 AM.Base.Reg = CurDAG->getRegister(0, VT);
486 }
487
488 if (!AM.IndexReg.getNode())
489 AM.IndexReg = CurDAG->getRegister(0, VT);
490
491 if (AM.BaseType == SystemZRRIAddressMode::RegBase)
492 Base = AM.Base.Reg;
493 else
494 Base = CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy());
495 Index = AM.IndexReg;
Anton Korobeynikov32407402009-07-16 13:48:23 +0000496 Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i64);
Anton Korobeynikov3360da92009-07-16 13:44:00 +0000497
498 return true;
499}
Anton Korobeynikov4403b932009-07-16 13:27:25 +0000500
Anton Korobeynikov711d5b62009-07-16 13:47:59 +0000501/// SelectLAAddr - it calls SelectAddr and determines if the maximal addressing
502/// mode it matches can be cost effectively emitted as an LA/LAY instruction.
503bool SystemZDAGToDAGISel::SelectLAAddr(SDValue Op, SDValue Addr,
Anton Korobeynikovc4368a12009-07-16 13:48:42 +0000504 SDValue &Base, SDValue &Disp, SDValue &Index) {
Anton Korobeynikov711d5b62009-07-16 13:47:59 +0000505 SystemZRRIAddressMode AM;
506
507 if (MatchAddress(Addr, AM))
508 return false;
509
510 MVT VT = Addr.getValueType();
511 unsigned Complexity = 0;
512 if (AM.BaseType == SystemZRRIAddressMode::RegBase)
513 if (AM.Base.Reg.getNode())
514 Complexity = 1;
515 else
516 AM.Base.Reg = CurDAG->getRegister(0, VT);
517 else if (AM.BaseType == SystemZRRIAddressMode::FrameIndexBase)
518 Complexity = 4;
519
520 if (AM.IndexReg.getNode())
521 Complexity += 1;
522 else
523 AM.IndexReg = CurDAG->getRegister(0, VT);
524
525 if (AM.Disp && (AM.Base.Reg.getNode() || AM.IndexReg.getNode()))
526 Complexity += 1;
527
528 if (Complexity > 2) {
529 if (AM.BaseType == SystemZRRIAddressMode::RegBase)
530 Base = AM.Base.Reg;
531 else
532 Base = CurDAG->getTargetFrameIndex(AM.Base.FrameIndex,
533 TLI.getPointerTy());
534 Index = AM.IndexReg;
Anton Korobeynikov32407402009-07-16 13:48:23 +0000535 Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i64);
Anton Korobeynikov711d5b62009-07-16 13:47:59 +0000536 return true;
537 }
538
539 return false;
540}
541
Anton Korobeynikov4403b932009-07-16 13:27:25 +0000542/// InstructionSelect - This callback is invoked by
543/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
544void SystemZDAGToDAGISel::InstructionSelect() {
545 DEBUG(BB->dump());
546
547 // Codegen the basic block.
548#ifndef NDEBUG
549 DOUT << "===== Instruction selection begins:\n";
550 Indent = 0;
551#endif
552 SelectRoot(*CurDAG);
553#ifndef NDEBUG
554 DOUT << "===== Instruction selection ends:\n";
555#endif
556
557 CurDAG->RemoveDeadNodes();
558}
559
560SDNode *SystemZDAGToDAGISel::Select(SDValue Op) {
561 SDNode *Node = Op.getNode();
562 DebugLoc dl = Op.getDebugLoc();
563
564 // Dump information about the Node being selected
565 #ifndef NDEBUG
566 DOUT << std::string(Indent, ' ') << "Selecting: ";
567 DEBUG(Node->dump(CurDAG));
568 DOUT << "\n";
569 Indent += 2;
570 #endif
571
572 // If we have a custom node, we already have selected!
573 if (Node->isMachineOpcode()) {
574 #ifndef NDEBUG
575 DOUT << std::string(Indent-2, ' ') << "== ";
576 DEBUG(Node->dump(CurDAG));
577 DOUT << "\n";
578 Indent -= 2;
579 #endif
580 return NULL;
581 }
582
583 // Select the default instruction
584 SDNode *ResNode = SelectCode(Op);
585
586 #ifndef NDEBUG
587 DOUT << std::string(Indent-2, ' ') << "=> ";
588 if (ResNode == NULL || ResNode == Op.getNode())
589 DEBUG(Op.getNode()->dump(CurDAG));
590 else
591 DEBUG(ResNode->dump(CurDAG));
592 DOUT << "\n";
593 Indent -= 2;
594 #endif
595
596 return ResNode;
597}