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"
16 #include "HexagonISelLowering.h"
17 #include "HexagonTargetMachine.h"
18 #include "llvm/CodeGen/SelectionDAGISel.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/Debug.h"
26 //===----------------------------------------------------------------------===//
27 // Instruction Selector Implementation
28 //===----------------------------------------------------------------------===//
30 //===--------------------------------------------------------------------===//
31 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
32 /// instructions for SelectionDAG operations.
35 class HexagonDAGToDAGISel : public SelectionDAGISel {
36 /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
37 /// make the right decision when generating code for different targets.
38 const HexagonSubtarget &Subtarget;
40 // Keep a reference to HexagonTargetMachine.
41 HexagonTargetMachine& TM;
42 const HexagonInstrInfo *TII;
45 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine)
46 : SelectionDAGISel(targetmachine),
47 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
49 TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
53 SDNode *Select(SDNode *N);
55 // Complex Pattern Selectors.
56 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
57 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
58 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
59 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
60 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
61 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
62 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
63 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
64 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
65 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
67 virtual const char *getPassName() const {
68 return "Hexagon DAG->DAG Pattern Instruction Selection";
71 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
72 /// inline asm expressions.
73 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
75 std::vector<SDValue> &OutOps);
76 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
78 SDNode *SelectLoad(SDNode *N);
79 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
80 SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
81 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
83 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
85 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
86 SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
87 SDNode *SelectStore(SDNode *N);
88 SDNode *SelectSHL(SDNode *N);
89 SDNode *SelectSelect(SDNode *N);
90 SDNode *SelectTruncate(SDNode *N);
91 SDNode *SelectMul(SDNode *N);
92 SDNode *SelectZeroExtend(SDNode *N);
93 SDNode *SelectIntrinsicWOChain(SDNode *N);
94 SDNode *SelectIntrinsicWChain(SDNode *N);
95 SDNode *SelectConstant(SDNode *N);
96 SDNode *SelectConstantFP(SDNode *N);
97 SDNode *SelectAdd(SDNode *N);
98 bool isConstExtProfitable(SDNode *N) const;
100 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
101 // [1..128], used in cmpb.gtu instructions.
102 inline SDValue XformU7ToU7M1Imm(signed Imm) {
103 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
104 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
107 // Include the pieces autogenerated from the target description.
108 #include "HexagonGenDAGISel.inc"
110 } // end anonymous namespace
113 /// createHexagonISelDag - This pass converts a legalized DAG into a
114 /// Hexagon-specific DAG, ready for instruction scheduling.
116 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM) {
117 return new HexagonDAGToDAGISel(TM);
120 static bool IsS11_0_Offset(SDNode * S) {
121 ConstantSDNode *N = cast<ConstantSDNode>(S);
123 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
125 int64_t v = (int64_t)N->getSExtValue();
130 static bool IsS11_1_Offset(SDNode * S) {
131 ConstantSDNode *N = cast<ConstantSDNode>(S);
133 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
135 int64_t v = (int64_t)N->getSExtValue();
136 return isShiftedInt<11,1>(v);
140 static bool IsS11_2_Offset(SDNode * S) {
141 ConstantSDNode *N = cast<ConstantSDNode>(S);
143 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
145 int64_t v = (int64_t)N->getSExtValue();
146 return isShiftedInt<11,2>(v);
150 static bool IsS11_3_Offset(SDNode * S) {
151 ConstantSDNode *N = cast<ConstantSDNode>(S);
153 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
155 int64_t v = (int64_t)N->getSExtValue();
156 return isShiftedInt<11,3>(v);
160 static bool IsU6_0_Offset(SDNode * S) {
161 ConstantSDNode *N = cast<ConstantSDNode>(S);
163 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
165 int64_t v = (int64_t)N->getSExtValue();
170 static bool IsU6_1_Offset(SDNode * S) {
171 ConstantSDNode *N = cast<ConstantSDNode>(S);
173 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
175 int64_t v = (int64_t)N->getSExtValue();
176 return isShiftedUInt<6,1>(v);
180 static bool IsU6_2_Offset(SDNode * S) {
181 ConstantSDNode *N = cast<ConstantSDNode>(S);
183 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
185 int64_t v = (int64_t)N->getSExtValue();
186 return isShiftedUInt<6,2>(v);
190 // Intrinsics that return a a predicate.
191 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
196 case Intrinsic::hexagon_C2_cmpeq:
197 case Intrinsic::hexagon_C2_cmpgt:
198 case Intrinsic::hexagon_C2_cmpgtu:
199 case Intrinsic::hexagon_C2_cmpgtup:
200 case Intrinsic::hexagon_C2_cmpgtp:
201 case Intrinsic::hexagon_C2_cmpeqp:
202 case Intrinsic::hexagon_C2_bitsset:
203 case Intrinsic::hexagon_C2_bitsclr:
204 case Intrinsic::hexagon_C2_cmpeqi:
205 case Intrinsic::hexagon_C2_cmpgti:
206 case Intrinsic::hexagon_C2_cmpgtui:
207 case Intrinsic::hexagon_C2_cmpgei:
208 case Intrinsic::hexagon_C2_cmpgeui:
209 case Intrinsic::hexagon_C2_cmplt:
210 case Intrinsic::hexagon_C2_cmpltu:
211 case Intrinsic::hexagon_C2_bitsclri:
212 case Intrinsic::hexagon_C2_and:
213 case Intrinsic::hexagon_C2_or:
214 case Intrinsic::hexagon_C2_xor:
215 case Intrinsic::hexagon_C2_andn:
216 case Intrinsic::hexagon_C2_not:
217 case Intrinsic::hexagon_C2_orn:
218 case Intrinsic::hexagon_C2_pxfer_map:
219 case Intrinsic::hexagon_C2_any8:
220 case Intrinsic::hexagon_C2_all8:
221 case Intrinsic::hexagon_A2_vcmpbeq:
222 case Intrinsic::hexagon_A2_vcmpbgtu:
223 case Intrinsic::hexagon_A2_vcmpheq:
224 case Intrinsic::hexagon_A2_vcmphgt:
225 case Intrinsic::hexagon_A2_vcmphgtu:
226 case Intrinsic::hexagon_A2_vcmpweq:
227 case Intrinsic::hexagon_A2_vcmpwgt:
228 case Intrinsic::hexagon_A2_vcmpwgtu:
229 case Intrinsic::hexagon_C2_tfrrp:
230 case Intrinsic::hexagon_S2_tstbit_i:
231 case Intrinsic::hexagon_S2_tstbit_r:
237 // Intrinsics that have predicate operands.
238 static unsigned doesIntrinsicContainPredicate(unsigned ID)
243 case Intrinsic::hexagon_C2_tfrpr:
244 return Hexagon::TFR_RsPd;
245 case Intrinsic::hexagon_C2_and:
246 return Hexagon::AND_pp;
247 case Intrinsic::hexagon_C2_xor:
248 return Hexagon::XOR_pp;
249 case Intrinsic::hexagon_C2_or:
250 return Hexagon::OR_pp;
251 case Intrinsic::hexagon_C2_not:
252 return Hexagon::NOT_p;
253 case Intrinsic::hexagon_C2_any8:
254 return Hexagon::ANY_pp;
255 case Intrinsic::hexagon_C2_all8:
256 return Hexagon::ALL_pp;
257 case Intrinsic::hexagon_C2_vitpack:
258 return Hexagon::VITPACK_pp;
259 case Intrinsic::hexagon_C2_mask:
260 return Hexagon::MASK_p;
261 case Intrinsic::hexagon_C2_mux:
262 return Hexagon::MUX_rr;
264 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
265 // that's how it's mapped in q6protos.h.
266 case Intrinsic::hexagon_C2_muxir:
267 return Hexagon::MUX_ri;
269 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
270 // that's how it's mapped in q6protos.h.
271 case Intrinsic::hexagon_C2_muxri:
272 return Hexagon::MUX_ir;
274 case Intrinsic::hexagon_C2_muxii:
275 return Hexagon::MUX_ii;
276 case Intrinsic::hexagon_C2_vmux:
277 return Hexagon::VMUX_prr64;
278 case Intrinsic::hexagon_S2_valignrb:
279 return Hexagon::VALIGN_rrp;
280 case Intrinsic::hexagon_S2_vsplicerb:
281 return Hexagon::VSPLICE_rrp;
286 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
287 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
290 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
293 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
296 if (MemType == MVT::i8 && isInt<11>(Offset)) {
304 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
305 // lowering for GlobalAddress nodes has already turned it into a
308 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
309 SDValue Chain = LD->getChain();
310 SDNode* Const32 = LD->getBasePtr().getNode();
313 if (Const32->getOpcode() == HexagonISD::CONST32 &&
314 ISD::isNormalLoad(LD)) {
315 SDValue Base = Const32->getOperand(0);
316 EVT LoadedVT = LD->getMemoryVT();
317 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
318 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
319 MVT PointerTy = TLI.getPointerTy();
320 const GlobalValue* GV =
321 cast<GlobalAddressSDNode>(Base)->getGlobal();
323 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
324 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
327 // Figure out base + offset opcode
328 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
329 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
330 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
331 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
332 else llvm_unreachable("unknown memory type");
334 // Build indexed load.
335 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
336 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
342 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
343 MemOp[0] = LD->getMemOperand();
344 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
345 ReplaceUses(LD, Result);
350 return SelectCode(LD);
354 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
358 SDValue Chain = LD->getChain();
359 EVT LoadedVT = LD->getMemoryVT();
360 SDValue Base = LD->getBasePtr();
361 SDValue Offset = LD->getOffset();
362 SDNode *OffsetNode = Offset.getNode();
363 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
364 SDValue N1 = LD->getOperand(1);
367 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
368 N1.getNode()->getValueType(0) == MVT::i32) {
369 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
370 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
371 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
372 MVT::Other, Base, TargetConst,
374 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
375 SDValue(Result_1, 0));
376 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
377 MemOp[0] = LD->getMemOperand();
378 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
379 const SDValue Froms[] = { SDValue(LD, 0),
383 const SDValue Tos[] = { SDValue(Result_2, 0),
384 SDValue(Result_1, 1),
387 ReplaceUses(Froms, Tos, 3);
390 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
391 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
392 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
393 MVT::Other, Base, TargetConst0,
395 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
396 MVT::i64, SDValue(Result_1, 0));
397 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
398 MVT::i32, Base, TargetConstVal,
399 SDValue(Result_1, 1));
400 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
401 MemOp[0] = LD->getMemOperand();
402 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
403 const SDValue Froms[] = { SDValue(LD, 0),
407 const SDValue Tos[] = { SDValue(Result_2, 0),
408 SDValue(Result_3, 0),
411 ReplaceUses(Froms, Tos, 3);
414 return SelectCode(LD);
418 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
422 SDValue Chain = LD->getChain();
423 EVT LoadedVT = LD->getMemoryVT();
424 SDValue Base = LD->getBasePtr();
425 SDValue Offset = LD->getOffset();
426 SDNode *OffsetNode = Offset.getNode();
427 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
428 SDValue N1 = LD->getOperand(1);
431 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
432 N1.getNode()->getValueType(0) == MVT::i32) {
433 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
434 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
435 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
436 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
437 MVT::i32, MVT::Other, Base,
438 TargetConstVal, Chain);
439 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
441 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
442 MVT::i64, MVT::Other,
444 SDValue(Result_1,0));
445 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
446 MemOp[0] = LD->getMemOperand();
447 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
448 const SDValue Froms[] = { SDValue(LD, 0),
452 const SDValue Tos[] = { SDValue(Result_3, 0),
453 SDValue(Result_1, 1),
456 ReplaceUses(Froms, Tos, 3);
460 // Generate an indirect load.
461 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
462 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
463 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
465 Base, TargetConst0, Chain);
466 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
468 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
469 MVT::i64, MVT::Other,
471 SDValue(Result_1,0));
472 // Add offset to base.
473 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
474 Base, TargetConstVal,
475 SDValue(Result_1, 1));
476 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
477 MemOp[0] = LD->getMemOperand();
478 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
479 const SDValue Froms[] = { SDValue(LD, 0),
483 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
484 SDValue(Result_4, 0), // New address.
487 ReplaceUses(Froms, Tos, 3);
491 return SelectCode(LD);
495 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
496 SDValue Chain = LD->getChain();
497 SDValue Base = LD->getBasePtr();
498 SDValue Offset = LD->getOffset();
499 SDNode *OffsetNode = Offset.getNode();
500 // Get the constant value.
501 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
502 EVT LoadedVT = LD->getMemoryVT();
505 // Check for zero ext loads.
506 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
508 // Figure out the opcode.
509 if (LoadedVT == MVT::i64) {
510 if (TII->isValidAutoIncImm(LoadedVT, Val))
511 Opcode = Hexagon::POST_LDrid;
513 Opcode = Hexagon::LDrid;
514 } else if (LoadedVT == MVT::i32) {
515 if (TII->isValidAutoIncImm(LoadedVT, Val))
516 Opcode = Hexagon::POST_LDriw;
518 Opcode = Hexagon::LDriw;
519 } else if (LoadedVT == MVT::i16) {
520 if (TII->isValidAutoIncImm(LoadedVT, Val))
521 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
523 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
524 } else if (LoadedVT == MVT::i8) {
525 if (TII->isValidAutoIncImm(LoadedVT, Val))
526 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
528 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
530 llvm_unreachable("unknown memory type");
532 // For zero ext i64 loads, we need to add combine instructions.
533 if (LD->getValueType(0) == MVT::i64 &&
534 LD->getExtensionType() == ISD::ZEXTLOAD) {
535 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
537 if (LD->getValueType(0) == MVT::i64 &&
538 LD->getExtensionType() == ISD::SEXTLOAD) {
539 // Handle sign ext i64 loads.
540 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
542 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
543 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
544 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
546 MVT::i32, MVT::Other, Base,
547 TargetConstVal, Chain);
548 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
549 MemOp[0] = LD->getMemOperand();
550 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
551 const SDValue Froms[] = { SDValue(LD, 0),
555 const SDValue Tos[] = { SDValue(Result, 0),
559 ReplaceUses(Froms, Tos, 3);
562 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
563 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
564 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
566 MVT::Other, Base, TargetConst0,
568 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
569 Base, TargetConstVal,
570 SDValue(Result_1, 1));
571 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
572 MemOp[0] = LD->getMemOperand();
573 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
574 const SDValue Froms[] = { SDValue(LD, 0),
578 const SDValue Tos[] = { SDValue(Result_1, 0),
579 SDValue(Result_2, 0),
582 ReplaceUses(Froms, Tos, 3);
588 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
590 DebugLoc dl = N->getDebugLoc();
591 LoadSDNode *LD = cast<LoadSDNode>(N);
592 ISD::MemIndexedMode AM = LD->getAddressingMode();
594 // Handle indexed loads.
595 if (AM != ISD::UNINDEXED) {
596 result = SelectIndexedLoad(LD, dl);
598 result = SelectBaseOffsetLoad(LD, dl);
605 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
606 SDValue Chain = ST->getChain();
607 SDValue Base = ST->getBasePtr();
608 SDValue Offset = ST->getOffset();
609 SDValue Value = ST->getValue();
610 SDNode *OffsetNode = Offset.getNode();
611 // Get the constant value.
612 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
613 EVT StoredVT = ST->getMemoryVT();
615 // Offset value must be within representable range
616 // and must have correct alignment properties.
617 if (TII->isValidAutoIncImm(StoredVT, Val)) {
618 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
622 // Figure out the post inc version of opcode.
623 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
624 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
625 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
626 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
627 else llvm_unreachable("unknown memory type");
629 // Build post increment store.
630 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
632 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
633 MemOp[0] = ST->getMemOperand();
634 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
636 ReplaceUses(ST, Result);
637 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
641 // Note: Order of operands matches the def of instruction:
642 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
643 // and it differs for POST_ST* for instance.
644 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
648 // Figure out the opcode.
649 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
650 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
651 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
652 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
653 else llvm_unreachable("unknown memory type");
655 // Build regular store.
656 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
657 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
659 // Build splitted incriment instruction.
660 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
663 SDValue(Result_1, 0));
664 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
665 MemOp[0] = ST->getMemOperand();
666 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
668 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
669 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
674 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
676 SDValue Chain = ST->getChain();
677 SDNode* Const32 = ST->getBasePtr().getNode();
678 SDValue Value = ST->getValue();
681 // Try to lower stores of GlobalAdresses into indexed stores. Custom
682 // lowering for GlobalAddress nodes has already turned it into a
683 // CONST32. Avoid truncating stores for the moment. Post-inc stores
684 // do the same. Don't think there's a reason for it, so will file a
686 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
687 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
688 SDValue Base = Const32->getOperand(0);
689 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
690 EVT StoredVT = ST->getMemoryVT();
691 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
692 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
693 MVT PointerTy = TLI.getPointerTy();
694 const GlobalValue* GV =
695 cast<GlobalAddressSDNode>(Base)->getGlobal();
697 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
698 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
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);