Proper name 16 bit libcalls
[llvm/msp430.git] / lib / Target / ARM / ARMISelDAGToDAG.cpp
blob3bc5ae91467dd49ff1abd4abbe535f93178f29de
1 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===//
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 ARM target.
12 //===----------------------------------------------------------------------===//
14 #include "ARM.h"
15 #include "ARMAddressingModes.h"
16 #include "ARMConstantPoolValue.h"
17 #include "ARMISelLowering.h"
18 #include "ARMTargetMachine.h"
19 #include "llvm/CallingConv.h"
20 #include "llvm/Constants.h"
21 #include "llvm/DerivedTypes.h"
22 #include "llvm/Function.h"
23 #include "llvm/Intrinsics.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/CodeGen/SelectionDAG.h"
28 #include "llvm/CodeGen/SelectionDAGISel.h"
29 #include "llvm/Target/TargetLowering.h"
30 #include "llvm/Target/TargetOptions.h"
31 #include "llvm/Support/Compiler.h"
32 #include "llvm/Support/Debug.h"
33 using namespace llvm;
35 //===--------------------------------------------------------------------===//
36 /// ARMDAGToDAGISel - ARM specific code to select ARM machine
37 /// instructions for SelectionDAG operations.
38 ///
39 namespace {
40 class ARMDAGToDAGISel : public SelectionDAGISel {
41 ARMTargetMachine &TM;
43 /// Subtarget - Keep a pointer to the ARMSubtarget around so that we can
44 /// make the right decision when generating code for different targets.
45 const ARMSubtarget *Subtarget;
47 public:
48 explicit ARMDAGToDAGISel(ARMTargetMachine &tm)
49 : SelectionDAGISel(tm), TM(tm),
50 Subtarget(&TM.getSubtarget<ARMSubtarget>()) {
53 virtual const char *getPassName() const {
54 return "ARM Instruction Selection";
57 SDNode *Select(SDValue Op);
58 virtual void InstructionSelect();
59 bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base,
60 SDValue &Offset, SDValue &Opc);
61 bool SelectAddrMode2Offset(SDValue Op, SDValue N,
62 SDValue &Offset, SDValue &Opc);
63 bool SelectAddrMode3(SDValue Op, SDValue N, SDValue &Base,
64 SDValue &Offset, SDValue &Opc);
65 bool SelectAddrMode3Offset(SDValue Op, SDValue N,
66 SDValue &Offset, SDValue &Opc);
67 bool SelectAddrMode5(SDValue Op, SDValue N, SDValue &Base,
68 SDValue &Offset);
70 bool SelectAddrModePC(SDValue Op, SDValue N, SDValue &Offset,
71 SDValue &Label);
73 bool SelectThumbAddrModeRR(SDValue Op, SDValue N, SDValue &Base,
74 SDValue &Offset);
75 bool SelectThumbAddrModeRI5(SDValue Op, SDValue N, unsigned Scale,
76 SDValue &Base, SDValue &OffImm,
77 SDValue &Offset);
78 bool SelectThumbAddrModeS1(SDValue Op, SDValue N, SDValue &Base,
79 SDValue &OffImm, SDValue &Offset);
80 bool SelectThumbAddrModeS2(SDValue Op, SDValue N, SDValue &Base,
81 SDValue &OffImm, SDValue &Offset);
82 bool SelectThumbAddrModeS4(SDValue Op, SDValue N, SDValue &Base,
83 SDValue &OffImm, SDValue &Offset);
84 bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base,
85 SDValue &OffImm);
87 bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A,
88 SDValue &B, SDValue &C);
90 // Include the pieces autogenerated from the target description.
91 #include "ARMGenDAGISel.inc"
95 void ARMDAGToDAGISel::InstructionSelect() {
96 DEBUG(BB->dump());
98 SelectRoot(*CurDAG);
99 CurDAG->RemoveDeadNodes();
102 bool ARMDAGToDAGISel::SelectAddrMode2(SDValue Op, SDValue N,
103 SDValue &Base, SDValue &Offset,
104 SDValue &Opc) {
105 if (N.getOpcode() == ISD::MUL) {
106 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
107 // X * [3,5,9] -> X + X * [2,4,8] etc.
108 int RHSC = (int)RHS->getZExtValue();
109 if (RHSC & 1) {
110 RHSC = RHSC & ~1;
111 ARM_AM::AddrOpc AddSub = ARM_AM::add;
112 if (RHSC < 0) {
113 AddSub = ARM_AM::sub;
114 RHSC = - RHSC;
116 if (isPowerOf2_32(RHSC)) {
117 unsigned ShAmt = Log2_32(RHSC);
118 Base = Offset = N.getOperand(0);
119 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
120 ARM_AM::lsl),
121 MVT::i32);
122 return true;
128 if (N.getOpcode() != ISD::ADD && N.getOpcode() != ISD::SUB) {
129 Base = N;
130 if (N.getOpcode() == ISD::FrameIndex) {
131 int FI = cast<FrameIndexSDNode>(N)->getIndex();
132 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
133 } else if (N.getOpcode() == ARMISD::Wrapper) {
134 Base = N.getOperand(0);
136 Offset = CurDAG->getRegister(0, MVT::i32);
137 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
138 ARM_AM::no_shift),
139 MVT::i32);
140 return true;
143 // Match simple R +/- imm12 operands.
144 if (N.getOpcode() == ISD::ADD)
145 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
146 int RHSC = (int)RHS->getZExtValue();
147 if ((RHSC >= 0 && RHSC < 0x1000) ||
148 (RHSC < 0 && RHSC > -0x1000)) { // 12 bits.
149 Base = N.getOperand(0);
150 if (Base.getOpcode() == ISD::FrameIndex) {
151 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
152 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
154 Offset = CurDAG->getRegister(0, MVT::i32);
156 ARM_AM::AddrOpc AddSub = ARM_AM::add;
157 if (RHSC < 0) {
158 AddSub = ARM_AM::sub;
159 RHSC = - RHSC;
161 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
162 ARM_AM::no_shift),
163 MVT::i32);
164 return true;
168 // Otherwise this is R +/- [possibly shifted] R
169 ARM_AM::AddrOpc AddSub = N.getOpcode() == ISD::ADD ? ARM_AM::add:ARM_AM::sub;
170 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(1));
171 unsigned ShAmt = 0;
173 Base = N.getOperand(0);
174 Offset = N.getOperand(1);
176 if (ShOpcVal != ARM_AM::no_shift) {
177 // Check to see if the RHS of the shift is a constant, if not, we can't fold
178 // it.
179 if (ConstantSDNode *Sh =
180 dyn_cast<ConstantSDNode>(N.getOperand(1).getOperand(1))) {
181 ShAmt = Sh->getZExtValue();
182 Offset = N.getOperand(1).getOperand(0);
183 } else {
184 ShOpcVal = ARM_AM::no_shift;
188 // Try matching (R shl C) + (R).
189 if (N.getOpcode() == ISD::ADD && ShOpcVal == ARM_AM::no_shift) {
190 ShOpcVal = ARM_AM::getShiftOpcForNode(N.getOperand(0));
191 if (ShOpcVal != ARM_AM::no_shift) {
192 // Check to see if the RHS of the shift is a constant, if not, we can't
193 // fold it.
194 if (ConstantSDNode *Sh =
195 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
196 ShAmt = Sh->getZExtValue();
197 Offset = N.getOperand(0).getOperand(0);
198 Base = N.getOperand(1);
199 } else {
200 ShOpcVal = ARM_AM::no_shift;
205 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
206 MVT::i32);
207 return true;
210 bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDValue Op, SDValue N,
211 SDValue &Offset, SDValue &Opc) {
212 unsigned Opcode = Op.getOpcode();
213 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
214 ? cast<LoadSDNode>(Op)->getAddressingMode()
215 : cast<StoreSDNode>(Op)->getAddressingMode();
216 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
217 ? ARM_AM::add : ARM_AM::sub;
218 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
219 int Val = (int)C->getZExtValue();
220 if (Val >= 0 && Val < 0x1000) { // 12 bits.
221 Offset = CurDAG->getRegister(0, MVT::i32);
222 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, Val,
223 ARM_AM::no_shift),
224 MVT::i32);
225 return true;
229 Offset = N;
230 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
231 unsigned ShAmt = 0;
232 if (ShOpcVal != ARM_AM::no_shift) {
233 // Check to see if the RHS of the shift is a constant, if not, we can't fold
234 // it.
235 if (ConstantSDNode *Sh = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
236 ShAmt = Sh->getZExtValue();
237 Offset = N.getOperand(0);
238 } else {
239 ShOpcVal = ARM_AM::no_shift;
243 Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
244 MVT::i32);
245 return true;
249 bool ARMDAGToDAGISel::SelectAddrMode3(SDValue Op, SDValue N,
250 SDValue &Base, SDValue &Offset,
251 SDValue &Opc) {
252 if (N.getOpcode() == ISD::SUB) {
253 // X - C is canonicalize to X + -C, no need to handle it here.
254 Base = N.getOperand(0);
255 Offset = N.getOperand(1);
256 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::sub, 0),MVT::i32);
257 return true;
260 if (N.getOpcode() != ISD::ADD) {
261 Base = N;
262 if (N.getOpcode() == ISD::FrameIndex) {
263 int FI = cast<FrameIndexSDNode>(N)->getIndex();
264 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
266 Offset = CurDAG->getRegister(0, MVT::i32);
267 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0),MVT::i32);
268 return true;
271 // If the RHS is +/- imm8, fold into addr mode.
272 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
273 int RHSC = (int)RHS->getZExtValue();
274 if ((RHSC >= 0 && RHSC < 256) ||
275 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed.
276 Base = N.getOperand(0);
277 if (Base.getOpcode() == ISD::FrameIndex) {
278 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
279 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
281 Offset = CurDAG->getRegister(0, MVT::i32);
283 ARM_AM::AddrOpc AddSub = ARM_AM::add;
284 if (RHSC < 0) {
285 AddSub = ARM_AM::sub;
286 RHSC = - RHSC;
288 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, RHSC),MVT::i32);
289 return true;
293 Base = N.getOperand(0);
294 Offset = N.getOperand(1);
295 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(ARM_AM::add, 0), MVT::i32);
296 return true;
299 bool ARMDAGToDAGISel::SelectAddrMode3Offset(SDValue Op, SDValue N,
300 SDValue &Offset, SDValue &Opc) {
301 unsigned Opcode = Op.getOpcode();
302 ISD::MemIndexedMode AM = (Opcode == ISD::LOAD)
303 ? cast<LoadSDNode>(Op)->getAddressingMode()
304 : cast<StoreSDNode>(Op)->getAddressingMode();
305 ARM_AM::AddrOpc AddSub = (AM == ISD::PRE_INC || AM == ISD::POST_INC)
306 ? ARM_AM::add : ARM_AM::sub;
307 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) {
308 int Val = (int)C->getZExtValue();
309 if (Val >= 0 && Val < 256) {
310 Offset = CurDAG->getRegister(0, MVT::i32);
311 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, Val), MVT::i32);
312 return true;
316 Offset = N;
317 Opc = CurDAG->getTargetConstant(ARM_AM::getAM3Opc(AddSub, 0), MVT::i32);
318 return true;
322 bool ARMDAGToDAGISel::SelectAddrMode5(SDValue Op, SDValue N,
323 SDValue &Base, SDValue &Offset) {
324 if (N.getOpcode() != ISD::ADD) {
325 Base = N;
326 if (N.getOpcode() == ISD::FrameIndex) {
327 int FI = cast<FrameIndexSDNode>(N)->getIndex();
328 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
329 } else if (N.getOpcode() == ARMISD::Wrapper) {
330 Base = N.getOperand(0);
332 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
333 MVT::i32);
334 return true;
337 // If the RHS is +/- imm8, fold into addr mode.
338 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
339 int RHSC = (int)RHS->getZExtValue();
340 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied by 4.
341 RHSC >>= 2;
342 if ((RHSC >= 0 && RHSC < 256) ||
343 (RHSC < 0 && RHSC > -256)) { // note -256 itself isn't allowed.
344 Base = N.getOperand(0);
345 if (Base.getOpcode() == ISD::FrameIndex) {
346 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
347 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
350 ARM_AM::AddrOpc AddSub = ARM_AM::add;
351 if (RHSC < 0) {
352 AddSub = ARM_AM::sub;
353 RHSC = - RHSC;
355 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(AddSub, RHSC),
356 MVT::i32);
357 return true;
362 Base = N;
363 Offset = CurDAG->getTargetConstant(ARM_AM::getAM5Opc(ARM_AM::add, 0),
364 MVT::i32);
365 return true;
368 bool ARMDAGToDAGISel::SelectAddrModePC(SDValue Op, SDValue N,
369 SDValue &Offset, SDValue &Label) {
370 if (N.getOpcode() == ARMISD::PIC_ADD && N.hasOneUse()) {
371 Offset = N.getOperand(0);
372 SDValue N1 = N.getOperand(1);
373 Label = CurDAG->getTargetConstant(cast<ConstantSDNode>(N1)->getZExtValue(),
374 MVT::i32);
375 return true;
377 return false;
380 bool ARMDAGToDAGISel::SelectThumbAddrModeRR(SDValue Op, SDValue N,
381 SDValue &Base, SDValue &Offset){
382 // FIXME dl should come from the parent load or store, not the address
383 DebugLoc dl = Op.getDebugLoc();
384 if (N.getOpcode() != ISD::ADD) {
385 Base = N;
386 // We must materialize a zero in a reg! Returning a constant here
387 // wouldn't work without additional code to position the node within
388 // ISel's topological ordering in a place where ISel will process it
389 // normally. Instead, just explicitly issue a tMOVri8 node!
390 Offset = SDValue(CurDAG->getTargetNode(ARM::tMOVi8, dl, MVT::i32,
391 CurDAG->getTargetConstant(0, MVT::i32)), 0);
392 return true;
395 Base = N.getOperand(0);
396 Offset = N.getOperand(1);
397 return true;
400 bool
401 ARMDAGToDAGISel::SelectThumbAddrModeRI5(SDValue Op, SDValue N,
402 unsigned Scale, SDValue &Base,
403 SDValue &OffImm, SDValue &Offset) {
404 if (Scale == 4) {
405 SDValue TmpBase, TmpOffImm;
406 if (SelectThumbAddrModeSP(Op, N, TmpBase, TmpOffImm))
407 return false; // We want to select tLDRspi / tSTRspi instead.
408 if (N.getOpcode() == ARMISD::Wrapper &&
409 N.getOperand(0).getOpcode() == ISD::TargetConstantPool)
410 return false; // We want to select tLDRpci instead.
413 if (N.getOpcode() != ISD::ADD) {
414 Base = (N.getOpcode() == ARMISD::Wrapper) ? N.getOperand(0) : N;
415 Offset = CurDAG->getRegister(0, MVT::i32);
416 OffImm = CurDAG->getTargetConstant(0, MVT::i32);
417 return true;
420 // Thumb does not have [sp, r] address mode.
421 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
422 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(N.getOperand(1));
423 if ((LHSR && LHSR->getReg() == ARM::SP) ||
424 (RHSR && RHSR->getReg() == ARM::SP)) {
425 Base = N;
426 Offset = CurDAG->getRegister(0, MVT::i32);
427 OffImm = CurDAG->getTargetConstant(0, MVT::i32);
428 return true;
431 // If the RHS is + imm5 * scale, fold into addr mode.
432 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
433 int RHSC = (int)RHS->getZExtValue();
434 if ((RHSC & (Scale-1)) == 0) { // The constant is implicitly multiplied.
435 RHSC /= Scale;
436 if (RHSC >= 0 && RHSC < 32) {
437 Base = N.getOperand(0);
438 Offset = CurDAG->getRegister(0, MVT::i32);
439 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
440 return true;
445 Base = N.getOperand(0);
446 Offset = N.getOperand(1);
447 OffImm = CurDAG->getTargetConstant(0, MVT::i32);
448 return true;
451 bool ARMDAGToDAGISel::SelectThumbAddrModeS1(SDValue Op, SDValue N,
452 SDValue &Base, SDValue &OffImm,
453 SDValue &Offset) {
454 return SelectThumbAddrModeRI5(Op, N, 1, Base, OffImm, Offset);
457 bool ARMDAGToDAGISel::SelectThumbAddrModeS2(SDValue Op, SDValue N,
458 SDValue &Base, SDValue &OffImm,
459 SDValue &Offset) {
460 return SelectThumbAddrModeRI5(Op, N, 2, Base, OffImm, Offset);
463 bool ARMDAGToDAGISel::SelectThumbAddrModeS4(SDValue Op, SDValue N,
464 SDValue &Base, SDValue &OffImm,
465 SDValue &Offset) {
466 return SelectThumbAddrModeRI5(Op, N, 4, Base, OffImm, Offset);
469 bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N,
470 SDValue &Base, SDValue &OffImm) {
471 if (N.getOpcode() == ISD::FrameIndex) {
472 int FI = cast<FrameIndexSDNode>(N)->getIndex();
473 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
474 OffImm = CurDAG->getTargetConstant(0, MVT::i32);
475 return true;
478 if (N.getOpcode() != ISD::ADD)
479 return false;
481 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(N.getOperand(0));
482 if (N.getOperand(0).getOpcode() == ISD::FrameIndex ||
483 (LHSR && LHSR->getReg() == ARM::SP)) {
484 // If the RHS is + imm8 * scale, fold into addr mode.
485 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
486 int RHSC = (int)RHS->getZExtValue();
487 if ((RHSC & 3) == 0) { // The constant is implicitly multiplied.
488 RHSC >>= 2;
489 if (RHSC >= 0 && RHSC < 256) {
490 Base = N.getOperand(0);
491 if (Base.getOpcode() == ISD::FrameIndex) {
492 int FI = cast<FrameIndexSDNode>(Base)->getIndex();
493 Base = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
495 OffImm = CurDAG->getTargetConstant(RHSC, MVT::i32);
496 return true;
502 return false;
505 bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op,
506 SDValue N,
507 SDValue &BaseReg,
508 SDValue &ShReg,
509 SDValue &Opc) {
510 ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
512 // Don't match base register only case. That is matched to a separate
513 // lower complexity pattern with explicit register operand.
514 if (ShOpcVal == ARM_AM::no_shift) return false;
516 BaseReg = N.getOperand(0);
517 unsigned ShImmVal = 0;
518 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
519 ShReg = CurDAG->getRegister(0, MVT::i32);
520 ShImmVal = RHS->getZExtValue() & 31;
521 } else {
522 ShReg = N.getOperand(1);
524 Opc = CurDAG->getTargetConstant(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal),
525 MVT::i32);
526 return true;
529 /// getAL - Returns a ARMCC::AL immediate node.
530 static inline SDValue getAL(SelectionDAG *CurDAG) {
531 return CurDAG->getTargetConstant((uint64_t)ARMCC::AL, MVT::i32);
535 SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
536 SDNode *N = Op.getNode();
537 DebugLoc dl = N->getDebugLoc();
539 if (N->isMachineOpcode())
540 return NULL; // Already selected.
542 switch (N->getOpcode()) {
543 default: break;
544 case ISD::Constant: {
545 unsigned Val = cast<ConstantSDNode>(N)->getZExtValue();
546 bool UseCP = true;
547 if (Subtarget->isThumb())
548 UseCP = (Val > 255 && // MOV
549 ~Val > 255 && // MOV + MVN
550 !ARM_AM::isThumbImmShiftedVal(Val)); // MOV + LSL
551 else
552 UseCP = (ARM_AM::getSOImmVal(Val) == -1 && // MOV
553 ARM_AM::getSOImmVal(~Val) == -1 && // MVN
554 !ARM_AM::isSOImmTwoPartVal(Val)); // two instrs.
555 if (UseCP) {
556 SDValue CPIdx =
557 CurDAG->getTargetConstantPool(ConstantInt::get(Type::Int32Ty, Val),
558 TLI.getPointerTy());
560 SDNode *ResNode;
561 if (Subtarget->isThumb())
562 ResNode = CurDAG->getTargetNode(ARM::tLDRcp, dl, MVT::i32, MVT::Other,
563 CPIdx, CurDAG->getEntryNode());
564 else {
565 SDValue Ops[] = {
566 CPIdx,
567 CurDAG->getRegister(0, MVT::i32),
568 CurDAG->getTargetConstant(0, MVT::i32),
569 getAL(CurDAG),
570 CurDAG->getRegister(0, MVT::i32),
571 CurDAG->getEntryNode()
573 ResNode=CurDAG->getTargetNode(ARM::LDRcp, dl, MVT::i32, MVT::Other,
574 Ops, 6);
576 ReplaceUses(Op, SDValue(ResNode, 0));
577 return NULL;
580 // Other cases are autogenerated.
581 break;
583 case ISD::FrameIndex: {
584 // Selects to ADDri FI, 0 which in turn will become ADDri SP, imm.
585 int FI = cast<FrameIndexSDNode>(N)->getIndex();
586 SDValue TFI = CurDAG->getTargetFrameIndex(FI, TLI.getPointerTy());
587 if (Subtarget->isThumb()) {
588 return CurDAG->SelectNodeTo(N, ARM::tADDrSPi, MVT::i32, TFI,
589 CurDAG->getTargetConstant(0, MVT::i32));
590 } else {
591 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, MVT::i32),
592 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
593 CurDAG->getRegister(0, MVT::i32) };
594 return CurDAG->SelectNodeTo(N, ARM::ADDri, MVT::i32, Ops, 5);
597 case ISD::ADD: {
598 if (!Subtarget->isThumb())
599 break;
600 // Select add sp, c to tADDhirr.
601 SDValue N0 = Op.getOperand(0);
602 SDValue N1 = Op.getOperand(1);
603 RegisterSDNode *LHSR = dyn_cast<RegisterSDNode>(Op.getOperand(0));
604 RegisterSDNode *RHSR = dyn_cast<RegisterSDNode>(Op.getOperand(1));
605 if (LHSR && LHSR->getReg() == ARM::SP) {
606 std::swap(N0, N1);
607 std::swap(LHSR, RHSR);
609 if (RHSR && RHSR->getReg() == ARM::SP) {
610 SDValue Val = SDValue(CurDAG->getTargetNode(ARM::tMOVlor2hir, dl,
611 Op.getValueType(), N0, N0), 0);
612 return CurDAG->SelectNodeTo(N, ARM::tADDhirr, Op.getValueType(), Val, N1);
614 break;
616 case ISD::MUL:
617 if (Subtarget->isThumb())
618 break;
619 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
620 unsigned RHSV = C->getZExtValue();
621 if (!RHSV) break;
622 if (isPowerOf2_32(RHSV-1)) { // 2^n+1?
623 SDValue V = Op.getOperand(0);
624 unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV-1));
625 SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
626 CurDAG->getTargetConstant(ShImm, MVT::i32),
627 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
628 CurDAG->getRegister(0, MVT::i32) };
629 return CurDAG->SelectNodeTo(N, ARM::ADDrs, MVT::i32, Ops, 7);
631 if (isPowerOf2_32(RHSV+1)) { // 2^n-1?
632 SDValue V = Op.getOperand(0);
633 unsigned ShImm = ARM_AM::getSORegOpc(ARM_AM::lsl, Log2_32(RHSV+1));
634 SDValue Ops[] = { V, V, CurDAG->getRegister(0, MVT::i32),
635 CurDAG->getTargetConstant(ShImm, MVT::i32),
636 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
637 CurDAG->getRegister(0, MVT::i32) };
638 return CurDAG->SelectNodeTo(N, ARM::RSBrs, MVT::i32, Ops, 7);
641 break;
642 case ARMISD::FMRRD:
643 return CurDAG->getTargetNode(ARM::FMRRD, dl, MVT::i32, MVT::i32,
644 Op.getOperand(0), getAL(CurDAG),
645 CurDAG->getRegister(0, MVT::i32));
646 case ISD::UMUL_LOHI: {
647 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
648 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
649 CurDAG->getRegister(0, MVT::i32) };
650 return CurDAG->getTargetNode(ARM::UMULL, dl, MVT::i32, MVT::i32, Ops, 5);
652 case ISD::SMUL_LOHI: {
653 SDValue Ops[] = { Op.getOperand(0), Op.getOperand(1),
654 getAL(CurDAG), CurDAG->getRegister(0, MVT::i32),
655 CurDAG->getRegister(0, MVT::i32) };
656 return CurDAG->getTargetNode(ARM::SMULL, dl, MVT::i32, MVT::i32, Ops, 5);
658 case ISD::LOAD: {
659 LoadSDNode *LD = cast<LoadSDNode>(Op);
660 ISD::MemIndexedMode AM = LD->getAddressingMode();
661 MVT LoadedVT = LD->getMemoryVT();
662 if (AM != ISD::UNINDEXED) {
663 SDValue Offset, AMOpc;
664 bool isPre = (AM == ISD::PRE_INC) || (AM == ISD::PRE_DEC);
665 unsigned Opcode = 0;
666 bool Match = false;
667 if (LoadedVT == MVT::i32 &&
668 SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
669 Opcode = isPre ? ARM::LDR_PRE : ARM::LDR_POST;
670 Match = true;
671 } else if (LoadedVT == MVT::i16 &&
672 SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
673 Match = true;
674 Opcode = (LD->getExtensionType() == ISD::SEXTLOAD)
675 ? (isPre ? ARM::LDRSH_PRE : ARM::LDRSH_POST)
676 : (isPre ? ARM::LDRH_PRE : ARM::LDRH_POST);
677 } else if (LoadedVT == MVT::i8 || LoadedVT == MVT::i1) {
678 if (LD->getExtensionType() == ISD::SEXTLOAD) {
679 if (SelectAddrMode3Offset(Op, LD->getOffset(), Offset, AMOpc)) {
680 Match = true;
681 Opcode = isPre ? ARM::LDRSB_PRE : ARM::LDRSB_POST;
683 } else {
684 if (SelectAddrMode2Offset(Op, LD->getOffset(), Offset, AMOpc)) {
685 Match = true;
686 Opcode = isPre ? ARM::LDRB_PRE : ARM::LDRB_POST;
691 if (Match) {
692 SDValue Chain = LD->getChain();
693 SDValue Base = LD->getBasePtr();
694 SDValue Ops[]= { Base, Offset, AMOpc, getAL(CurDAG),
695 CurDAG->getRegister(0, MVT::i32), Chain };
696 return CurDAG->getTargetNode(Opcode, dl, MVT::i32, MVT::i32,
697 MVT::Other, Ops, 6);
700 // Other cases are autogenerated.
701 break;
703 case ARMISD::BRCOND: {
704 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
705 // Emits: (Bcc:void (bb:Other):$dst, (imm:i32):$cc)
706 // Pattern complexity = 6 cost = 1 size = 0
708 // Pattern: (ARMbrcond:void (bb:Other):$dst, (imm:i32):$cc)
709 // Emits: (tBcc:void (bb:Other):$dst, (imm:i32):$cc)
710 // Pattern complexity = 6 cost = 1 size = 0
712 unsigned Opc = Subtarget->isThumb() ? ARM::tBcc : ARM::Bcc;
713 SDValue Chain = Op.getOperand(0);
714 SDValue N1 = Op.getOperand(1);
715 SDValue N2 = Op.getOperand(2);
716 SDValue N3 = Op.getOperand(3);
717 SDValue InFlag = Op.getOperand(4);
718 assert(N1.getOpcode() == ISD::BasicBlock);
719 assert(N2.getOpcode() == ISD::Constant);
720 assert(N3.getOpcode() == ISD::Register);
722 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
723 cast<ConstantSDNode>(N2)->getZExtValue()),
724 MVT::i32);
725 SDValue Ops[] = { N1, Tmp2, N3, Chain, InFlag };
726 SDNode *ResNode = CurDAG->getTargetNode(Opc, dl, MVT::Other,
727 MVT::Flag, Ops, 5);
728 Chain = SDValue(ResNode, 0);
729 if (Op.getNode()->getNumValues() == 2) {
730 InFlag = SDValue(ResNode, 1);
731 ReplaceUses(SDValue(Op.getNode(), 1), InFlag);
733 ReplaceUses(SDValue(Op.getNode(), 0), SDValue(Chain.getNode(), Chain.getResNo()));
734 return NULL;
736 case ARMISD::CMOV: {
737 bool isThumb = Subtarget->isThumb();
738 MVT VT = Op.getValueType();
739 SDValue N0 = Op.getOperand(0);
740 SDValue N1 = Op.getOperand(1);
741 SDValue N2 = Op.getOperand(2);
742 SDValue N3 = Op.getOperand(3);
743 SDValue InFlag = Op.getOperand(4);
744 assert(N2.getOpcode() == ISD::Constant);
745 assert(N3.getOpcode() == ISD::Register);
747 // Pattern: (ARMcmov:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
748 // Emits: (MOVCCs:i32 GPR:i32:$false, so_reg:i32:$true, (imm:i32):$cc)
749 // Pattern complexity = 18 cost = 1 size = 0
750 SDValue CPTmp0;
751 SDValue CPTmp1;
752 SDValue CPTmp2;
753 if (!isThumb && VT == MVT::i32 &&
754 SelectShifterOperandReg(Op, N1, CPTmp0, CPTmp1, CPTmp2)) {
755 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
756 cast<ConstantSDNode>(N2)->getZExtValue()),
757 MVT::i32);
758 SDValue Ops[] = { N0, CPTmp0, CPTmp1, CPTmp2, Tmp2, N3, InFlag };
759 return CurDAG->SelectNodeTo(Op.getNode(), ARM::MOVCCs, MVT::i32, Ops, 7);
762 // Pattern: (ARMcmov:i32 GPR:i32:$false,
763 // (imm:i32)<<P:Predicate_so_imm>><<X:so_imm_XFORM>>:$true,
764 // (imm:i32):$cc)
765 // Emits: (MOVCCi:i32 GPR:i32:$false,
766 // (so_imm_XFORM:i32 (imm:i32):$true), (imm:i32):$cc)
767 // Pattern complexity = 10 cost = 1 size = 0
768 if (VT == MVT::i32 &&
769 N3.getOpcode() == ISD::Constant &&
770 Predicate_so_imm(N3.getNode())) {
771 SDValue Tmp1 = CurDAG->getTargetConstant(((unsigned)
772 cast<ConstantSDNode>(N1)->getZExtValue()),
773 MVT::i32);
774 Tmp1 = Transform_so_imm_XFORM(Tmp1.getNode());
775 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
776 cast<ConstantSDNode>(N2)->getZExtValue()),
777 MVT::i32);
778 SDValue Ops[] = { N0, Tmp1, Tmp2, N3, InFlag };
779 return CurDAG->SelectNodeTo(Op.getNode(), ARM::MOVCCi, MVT::i32, Ops, 5);
782 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
783 // Emits: (MOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
784 // Pattern complexity = 6 cost = 1 size = 0
786 // Pattern: (ARMcmov:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
787 // Emits: (tMOVCCr:i32 GPR:i32:$false, GPR:i32:$true, (imm:i32):$cc)
788 // Pattern complexity = 6 cost = 11 size = 0
790 // Also FCPYScc and FCPYDcc.
791 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
792 cast<ConstantSDNode>(N2)->getZExtValue()),
793 MVT::i32);
794 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag };
795 unsigned Opc = 0;
796 switch (VT.getSimpleVT()) {
797 default: assert(false && "Illegal conditional move type!");
798 break;
799 case MVT::i32:
800 Opc = isThumb ? ARM::tMOVCCr : ARM::MOVCCr;
801 break;
802 case MVT::f32:
803 Opc = ARM::FCPYScc;
804 break;
805 case MVT::f64:
806 Opc = ARM::FCPYDcc;
807 break;
809 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5);
811 case ARMISD::CNEG: {
812 MVT VT = Op.getValueType();
813 SDValue N0 = Op.getOperand(0);
814 SDValue N1 = Op.getOperand(1);
815 SDValue N2 = Op.getOperand(2);
816 SDValue N3 = Op.getOperand(3);
817 SDValue InFlag = Op.getOperand(4);
818 assert(N2.getOpcode() == ISD::Constant);
819 assert(N3.getOpcode() == ISD::Register);
821 SDValue Tmp2 = CurDAG->getTargetConstant(((unsigned)
822 cast<ConstantSDNode>(N2)->getZExtValue()),
823 MVT::i32);
824 SDValue Ops[] = { N0, N1, Tmp2, N3, InFlag };
825 unsigned Opc = 0;
826 switch (VT.getSimpleVT()) {
827 default: assert(false && "Illegal conditional move type!");
828 break;
829 case MVT::f32:
830 Opc = ARM::FNEGScc;
831 break;
832 case MVT::f64:
833 Opc = ARM::FNEGDcc;
834 break;
836 return CurDAG->SelectNodeTo(Op.getNode(), Opc, VT, Ops, 5);
839 case ISD::DECLARE: {
840 SDValue Chain = Op.getOperand(0);
841 SDValue N1 = Op.getOperand(1);
842 SDValue N2 = Op.getOperand(2);
843 FrameIndexSDNode *FINode = dyn_cast<FrameIndexSDNode>(N1);
844 // FIXME: handle VLAs.
845 if (!FINode) {
846 ReplaceUses(Op.getValue(0), Chain);
847 return NULL;
849 if (N2.getOpcode() == ARMISD::PIC_ADD && isa<LoadSDNode>(N2.getOperand(0)))
850 N2 = N2.getOperand(0);
851 LoadSDNode *Ld = dyn_cast<LoadSDNode>(N2);
852 if (!Ld) {
853 ReplaceUses(Op.getValue(0), Chain);
854 return NULL;
856 SDValue BasePtr = Ld->getBasePtr();
857 assert(BasePtr.getOpcode() == ARMISD::Wrapper &&
858 isa<ConstantPoolSDNode>(BasePtr.getOperand(0)) &&
859 "llvm.dbg.variable should be a constantpool node");
860 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(BasePtr.getOperand(0));
861 GlobalValue *GV = 0;
862 if (CP->isMachineConstantPoolEntry()) {
863 ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)CP->getMachineCPVal();
864 GV = ACPV->getGV();
865 } else
866 GV = dyn_cast<GlobalValue>(CP->getConstVal());
867 if (!GV) {
868 ReplaceUses(Op.getValue(0), Chain);
869 return NULL;
872 SDValue Tmp1 = CurDAG->getTargetFrameIndex(FINode->getIndex(),
873 TLI.getPointerTy());
874 SDValue Tmp2 = CurDAG->getTargetGlobalAddress(GV, TLI.getPointerTy());
875 SDValue Ops[] = { Tmp1, Tmp2, Chain };
876 return CurDAG->getTargetNode(TargetInstrInfo::DECLARE, dl,
877 MVT::Other, Ops, 3);
881 return SelectCode(Op);
884 /// createARMISelDag - This pass converts a legalized DAG into a
885 /// ARM-specific DAG, ready for instruction scheduling.
887 FunctionPass *llvm::createARMISelDag(ARMTargetMachine &TM) {
888 return new ARMDAGToDAGISel(TM);