llvm.org GIT mirror llvm / 77f452d
Updated i128 sext support for CellSPU backend, contributed by Ken Werner (IBM) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80042 91177308-0d34-0410-b5e6-96231b3b80d8 Scott Michel 11 years ago
2 changed file(s) with 65 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
349349 // Custom lower i128 -> i64 truncates
350350 setOperationAction(ISD::TRUNCATE, MVT::i64, Custom);
351351
352 // Custom lower i64 -> i128 sign extend
352 // Custom lower i32/i64 -> i128 sign extend
353353 setOperationAction(ISD::SIGN_EXTEND, MVT::i128, Custom);
354354
355355 setOperationAction(ISD::FP_TO_SINT, MVT::i8, Promote);
26092609 return SDValue(); // Leave the truncate unmolested
26102610 }
26112611
2612 //! Custom lower ISD::SIGN_EXTEND
2612 /*!
2613 * Emit the instruction sequence for i64/i32 -> i128 sign extend. The basic
2614 * algorithm is to duplicate the sign bit using rotmai to generate at
2615 * least one byte full of sign bits. Then propagate the "sign-byte" into
2616 * the leftmost words and the i64/i32 into the rightmost words using shufb.
2617 *
2618 * @param Op The sext operand
2619 * @param DAG The current DAG
2620 * @return The SDValue with the entire instruction sequence
2621 */
26132622 static SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG)
26142623 {
2624 DebugLoc dl = Op.getDebugLoc();
2625
26152626 // Type to extend to
2616 EVT VT = Op.getValueType();
2617 DebugLoc dl = Op.getDebugLoc();
2627 MVT OpVT = Op.getValueType().getSimpleVT();
2628 EVT VecVT = EVT::getVectorVT(*DAG.getContext(),
2629 OpVT, (128 / OpVT.getSizeInBits()));
26182630
26192631 // Type to extend from
26202632 SDValue Op0 = Op.getOperand(0);
2621 EVT Op0VT = Op0.getValueType();
2622
2623 assert((VT == MVT::i128 && Op0VT == MVT::i64) &&
2633 MVT Op0VT = Op0.getValueType().getSimpleVT();
2634
2635 // The type to extend to needs to be a i128 and
2636 // the type to extend from needs to be i64 or i32.
2637 assert((OpVT == MVT::i128 && (Op0VT == MVT::i64 || Op0VT == MVT::i32)) &&
26242638 "LowerSIGN_EXTEND: input and/or output operand have wrong size");
26252639
26262640 // Create shuffle mask
2627 unsigned mask1 = 0x10101010; // byte 0 - 3 and 4 - 7
2628 unsigned mask2 = 0x01020304; // byte 8 - 11
2629 unsigned mask3 = 0x05060708; // byte 12 - 15
2641 unsigned mask1 = 0x10101010; // byte 0 - 3 and 4 - 7
2642 unsigned mask2 = Op0VT == MVT::i64 ? 0x00010203 : 0x10101010; // byte 8 - 11
2643 unsigned mask3 = Op0VT == MVT::i64 ? 0x04050607 : 0x00010203; // byte 12 - 15
26302644 SDValue shufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v4i32,
26312645 DAG.getConstant(mask1, MVT::i32),
26322646 DAG.getConstant(mask1, MVT::i32),
26332647 DAG.getConstant(mask2, MVT::i32),
26342648 DAG.getConstant(mask3, MVT::i32));
26352649
2636 // Word wise arithmetic right shift to generate a byte that contains sign bits
2650 // Word wise arithmetic right shift to generate at least one byte
2651 // that contains sign bits.
2652 MVT mvt = Op0VT == MVT::i64 ? MVT::v2i64 : MVT::v4i32;
26372653 SDValue sraVal = DAG.getNode(ISD::SRA,
26382654 dl,
2639 MVT::v2i64,
2640 DAG.getNode(SPUISD::PREFSLOT2VEC, dl, MVT::v2i64, Op0, Op0),
2655 mvt,
2656 DAG.getNode(SPUISD::PREFSLOT2VEC, dl, mvt, Op0, Op0),
26412657 DAG.getConstant(31, MVT::i32));
26422658
2643 // shuffle bytes - copies the sign bits into the upper 64 bits
2644 // and the input value into the lower 64 bits
2645 SDValue extShuffle = DAG.getNode(SPUISD::SHUFB, dl, MVT::v2i64,
2646 Op0, sraVal, shufMask);
2659 // Shuffle bytes - Copy the sign bits into the upper 64 bits
2660 // and the input value into the lower 64 bits.
2661 SDValue extShuffle = DAG.getNode(SPUISD::SHUFB, dl, mvt,
2662 DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i128, Op0), sraVal, shufMask);
26472663
26482664 return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i128, extShuffle);
26492665 }
55
66 define i128 @sext_i64_i128(i64 %a) {
77 entry:
8 %0 = sext i64 %a to i128
9 ret i128 %0
810 ; CHECK: long 269488144
911 ; CHECK: long 269488144
10 ; CHECK: long 16909060
11 ; CHECK: long 84281096
12 ; CHECK: long 66051
13 ; CHECK: long 67438087
1214 ; CHECK: rotmai
1315 ; CHECK: lqa
1416 ; CHECK: shufb
15 %0 = sext i64 %a to i128
17 }
18
19 define i128 @sext_i32_i128(i32 %a) {
20 entry:
21 %0 = sext i32 %a to i128
1622 ret i128 %0
23 ; CHECK: long 269488144
24 ; CHECK: long 269488144
25 ; CHECK: long 269488144
26 ; CHECK: long 66051
27 ; CHECK: rotmai
28 ; CHECK: lqa
29 ; CHECK: shufb
1730 }
31
32 define i128 @sext_i32_i128a(float %a) {
33 entry:
34 %0 = call i32 @myfunc(float %a)
35 %1 = sext i32 %0 to i128
36 ret i128 %1
37 ; CHECK: long 269488144
38 ; CHECK: long 269488144
39 ; CHECK: long 269488144
40 ; CHECK: long 66051
41 ; CHECK: rotmai
42 ; CHECK: lqa
43 ; CHECK: shufb
44 }
45
46 declare i32 @myfunc(float)