llvm.org GIT mirror llvm / 21213e7
CellSPU: - Add preliminary support for v2i32; load/store generates the right code but there's a lot work to be done to make this vector type operational. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61829 91177308-0d34-0410-b5e6-96231b3b80d8 Scott Michel 11 years ago
7 changed file(s) with 38 addition(s) and 61 deletion(s). Raw diff Collapse all Expand all
2020
2121 // Return-value convention for Cell SPU: Everything can be passed back via $3:
2222 def RetCC_SPU : CallingConv<[
23 CCIfType<[i8], CCAssignToReg<[R3]>>,
24 CCIfType<[i16], CCAssignToReg<[R3]>>,
25 CCIfType<[i32], CCAssignToReg<[R3]>>,
26 CCIfType<[i64], CCAssignToReg<[R3]>>,
27 CCIfType<[i128], CCAssignToReg<[R3]>>,
23 CCIfType<[i8], CCAssignToReg<[R3]>>,
24 CCIfType<[i16], CCAssignToReg<[R3]>>,
25 CCIfType<[i32], CCAssignToReg<[R3]>>,
26 CCIfType<[i64], CCAssignToReg<[R3]>>,
27 CCIfType<[i128], CCAssignToReg<[R3]>>,
2828 CCIfType<[f32, f64], CCAssignToReg<[R3]>>,
29 CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[R3]>>
29 CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[R3]>>,
30 CCIfType<[v2i32], CCAssignToReg<[R3]>>
3031 ]>;
3132
3233
325325 addRegisterClass(MVT::v2i64, SPU::VECREGRegisterClass);
326326 addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
327327 addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
328
329 // "Odd size" vector classes that we're willing to support:
330 addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
328331
329332 for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
330333 i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
416419 node_names[(unsigned) SPUISD::CARRY_GENERATE] = "SPUISD::CARRY_GENERATE";
417420 node_names[(unsigned) SPUISD::SUB_EXTENDED] = "SPUISD::SUB_EXTENDED";
418421 node_names[(unsigned) SPUISD::BORROW_GENERATE] = "SPUISD::BORROW_GENERATE";
419 node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
420422 }
421423
422424 std::map::iterator i = node_names.find(Opcode);
10281030 return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
10291031 }
10301032
1031 static
1032 SDValue
1033 static SDValue
10331034 LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
10341035 CallSDNode *TheCall = cast(Op.getNode());
10351036 SDValue Chain = TheCall->getChain();
16171618 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
16181619 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
16191620 }
1621 case MVT::v2i32: {
1622 unsigned int Value = SplatBits;
1623 SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
1624 return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T);
1625 }
16201626 case MVT::v2i64: {
16211627 uint64_t val = SplatBits;
16221628 uint32_t upper = uint32_t(val >> 32);
24482454
24492455 case MVT::i64:
24502456 break;
2451 }
2452
2453 return SDValue();
2454 }
2455
2456 //! Lower ISD::SETCC
2457 /*!
2458 Lower i64 condition code handling.
2459 */
2460
2461 static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) {
2462 MVT VT = Op.getValueType();
2463 SDValue lhs = Op.getOperand(0);
2464 SDValue rhs = Op.getOperand(1);
2465 SDValue condition = Op.getOperand(2);
2466
2467 if (VT == MVT::i32 && lhs.getValueType() == MVT::i64) {
2468 // Expand the i64 comparisons to what Cell can actually support,
2469 // which is eq, ugt and sgt:
2470 #if 0
2471 CondCodeSDNode *ccvalue = dyn_cast(condition);
2472
2473 switch (ccvalue->get()) {
2474 case
2475 }
2476 #endif
24772457 }
24782458
24792459 return SDValue();
26462626
26472627 case ISD::TRUNCATE:
26482628 return LowerTRUNCATE(Op, DAG);
2649
2650 case ISD::SETCC:
2651 return LowerSETCC(Op, DAG);
26522629 }
26532630
26542631 return SDValue();
29702947 case SPUISD::ROTBYTES_LEFT:
29712948 case SPUISD::SELECT_MASK:
29722949 case SPUISD::SELB:
2973 case SPUISD::SEXT32TO64:
29742950 #endif
29752951 }
29762952 }
5151 ROTBYTES_LEFT_BITS, ///< Rotate bytes left by bit shift count
5252 SELECT_MASK, ///< Select Mask (FSM, FSMB, FSMH, FSMBI)
5353 SELB, ///< Select bits -> (b & mask) | (a & ~mask)
54 GATHER_BITS, ///< Gather bits from bytes/words/halfwords
5554 ADD_EXTENDED, ///< Add extended, with carry
5655 CARRY_GENERATE, ///< Carry generate for ADD_EXTENDED
5756 SUB_EXTENDED, ///< Subtract extended, with borrow
5857 BORROW_GENERATE, ///< Borrow generate for SUB_EXTENDED
59 SEXT32TO64, ///< Sign-extended 32-bit const -> 64-bits
6058 LAST_SPUISD ///< Last user-defined instruction
6159 };
6260 }
7070 def v4f32: LoadDFormVec;
7171 def v2f64: LoadDFormVec;
7272
73 def v2i32: LoadDFormVec;
74
7375 def r128: LoadDForm;
7476 def r64: LoadDForm;
7577 def r32: LoadDForm;
102104 def v4f32: LoadAFormVec;
103105 def v2f64: LoadAFormVec;
104106
107 def v2i32: LoadAFormVec;
108
105109 def r128: LoadAForm;
106110 def r64: LoadAForm;
107111 def r32: LoadAForm;
134138 def v4f32: LoadXFormVec;
135139 def v2f64: LoadXFormVec;
136140
141 def v2i32: LoadXFormVec;
142
137143 def r128: LoadXForm;
138144 def r64: LoadXForm;
139145 def r32: LoadXForm;
182188 def v4f32: StoreDFormVec;
183189 def v2f64: StoreDFormVec;
184190
191 def v2i32: StoreDFormVec;
192
185193 def r128: StoreDForm;
186194 def r64: StoreDForm;
187195 def r32: StoreDForm;
212220 def v4f32: StoreAFormVec;
213221 def v2f64: StoreAFormVec;
214222
223 def v2i32: StoreAFormVec;
224
215225 def r128: StoreAForm;
216226 def r64: StoreAForm;
217227 def r32: StoreAForm;
243253 def v2i64: StoreXFormVec;
244254 def v4f32: StoreXFormVec;
245255 def v2f64: StoreXFormVec;
256
257 def v2i32: StoreXFormVec;
246258
247259 def r128: StoreXForm;
248260 def r64: StoreXForm;
10431055
10441056 class GBBRegInst:
10451057 GBBInst<(outs rclass:$rT), (ins VECREG:$rA),
1046 [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
1058 [/* no pattern */]>;
10471059
10481060 class GBBVecInst:
10491061 GBBInst<(outs VECREG:$rT), (ins VECREG:$rA),
1050 [(set (vectype VECREG:$rT), (SPUgatherbits (vectype VECREG:$rA)))]>;
1062 [/* no pattern */]>;
10511063
10521064 multiclass GatherBitsFromBytes {
10531065 def v16i8_r32: GBBRegInst;
10691081
10701082 class GBHRegInst:
10711083 GBHInst<(outs rclass:$rT), (ins VECREG:$rA),
1072 [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
1084 [/* no pattern */]>;
10731085
10741086 class GBHVecInst:
10751087 GBHInst<(outs VECREG:$rT), (ins VECREG:$rA),
1076 [(set (vectype VECREG:$rT),
1077 (SPUgatherbits (vectype VECREG:$rA)))]>;
1088 [/* no pattern */]>;
10781089
10791090 multiclass GatherBitsHalfword {
10801091 def v8i16_r32: GBHRegInst;
10961107
10971108 class GBRegInst:
10981109 GBInst<(outs rclass:$rT), (ins VECREG:$rA),
1099 [(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
1110 [/* no pattern */]>;
11001111
11011112 class GBVecInst:
11021113 GBInst<(outs VECREG:$rT), (ins VECREG:$rA),
1103 [(set (vectype VECREG:$rT),
1104 (SPUgatherbits (vectype VECREG:$rA)))]>;
1114 [/* no pattern */]>;
11051115
11061116 multiclass GatherBitsWord {
11071117 def v4i32_r32: GBRegInst;
6060 def SPUvecshift_type: SDTypeProfile<1, 2, [
6161 SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
6262
63 // SPU gather bits:
64 // This instruction looks at each vector (word|halfword|byte) slot's low bit
65 // and forms a mask in the low order bits of the first word's preferred slot.
66 def SPUgatherbits_type: SDTypeProfile<1, 1, [
67 /* no type constraints defined */
68 ]>;
69
7063 //===----------------------------------------------------------------------===//
7164 // Synthetic/pseudo-instructions
7265 //===----------------------------------------------------------------------===//
114107 // SPU select bits instruction
115108 def SPUselb: SDNode<"SPUISD::SELB", SPUselb_type, []>;
116109
117 // SPU gather bits instruction:
118 def SPUgatherbits: SDNode<"SPUISD::GATHER_BITS", SPUgatherbits_type, []>;
119
120110 def SDTprefslot2vec: SDTypeProfile<1, 1, []>;
121111 def SPUprefslot2vec: SDNode<"SPUISD::PREFSLOT2VEC", SDTprefslot2vec, []>;
122112
392392 }
393393
394394 // The SPU's registers as vector registers:
395 def VECREG : RegisterClass<"SPU", [v16i8,v8i16,v4i32,v4f32,v2i64,v2f64], 128,
395 def VECREG : RegisterClass<"SPU",
396 [v16i8,v8i16,v2i32,v4i32,v4f32,v2i64,v2f64],
397 128,
396398 [
397399 /* volatile register */
398400 R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
8484 /// properties of this subtarget.
8585 const char *getTargetDataString() const {
8686 return "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128"
87 "-i16:16:128-i8:8:128-i1:8:128-a:0:128-v128:128:128"
87 "-i16:16:128-i8:8:128-i1:8:128-a:0:128-v64:128:128-v128:128:128"
8888 "-s:128:128";
8989 }
9090 };