1 //==-- HexagonISelDAGToDAG.cpp - A dag to dag inst selector for Hexagon ----==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines an instruction selector for the Hexagon target.
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "hexagon-isel"
15 #include "HexagonISelLowering.h"
16 #include "HexagonTargetMachine.h"
17 #include "llvm/Intrinsics.h"
18 #include "llvm/CodeGen/SelectionDAGISel.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/Debug.h"
25 //===----------------------------------------------------------------------===//
26 // Instruction Selector Implementation
27 //===----------------------------------------------------------------------===//
29 //===--------------------------------------------------------------------===//
30 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
31 /// instructions for SelectionDAG operations.
34 class HexagonDAGToDAGISel : public SelectionDAGISel {
35 /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
36 /// make the right decision when generating code for different targets.
37 const HexagonSubtarget &Subtarget;
39 // Keep a reference to HexagonTargetMachine.
40 HexagonTargetMachine& TM;
41 const HexagonInstrInfo *TII;
44 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine)
45 : SelectionDAGISel(targetmachine),
46 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
48 TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
52 SDNode *Select(SDNode *N);
54 // Complex Pattern Selectors.
55 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
56 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
57 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
58 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
59 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
60 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
61 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
62 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
63 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
64 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
66 virtual const char *getPassName() const {
67 return "Hexagon DAG->DAG Pattern Instruction Selection";
70 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
71 /// inline asm expressions.
72 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
74 std::vector<SDValue> &OutOps);
75 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
77 SDNode *SelectLoad(SDNode *N);
78 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
79 SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
80 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
82 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
84 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
85 SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
86 SDNode *SelectStore(SDNode *N);
87 SDNode *SelectSHL(SDNode *N);
88 SDNode *SelectSelect(SDNode *N);
89 SDNode *SelectTruncate(SDNode *N);
90 SDNode *SelectMul(SDNode *N);
91 SDNode *SelectZeroExtend(SDNode *N);
92 SDNode *SelectIntrinsicWOChain(SDNode *N);
93 SDNode *SelectConstant(SDNode *N);
94 SDNode *SelectAdd(SDNode *N);
96 // Include the pieces autogenerated from the target description.
97 #include "HexagonGenDAGISel.inc"
99 } // end anonymous namespace
102 /// createHexagonISelDag - This pass converts a legalized DAG into a
103 /// Hexagon-specific DAG, ready for instruction scheduling.
105 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM) {
106 return new HexagonDAGToDAGISel(TM);
109 static bool IsS11_0_Offset(SDNode * S) {
110 ConstantSDNode *N = cast<ConstantSDNode>(S);
112 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
114 int64_t v = (int64_t)N->getSExtValue();
119 static bool IsS11_1_Offset(SDNode * S) {
120 ConstantSDNode *N = cast<ConstantSDNode>(S);
122 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
124 int64_t v = (int64_t)N->getSExtValue();
125 return isShiftedInt<11,1>(v);
129 static bool IsS11_2_Offset(SDNode * S) {
130 ConstantSDNode *N = cast<ConstantSDNode>(S);
132 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
134 int64_t v = (int64_t)N->getSExtValue();
135 return isShiftedInt<11,2>(v);
139 static bool IsS11_3_Offset(SDNode * S) {
140 ConstantSDNode *N = cast<ConstantSDNode>(S);
142 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
144 int64_t v = (int64_t)N->getSExtValue();
145 return isShiftedInt<11,3>(v);
149 static bool IsU6_0_Offset(SDNode * S) {
150 ConstantSDNode *N = cast<ConstantSDNode>(S);
152 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
154 int64_t v = (int64_t)N->getSExtValue();
159 static bool IsU6_1_Offset(SDNode * S) {
160 ConstantSDNode *N = cast<ConstantSDNode>(S);
162 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
164 int64_t v = (int64_t)N->getSExtValue();
165 return isShiftedUInt<6,1>(v);
169 static bool IsU6_2_Offset(SDNode * S) {
170 ConstantSDNode *N = cast<ConstantSDNode>(S);
172 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
174 int64_t v = (int64_t)N->getSExtValue();
175 return isShiftedUInt<6,2>(v);
179 // Intrinsics that return a a predicate.
180 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
185 case Intrinsic::hexagon_C2_cmpeq:
186 case Intrinsic::hexagon_C2_cmpgt:
187 case Intrinsic::hexagon_C2_cmpgtu:
188 case Intrinsic::hexagon_C2_cmpgtup:
189 case Intrinsic::hexagon_C2_cmpgtp:
190 case Intrinsic::hexagon_C2_cmpeqp:
191 case Intrinsic::hexagon_C2_bitsset:
192 case Intrinsic::hexagon_C2_bitsclr:
193 case Intrinsic::hexagon_C2_cmpeqi:
194 case Intrinsic::hexagon_C2_cmpgti:
195 case Intrinsic::hexagon_C2_cmpgtui:
196 case Intrinsic::hexagon_C2_cmpgei:
197 case Intrinsic::hexagon_C2_cmpgeui:
198 case Intrinsic::hexagon_C2_cmplt:
199 case Intrinsic::hexagon_C2_cmpltu:
200 case Intrinsic::hexagon_C2_bitsclri:
201 case Intrinsic::hexagon_C2_and:
202 case Intrinsic::hexagon_C2_or:
203 case Intrinsic::hexagon_C2_xor:
204 case Intrinsic::hexagon_C2_andn:
205 case Intrinsic::hexagon_C2_not:
206 case Intrinsic::hexagon_C2_orn:
207 case Intrinsic::hexagon_C2_pxfer_map:
208 case Intrinsic::hexagon_C2_any8:
209 case Intrinsic::hexagon_C2_all8:
210 case Intrinsic::hexagon_A2_vcmpbeq:
211 case Intrinsic::hexagon_A2_vcmpbgtu:
212 case Intrinsic::hexagon_A2_vcmpheq:
213 case Intrinsic::hexagon_A2_vcmphgt:
214 case Intrinsic::hexagon_A2_vcmphgtu:
215 case Intrinsic::hexagon_A2_vcmpweq:
216 case Intrinsic::hexagon_A2_vcmpwgt:
217 case Intrinsic::hexagon_A2_vcmpwgtu:
218 case Intrinsic::hexagon_C2_tfrrp:
219 case Intrinsic::hexagon_S2_tstbit_i:
220 case Intrinsic::hexagon_S2_tstbit_r:
226 // Intrinsics that have predicate operands.
227 static unsigned doesIntrinsicContainPredicate(unsigned ID)
232 case Intrinsic::hexagon_C2_tfrpr:
233 return Hexagon::TFR_RsPd;
234 case Intrinsic::hexagon_C2_and:
235 return Hexagon::AND_pp;
236 case Intrinsic::hexagon_C2_xor:
237 return Hexagon::XOR_pp;
238 case Intrinsic::hexagon_C2_or:
239 return Hexagon::OR_pp;
240 case Intrinsic::hexagon_C2_not:
241 return Hexagon::NOT_pp;
242 case Intrinsic::hexagon_C2_any8:
243 return Hexagon::ANY_pp;
244 case Intrinsic::hexagon_C2_all8:
245 return Hexagon::ALL_pp;
246 case Intrinsic::hexagon_C2_vitpack:
247 return Hexagon::VITPACK_pp;
248 case Intrinsic::hexagon_C2_mask:
249 return Hexagon::MASK_p;
250 case Intrinsic::hexagon_C2_mux:
251 return Hexagon::MUX_rr;
253 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
254 // that's how it's mapped in q6protos.h.
255 case Intrinsic::hexagon_C2_muxir:
256 return Hexagon::MUX_ri;
258 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
259 // that's how it's mapped in q6protos.h.
260 case Intrinsic::hexagon_C2_muxri:
261 return Hexagon::MUX_ir;
263 case Intrinsic::hexagon_C2_muxii:
264 return Hexagon::MUX_ii;
265 case Intrinsic::hexagon_C2_vmux:
266 return Hexagon::VMUX_prr64;
267 case Intrinsic::hexagon_S2_valignrb:
268 return Hexagon::VALIGN_rrp;
269 case Intrinsic::hexagon_S2_vsplicerb:
270 return Hexagon::VSPLICE_rrp;
275 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
276 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
279 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
282 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
285 if (MemType == MVT::i8 && isInt<11>(Offset)) {
293 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
294 // lowering for GlobalAddress nodes has already turned it into a
297 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
298 SDValue Chain = LD->getChain();
299 SDNode* Const32 = LD->getBasePtr().getNode();
302 if (Const32->getOpcode() == HexagonISD::CONST32 &&
303 ISD::isNormalLoad(LD)) {
304 SDValue Base = Const32->getOperand(0);
305 EVT LoadedVT = LD->getMemoryVT();
306 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
307 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
308 MVT PointerTy = TLI.getPointerTy();
309 const GlobalValue* GV =
310 cast<GlobalAddressSDNode>(Base)->getGlobal();
312 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
313 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
316 // Figure out base + offset opcode
317 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
318 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
319 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
320 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
321 else assert (0 && "unknown memory type");
323 // Build indexed load.
324 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
325 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
331 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
332 MemOp[0] = LD->getMemOperand();
333 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
334 ReplaceUses(LD, Result);
339 return SelectCode(LD);
343 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
347 SDValue Chain = LD->getChain();
348 EVT LoadedVT = LD->getMemoryVT();
349 SDValue Base = LD->getBasePtr();
350 SDValue Offset = LD->getOffset();
351 SDNode *OffsetNode = Offset.getNode();
352 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
353 SDValue N1 = LD->getOperand(1);
356 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
357 N1.getNode()->getValueType(0) == MVT::i32) {
358 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
359 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
360 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
361 MVT::Other, Base, TargetConst,
363 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
364 SDValue(Result_1, 0));
365 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
366 MemOp[0] = LD->getMemOperand();
367 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
368 const SDValue Froms[] = { SDValue(LD, 0),
372 const SDValue Tos[] = { SDValue(Result_2, 0),
373 SDValue(Result_1, 1),
376 ReplaceUses(Froms, Tos, 3);
379 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
380 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
381 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
382 MVT::Other, Base, TargetConst0,
384 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
385 MVT::i64, SDValue(Result_1, 0));
386 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
387 MVT::i32, Base, TargetConstVal,
388 SDValue(Result_1, 1));
389 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
390 MemOp[0] = LD->getMemOperand();
391 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
392 const SDValue Froms[] = { SDValue(LD, 0),
396 const SDValue Tos[] = { SDValue(Result_2, 0),
397 SDValue(Result_3, 0),
400 ReplaceUses(Froms, Tos, 3);
403 return SelectCode(LD);
407 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
411 SDValue Chain = LD->getChain();
412 EVT LoadedVT = LD->getMemoryVT();
413 SDValue Base = LD->getBasePtr();
414 SDValue Offset = LD->getOffset();
415 SDNode *OffsetNode = Offset.getNode();
416 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
417 SDValue N1 = LD->getOperand(1);
420 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
421 N1.getNode()->getValueType(0) == MVT::i32) {
422 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
423 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
424 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
425 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
426 MVT::i32, MVT::Other, Base,
427 TargetConstVal, Chain);
428 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
430 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
431 MVT::i64, MVT::Other,
433 SDValue(Result_1,0));
434 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
435 MemOp[0] = LD->getMemOperand();
436 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
437 const SDValue Froms[] = { SDValue(LD, 0),
441 const SDValue Tos[] = { SDValue(Result_3, 0),
442 SDValue(Result_1, 1),
445 ReplaceUses(Froms, Tos, 3);
449 // Generate an indirect load.
450 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
451 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
452 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
454 Base, TargetConst0, Chain);
455 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
457 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
458 MVT::i64, MVT::Other,
460 SDValue(Result_1,0));
461 // Add offset to base.
462 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
463 Base, TargetConstVal,
464 SDValue(Result_1, 1));
465 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
466 MemOp[0] = LD->getMemOperand();
467 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
468 const SDValue Froms[] = { SDValue(LD, 0),
472 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
473 SDValue(Result_4, 0), // New address.
476 ReplaceUses(Froms, Tos, 3);
480 return SelectCode(LD);
484 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
485 SDValue Chain = LD->getChain();
486 SDValue Base = LD->getBasePtr();
487 SDValue Offset = LD->getOffset();
488 SDNode *OffsetNode = Offset.getNode();
489 // Get the constant value.
490 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
491 EVT LoadedVT = LD->getMemoryVT();
494 // Check for zero ext loads.
495 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
497 // Figure out the opcode.
498 if (LoadedVT == MVT::i64) {
499 if (TII->isValidAutoIncImm(LoadedVT, Val))
500 Opcode = Hexagon::POST_LDrid;
502 Opcode = Hexagon::LDrid;
503 } else if (LoadedVT == MVT::i32) {
504 if (TII->isValidAutoIncImm(LoadedVT, Val))
505 Opcode = Hexagon::POST_LDriw;
507 Opcode = Hexagon::LDriw;
508 } else if (LoadedVT == MVT::i16) {
509 if (TII->isValidAutoIncImm(LoadedVT, Val))
510 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
512 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
513 } else if (LoadedVT == MVT::i8) {
514 if (TII->isValidAutoIncImm(LoadedVT, Val))
515 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
517 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
519 assert (0 && "unknown memory type");
521 // For zero ext i64 loads, we need to add combine instructions.
522 if (LD->getValueType(0) == MVT::i64 &&
523 LD->getExtensionType() == ISD::ZEXTLOAD) {
524 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
526 if (LD->getValueType(0) == MVT::i64 &&
527 LD->getExtensionType() == ISD::SEXTLOAD) {
528 // Handle sign ext i64 loads.
529 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
531 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
532 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
533 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
535 MVT::i32, MVT::Other, Base,
536 TargetConstVal, Chain);
537 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
538 MemOp[0] = LD->getMemOperand();
539 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
540 const SDValue Froms[] = { SDValue(LD, 0),
544 const SDValue Tos[] = { SDValue(Result, 0),
548 ReplaceUses(Froms, Tos, 3);
551 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
552 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
553 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
555 MVT::Other, Base, TargetConst0,
557 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
558 Base, TargetConstVal,
559 SDValue(Result_1, 1));
560 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
561 MemOp[0] = LD->getMemOperand();
562 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
563 const SDValue Froms[] = { SDValue(LD, 0),
567 const SDValue Tos[] = { SDValue(Result_1, 0),
568 SDValue(Result_2, 0),
571 ReplaceUses(Froms, Tos, 3);
575 return SelectCode(LD);
579 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
581 DebugLoc dl = N->getDebugLoc();
582 LoadSDNode *LD = cast<LoadSDNode>(N);
583 ISD::MemIndexedMode AM = LD->getAddressingMode();
585 // Handle indexed loads.
586 if (AM != ISD::UNINDEXED) {
587 result = SelectIndexedLoad(LD, dl);
589 result = SelectBaseOffsetLoad(LD, dl);
596 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
597 SDValue Chain = ST->getChain();
598 SDValue Base = ST->getBasePtr();
599 SDValue Offset = ST->getOffset();
600 SDValue Value = ST->getValue();
601 SDNode *OffsetNode = Offset.getNode();
602 // Get the constant value.
603 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
604 EVT StoredVT = ST->getMemoryVT();
606 // Offset value must be within representable range
607 // and must have correct alignment properties.
608 if (TII->isValidAutoIncImm(StoredVT, Val)) {
609 SDValue Ops[] = { Value, Base,
610 CurDAG->getTargetConstant(Val, MVT::i32), Chain};
613 // Figure out the post inc version of opcode.
614 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
615 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
616 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
617 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
618 else assert (0 && "unknown memory type");
620 // Build post increment store.
621 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
623 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
624 MemOp[0] = ST->getMemOperand();
625 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
627 ReplaceUses(ST, Result);
628 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
632 // Note: Order of operands matches the def of instruction:
633 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
634 // and it differs for POST_ST* for instance.
635 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
639 // Figure out the opcode.
640 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
641 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw;
642 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
643 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
644 else assert (0 && "unknown memory type");
646 // Build regular store.
647 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
648 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
650 // Build splitted incriment instruction.
651 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
654 SDValue(Result_1, 0));
655 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
656 MemOp[0] = ST->getMemOperand();
657 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
659 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
660 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
665 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
667 SDValue Chain = ST->getChain();
668 SDNode* Const32 = ST->getBasePtr().getNode();
669 SDValue Value = ST->getValue();
672 // Try to lower stores of GlobalAdresses into indexed stores. Custom
673 // lowering for GlobalAddress nodes has already turned it into a
674 // CONST32. Avoid truncating stores for the moment. Post-inc stores
675 // do the same. Don't think there's a reason for it, so will file a
677 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
678 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
679 SDValue Base = Const32->getOperand(0);
680 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
681 EVT StoredVT = ST->getMemoryVT();
682 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
683 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
684 MVT PointerTy = TLI.getPointerTy();
685 const GlobalValue* GV =
686 cast<GlobalAddressSDNode>(Base)->getGlobal();
688 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
689 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
693 // Figure out base + offset opcode
694 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
695 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
696 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
697 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
698 else assert (0 && "unknown memory type");
700 SDValue Ops[] = {SDValue(NewBase,0),
701 CurDAG->getTargetConstant(Offset,PointerTy),
703 // build indexed store
704 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
706 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
707 MemOp[0] = ST->getMemOperand();
708 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
709 ReplaceUses(ST, Result);
715 return SelectCode(ST);
719 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
720 DebugLoc dl = N->getDebugLoc();
721 StoreSDNode *ST = cast<StoreSDNode>(N);
722 ISD::MemIndexedMode AM = ST->getAddressingMode();
724 // Handle indexed stores.
725 if (AM != ISD::UNINDEXED) {
726 return SelectIndexedStore(ST, dl);
729 return SelectBaseOffsetStore(ST, dl);
732 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
733 DebugLoc dl = N->getDebugLoc();
736 // %conv.i = sext i32 %tmp1 to i64
737 // %conv2.i = sext i32 %add to i64
738 // %mul.i = mul nsw i64 %conv2.i, %conv.i
740 // --- match with the following ---
742 // %mul.i = mpy (%tmp1, %add)
745 if (N->getValueType(0) == MVT::i64) {
746 // Shifting a i64 signed multiply.
747 SDValue MulOp0 = N->getOperand(0);
748 SDValue MulOp1 = N->getOperand(1);
753 // Handle sign_extend and sextload.
754 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
755 SDValue Sext0 = MulOp0.getOperand(0);
756 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
761 } else if (MulOp0.getOpcode() == ISD::LOAD) {
762 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
763 if (LD->getMemoryVT() != MVT::i32 ||
764 LD->getExtensionType() != ISD::SEXTLOAD ||
765 LD->getAddressingMode() != ISD::UNINDEXED) {
769 SDValue Chain = LD->getChain();
770 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
771 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
773 LD->getBasePtr(), TargetConst0,
776 return SelectCode(N);
779 // Same goes for the second operand.
780 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
781 SDValue Sext1 = MulOp1.getOperand(0);
782 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
783 return SelectCode(N);
787 } else if (MulOp1.getOpcode() == ISD::LOAD) {
788 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
789 if (LD->getMemoryVT() != MVT::i32 ||
790 LD->getExtensionType() != ISD::SEXTLOAD ||
791 LD->getAddressingMode() != ISD::UNINDEXED) {
792 return SelectCode(N);
795 SDValue Chain = LD->getChain();
796 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
797 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
799 LD->getBasePtr(), TargetConst0,
802 return SelectCode(N);
805 // Generate a mpy instruction.
806 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
808 ReplaceUses(N, Result);
812 return SelectCode(N);
816 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
817 DebugLoc dl = N->getDebugLoc();
818 SDValue N0 = N->getOperand(0);
819 if (N0.getOpcode() == ISD::SETCC) {
820 SDValue N00 = N0.getOperand(0);
821 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
822 SDValue N000 = N00.getOperand(0);
823 SDValue N001 = N00.getOperand(1);
824 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
825 SDValue N01 = N0.getOperand(1);
826 SDValue N02 = N0.getOperand(2);
828 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
829 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
830 // IntRegs:i32:$src2)
831 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
832 // Pattern complexity = 9 cost = 1 size = 0.
833 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
834 SDValue N1 = N->getOperand(1);
836 SDValue N2 = N->getOperand(2);
838 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
839 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
840 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
842 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
844 SDValue(SextNode, 0),
846 ReplaceUses(N, Result);
852 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
853 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
854 // IntRegs:i32:$src2)
855 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
856 // Pattern complexity = 9 cost = 1 size = 0.
857 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
858 SDValue N1 = N->getOperand(1);
860 SDValue N2 = N->getOperand(2);
862 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
863 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
864 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
866 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
868 SDValue(SextNode, 0),
870 ReplaceUses(N, Result);
879 return SelectCode(N);
883 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
884 DebugLoc dl = N->getDebugLoc();
885 SDValue Shift = N->getOperand(0);
888 // %conv.i = sext i32 %tmp1 to i64
889 // %conv2.i = sext i32 %add to i64
890 // %mul.i = mul nsw i64 %conv2.i, %conv.i
891 // %shr5.i = lshr i64 %mul.i, 32
892 // %conv3.i = trunc i64 %shr5.i to i32
894 // --- match with the following ---
896 // %conv3.i = mpy (%tmp1, %add)
899 if (N->getValueType(0) == MVT::i32) {
901 if (Shift.getNode()->getValueType(0) == MVT::i64) {
902 // Trunc child is logical shift right.
903 if (Shift.getOpcode() != ISD::SRL) {
904 return SelectCode(N);
907 SDValue ShiftOp0 = Shift.getOperand(0);
908 SDValue ShiftOp1 = Shift.getOperand(1);
911 if (ShiftOp1.getOpcode() != ISD::Constant) {
912 return SelectCode(N);
916 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
917 if (ShiftConst != 32) {
918 return SelectCode(N);
921 // Shifting a i64 signed multiply
922 SDValue Mul = ShiftOp0;
923 if (Mul.getOpcode() != ISD::MUL) {
924 return SelectCode(N);
927 SDValue MulOp0 = Mul.getOperand(0);
928 SDValue MulOp1 = Mul.getOperand(1);
933 // Handle sign_extend and sextload
934 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
935 SDValue Sext0 = MulOp0.getOperand(0);
936 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
937 return SelectCode(N);
941 } else if (MulOp0.getOpcode() == ISD::LOAD) {
942 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
943 if (LD->getMemoryVT() != MVT::i32 ||
944 LD->getExtensionType() != ISD::SEXTLOAD ||
945 LD->getAddressingMode() != ISD::UNINDEXED) {
946 return SelectCode(N);
949 SDValue Chain = LD->getChain();
950 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
951 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
954 TargetConst0, Chain), 0);
956 return SelectCode(N);
959 // Same goes for the second operand.
960 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
961 SDValue Sext1 = MulOp1.getOperand(0);
962 if (Sext1.getNode()->getValueType(0) != MVT::i32)
963 return SelectCode(N);
966 } else if (MulOp1.getOpcode() == ISD::LOAD) {
967 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
968 if (LD->getMemoryVT() != MVT::i32 ||
969 LD->getExtensionType() != ISD::SEXTLOAD ||
970 LD->getAddressingMode() != ISD::UNINDEXED) {
971 return SelectCode(N);
974 SDValue Chain = LD->getChain();
975 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
976 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
979 TargetConst0, Chain), 0);
981 return SelectCode(N);
984 // Generate a mpy instruction.
985 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
987 ReplaceUses(N, Result);
992 return SelectCode(N);
996 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
997 DebugLoc dl = N->getDebugLoc();
998 if (N->getValueType(0) == MVT::i32) {
999 SDValue Shl_0 = N->getOperand(0);
1000 SDValue Shl_1 = N->getOperand(1);
1002 if (Shl_1.getOpcode() == ISD::Constant) {
1003 if (Shl_0.getOpcode() == ISD::MUL) {
1004 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1005 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1006 // RHS of mul is const.
1007 if (Mul_1.getOpcode() == ISD::Constant) {
1009 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1011 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1012 int32_t ValConst = MulConst << ShlConst;
1013 SDValue Val = CurDAG->getTargetConstant(ValConst,
1015 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1016 if (isInt<9>(CN->getSExtValue())) {
1018 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1019 MVT::i32, Mul_0, Val);
1020 ReplaceUses(N, Result);
1025 } else if (Shl_0.getOpcode() == ISD::SUB) {
1026 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1027 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1028 if (Sub_0.getOpcode() == ISD::Constant) {
1030 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1031 if (SubConst == 0) {
1032 if (Sub_1.getOpcode() == ISD::SHL) {
1033 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1034 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1035 if (Shl2_1.getOpcode() == ISD::Constant) {
1037 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1039 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1040 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1041 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1042 if (ConstantSDNode *CN =
1043 dyn_cast<ConstantSDNode>(Val.getNode()))
1044 if (isInt<9>(CN->getSExtValue())) {
1046 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1048 ReplaceUses(N, Result);
1058 return SelectCode(N);
1063 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1064 // result of the intrinsic is predicate); convert the zero_extend to
1065 // transfer instruction.
1067 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1068 // converted into a MUX as predicate registers defined as 1 bit in the
1069 // compiler. Architecture defines them as 8-bit registers.
1070 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1072 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1073 DebugLoc dl = N->getDebugLoc();
1074 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1075 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1077 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1078 if (doesIntrinsicReturnPredicate(ID)) {
1079 // Now we need to differentiate target data types.
1080 if (N->getValueType(0) == MVT::i64) {
1081 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1082 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1083 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1085 SDValue(IsIntrinsic, 0));
1086 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1089 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1090 MVT::i64, MVT::Other,
1091 SDValue(Result_2, 0),
1092 SDValue(Result_1, 0));
1093 ReplaceUses(N, Result_3);
1096 if (N->getValueType(0) == MVT::i32) {
1097 // Convert the zero_extend to Rs = Pd
1098 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1100 SDValue(IsIntrinsic, 0));
1101 ReplaceUses(N, RsPd);
1104 assert(0 && "Unexpected value type");
1107 return SelectCode(N);
1112 // Checking for intrinsics which have predicate registers as operand(s)
1113 // and lowering to the actual intrinsic.
1115 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1116 DebugLoc dl = N->getDebugLoc();
1117 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1118 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1120 // We are concerned with only those intrinsics that have predicate registers
1121 // as at least one of the operands.
1122 if (IntrinsicWithPred) {
1123 SmallVector<SDValue, 8> Ops;
1124 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1125 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1127 // Iterate over all the operands of the intrinsics.
1128 // For PredRegs, do the transfer.
1129 // For Double/Int Regs, just preserve the value
1130 // For immediates, lower it.
1131 for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1132 SDNode *Arg = N->getOperand(i).getNode();
1133 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI);
1135 if (RC == Hexagon::IntRegsRegisterClass ||
1136 RC == Hexagon::DoubleRegsRegisterClass) {
1137 Ops.push_back(SDValue(Arg, 0));
1138 } else if (RC == Hexagon::PredRegsRegisterClass) {
1140 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1142 Ops.push_back(SDValue(PdRs,0));
1143 } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
1144 // This is immediate operand. Lower it here making sure that we DO have
1145 // const SDNode for immediate value.
1146 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1147 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1148 Ops.push_back(SDVal);
1150 assert(0 && "Unimplemented");
1153 EVT ReturnValueVT = N->getValueType(0);
1154 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1156 Ops.data(), Ops.size());
1157 ReplaceUses(N, Result);
1160 return SelectCode(N);
1165 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1167 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1168 DebugLoc dl = N->getDebugLoc();
1169 if (N->getValueType(0) == MVT::i1) {
1171 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1173 // Create the IntReg = 1 node.
1175 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1176 CurDAG->getTargetConstant(0, MVT::i32));
1179 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1180 SDValue(IntRegTFR, 0));
1183 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_pp, dl, MVT::i1,
1187 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1188 SDValue(Pd, 0), SDValue(NotPd, 0));
1190 // We have just built:
1192 // Pd = xor(not(Pd), Pd)
1194 ReplaceUses(N, Result);
1199 return SelectCode(N);
1204 // Map add followed by a asr -> asr +=.
1206 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1207 DebugLoc dl = N->getDebugLoc();
1208 if (N->getValueType(0) != MVT::i32) {
1209 return SelectCode(N);
1211 // Identify nodes of the form: add(asr(...)).
1212 SDNode* Src1 = N->getOperand(0).getNode();
1213 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1214 || Src1->getValueType(0) != MVT::i32) {
1215 return SelectCode(N);
1218 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1219 // Rd and Rd' are assigned to the same register
1220 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_rr_acc, dl, MVT::i32,
1222 Src1->getOperand(0),
1223 Src1->getOperand(1));
1224 ReplaceUses(N, Result);
1230 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1231 if (N->isMachineOpcode())
1232 return NULL; // Already selected.
1235 switch (N->getOpcode()) {
1237 return SelectConstant(N);
1240 return SelectAdd(N);
1243 return SelectSHL(N);
1246 return SelectLoad(N);
1249 return SelectStore(N);
1252 return SelectSelect(N);
1255 return SelectTruncate(N);
1258 return SelectMul(N);
1260 case ISD::ZERO_EXTEND:
1261 return SelectZeroExtend(N);
1263 case ISD::INTRINSIC_WO_CHAIN:
1264 return SelectIntrinsicWOChain(N);
1267 return SelectCode(N);
1272 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1273 // to define these instructions.
1275 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1277 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1278 Addr.getOpcode() == ISD::TargetGlobalAddress)
1279 return false; // Direct calls.
1281 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1282 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1283 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1287 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1292 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1294 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1295 Addr.getOpcode() == ISD::TargetGlobalAddress)
1296 return false; // Direct calls.
1298 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1299 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1300 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1301 return (IsS11_0_Offset(Offset.getNode()));
1304 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1305 return (IsS11_0_Offset(Offset.getNode()));
1309 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1311 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1312 Addr.getOpcode() == ISD::TargetGlobalAddress)
1313 return false; // Direct calls.
1315 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1316 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1317 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1318 return (IsS11_1_Offset(Offset.getNode()));
1321 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1322 return (IsS11_1_Offset(Offset.getNode()));
1326 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1328 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1329 Addr.getOpcode() == ISD::TargetGlobalAddress)
1330 return false; // Direct calls.
1332 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1333 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1334 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1335 return (IsS11_2_Offset(Offset.getNode()));
1338 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1339 return (IsS11_2_Offset(Offset.getNode()));
1343 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1345 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1346 Addr.getOpcode() == ISD::TargetGlobalAddress)
1347 return false; // Direct calls.
1349 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1350 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1351 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1352 return (IsU6_0_Offset(Offset.getNode()));
1355 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1356 return (IsU6_0_Offset(Offset.getNode()));
1360 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1362 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1363 Addr.getOpcode() == ISD::TargetGlobalAddress)
1364 return false; // Direct calls.
1366 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1367 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1368 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1369 return (IsU6_1_Offset(Offset.getNode()));
1372 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1373 return (IsU6_1_Offset(Offset.getNode()));
1377 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1379 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1380 Addr.getOpcode() == ISD::TargetGlobalAddress)
1381 return false; // Direct calls.
1383 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1384 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1385 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1386 return (IsU6_2_Offset(Offset.getNode()));
1389 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1390 return (IsU6_2_Offset(Offset.getNode()));
1394 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1397 if (Addr.getOpcode() != ISD::ADD) {
1398 return(SelectADDRriS11_2(Addr, Base, Offset));
1401 return SelectADDRriS11_2(Addr, Base, Offset);
1405 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1407 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1408 Addr.getOpcode() == ISD::TargetGlobalAddress)
1409 return false; // Direct calls.
1411 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1412 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1413 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1414 return (IsS11_3_Offset(Offset.getNode()));
1417 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1418 return (IsS11_3_Offset(Offset.getNode()));
1421 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1423 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1424 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1425 Addr.getOpcode() == ISD::TargetGlobalAddress)
1426 return false; // Direct calls.
1428 if (Addr.getOpcode() == ISD::ADD) {
1429 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1430 if (isInt<13>(CN->getSExtValue()))
1431 return false; // Let the reg+imm pattern catch this!
1432 R1 = Addr.getOperand(0);
1433 R2 = Addr.getOperand(1);
1443 // Handle generic address case. It is accessed from inlined asm =m constraints,
1444 // which could have any kind of pointer.
1445 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1446 SDValue &Base, SDValue &Offset) {
1447 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1448 Addr.getOpcode() == ISD::TargetGlobalAddress)
1449 return false; // Direct calls.
1451 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1452 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1453 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1457 if (Addr.getOpcode() == ISD::ADD) {
1458 Base = Addr.getOperand(0);
1459 Offset = Addr.getOperand(1);
1464 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1469 bool HexagonDAGToDAGISel::
1470 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1471 std::vector<SDValue> &OutOps) {
1474 switch (ConstraintCode) {
1475 case 'o': // Offsetable.
1476 case 'v': // Not offsetable.
1477 default: return true;
1478 case 'm': // Memory.
1479 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1484 OutOps.push_back(Op0);
1485 OutOps.push_back(Op1);