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/ADT/DenseMap.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/CodeGen/SelectionDAGISel.h"
21 #include "llvm/Support/CommandLine.h"
22 #include "llvm/Support/Compiler.h"
23 #include "llvm/Support/Debug.h"
28 MaxNumOfUsesForConstExtenders("ga-max-num-uses-for-constant-extenders",
29 cl::Hidden, cl::init(2),
30 cl::desc("Maximum number of uses of a global address such that we still us a"
31 "constant extended instruction"));
33 //===----------------------------------------------------------------------===//
34 // Instruction Selector Implementation
35 //===----------------------------------------------------------------------===//
38 void initializeHexagonDAGToDAGISelPass(PassRegistry&);
41 //===--------------------------------------------------------------------===//
42 /// HexagonDAGToDAGISel - Hexagon specific code to select Hexagon machine
43 /// instructions for SelectionDAG operations.
46 class HexagonDAGToDAGISel : public SelectionDAGISel {
47 /// Subtarget - Keep a pointer to the Hexagon Subtarget around so that we can
48 /// make the right decision when generating code for different targets.
49 const HexagonSubtarget &Subtarget;
51 // Keep a reference to HexagonTargetMachine.
52 HexagonTargetMachine& TM;
53 const HexagonInstrInfo *TII;
54 DenseMap<const GlobalValue *, unsigned> GlobalAddressUseCountMap;
56 explicit HexagonDAGToDAGISel(HexagonTargetMachine &targetmachine,
57 CodeGenOpt::Level OptLevel)
58 : SelectionDAGISel(targetmachine, OptLevel),
59 Subtarget(targetmachine.getSubtarget<HexagonSubtarget>()),
61 TII(static_cast<const HexagonInstrInfo*>(TM.getInstrInfo())) {
62 initializeHexagonDAGToDAGISelPass(*PassRegistry::getPassRegistry());
64 bool hasNumUsesBelowThresGA(SDNode *N) const;
66 SDNode *Select(SDNode *N);
68 // Complex Pattern Selectors.
69 inline bool foldGlobalAddress(SDValue &N, SDValue &R);
70 inline bool foldGlobalAddressGP(SDValue &N, SDValue &R);
71 bool foldGlobalAddressImpl(SDValue &N, SDValue &R, bool ShouldLookForGP);
72 bool SelectADDRri(SDValue& N, SDValue &R1, SDValue &R2);
73 bool SelectADDRriS11_0(SDValue& N, SDValue &R1, SDValue &R2);
74 bool SelectADDRriS11_1(SDValue& N, SDValue &R1, SDValue &R2);
75 bool SelectADDRriS11_2(SDValue& N, SDValue &R1, SDValue &R2);
76 bool SelectMEMriS11_2(SDValue& Addr, SDValue &Base, SDValue &Offset);
77 bool SelectADDRriS11_3(SDValue& N, SDValue &R1, SDValue &R2);
78 bool SelectADDRrr(SDValue &Addr, SDValue &Base, SDValue &Offset);
79 bool SelectADDRriU6_0(SDValue& N, SDValue &R1, SDValue &R2);
80 bool SelectADDRriU6_1(SDValue& N, SDValue &R1, SDValue &R2);
81 bool SelectADDRriU6_2(SDValue& N, SDValue &R1, SDValue &R2);
83 virtual const char *getPassName() const {
84 return "Hexagon DAG->DAG Pattern Instruction Selection";
87 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
88 /// inline asm expressions.
89 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
91 std::vector<SDValue> &OutOps);
92 bool SelectAddr(SDNode *Op, SDValue Addr, SDValue &Base, SDValue &Offset);
94 SDNode *SelectLoad(SDNode *N);
95 SDNode *SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl);
96 SDNode *SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl);
97 SDNode *SelectIndexedLoadZeroExtend64(LoadSDNode *LD, unsigned Opcode,
99 SDNode *SelectIndexedLoadSignExtend64(LoadSDNode *LD, unsigned Opcode,
101 SDNode *SelectBaseOffsetStore(StoreSDNode *ST, DebugLoc dl);
102 SDNode *SelectIndexedStore(StoreSDNode *ST, DebugLoc dl);
103 SDNode *SelectStore(SDNode *N);
104 SDNode *SelectSHL(SDNode *N);
105 SDNode *SelectSelect(SDNode *N);
106 SDNode *SelectTruncate(SDNode *N);
107 SDNode *SelectMul(SDNode *N);
108 SDNode *SelectZeroExtend(SDNode *N);
109 SDNode *SelectIntrinsicWOChain(SDNode *N);
110 SDNode *SelectIntrinsicWChain(SDNode *N);
111 SDNode *SelectConstant(SDNode *N);
112 SDNode *SelectConstantFP(SDNode *N);
113 SDNode *SelectAdd(SDNode *N);
114 bool isConstExtProfitable(SDNode *N) const;
116 // XformMskToBitPosU5Imm - Returns the bit position which
117 // the single bit 32 bit mask represents.
118 // Used in Clr and Set bit immediate memops.
119 SDValue XformMskToBitPosU5Imm(uint32_t Imm) {
121 bitPos = Log2_32(Imm);
122 assert(bitPos >= 0 && bitPos < 32 &&
123 "Constant out of range for 32 BitPos Memops");
124 return CurDAG->getTargetConstant(bitPos, MVT::i32);
127 // XformMskToBitPosU4Imm - Returns the bit position which the single bit 16 bit
128 // mask represents. Used in Clr and Set bit immediate memops.
129 SDValue XformMskToBitPosU4Imm(uint16_t Imm) {
130 return XformMskToBitPosU5Imm(Imm);
133 // XformMskToBitPosU3Imm - Returns the bit position which the single bit 8 bit
134 // mask represents. Used in Clr and Set bit immediate memops.
135 SDValue XformMskToBitPosU3Imm(uint8_t Imm) {
136 return XformMskToBitPosU5Imm(Imm);
139 // Return true if there is exactly one bit set in V, i.e., if V is one of the
140 // following integers: 2^0, 2^1, ..., 2^31.
141 bool ImmIsSingleBit(uint32_t v) const {
142 uint32_t c = CountPopulation_64(v);
143 // Only return true if we counted 1 bit.
147 // XformM5ToU5Imm - Return a target constant with the specified value, of type
148 // i32 where the negative literal is transformed into a positive literal for
150 inline SDValue XformM5ToU5Imm(signed Imm) {
151 assert( (Imm >= -31 && Imm <= -1) && "Constant out of range for Memops");
152 return CurDAG->getTargetConstant( - Imm, MVT::i32);
156 // XformU7ToU7M1Imm - Return a target constant decremented by 1, in range
157 // [1..128], used in cmpb.gtu instructions.
158 inline SDValue XformU7ToU7M1Imm(signed Imm) {
159 assert((Imm >= 1 && Imm <= 128) && "Constant out of range for cmpb op");
160 return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
163 // Include the pieces autogenerated from the target description.
164 #include "HexagonGenDAGISel.inc"
166 } // end anonymous namespace
169 /// createHexagonISelDag - This pass converts a legalized DAG into a
170 /// Hexagon-specific DAG, ready for instruction scheduling.
172 FunctionPass *llvm::createHexagonISelDag(HexagonTargetMachine &TM,
173 CodeGenOpt::Level OptLevel) {
174 return new HexagonDAGToDAGISel(TM, OptLevel);
177 static void initializePassOnce(PassRegistry &Registry) {
178 const char *Name = "Hexagon DAG->DAG Pattern Instruction Selection";
179 PassInfo *PI = new PassInfo(Name, "hexagon-isel",
180 &SelectionDAGISel::ID, 0, false, false);
181 Registry.registerPass(*PI, true);
184 void llvm::initializeHexagonDAGToDAGISelPass(PassRegistry &Registry) {
185 CALL_ONCE_INITIALIZATION(initializePassOnce)
189 static bool IsS11_0_Offset(SDNode * S) {
190 ConstantSDNode *N = cast<ConstantSDNode>(S);
192 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
194 int64_t v = (int64_t)N->getSExtValue();
199 static bool IsS11_1_Offset(SDNode * S) {
200 ConstantSDNode *N = cast<ConstantSDNode>(S);
202 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
204 int64_t v = (int64_t)N->getSExtValue();
205 return isShiftedInt<11,1>(v);
209 static bool IsS11_2_Offset(SDNode * S) {
210 ConstantSDNode *N = cast<ConstantSDNode>(S);
212 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
214 int64_t v = (int64_t)N->getSExtValue();
215 return isShiftedInt<11,2>(v);
219 static bool IsS11_3_Offset(SDNode * S) {
220 ConstantSDNode *N = cast<ConstantSDNode>(S);
222 // immS16 predicate - True if the immediate fits in a 16-bit sign extended
224 int64_t v = (int64_t)N->getSExtValue();
225 return isShiftedInt<11,3>(v);
229 static bool IsU6_0_Offset(SDNode * S) {
230 ConstantSDNode *N = cast<ConstantSDNode>(S);
232 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
234 int64_t v = (int64_t)N->getSExtValue();
239 static bool IsU6_1_Offset(SDNode * S) {
240 ConstantSDNode *N = cast<ConstantSDNode>(S);
242 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
244 int64_t v = (int64_t)N->getSExtValue();
245 return isShiftedUInt<6,1>(v);
249 static bool IsU6_2_Offset(SDNode * S) {
250 ConstantSDNode *N = cast<ConstantSDNode>(S);
252 // u6 predicate - True if the immediate fits in a 6-bit unsigned extended
254 int64_t v = (int64_t)N->getSExtValue();
255 return isShiftedUInt<6,2>(v);
259 // Intrinsics that return a a predicate.
260 static unsigned doesIntrinsicReturnPredicate(unsigned ID)
265 case Intrinsic::hexagon_C2_cmpeq:
266 case Intrinsic::hexagon_C2_cmpgt:
267 case Intrinsic::hexagon_C2_cmpgtu:
268 case Intrinsic::hexagon_C2_cmpgtup:
269 case Intrinsic::hexagon_C2_cmpgtp:
270 case Intrinsic::hexagon_C2_cmpeqp:
271 case Intrinsic::hexagon_C2_bitsset:
272 case Intrinsic::hexagon_C2_bitsclr:
273 case Intrinsic::hexagon_C2_cmpeqi:
274 case Intrinsic::hexagon_C2_cmpgti:
275 case Intrinsic::hexagon_C2_cmpgtui:
276 case Intrinsic::hexagon_C2_cmpgei:
277 case Intrinsic::hexagon_C2_cmpgeui:
278 case Intrinsic::hexagon_C2_cmplt:
279 case Intrinsic::hexagon_C2_cmpltu:
280 case Intrinsic::hexagon_C2_bitsclri:
281 case Intrinsic::hexagon_C2_and:
282 case Intrinsic::hexagon_C2_or:
283 case Intrinsic::hexagon_C2_xor:
284 case Intrinsic::hexagon_C2_andn:
285 case Intrinsic::hexagon_C2_not:
286 case Intrinsic::hexagon_C2_orn:
287 case Intrinsic::hexagon_C2_pxfer_map:
288 case Intrinsic::hexagon_C2_any8:
289 case Intrinsic::hexagon_C2_all8:
290 case Intrinsic::hexagon_A2_vcmpbeq:
291 case Intrinsic::hexagon_A2_vcmpbgtu:
292 case Intrinsic::hexagon_A2_vcmpheq:
293 case Intrinsic::hexagon_A2_vcmphgt:
294 case Intrinsic::hexagon_A2_vcmphgtu:
295 case Intrinsic::hexagon_A2_vcmpweq:
296 case Intrinsic::hexagon_A2_vcmpwgt:
297 case Intrinsic::hexagon_A2_vcmpwgtu:
298 case Intrinsic::hexagon_C2_tfrrp:
299 case Intrinsic::hexagon_S2_tstbit_i:
300 case Intrinsic::hexagon_S2_tstbit_r:
306 // Intrinsics that have predicate operands.
307 static unsigned doesIntrinsicContainPredicate(unsigned ID)
312 case Intrinsic::hexagon_C2_tfrpr:
313 return Hexagon::TFR_RsPd;
314 case Intrinsic::hexagon_C2_and:
315 return Hexagon::AND_pp;
316 case Intrinsic::hexagon_C2_xor:
317 return Hexagon::XOR_pp;
318 case Intrinsic::hexagon_C2_or:
319 return Hexagon::OR_pp;
320 case Intrinsic::hexagon_C2_not:
321 return Hexagon::NOT_p;
322 case Intrinsic::hexagon_C2_any8:
323 return Hexagon::ANY_pp;
324 case Intrinsic::hexagon_C2_all8:
325 return Hexagon::ALL_pp;
326 case Intrinsic::hexagon_C2_vitpack:
327 return Hexagon::VITPACK_pp;
328 case Intrinsic::hexagon_C2_mask:
329 return Hexagon::MASK_p;
330 case Intrinsic::hexagon_C2_mux:
331 return Hexagon::MUX_rr;
333 // Mapping hexagon_C2_muxir to MUX_pri. This is pretty weird - but
334 // that's how it's mapped in q6protos.h.
335 case Intrinsic::hexagon_C2_muxir:
336 return Hexagon::MUX_ri;
338 // Mapping hexagon_C2_muxri to MUX_pir. This is pretty weird - but
339 // that's how it's mapped in q6protos.h.
340 case Intrinsic::hexagon_C2_muxri:
341 return Hexagon::MUX_ir;
343 case Intrinsic::hexagon_C2_muxii:
344 return Hexagon::MUX_ii;
345 case Intrinsic::hexagon_C2_vmux:
346 return Hexagon::VMUX_prr64;
347 case Intrinsic::hexagon_S2_valignrb:
348 return Hexagon::VALIGN_rrp;
349 case Intrinsic::hexagon_S2_vsplicerb:
350 return Hexagon::VSPLICE_rrp;
355 static bool OffsetFitsS11(EVT MemType, int64_t Offset) {
356 if (MemType == MVT::i64 && isShiftedInt<11,3>(Offset)) {
359 if (MemType == MVT::i32 && isShiftedInt<11,2>(Offset)) {
362 if (MemType == MVT::i16 && isShiftedInt<11,1>(Offset)) {
365 if (MemType == MVT::i8 && isInt<11>(Offset)) {
373 // Try to lower loads of GlobalAdresses into base+offset loads. Custom
374 // lowering for GlobalAddress nodes has already turned it into a
377 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetLoad(LoadSDNode *LD, DebugLoc dl) {
378 SDValue Chain = LD->getChain();
379 SDNode* Const32 = LD->getBasePtr().getNode();
382 if (Const32->getOpcode() == HexagonISD::CONST32 &&
383 ISD::isNormalLoad(LD)) {
384 SDValue Base = Const32->getOperand(0);
385 EVT LoadedVT = LD->getMemoryVT();
386 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
387 if (Offset != 0 && OffsetFitsS11(LoadedVT, Offset)) {
388 MVT PointerTy = TLI.getPointerTy();
389 const GlobalValue* GV =
390 cast<GlobalAddressSDNode>(Base)->getGlobal();
392 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
393 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
396 // Figure out base + offset opcode
397 if (LoadedVT == MVT::i64) Opcode = Hexagon::LDrid_indexed;
398 else if (LoadedVT == MVT::i32) Opcode = Hexagon::LDriw_indexed;
399 else if (LoadedVT == MVT::i16) Opcode = Hexagon::LDrih_indexed;
400 else if (LoadedVT == MVT::i8) Opcode = Hexagon::LDrib_indexed;
401 else llvm_unreachable("unknown memory type");
403 // Build indexed load.
404 SDValue TargetConstOff = CurDAG->getTargetConstant(Offset, PointerTy);
405 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
411 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
412 MemOp[0] = LD->getMemOperand();
413 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
414 ReplaceUses(LD, Result);
419 return SelectCode(LD);
423 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadSignExtend64(LoadSDNode *LD,
427 SDValue Chain = LD->getChain();
428 EVT LoadedVT = LD->getMemoryVT();
429 SDValue Base = LD->getBasePtr();
430 SDValue Offset = LD->getOffset();
431 SDNode *OffsetNode = Offset.getNode();
432 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
433 SDValue N1 = LD->getOperand(1);
436 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
437 N1.getNode()->getValueType(0) == MVT::i32) {
438 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
439 SDValue TargetConst = CurDAG->getTargetConstant(Val, MVT::i32);
440 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32, MVT::i32,
441 MVT::Other, Base, TargetConst,
443 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl, MVT::i64,
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_2, 0),
453 SDValue(Result_1, 1),
456 ReplaceUses(Froms, Tos, 3);
459 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
460 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
461 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
462 MVT::Other, Base, TargetConst0,
464 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::SXTW, dl,
465 MVT::i64, SDValue(Result_1, 0));
466 SDNode* Result_3 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl,
467 MVT::i32, Base, TargetConstVal,
468 SDValue(Result_1, 1));
469 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
470 MemOp[0] = LD->getMemOperand();
471 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
472 const SDValue Froms[] = { SDValue(LD, 0),
476 const SDValue Tos[] = { SDValue(Result_2, 0),
477 SDValue(Result_3, 0),
480 ReplaceUses(Froms, Tos, 3);
483 return SelectCode(LD);
487 SDNode *HexagonDAGToDAGISel::SelectIndexedLoadZeroExtend64(LoadSDNode *LD,
491 SDValue Chain = LD->getChain();
492 EVT LoadedVT = LD->getMemoryVT();
493 SDValue Base = LD->getBasePtr();
494 SDValue Offset = LD->getOffset();
495 SDNode *OffsetNode = Offset.getNode();
496 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
497 SDValue N1 = LD->getOperand(1);
500 if (SelectADDRriS11_2(N1, CPTmpN1_0, CPTmpN1_1) &&
501 N1.getNode()->getValueType(0) == MVT::i32) {
502 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
503 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
504 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
505 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
506 MVT::i32, MVT::Other, Base,
507 TargetConstVal, Chain);
508 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
510 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
511 MVT::i64, MVT::Other,
513 SDValue(Result_1,0));
514 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
515 MemOp[0] = LD->getMemOperand();
516 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
517 const SDValue Froms[] = { SDValue(LD, 0),
521 const SDValue Tos[] = { SDValue(Result_3, 0),
522 SDValue(Result_1, 1),
525 ReplaceUses(Froms, Tos, 3);
529 // Generate an indirect load.
530 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
531 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
532 SDNode *Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
534 Base, TargetConst0, Chain);
535 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
537 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
538 MVT::i64, MVT::Other,
540 SDValue(Result_1,0));
541 // Add offset to base.
542 SDNode* Result_4 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
543 Base, TargetConstVal,
544 SDValue(Result_1, 1));
545 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
546 MemOp[0] = LD->getMemOperand();
547 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
548 const SDValue Froms[] = { SDValue(LD, 0),
552 const SDValue Tos[] = { SDValue(Result_3, 0), // Load value.
553 SDValue(Result_4, 0), // New address.
556 ReplaceUses(Froms, Tos, 3);
560 return SelectCode(LD);
564 SDNode *HexagonDAGToDAGISel::SelectIndexedLoad(LoadSDNode *LD, DebugLoc dl) {
565 SDValue Chain = LD->getChain();
566 SDValue Base = LD->getBasePtr();
567 SDValue Offset = LD->getOffset();
568 SDNode *OffsetNode = Offset.getNode();
569 // Get the constant value.
570 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
571 EVT LoadedVT = LD->getMemoryVT();
574 // Check for zero ext loads.
575 bool zextval = (LD->getExtensionType() == ISD::ZEXTLOAD);
577 // Figure out the opcode.
578 if (LoadedVT == MVT::i64) {
579 if (TII->isValidAutoIncImm(LoadedVT, Val))
580 Opcode = Hexagon::POST_LDrid;
582 Opcode = Hexagon::LDrid;
583 } else if (LoadedVT == MVT::i32) {
584 if (TII->isValidAutoIncImm(LoadedVT, Val))
585 Opcode = Hexagon::POST_LDriw;
587 Opcode = Hexagon::LDriw;
588 } else if (LoadedVT == MVT::i16) {
589 if (TII->isValidAutoIncImm(LoadedVT, Val))
590 Opcode = zextval ? Hexagon::POST_LDriuh : Hexagon::POST_LDrih;
592 Opcode = zextval ? Hexagon::LDriuh : Hexagon::LDrih;
593 } else if (LoadedVT == MVT::i8) {
594 if (TII->isValidAutoIncImm(LoadedVT, Val))
595 Opcode = zextval ? Hexagon::POST_LDriub : Hexagon::POST_LDrib;
597 Opcode = zextval ? Hexagon::LDriub : Hexagon::LDrib;
599 llvm_unreachable("unknown memory type");
601 // For zero ext i64 loads, we need to add combine instructions.
602 if (LD->getValueType(0) == MVT::i64 &&
603 LD->getExtensionType() == ISD::ZEXTLOAD) {
604 return SelectIndexedLoadZeroExtend64(LD, Opcode, dl);
606 if (LD->getValueType(0) == MVT::i64 &&
607 LD->getExtensionType() == ISD::SEXTLOAD) {
608 // Handle sign ext i64 loads.
609 return SelectIndexedLoadSignExtend64(LD, Opcode, dl);
611 if (TII->isValidAutoIncImm(LoadedVT, Val)) {
612 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
613 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
615 MVT::i32, MVT::Other, Base,
616 TargetConstVal, Chain);
617 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
618 MemOp[0] = LD->getMemOperand();
619 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
620 const SDValue Froms[] = { SDValue(LD, 0),
624 const SDValue Tos[] = { SDValue(Result, 0),
628 ReplaceUses(Froms, Tos, 3);
631 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
632 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
633 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl,
635 MVT::Other, Base, TargetConst0,
637 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
638 Base, TargetConstVal,
639 SDValue(Result_1, 1));
640 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
641 MemOp[0] = LD->getMemOperand();
642 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
643 const SDValue Froms[] = { SDValue(LD, 0),
647 const SDValue Tos[] = { SDValue(Result_1, 0),
648 SDValue(Result_2, 0),
651 ReplaceUses(Froms, Tos, 3);
657 SDNode *HexagonDAGToDAGISel::SelectLoad(SDNode *N) {
659 DebugLoc dl = N->getDebugLoc();
660 LoadSDNode *LD = cast<LoadSDNode>(N);
661 ISD::MemIndexedMode AM = LD->getAddressingMode();
663 // Handle indexed loads.
664 if (AM != ISD::UNINDEXED) {
665 result = SelectIndexedLoad(LD, dl);
667 result = SelectBaseOffsetLoad(LD, dl);
674 SDNode *HexagonDAGToDAGISel::SelectIndexedStore(StoreSDNode *ST, DebugLoc dl) {
675 SDValue Chain = ST->getChain();
676 SDValue Base = ST->getBasePtr();
677 SDValue Offset = ST->getOffset();
678 SDValue Value = ST->getValue();
679 SDNode *OffsetNode = Offset.getNode();
680 // Get the constant value.
681 int32_t Val = cast<ConstantSDNode>(OffsetNode)->getSExtValue();
682 EVT StoredVT = ST->getMemoryVT();
684 // Offset value must be within representable range
685 // and must have correct alignment properties.
686 if (TII->isValidAutoIncImm(StoredVT, Val)) {
687 SDValue Ops[] = {Base, CurDAG->getTargetConstant(Val, MVT::i32), Value,
691 // Figure out the post inc version of opcode.
692 if (StoredVT == MVT::i64) Opcode = Hexagon::POST_STdri;
693 else if (StoredVT == MVT::i32) Opcode = Hexagon::POST_STwri;
694 else if (StoredVT == MVT::i16) Opcode = Hexagon::POST_SThri;
695 else if (StoredVT == MVT::i8) Opcode = Hexagon::POST_STbri;
696 else llvm_unreachable("unknown memory type");
698 // Build post increment store.
699 SDNode* Result = CurDAG->getMachineNode(Opcode, dl, MVT::i32,
701 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
702 MemOp[0] = ST->getMemOperand();
703 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
705 ReplaceUses(ST, Result);
706 ReplaceUses(SDValue(ST,1), SDValue(Result,1));
710 // Note: Order of operands matches the def of instruction:
711 // def STrid : STInst<(outs), (ins MEMri:$addr, DoubleRegs:$src1), ...
712 // and it differs for POST_ST* for instance.
713 SDValue Ops[] = { Base, CurDAG->getTargetConstant(0, MVT::i32), Value,
717 // Figure out the opcode.
718 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid;
719 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
720 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih;
721 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib;
722 else llvm_unreachable("unknown memory type");
724 // Build regular store.
725 SDValue TargetConstVal = CurDAG->getTargetConstant(Val, MVT::i32);
726 SDNode* Result_1 = CurDAG->getMachineNode(Opcode, dl, MVT::Other, Ops,
728 // Build splitted incriment instruction.
729 SDNode* Result_2 = CurDAG->getMachineNode(Hexagon::ADD_ri, dl, MVT::i32,
732 SDValue(Result_1, 0));
733 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
734 MemOp[0] = ST->getMemOperand();
735 cast<MachineSDNode>(Result_1)->setMemRefs(MemOp, MemOp + 1);
737 ReplaceUses(SDValue(ST,0), SDValue(Result_2,0));
738 ReplaceUses(SDValue(ST,1), SDValue(Result_1,0));
743 SDNode *HexagonDAGToDAGISel::SelectBaseOffsetStore(StoreSDNode *ST,
745 SDValue Chain = ST->getChain();
746 SDNode* Const32 = ST->getBasePtr().getNode();
747 SDValue Value = ST->getValue();
750 // Try to lower stores of GlobalAdresses into indexed stores. Custom
751 // lowering for GlobalAddress nodes has already turned it into a
752 // CONST32. Avoid truncating stores for the moment. Post-inc stores
753 // do the same. Don't think there's a reason for it, so will file a
755 if ((Const32->getOpcode() == HexagonISD::CONST32) &&
756 !(Value.getValueType() == MVT::i64 && ST->isTruncatingStore())) {
757 SDValue Base = Const32->getOperand(0);
758 if (Base.getOpcode() == ISD::TargetGlobalAddress) {
759 EVT StoredVT = ST->getMemoryVT();
760 int64_t Offset = cast<GlobalAddressSDNode>(Base)->getOffset();
761 if (Offset != 0 && OffsetFitsS11(StoredVT, Offset)) {
762 MVT PointerTy = TLI.getPointerTy();
763 const GlobalValue* GV =
764 cast<GlobalAddressSDNode>(Base)->getGlobal();
766 CurDAG->getTargetGlobalAddress(GV, dl, PointerTy, 0);
767 SDNode* NewBase = CurDAG->getMachineNode(Hexagon::CONST32_set,
771 // Figure out base + offset opcode
772 if (StoredVT == MVT::i64) Opcode = Hexagon::STrid_indexed;
773 else if (StoredVT == MVT::i32) Opcode = Hexagon::STriw_indexed;
774 else if (StoredVT == MVT::i16) Opcode = Hexagon::STrih_indexed;
775 else if (StoredVT == MVT::i8) Opcode = Hexagon::STrib_indexed;
776 else llvm_unreachable("unknown memory type");
778 SDValue Ops[] = {SDValue(NewBase,0),
779 CurDAG->getTargetConstant(Offset,PointerTy),
781 // build indexed store
782 SDNode* Result = CurDAG->getMachineNode(Opcode, dl,
784 MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1);
785 MemOp[0] = ST->getMemOperand();
786 cast<MachineSDNode>(Result)->setMemRefs(MemOp, MemOp + 1);
787 ReplaceUses(ST, Result);
793 return SelectCode(ST);
797 SDNode *HexagonDAGToDAGISel::SelectStore(SDNode *N) {
798 DebugLoc dl = N->getDebugLoc();
799 StoreSDNode *ST = cast<StoreSDNode>(N);
800 ISD::MemIndexedMode AM = ST->getAddressingMode();
802 // Handle indexed stores.
803 if (AM != ISD::UNINDEXED) {
804 return SelectIndexedStore(ST, dl);
807 return SelectBaseOffsetStore(ST, dl);
810 SDNode *HexagonDAGToDAGISel::SelectMul(SDNode *N) {
811 DebugLoc dl = N->getDebugLoc();
814 // %conv.i = sext i32 %tmp1 to i64
815 // %conv2.i = sext i32 %add to i64
816 // %mul.i = mul nsw i64 %conv2.i, %conv.i
818 // --- match with the following ---
820 // %mul.i = mpy (%tmp1, %add)
823 if (N->getValueType(0) == MVT::i64) {
824 // Shifting a i64 signed multiply.
825 SDValue MulOp0 = N->getOperand(0);
826 SDValue MulOp1 = N->getOperand(1);
831 // Handle sign_extend and sextload.
832 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
833 SDValue Sext0 = MulOp0.getOperand(0);
834 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
835 return SelectCode(N);
839 } else if (MulOp0.getOpcode() == ISD::LOAD) {
840 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
841 if (LD->getMemoryVT() != MVT::i32 ||
842 LD->getExtensionType() != ISD::SEXTLOAD ||
843 LD->getAddressingMode() != ISD::UNINDEXED) {
844 return SelectCode(N);
847 SDValue Chain = LD->getChain();
848 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
849 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
851 LD->getBasePtr(), TargetConst0,
854 return SelectCode(N);
857 // Same goes for the second operand.
858 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
859 SDValue Sext1 = MulOp1.getOperand(0);
860 if (Sext1.getNode()->getValueType(0) != MVT::i32) {
861 return SelectCode(N);
865 } else if (MulOp1.getOpcode() == ISD::LOAD) {
866 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
867 if (LD->getMemoryVT() != MVT::i32 ||
868 LD->getExtensionType() != ISD::SEXTLOAD ||
869 LD->getAddressingMode() != ISD::UNINDEXED) {
870 return SelectCode(N);
873 SDValue Chain = LD->getChain();
874 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
875 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
877 LD->getBasePtr(), TargetConst0,
880 return SelectCode(N);
883 // Generate a mpy instruction.
884 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY64, dl, MVT::i64,
886 ReplaceUses(N, Result);
890 return SelectCode(N);
894 SDNode *HexagonDAGToDAGISel::SelectSelect(SDNode *N) {
895 DebugLoc dl = N->getDebugLoc();
896 SDValue N0 = N->getOperand(0);
897 if (N0.getOpcode() == ISD::SETCC) {
898 SDValue N00 = N0.getOperand(0);
899 if (N00.getOpcode() == ISD::SIGN_EXTEND_INREG) {
900 SDValue N000 = N00.getOperand(0);
901 SDValue N001 = N00.getOperand(1);
902 if (cast<VTSDNode>(N001)->getVT() == MVT::i16) {
903 SDValue N01 = N0.getOperand(1);
904 SDValue N02 = N0.getOperand(2);
906 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
907 // i16:Other),IntRegs:i32:$src1, SETLT:Other),IntRegs:i32:$src1,
908 // IntRegs:i32:$src2)
909 // Emits: (MAXh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
910 // Pattern complexity = 9 cost = 1 size = 0.
911 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETLT) {
912 SDValue N1 = N->getOperand(1);
914 SDValue N2 = N->getOperand(2);
916 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
917 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
918 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
920 SDNode *Result = CurDAG->getMachineNode(Hexagon::MAXw_rr, dl,
922 SDValue(SextNode, 0),
924 ReplaceUses(N, Result);
930 // Pattern: (select:i32 (setcc:i1 (sext_inreg:i32 IntRegs:i32:$src2,
931 // i16:Other), IntRegs:i32:$src1, SETGT:Other), IntRegs:i32:$src1,
932 // IntRegs:i32:$src2)
933 // Emits: (MINh_rr:i32 IntRegs:i32:$src1, IntRegs:i32:$src2)
934 // Pattern complexity = 9 cost = 1 size = 0.
935 if (cast<CondCodeSDNode>(N02)->get() == ISD::SETGT) {
936 SDValue N1 = N->getOperand(1);
938 SDValue N2 = N->getOperand(2);
940 N0.getNode()->getValueType(N0.getResNo()) == MVT::i1 &&
941 N00.getNode()->getValueType(N00.getResNo()) == MVT::i32) {
942 SDNode *SextNode = CurDAG->getMachineNode(Hexagon::SXTH, dl,
944 SDNode *Result = CurDAG->getMachineNode(Hexagon::MINw_rr, dl,
946 SDValue(SextNode, 0),
948 ReplaceUses(N, Result);
957 return SelectCode(N);
961 SDNode *HexagonDAGToDAGISel::SelectTruncate(SDNode *N) {
962 DebugLoc dl = N->getDebugLoc();
963 SDValue Shift = N->getOperand(0);
966 // %conv.i = sext i32 %tmp1 to i64
967 // %conv2.i = sext i32 %add to i64
968 // %mul.i = mul nsw i64 %conv2.i, %conv.i
969 // %shr5.i = lshr i64 %mul.i, 32
970 // %conv3.i = trunc i64 %shr5.i to i32
972 // --- match with the following ---
974 // %conv3.i = mpy (%tmp1, %add)
977 if (N->getValueType(0) == MVT::i32) {
979 if (Shift.getNode()->getValueType(0) == MVT::i64) {
980 // Trunc child is logical shift right.
981 if (Shift.getOpcode() != ISD::SRL) {
982 return SelectCode(N);
985 SDValue ShiftOp0 = Shift.getOperand(0);
986 SDValue ShiftOp1 = Shift.getOperand(1);
989 if (ShiftOp1.getOpcode() != ISD::Constant) {
990 return SelectCode(N);
994 cast<ConstantSDNode>(ShiftOp1.getNode())->getSExtValue();
995 if (ShiftConst != 32) {
996 return SelectCode(N);
999 // Shifting a i64 signed multiply
1000 SDValue Mul = ShiftOp0;
1001 if (Mul.getOpcode() != ISD::MUL) {
1002 return SelectCode(N);
1005 SDValue MulOp0 = Mul.getOperand(0);
1006 SDValue MulOp1 = Mul.getOperand(1);
1011 // Handle sign_extend and sextload
1012 if (MulOp0.getOpcode() == ISD::SIGN_EXTEND) {
1013 SDValue Sext0 = MulOp0.getOperand(0);
1014 if (Sext0.getNode()->getValueType(0) != MVT::i32) {
1015 return SelectCode(N);
1019 } else if (MulOp0.getOpcode() == ISD::LOAD) {
1020 LoadSDNode *LD = cast<LoadSDNode>(MulOp0.getNode());
1021 if (LD->getMemoryVT() != MVT::i32 ||
1022 LD->getExtensionType() != ISD::SEXTLOAD ||
1023 LD->getAddressingMode() != ISD::UNINDEXED) {
1024 return SelectCode(N);
1027 SDValue Chain = LD->getChain();
1028 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1029 OP0 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1032 TargetConst0, Chain), 0);
1034 return SelectCode(N);
1037 // Same goes for the second operand.
1038 if (MulOp1.getOpcode() == ISD::SIGN_EXTEND) {
1039 SDValue Sext1 = MulOp1.getOperand(0);
1040 if (Sext1.getNode()->getValueType(0) != MVT::i32)
1041 return SelectCode(N);
1044 } else if (MulOp1.getOpcode() == ISD::LOAD) {
1045 LoadSDNode *LD = cast<LoadSDNode>(MulOp1.getNode());
1046 if (LD->getMemoryVT() != MVT::i32 ||
1047 LD->getExtensionType() != ISD::SEXTLOAD ||
1048 LD->getAddressingMode() != ISD::UNINDEXED) {
1049 return SelectCode(N);
1052 SDValue Chain = LD->getChain();
1053 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1054 OP1 = SDValue (CurDAG->getMachineNode(Hexagon::LDriw, dl, MVT::i32,
1057 TargetConst0, Chain), 0);
1059 return SelectCode(N);
1062 // Generate a mpy instruction.
1063 SDNode *Result = CurDAG->getMachineNode(Hexagon::MPY, dl, MVT::i32,
1065 ReplaceUses(N, Result);
1070 return SelectCode(N);
1074 SDNode *HexagonDAGToDAGISel::SelectSHL(SDNode *N) {
1075 DebugLoc dl = N->getDebugLoc();
1076 if (N->getValueType(0) == MVT::i32) {
1077 SDValue Shl_0 = N->getOperand(0);
1078 SDValue Shl_1 = N->getOperand(1);
1080 if (Shl_1.getOpcode() == ISD::Constant) {
1081 if (Shl_0.getOpcode() == ISD::MUL) {
1082 SDValue Mul_0 = Shl_0.getOperand(0); // Val
1083 SDValue Mul_1 = Shl_0.getOperand(1); // Const
1084 // RHS of mul is const.
1085 if (Mul_1.getOpcode() == ISD::Constant) {
1087 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1089 cast<ConstantSDNode>(Mul_1.getNode())->getSExtValue();
1090 int32_t ValConst = MulConst << ShlConst;
1091 SDValue Val = CurDAG->getTargetConstant(ValConst,
1093 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val.getNode()))
1094 if (isInt<9>(CN->getSExtValue())) {
1096 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl,
1097 MVT::i32, Mul_0, Val);
1098 ReplaceUses(N, Result);
1103 } else if (Shl_0.getOpcode() == ISD::SUB) {
1104 SDValue Sub_0 = Shl_0.getOperand(0); // Const 0
1105 SDValue Sub_1 = Shl_0.getOperand(1); // Val
1106 if (Sub_0.getOpcode() == ISD::Constant) {
1108 cast<ConstantSDNode>(Sub_0.getNode())->getSExtValue();
1109 if (SubConst == 0) {
1110 if (Sub_1.getOpcode() == ISD::SHL) {
1111 SDValue Shl2_0 = Sub_1.getOperand(0); // Val
1112 SDValue Shl2_1 = Sub_1.getOperand(1); // Const
1113 if (Shl2_1.getOpcode() == ISD::Constant) {
1115 cast<ConstantSDNode>(Shl_1.getNode())->getSExtValue();
1117 cast<ConstantSDNode>(Shl2_1.getNode())->getSExtValue();
1118 int32_t ValConst = 1 << (ShlConst+Shl2Const);
1119 SDValue Val = CurDAG->getTargetConstant(-ValConst, MVT::i32);
1120 if (ConstantSDNode *CN =
1121 dyn_cast<ConstantSDNode>(Val.getNode()))
1122 if (isInt<9>(CN->getSExtValue())) {
1124 CurDAG->getMachineNode(Hexagon::MPYI_ri, dl, MVT::i32,
1126 ReplaceUses(N, Result);
1136 return SelectCode(N);
1141 // If there is an zero_extend followed an intrinsic in DAG (this means - the
1142 // result of the intrinsic is predicate); convert the zero_extend to
1143 // transfer instruction.
1145 // Zero extend -> transfer is lowered here. Otherwise, zero_extend will be
1146 // converted into a MUX as predicate registers defined as 1 bit in the
1147 // compiler. Architecture defines them as 8-bit registers.
1148 // We want to preserve all the lower 8-bits and, not just 1 LSB bit.
1150 SDNode *HexagonDAGToDAGISel::SelectZeroExtend(SDNode *N) {
1151 DebugLoc dl = N->getDebugLoc();
1152 SDNode *IsIntrinsic = N->getOperand(0).getNode();
1153 if ((IsIntrinsic->getOpcode() == ISD::INTRINSIC_WO_CHAIN)) {
1155 cast<ConstantSDNode>(IsIntrinsic->getOperand(0))->getZExtValue();
1156 if (doesIntrinsicReturnPredicate(ID)) {
1157 // Now we need to differentiate target data types.
1158 if (N->getValueType(0) == MVT::i64) {
1159 // Convert the zero_extend to Rs = Pd followed by COMBINE_rr(0,Rs).
1160 SDValue TargetConst0 = CurDAG->getTargetConstant(0, MVT::i32);
1161 SDNode *Result_1 = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1163 SDValue(IsIntrinsic, 0));
1164 SDNode *Result_2 = CurDAG->getMachineNode(Hexagon::TFRI, dl,
1167 SDNode *Result_3 = CurDAG->getMachineNode(Hexagon::COMBINE_rr, dl,
1168 MVT::i64, MVT::Other,
1169 SDValue(Result_2, 0),
1170 SDValue(Result_1, 0));
1171 ReplaceUses(N, Result_3);
1174 if (N->getValueType(0) == MVT::i32) {
1175 // Convert the zero_extend to Rs = Pd
1176 SDNode* RsPd = CurDAG->getMachineNode(Hexagon::TFR_RsPd, dl,
1178 SDValue(IsIntrinsic, 0));
1179 ReplaceUses(N, RsPd);
1182 llvm_unreachable("Unexpected value type");
1185 return SelectCode(N);
1190 // Checking for intrinsics which have predicate registers as operand(s)
1191 // and lowering to the actual intrinsic.
1193 SDNode *HexagonDAGToDAGISel::SelectIntrinsicWOChain(SDNode *N) {
1194 DebugLoc dl = N->getDebugLoc();
1195 unsigned ID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
1196 unsigned IntrinsicWithPred = doesIntrinsicContainPredicate(ID);
1198 // We are concerned with only those intrinsics that have predicate registers
1199 // as at least one of the operands.
1200 if (IntrinsicWithPred) {
1201 SmallVector<SDValue, 8> Ops;
1202 const MCInstrDesc &MCID = TII->get(IntrinsicWithPred);
1203 const TargetRegisterInfo *TRI = TM.getRegisterInfo();
1205 // Iterate over all the operands of the intrinsics.
1206 // For PredRegs, do the transfer.
1207 // For Double/Int Regs, just preserve the value
1208 // For immediates, lower it.
1209 for (unsigned i = 1; i < N->getNumOperands(); ++i) {
1210 SDNode *Arg = N->getOperand(i).getNode();
1211 const TargetRegisterClass *RC = TII->getRegClass(MCID, i, TRI, *MF);
1213 if (RC == &Hexagon::IntRegsRegClass ||
1214 RC == &Hexagon::DoubleRegsRegClass) {
1215 Ops.push_back(SDValue(Arg, 0));
1216 } else if (RC == &Hexagon::PredRegsRegClass) {
1218 SDNode *PdRs = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1220 Ops.push_back(SDValue(PdRs,0));
1221 } else if (RC == NULL && (dyn_cast<ConstantSDNode>(Arg) != NULL)) {
1222 // This is immediate operand. Lower it here making sure that we DO have
1223 // const SDNode for immediate value.
1224 int32_t Val = cast<ConstantSDNode>(Arg)->getSExtValue();
1225 SDValue SDVal = CurDAG->getTargetConstant(Val, MVT::i32);
1226 Ops.push_back(SDVal);
1228 llvm_unreachable("Unimplemented");
1231 EVT ReturnValueVT = N->getValueType(0);
1232 SDNode *Result = CurDAG->getMachineNode(IntrinsicWithPred, dl,
1234 Ops.data(), Ops.size());
1235 ReplaceUses(N, Result);
1238 return SelectCode(N);
1242 // Map floating point constant values.
1244 SDNode *HexagonDAGToDAGISel::SelectConstantFP(SDNode *N) {
1245 DebugLoc dl = N->getDebugLoc();
1246 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N);
1247 APFloat APF = CN->getValueAPF();
1248 if (N->getValueType(0) == MVT::f32) {
1249 return CurDAG->getMachineNode(Hexagon::TFRI_f, dl, MVT::f32,
1250 CurDAG->getTargetConstantFP(APF.convertToFloat(), MVT::f32));
1252 else if (N->getValueType(0) == MVT::f64) {
1253 return CurDAG->getMachineNode(Hexagon::CONST64_Float_Real, dl, MVT::f64,
1254 CurDAG->getTargetConstantFP(APF.convertToDouble(), MVT::f64));
1257 return SelectCode(N);
1262 // Map predicate true (encoded as -1 in LLVM) to a XOR.
1264 SDNode *HexagonDAGToDAGISel::SelectConstant(SDNode *N) {
1265 DebugLoc dl = N->getDebugLoc();
1266 if (N->getValueType(0) == MVT::i1) {
1268 int32_t Val = cast<ConstantSDNode>(N)->getSExtValue();
1270 // Create the IntReg = 1 node.
1272 CurDAG->getMachineNode(Hexagon::TFRI, dl, MVT::i32,
1273 CurDAG->getTargetConstant(0, MVT::i32));
1276 SDNode* Pd = CurDAG->getMachineNode(Hexagon::TFR_PdRs, dl, MVT::i1,
1277 SDValue(IntRegTFR, 0));
1280 SDNode* NotPd = CurDAG->getMachineNode(Hexagon::NOT_p, dl, MVT::i1,
1284 Result = CurDAG->getMachineNode(Hexagon::XOR_pp, dl, MVT::i1,
1285 SDValue(Pd, 0), SDValue(NotPd, 0));
1287 // We have just built:
1289 // Pd = xor(not(Pd), Pd)
1291 ReplaceUses(N, Result);
1296 return SelectCode(N);
1301 // Map add followed by a asr -> asr +=.
1303 SDNode *HexagonDAGToDAGISel::SelectAdd(SDNode *N) {
1304 DebugLoc dl = N->getDebugLoc();
1305 if (N->getValueType(0) != MVT::i32) {
1306 return SelectCode(N);
1308 // Identify nodes of the form: add(asr(...)).
1309 SDNode* Src1 = N->getOperand(0).getNode();
1310 if (Src1->getOpcode() != ISD::SRA || !Src1->hasOneUse()
1311 || Src1->getValueType(0) != MVT::i32) {
1312 return SelectCode(N);
1315 // Build Rd = Rd' + asr(Rs, Rt). The machine constraints will ensure that
1316 // Rd and Rd' are assigned to the same register
1317 SDNode* Result = CurDAG->getMachineNode(Hexagon::ASR_ADD_rr, dl, MVT::i32,
1319 Src1->getOperand(0),
1320 Src1->getOperand(1));
1321 ReplaceUses(N, Result);
1327 SDNode *HexagonDAGToDAGISel::Select(SDNode *N) {
1328 if (N->isMachineOpcode())
1329 return NULL; // Already selected.
1332 switch (N->getOpcode()) {
1334 return SelectConstant(N);
1336 case ISD::ConstantFP:
1337 return SelectConstantFP(N);
1340 return SelectAdd(N);
1343 return SelectSHL(N);
1346 return SelectLoad(N);
1349 return SelectStore(N);
1352 return SelectSelect(N);
1355 return SelectTruncate(N);
1358 return SelectMul(N);
1360 case ISD::ZERO_EXTEND:
1361 return SelectZeroExtend(N);
1363 case ISD::INTRINSIC_WO_CHAIN:
1364 return SelectIntrinsicWOChain(N);
1367 return SelectCode(N);
1372 // Hexagon_TODO: Five functions for ADDRri?! Surely there must be a better way
1373 // to define these instructions.
1375 bool HexagonDAGToDAGISel::SelectADDRri(SDValue& Addr, SDValue &Base,
1377 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1378 Addr.getOpcode() == ISD::TargetGlobalAddress)
1379 return false; // Direct calls.
1381 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1382 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1383 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1387 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1392 bool HexagonDAGToDAGISel::SelectADDRriS11_0(SDValue& Addr, SDValue &Base,
1394 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1395 Addr.getOpcode() == ISD::TargetGlobalAddress)
1396 return false; // Direct calls.
1398 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1399 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1400 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1401 return (IsS11_0_Offset(Offset.getNode()));
1404 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1405 return (IsS11_0_Offset(Offset.getNode()));
1409 bool HexagonDAGToDAGISel::SelectADDRriS11_1(SDValue& Addr, SDValue &Base,
1411 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1412 Addr.getOpcode() == ISD::TargetGlobalAddress)
1413 return false; // Direct calls.
1415 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1416 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1417 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1418 return (IsS11_1_Offset(Offset.getNode()));
1421 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1422 return (IsS11_1_Offset(Offset.getNode()));
1426 bool HexagonDAGToDAGISel::SelectADDRriS11_2(SDValue& Addr, SDValue &Base,
1428 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1429 Addr.getOpcode() == ISD::TargetGlobalAddress)
1430 return false; // Direct calls.
1432 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1433 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1434 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1435 return (IsS11_2_Offset(Offset.getNode()));
1438 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1439 return (IsS11_2_Offset(Offset.getNode()));
1443 bool HexagonDAGToDAGISel::SelectADDRriU6_0(SDValue& Addr, SDValue &Base,
1445 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1446 Addr.getOpcode() == ISD::TargetGlobalAddress)
1447 return false; // Direct calls.
1449 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1450 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1451 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1452 return (IsU6_0_Offset(Offset.getNode()));
1455 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1456 return (IsU6_0_Offset(Offset.getNode()));
1460 bool HexagonDAGToDAGISel::SelectADDRriU6_1(SDValue& Addr, SDValue &Base,
1462 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1463 Addr.getOpcode() == ISD::TargetGlobalAddress)
1464 return false; // Direct calls.
1466 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1467 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1468 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1469 return (IsU6_1_Offset(Offset.getNode()));
1472 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1473 return (IsU6_1_Offset(Offset.getNode()));
1477 bool HexagonDAGToDAGISel::SelectADDRriU6_2(SDValue& Addr, SDValue &Base,
1479 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1480 Addr.getOpcode() == ISD::TargetGlobalAddress)
1481 return false; // Direct calls.
1483 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1484 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1485 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1486 return (IsU6_2_Offset(Offset.getNode()));
1489 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1490 return (IsU6_2_Offset(Offset.getNode()));
1494 bool HexagonDAGToDAGISel::SelectMEMriS11_2(SDValue& Addr, SDValue &Base,
1497 if (Addr.getOpcode() != ISD::ADD) {
1498 return(SelectADDRriS11_2(Addr, Base, Offset));
1501 return SelectADDRriS11_2(Addr, Base, Offset);
1505 bool HexagonDAGToDAGISel::SelectADDRriS11_3(SDValue& Addr, SDValue &Base,
1507 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1508 Addr.getOpcode() == ISD::TargetGlobalAddress)
1509 return false; // Direct calls.
1511 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1512 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1513 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1514 return (IsS11_3_Offset(Offset.getNode()));
1517 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1518 return (IsS11_3_Offset(Offset.getNode()));
1521 bool HexagonDAGToDAGISel::SelectADDRrr(SDValue &Addr, SDValue &R1,
1523 if (Addr.getOpcode() == ISD::FrameIndex) return false;
1524 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1525 Addr.getOpcode() == ISD::TargetGlobalAddress)
1526 return false; // Direct calls.
1528 if (Addr.getOpcode() == ISD::ADD) {
1529 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
1530 if (isInt<13>(CN->getSExtValue()))
1531 return false; // Let the reg+imm pattern catch this!
1532 R1 = Addr.getOperand(0);
1533 R2 = Addr.getOperand(1);
1543 // Handle generic address case. It is accessed from inlined asm =m constraints,
1544 // which could have any kind of pointer.
1545 bool HexagonDAGToDAGISel::SelectAddr(SDNode *Op, SDValue Addr,
1546 SDValue &Base, SDValue &Offset) {
1547 if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
1548 Addr.getOpcode() == ISD::TargetGlobalAddress)
1549 return false; // Direct calls.
1551 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
1552 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
1553 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1557 if (Addr.getOpcode() == ISD::ADD) {
1558 Base = Addr.getOperand(0);
1559 Offset = Addr.getOperand(1);
1564 Offset = CurDAG->getTargetConstant(0, MVT::i32);
1569 bool HexagonDAGToDAGISel::
1570 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
1571 std::vector<SDValue> &OutOps) {
1574 switch (ConstraintCode) {
1575 case 'o': // Offsetable.
1576 case 'v': // Not offsetable.
1577 default: return true;
1578 case 'm': // Memory.
1579 if (!SelectAddr(Op.getNode(), Op, Op0, Op1))
1584 OutOps.push_back(Op0);
1585 OutOps.push_back(Op1);
1589 bool HexagonDAGToDAGISel::isConstExtProfitable(SDNode *N) const {
1590 unsigned UseCount = 0;
1591 for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
1595 return (UseCount <= 1);
1599 //===--------------------------------------------------------------------===//
1600 // Return 'true' if use count of the global address is below threshold.
1601 //===--------------------------------------------------------------------===//
1602 bool HexagonDAGToDAGISel::hasNumUsesBelowThresGA(SDNode *N) const {
1603 assert(N->getOpcode() == ISD::TargetGlobalAddress &&
1604 "Expecting a target global address");
1606 // Always try to fold the address.
1607 if (TM.getOptLevel() == CodeGenOpt::Aggressive)
1610 GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
1611 DenseMap<const GlobalValue *, unsigned>::const_iterator GI =
1612 GlobalAddressUseCountMap.find(GA->getGlobal());
1614 if (GI == GlobalAddressUseCountMap.end())
1617 return GI->second <= MaxNumOfUsesForConstExtenders;
1620 //===--------------------------------------------------------------------===//
1621 // Return true if the non GP-relative global address can be folded.
1622 //===--------------------------------------------------------------------===//
1623 inline bool HexagonDAGToDAGISel::foldGlobalAddress(SDValue &N, SDValue &R) {
1624 return foldGlobalAddressImpl(N, R, false);
1627 //===--------------------------------------------------------------------===//
1628 // Return true if the GP-relative global address can be folded.
1629 //===--------------------------------------------------------------------===//
1630 inline bool HexagonDAGToDAGISel::foldGlobalAddressGP(SDValue &N, SDValue &R) {
1631 return foldGlobalAddressImpl(N, R, true);
1634 //===--------------------------------------------------------------------===//
1635 // Fold offset of the global address if number of uses are below threshold.
1636 //===--------------------------------------------------------------------===//
1637 bool HexagonDAGToDAGISel::foldGlobalAddressImpl(SDValue &N, SDValue &R,
1638 bool ShouldLookForGP) {
1639 if (N.getOpcode() == ISD::ADD) {
1640 SDValue N0 = N.getOperand(0);
1641 SDValue N1 = N.getOperand(1);
1642 if ((ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32_GP)) ||
1643 (!ShouldLookForGP && (N0.getOpcode() == HexagonISD::CONST32))) {
1644 ConstantSDNode *Const = dyn_cast<ConstantSDNode>(N1);
1645 GlobalAddressSDNode *GA =
1646 dyn_cast<GlobalAddressSDNode>(N0.getOperand(0));
1649 (GA->getOpcode() == ISD::TargetGlobalAddress)) {
1650 if ((N0.getOpcode() == HexagonISD::CONST32) &&
1651 !hasNumUsesBelowThresGA(GA))
1653 R = CurDAG->getTargetGlobalAddress(GA->getGlobal(),
1654 Const->getDebugLoc(),
1657 (uint64_t)Const->getSExtValue());