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 *SelectIntrinsicWChain(SDNode *N);
94 SDNode *SelectConstant(SDNode *N);
95 SDNode *SelectConstantFP(SDNode *N);
96 SDNode *SelectAdd(SDNode *N);
97 bool isConstExtProfitable(SDNode *N) const;
99 // Include the pieces autogenerated from the target description.
100 #include "HexagonGenDAGISel.inc"
102 } // end anonymous namespace
105 /// createHexagonISelDag - This pass converts a legalized DAG into a
106 /// Hexagon-specific DAG, ready for instruction scheduling.
108 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM) {
109 return new HexagonDAGToDAGISel(TM);
112 static bool IsS11_0_Offset(SDNode * S) {
113 ConstantSDNode *N = cast<ConstantSDNode>(S);
115 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
117 int64_t v = (int64_t)N->getSExtValue();
122 static bool IsS11_1_Offset(SDNode * S) {
123 ConstantSDNode *N = cast<ConstantSDNode>(S);
125 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
127 int64_t v = (int64_t)N->getSExtValue();
128 return isShiftedInt<11,1>(v);
132 static bool IsS11_2_Offset(SDNode * S) {
133 ConstantSDNode *N = cast<ConstantSDNode>(S);
135 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
137 int64_t v = (int64_t)N->getSExtValue();
138 return isShiftedInt<11,2>(v);
142 static bool IsS11_3_Offset(SDNode * S) {
143 ConstantSDNode *N = cast<ConstantSDNode>(S);
145 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
147 int64_t v = (int64_t)N->getSExtValue();
148 return isShiftedInt<11,3>(v);
152 static bool IsU6_0_Offset(SDNode * S) {
153 ConstantSDNode *N = cast<ConstantSDNode>(S);
155 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
157 int64_t v = (int64_t)N->getSExtValue();
162 static bool IsU6_1_Offset(SDNode * S) {
163 ConstantSDNode *N = cast<ConstantSDNode>(S);
165 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
167 int64_t v = (int64_t)N->getSExtValue();
168 return isShiftedUInt<6,1>(v);
172 static bool IsU6_2_Offset(SDNode * S) {
173 ConstantSDNode *N = cast<ConstantSDNode>(S);
175 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
177 int64_t v = (int64_t)N->getSExtValue();
178 return isShiftedUInt<6,2>(v);
182 // Intrinsics that return a a predicate.
183 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
188 case Intrinsic::hexagon_C2_cmpeq:
189 case Intrinsic::hexagon_C2_cmpgt:
190 case Intrinsic::hexagon_C2_cmpgtu:
191 case Intrinsic::hexagon_C2_cmpgtup:
192 case Intrinsic::hexagon_C2_cmpgtp:
193 case Intrinsic::hexagon_C2_cmpeqp:
194 case Intrinsic::hexagon_C2_bitsset:
195 case Intrinsic::hexagon_C2_bitsclr:
196 case Intrinsic::hexagon_C2_cmpeqi:
197 case Intrinsic::hexagon_C2_cmpgti:
198 case Intrinsic::hexagon_C2_cmpgtui:
199 case Intrinsic::hexagon_C2_cmpgei:
200 case Intrinsic::hexagon_C2_cmpgeui:
201 case Intrinsic::hexagon_C2_cmplt:
202 case Intrinsic::hexagon_C2_cmpltu:
203 case Intrinsic::hexagon_C2_bitsclri:
204 case Intrinsic::hexagon_C2_and:
205 case Intrinsic::hexagon_C2_or:
206 case Intrinsic::hexagon_C2_xor:
207 case Intrinsic::hexagon_C2_andn:
208 case Intrinsic::hexagon_C2_not:
209 case Intrinsic::hexagon_C2_orn:
210 case Intrinsic::hexagon_C2_pxfer_map:
211 case Intrinsic::hexagon_C2_any8:
212 case Intrinsic::hexagon_C2_all8:
213 case Intrinsic::hexagon_A2_vcmpbeq:
214 case Intrinsic::hexagon_A2_vcmpbgtu:
215 case Intrinsic::hexagon_A2_vcmpheq:
216 case Intrinsic::hexagon_A2_vcmphgt:
217 case Intrinsic::hexagon_A2_vcmphgtu:
218 case Intrinsic::hexagon_A2_vcmpweq:
219 case Intrinsic::hexagon_A2_vcmpwgt:
220 case Intrinsic::hexagon_A2_vcmpwgtu:
221 case Intrinsic::hexagon_C2_tfrrp:
222 case Intrinsic::hexagon_S2_tstbit_i:
223 case Intrinsic::hexagon_S2_tstbit_r:
229 // Intrinsics that have predicate operands.
230 static unsigned doesIntrinsicContainPredicate(unsigned ID)
235 case Intrinsic::hexagon_C2_tfrpr:
236 return Hexagon::TFR_RsPd;
237 case Intrinsic::hexagon_C2_and:
238 return Hexagon::AND_pp;
239 case Intrinsic::hexagon_C2_xor:
240 return Hexagon::XOR_pp;
241 case Intrinsic::hexagon_C2_or:
242 return Hexagon::OR_pp;
243 case Intrinsic::hexagon_C2_not:
244 return Hexagon::NOT_p;
245 case Intrinsic::hexagon_C2_any8:
246 return Hexagon::ANY_pp;
247 case Intrinsic::hexagon_C2_all8:
248 return Hexagon::ALL_pp;
249 case Intrinsic::hexagon_C2_vitpack:
250 return Hexagon::VITPACK_pp;
251 case Intrinsic::hexagon_C2_mask:
252 return Hexagon::MASK_p;
253 case Intrinsic::hexagon_C2_mux:
254 return Hexagon::MUX_rr;
256 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
257 // that's how it's mapped in q6protos.h.
258 case Intrinsic::hexagon_C2_muxir:
259 return Hexagon::MUX_ri;
261 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
262 // that's how it's mapped in q6protos.h.
263 case Intrinsic::hexagon_C2_muxri:
264 return Hexagon::MUX_ir;
266 case Intrinsic::hexagon_C2_muxii:
267 return Hexagon::MUX_ii;
268 case Intrinsic::hexagon_C2_vmux:
269 return Hexagon::VMUX_prr64;
270 case Intrinsic::hexagon_S2_valignrb:
271 return Hexagon::VALIGN_rrp;
272 case Intrinsic::hexagon_S2_vsplicerb:
273 return Hexagon::VSPLICE_rrp;
278 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
279 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
282 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
285 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
288 if (MemType == MVT::i8 && isInt<11>(Offset)) {
296 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
297 // lowering for GlobalAddress nodes has already turned it into a
300 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
301 SDValue Chain = LD->getChain();
302 SDNode* Const32 = LD->getBasePtr().getNode();
305 if (Const32->getOpcode() == HexagonISD::CONST32 &&
306 ISD::isNormalLoad(LD)) {
307 SDValue Base = Const32->getOperand(0);
308 EVT LoadedVT = LD->getMemoryVT();
309 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
310 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
311 MVT PointerTy = TLI.getPointerTy();
312 const GlobalValue* GV =
313 cast<GlobalAddressSDNode>(Base)->getGlobal();
315 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
317 if (Subtarget.hasV4TOps())
318 NewBase = CurDAG->getMachineNode(Hexagon::TFRI_V4,
319 dl, PointerTy, TargAddr);
321 NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
322 dl, PointerTy, TargAddr);
323 // Figure out base + offset opcode
324 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
325 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
326 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
327 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
328 else llvm_unreachable("unknown memory type");
330 // Build indexed load.
331 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
332 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
338 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
339 MemOp[0] = LD->getMemOperand();
340 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
341 ReplaceUses(LD, Result);
346 return SelectCode(LD);
350 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
354 SDValue Chain = LD->getChain();
355 EVT LoadedVT = LD->getMemoryVT();
356 SDValue Base = LD->getBasePtr();
357 SDValue Offset = LD->getOffset();
358 SDNode *OffsetNode = Offset.getNode();
359 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
360 SDValue N1 = LD->getOperand(1);
363 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
364 N1.getNode()->getValueType(0) == MVT::i32) {
365 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
366 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
367 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
368 MVT::Other, Base, TargetConst,
370 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
371 SDValue(Result_1, 0));
372 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
373 MemOp[0] = LD->getMemOperand();
374 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
375 const SDValue Froms[] = { SDValue(LD, 0),
379 const SDValue Tos[] = { SDValue(Result_2, 0),
380 SDValue(Result_1, 1),
383 ReplaceUses(Froms, Tos, 3);
386 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
387 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
388 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
389 MVT::Other, Base, TargetConst0,
391 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
392 MVT::i64, SDValue(Result_1, 0));
393 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
394 MVT::i32, Base, TargetConstVal,
395 SDValue(Result_1, 1));
396 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
397 MemOp[0] = LD->getMemOperand();
398 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
399 const SDValue Froms[] = { SDValue(LD, 0),
403 const SDValue Tos[] = { SDValue(Result_2, 0),
404 SDValue(Result_3, 0),
407 ReplaceUses(Froms, Tos, 3);
410 return SelectCode(LD);
414 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
418 SDValue Chain = LD->getChain();
419 EVT LoadedVT = LD->getMemoryVT();
420 SDValue Base = LD->getBasePtr();
421 SDValue Offset = LD->getOffset();
422 SDNode *OffsetNode = Offset.getNode();
423 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
424 SDValue N1 = LD->getOperand(1);
427 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
428 N1.getNode()->getValueType(0) == MVT::i32) {
429 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
430 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
431 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
432 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
433 MVT::i32, MVT::Other, Base,
434 TargetConstVal, Chain);
435 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
437 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
438 MVT::i64, MVT::Other,
440 SDValue(Result_1,0));
441 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
442 MemOp[0] = LD->getMemOperand();
443 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
444 const SDValue Froms[] = { SDValue(LD, 0),
448 const SDValue Tos[] = { SDValue(Result_3, 0),
449 SDValue(Result_1, 1),
452 ReplaceUses(Froms, Tos, 3);
456 // Generate an indirect load.
457 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
458 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
459 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
461 Base, TargetConst0, Chain);
462 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
464 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
465 MVT::i64, MVT::Other,
467 SDValue(Result_1,0));
468 // Add offset to base.
469 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
470 Base, TargetConstVal,
471 SDValue(Result_1, 1));
472 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
473 MemOp[0] = LD->getMemOperand();
474 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
475 const SDValue Froms[] = { SDValue(LD, 0),
479 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
480 SDValue(Result_4, 0), // New address.
483 ReplaceUses(Froms, Tos, 3);
487 return SelectCode(LD);
491 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
492 SDValue Chain = LD->getChain();
493 SDValue Base = LD->getBasePtr();
494 SDValue Offset = LD->getOffset();
495 SDNode *OffsetNode = Offset.getNode();
496 // Get the constant value.
497 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
498 EVT LoadedVT = LD->getMemoryVT();
501 // Check for zero ext loads.
502 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
504 // Figure out the opcode.
505 if (LoadedVT == MVT::i64) {
506 if (TII->isValidAutoIncImm(LoadedVT, Val))
507 Opcode = Hexagon::POST_LDrid;
509 Opcode = Hexagon::LDrid;
510 } else if (LoadedVT == MVT::i32) {
511 if (TII->isValidAutoIncImm(LoadedVT, Val))
512 Opcode = Hexagon::POST_LDriw;
514 Opcode = Hexagon::LDriw;
515 } else if (LoadedVT == MVT::i16) {
516 if (TII->isValidAutoIncImm(LoadedVT, Val))
517 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
519 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
520 } else if (LoadedVT == MVT::i8) {
521 if (TII->isValidAutoIncImm(LoadedVT, Val))
522 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
524 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
526 llvm_unreachable("unknown memory type");
528 // For zero ext i64 loads, we need to add combine instructions.
529 if (LD->getValueType(0) == MVT::i64 &&
530 LD->getExtensionType() == ISD::ZEXTLOAD) {
531 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
533 if (LD->getValueType(0) == MVT::i64 &&
534 LD->getExtensionType() == ISD::SEXTLOAD) {
535 // Handle sign ext i64 loads.
536 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
538 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
539 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
540 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
542 MVT::i32, MVT::Other, Base,
543 TargetConstVal, Chain);
544 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
545 MemOp[0] = LD->getMemOperand();
546 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
547 const SDValue Froms[] = { SDValue(LD, 0),
551 const SDValue Tos[] = { SDValue(Result, 0),
555 ReplaceUses(Froms, Tos, 3);
558 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
559 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
560 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
562 MVT::Other, Base, TargetConst0,
564 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
565 Base, TargetConstVal,
566 SDValue(Result_1, 1));
567 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
568 MemOp[0] = LD->getMemOperand();
569 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
570 const SDValue Froms[] = { SDValue(LD, 0),
574 const SDValue Tos[] = { SDValue(Result_1, 0),
575 SDValue(Result_2, 0),
578 ReplaceUses(Froms, Tos, 3);
584 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
586 DebugLoc dl = N->getDebugLoc();
587 LoadSDNode *LD = cast<LoadSDNode>(N);
588 ISD::MemIndexedMode AM = LD->getAddressingMode();
590 // Handle indexed loads.
591 if (AM != ISD::UNINDEXED) {
592 result = SelectIndexedLoad(LD, dl);
594 result = SelectBaseOffsetLoad(LD, dl);
601 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
602 SDValue Chain = ST->getChain();
603 SDValue Base = ST->getBasePtr();
604 SDValue Offset = ST->getOffset();
605 SDValue Value = ST->getValue();
606 SDNode *OffsetNode = Offset.getNode();
607 // Get the constant value.
608 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
609 EVT StoredVT = ST->getMemoryVT();
611 // Offset value must be within representable range
612 // and must have correct alignment properties.
613 if (TII->isValidAutoIncImm(StoredVT, Val)) {
614 SDValue Ops[] = { Value, Base,
615 CurDAG->getTargetConstant(Val, MVT::i32), Chain};
618 // Figure out the post inc version of opcode.
619 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
620 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
621 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
622 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
623 else llvm_unreachable("unknown memory type");
625 // Build post increment store.
626 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
628 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
629 MemOp[0] = ST->getMemOperand();
630 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
632 ReplaceUses(ST, Result);
633 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
637 // Note: Order of operands matches the def of instruction:
638 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
639 // and it differs for POST_ST* for instance.
640 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
644 // Figure out the opcode.
645 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
646 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
647 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
648 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
649 else llvm_unreachable("unknown memory type");
651 // Build regular store.
652 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
653 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
655 // Build splitted incriment instruction.
656 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
659 SDValue(Result_1, 0));
660 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
661 MemOp[0] = ST->getMemOperand();
662 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
664 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
665 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
670 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
672 SDValue Chain = ST->getChain();
673 SDNode* Const32 = ST->getBasePtr().getNode();
674 SDValue Value = ST->getValue();
677 // Try to lower stores of GlobalAdresses into indexed stores. Custom
678 // lowering for GlobalAddress nodes has already turned it into a
679 // CONST32. Avoid truncating stores for the moment. Post-inc stores
680 // do the same. Don't think there's a reason for it, so will file a
682 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
683 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
684 SDValue Base = Const32->getOperand(0);
685 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
686 EVT StoredVT = ST->getMemoryVT();
687 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
688 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
689 MVT PointerTy = TLI.getPointerTy();
690 const GlobalValue* GV =
691 cast<GlobalAddressSDNode>(Base)->getGlobal();
693 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
695 if (Subtarget.hasV4TOps())
696 NewBase = CurDAG->getMachineNode(Hexagon::TFRI_V4,
697 dl, PointerTy, TargAddr);
699 NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
700 dl, PointerTy, TargAddr);
702 // Figure out base + offset opcode
703 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
704 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
705 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
706 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
707 else llvm_unreachable("unknown memory type");
709 SDValue Ops[] = {SDValue(NewBase,0),
710 CurDAG->getTargetConstant(Offset,PointerTy),
712 // build indexed store
713 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
715 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
716 MemOp[0] = ST->getMemOperand();
717 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
718 ReplaceUses(ST, Result);
724 return SelectCode(ST);
728 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
729 DebugLoc dl = N->getDebugLoc();
730 StoreSDNode *ST = cast<StoreSDNode>(N);
731 ISD::MemIndexedMode AM = ST->getAddressingMode();
733 // Handle indexed stores.
734 if (AM != ISD::UNINDEXED) {
735 return SelectIndexedStore(ST, dl);
738 return SelectBaseOffsetStore(ST, dl);
741 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
742 DebugLoc dl = N->getDebugLoc();
745 // %conv.i = sext i32 %tmp1 to i64
746 // %conv2.i = sext i32 %add to i64
747 // %mul.i = mul nsw i64 %conv2.i, %conv.i
749 // --- match with the following ---
751 // %mul.i = mpy (%tmp1, %add)
754 if (N->getValueType(0) == MVT::i64) {
755 // Shifting a i64 signed multiply.
756 SDValue MulOp0 = N->getOperand(0);
757 SDValue MulOp1 = N->getOperand(1);
762 // Handle sign_extend and sextload.
763 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
764 SDValue Sext0 = MulOp0.getOperand(0);
765 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
766 return SelectCode(N);
770 } else if (MulOp0.getOpcode() == ISD::LOAD) {
771 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
772 if (LD->getMemoryVT() != MVT::i32 ||
773 LD->getExtensionType() != ISD::SEXTLOAD ||
774 LD->getAddressingMode() != ISD::UNINDEXED) {
775 return SelectCode(N);
778 SDValue Chain = LD->getChain();
779 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
780 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
782 LD->getBasePtr(), TargetConst0,
785 return SelectCode(N);
788 // Same goes for the second operand.
789 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
790 SDValue Sext1 = MulOp1.getOperand(0);
791 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
792 return SelectCode(N);
796 } else if (MulOp1.getOpcode() == ISD::LOAD) {
797 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
798 if (LD->getMemoryVT() != MVT::i32 ||
799 LD->getExtensionType() != ISD::SEXTLOAD ||
800 LD->getAddressingMode() != ISD::UNINDEXED) {
801 return SelectCode(N);
804 SDValue Chain = LD->getChain();
805 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
806 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
808 LD->getBasePtr(), TargetConst0,
811 return SelectCode(N);
814 // Generate a mpy instruction.
815 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
817 ReplaceUses(N, Result);
821 return SelectCode(N);
825 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
826 DebugLoc dl = N->getDebugLoc();
827 SDValue N0 = N->getOperand(0);
828 if (N0.getOpcode() == ISD::SETCC) {
829 SDValue N00 = N0.getOperand(0);
830 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
831 SDValue N000 = N00.getOperand(0);
832 SDValue N001 = N00.getOperand(1);
833 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
834 SDValue N01 = N0.getOperand(1);
835 SDValue N02 = N0.getOperand(2);
837 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
838 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
839 // IntRegs:i32:$src2)
840 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
841 // Pattern complexity = 9 cost = 1 size = 0.
842 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
843 SDValue N1 = N->getOperand(1);
845 SDValue N2 = N->getOperand(2);
847 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
848 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
849 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
851 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
853 SDValue(SextNode, 0),
855 ReplaceUses(N, Result);
861 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
862 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
863 // IntRegs:i32:$src2)
864 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
865 // Pattern complexity = 9 cost = 1 size = 0.
866 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
867 SDValue N1 = N->getOperand(1);
869 SDValue N2 = N->getOperand(2);
871 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
872 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
873 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
875 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
877 SDValue(SextNode, 0),
879 ReplaceUses(N, Result);
888 return SelectCode(N);
892 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
893 DebugLoc dl = N->getDebugLoc();
894 SDValue Shift = N->getOperand(0);
897 // %conv.i = sext i32 %tmp1 to i64
898 // %conv2.i = sext i32 %add to i64
899 // %mul.i = mul nsw i64 %conv2.i, %conv.i
900 // %shr5.i = lshr i64 %mul.i, 32
901 // %conv3.i = trunc i64 %shr5.i to i32
903 // --- match with the following ---
905 // %conv3.i = mpy (%tmp1, %add)
908 if (N->getValueType(0) == MVT::i32) {
910 if (Shift.getNode()->getValueType(0) == MVT::i64) {
911 // Trunc child is logical shift right.
912 if (Shift.getOpcode() != ISD::SRL) {
913 return SelectCode(N);
916 SDValue ShiftOp0 = Shift.getOperand(0);
917 SDValue ShiftOp1 = Shift.getOperand(1);
920 if (ShiftOp1.getOpcode() != ISD::Constant) {
921 return SelectCode(N);
925 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
926 if (ShiftConst != 32) {
927 return SelectCode(N);
930 // Shifting a i64 signed multiply
931 SDValue Mul = ShiftOp0;
932 if (Mul.getOpcode() != ISD::MUL) {
933 return SelectCode(N);
936 SDValue MulOp0 = Mul.getOperand(0);
937 SDValue MulOp1 = Mul.getOperand(1);
942 // Handle sign_extend and sextload
943 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
944 SDValue Sext0 = MulOp0.getOperand(0);
945 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
946 return SelectCode(N);
950 } else if (MulOp0.getOpcode() == ISD::LOAD) {
951 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
952 if (LD->getMemoryVT() != MVT::i32 ||
953 LD->getExtensionType() != ISD::SEXTLOAD ||
954 LD->getAddressingMode() != ISD::UNINDEXED) {
955 return SelectCode(N);
958 SDValue Chain = LD->getChain();
959 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
960 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
963 TargetConst0, Chain), 0);
965 return SelectCode(N);
968 // Same goes for the second operand.
969 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
970 SDValue Sext1 = MulOp1.getOperand(0);
971 if (Sext1.getNode()->getValueType(0) != MVT::i32)
972 return SelectCode(N);
975 } else if (MulOp1.getOpcode() == ISD::LOAD) {
976 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
977 if (LD->getMemoryVT() != MVT::i32 ||
978 LD->getExtensionType() != ISD::SEXTLOAD ||
979 LD->getAddressingMode() != ISD::UNINDEXED) {
980 return SelectCode(N);
983 SDValue Chain = LD->getChain();
984 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
985 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
988 TargetConst0, Chain), 0);
990 return SelectCode(N);
993 // Generate a mpy instruction.
994 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
996 ReplaceUses(N, Result);
1001 return SelectCode(N);
1005 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
1006 DebugLoc dl = N->getDebugLoc();
1007 if (N->getValueType(0) == MVT::i32) {
1008 SDValue Shl_0 = N->getOperand(0);
1009 SDValue Shl_1 = N->getOperand(1);
1011 if (Shl_1.getOpcode() == ISD::Constant) {
1012 if (Shl_0.getOpcode() == ISD::MUL) {
1013 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1014 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1015 // RHS of mul is const.
1016 if (Mul_1.getOpcode() == ISD::Constant) {
1018 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1020 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1021 int32_t ValConst = MulConst << ShlConst;
1022 SDValue Val = CurDAG->getTargetConstant(ValConst,
1024 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1025 if (isInt<9>(CN->getSExtValue())) {
1027 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1028 MVT::i32, Mul_0, Val);
1029 ReplaceUses(N, Result);
1034 } else if (Shl_0.getOpcode() == ISD::SUB) {
1035 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1036 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1037 if (Sub_0.getOpcode() == ISD::Constant) {
1039 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1040 if (SubConst == 0) {
1041 if (Sub_1.getOpcode() == ISD::SHL) {
1042 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1043 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1044 if (Shl2_1.getOpcode() == ISD::Constant) {
1046 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1048 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1049 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1050 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1051 if (ConstantSDNode *CN =
1052 dyn_cast<ConstantSDNode>(Val.getNode()))
1053 if (isInt<9>(CN->getSExtValue())) {
1055 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1057 ReplaceUses(N, Result);
1067 return SelectCode(N);
1072 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1073 // result of the intrinsic is predicate); convert the zero_extend to
1074 // transfer instruction.
1076 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1077 // converted into a MUX as predicate registers defined as 1 bit in the
1078 // compiler. Architecture defines them as 8-bit registers.
1079 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1081 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1082 DebugLoc dl = N->getDebugLoc();
1083 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1084 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1086 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1087 if (doesIntrinsicReturnPredicate(ID)) {
1088 // Now we need to differentiate target data types.
1089 if (N->getValueType(0) == MVT::i64) {
1090 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1091 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1092 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1094 SDValue(IsIntrinsic, 0));
1095 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1098 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1099 MVT::i64, MVT::Other,
1100 SDValue(Result_2, 0),
1101 SDValue(Result_1, 0));
1102 ReplaceUses(N, Result_3);
1105 if (N->getValueType(0) == MVT::i32) {
1106 // Convert the zero_extend to Rs = Pd
1107 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1109 SDValue(IsIntrinsic, 0));
1110 ReplaceUses(N, RsPd);
1113 llvm_unreachable("Unexpected value type");
1116 return SelectCode(N);
1121 // Checking for intrinsics which have predicate registers as operand(s)
1122 // and lowering to the actual intrinsic.
1124 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1125 DebugLoc dl = N->getDebugLoc();
1126 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1127 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1129 // We are concerned with only those intrinsics that have predicate registers
1130 // as at least one of the operands.
1131 if (IntrinsicWithPred) {
1132 SmallVector<SDValue, 8> Ops;
1133 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1134 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1136 // Iterate over all the operands of the intrinsics.
1137 // For PredRegs, do the transfer.
1138 // For Double/Int Regs, just preserve the value
1139 // For immediates, lower it.
1140 for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1141 SDNode *Arg = N->getOperand(i).getNode();
1142 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);
1144 if (RC == &Hexagon::IntRegsRegClass ||
1145 RC == &Hexagon::DoubleRegsRegClass) {
1146 Ops.push_back(SDValue(Arg, 0));
1147 } else if (RC == &Hexagon::PredRegsRegClass) {
1149 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1151 Ops.push_back(SDValue(PdRs,0));
1152 } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
1153 // This is immediate operand. Lower it here making sure that we DO have
1154 // const SDNode for immediate value.
1155 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1156 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1157 Ops.push_back(SDVal);
1159 llvm_unreachable("Unimplemented");
1162 EVT ReturnValueVT = N->getValueType(0);
1163 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1165 Ops.data(), Ops.size());
1166 ReplaceUses(N, Result);
1169 return SelectCode(N);
1173 // Map floating point constant values.
1175 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1176 DebugLoc dl = N->getDebugLoc();
1177 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1178 APFloat APF = CN->getValueAPF();
1179 if (N->getValueType(0) == MVT::f32) {
1180 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1181 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1183 else if (N->getValueType(0) == MVT::f64) {
1184 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1185 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1188 return SelectCode(N);
1193 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1195 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1196 DebugLoc dl = N->getDebugLoc();
1197 if (N->getValueType(0) == MVT::i1) {
1199 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1201 // Create the IntReg = 1 node.
1203 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1204 CurDAG->getTargetConstant(0, MVT::i32));
1207 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1208 SDValue(IntRegTFR, 0));
1211 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1215 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1216 SDValue(Pd, 0), SDValue(NotPd, 0));
1218 // We have just built:
1220 // Pd = xor(not(Pd), Pd)
1222 ReplaceUses(N, Result);
1227 return SelectCode(N);
1232 // Map add followed by a asr -> asr +=.
1234 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1235 DebugLoc dl = N->getDebugLoc();
1236 if (N->getValueType(0) != MVT::i32) {
1237 return SelectCode(N);
1239 // Identify nodes of the form: add(asr(...)).
1240 SDNode* Src1 = N->getOperand(0).getNode();
1241 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1242 || Src1->getValueType(0) != MVT::i32) {
1243 return SelectCode(N);
1246 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1247 // Rd and Rd' are assigned to the same register
1248 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1250 Src1->getOperand(0),
1251 Src1->getOperand(1));
1252 ReplaceUses(N, Result);
1258 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1259 if (N->isMachineOpcode())
1260 return NULL; // Already selected.
1263 switch (N->getOpcode()) {
1265 return SelectConstant(N);
1267 case ISD::ConstantFP:
1268 return SelectConstantFP(N);
1271 return SelectAdd(N);
1274 return SelectSHL(N);
1277 return SelectLoad(N);
1280 return SelectStore(N);
1283 return SelectSelect(N);
1286 return SelectTruncate(N);
1289 return SelectMul(N);
1291 case ISD::ZERO_EXTEND:
1292 return SelectZeroExtend(N);
1294 case ISD::INTRINSIC_WO_CHAIN:
1295 return SelectIntrinsicWOChain(N);
1298 return SelectCode(N);
1303 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1304 // to define these instructions.
1306 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1308 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1309 Addr.getOpcode() == ISD::TargetGlobalAddress)
1310 return false; // Direct calls.
1312 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1313 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1314 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1318 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1323 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1325 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1326 Addr.getOpcode() == ISD::TargetGlobalAddress)
1327 return false; // Direct calls.
1329 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1330 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1331 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1332 return (IsS11_0_Offset(Offset.getNode()));
1335 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1336 return (IsS11_0_Offset(Offset.getNode()));
1340 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1342 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1343 Addr.getOpcode() == ISD::TargetGlobalAddress)
1344 return false; // Direct calls.
1346 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1347 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1348 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1349 return (IsS11_1_Offset(Offset.getNode()));
1352 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1353 return (IsS11_1_Offset(Offset.getNode()));
1357 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1359 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1360 Addr.getOpcode() == ISD::TargetGlobalAddress)
1361 return false; // Direct calls.
1363 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1364 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1365 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1366 return (IsS11_2_Offset(Offset.getNode()));
1369 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1370 return (IsS11_2_Offset(Offset.getNode()));
1374 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1376 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1377 Addr.getOpcode() == ISD::TargetGlobalAddress)
1378 return false; // Direct calls.
1380 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1381 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1382 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1383 return (IsU6_0_Offset(Offset.getNode()));
1386 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1387 return (IsU6_0_Offset(Offset.getNode()));
1391 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1393 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1394 Addr.getOpcode() == ISD::TargetGlobalAddress)
1395 return false; // Direct calls.
1397 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1398 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1399 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1400 return (IsU6_1_Offset(Offset.getNode()));
1403 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1404 return (IsU6_1_Offset(Offset.getNode()));
1408 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1410 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1411 Addr.getOpcode() == ISD::TargetGlobalAddress)
1412 return false; // Direct calls.
1414 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1415 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1416 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1417 return (IsU6_2_Offset(Offset.getNode()));
1420 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1421 return (IsU6_2_Offset(Offset.getNode()));
1425 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1428 if (Addr.getOpcode() != ISD::ADD) {
1429 return(SelectADDRriS11_2(Addr, Base, Offset));
1432 return SelectADDRriS11_2(Addr, Base, Offset);
1436 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1438 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1439 Addr.getOpcode() == ISD::TargetGlobalAddress)
1440 return false; // Direct calls.
1442 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1443 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1444 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1445 return (IsS11_3_Offset(Offset.getNode()));
1448 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1449 return (IsS11_3_Offset(Offset.getNode()));
1452 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1454 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1455 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1456 Addr.getOpcode() == ISD::TargetGlobalAddress)
1457 return false; // Direct calls.
1459 if (Addr.getOpcode() == ISD::ADD) {
1460 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1461 if (isInt<13>(CN->getSExtValue()))
1462 return false; // Let the reg+imm pattern catch this!
1463 R1 = Addr.getOperand(0);
1464 R2 = Addr.getOperand(1);
1474 // Handle generic address case. It is accessed from inlined asm =m constraints,
1475 // which could have any kind of pointer.
1476 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1477 SDValue &Base, SDValue &Offset) {
1478 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1479 Addr.getOpcode() == ISD::TargetGlobalAddress)
1480 return false; // Direct calls.
1482 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1483 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1484 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1488 if (Addr.getOpcode() == ISD::ADD) {
1489 Base = Addr.getOperand(0);
1490 Offset = Addr.getOperand(1);
1495 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1500 bool HexagonDAGToDAGISel::
1501 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1502 std::vector<SDValue> &OutOps) {
1505 switch (ConstraintCode) {
1506 case 'o': // Offsetable.
1507 case 'v': // Not offsetable.
1508 default: return true;
1509 case 'm': // Memory.
1510 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1515 OutOps.push_back(Op0);
1516 OutOps.push_back(Op1);
1520 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1521 unsigned UseCount = 0;
1522 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1526 return (UseCount <= 1);