// Return-value convention for Cell SPU: return value to be passed in reg 3-74
def RetCC_SPU : CallingConv<[
- CCIfType<[i8,i16,i32,i64,i128,f32,f64,v16i8,v8i16,v4i32,v2i64,v4f32,v2f64,
- v2i32, v2f32],
+ CCIfType<[i8,i16,i32,i64,i128,f32,f64,v16i8,v8i16,v4i32,v2i64,v4f32,v2f64],
CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11,
R12, R13, R14, R15, R16, R17, R18, R19, R20,
R21, R22, R23, R24, R25, R26, R27, R28, R29,
//===----------------------------------------------------------------------===//
def CCC_SPU : CallingConv<[
CCIfType<[i8, i16, i32, i64, i128, f32, f64,
- v16i8, v8i16, v4i32, v4f32, v2i64, v2f64, v2i32, v2f32],
+ v16i8, v8i16, v4i32, v4f32, v2i64, v2f64],
CCAssignToReg<[R3, R4, R5, R6, R7, R8, R9, R10, R11,
R12, R13, R14, R15, R16, R17, R18, R19, R20,
R21, R22, R23, R24, R25, R26, R27, R28, R29,
addRegisterClass(MVT::v4f32, SPU::VECREGRegisterClass);
addRegisterClass(MVT::v2f64, SPU::VECREGRegisterClass);
- // "Odd size" vector classes that we're willing to support:
- addRegisterClass(MVT::v2i32, SPU::VECREGRegisterClass);
- addRegisterClass(MVT::v2f32, SPU::VECREGRegisterClass);
-
for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
MVT::SimpleValueType VT = (MVT::SimpleValueType)i;
setOperationAction(ISD::FDIV, MVT::v4f32, Legal);
- setOperationAction(ISD::STORE, MVT::v2i32, Custom);
- setOperationAction(ISD::STORE, MVT::v2f32, Custom);
-
setShiftAmountType(MVT::i32);
setBooleanContents(ZeroOrNegativeOneBooleanContent);
case MVT::v4i32:
case MVT::v8i16:
case MVT::v16i8:
- case MVT::v2i32:
- case MVT::v2f32:
ArgRegClass = &SPU::VECREGRegClass;
break;
}
SDValue T = DAG.getConstant(unsigned(SplatBits), VT.getVectorElementType());
return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, T, T, T, T);
}
- case MVT::v2f32:
- case MVT::v2i32: {
- return SDValue();
- }
case MVT::v2i64: {
return SPU::LowerV2I64Splat(VT, DAG, SplatBits, dl);
}
} else if (EltVT == MVT::i16) {
V2EltIdx0 = 8;
maskVT = MVT::v8i16;
- } else if (VecVT == MVT::v2i32 || VecVT == MVT::v2f32 ) {
- V2EltIdx0 = 2;
- maskVT = MVT::v4i32;
} else if (EltVT == MVT::i32 || EltVT == MVT::f32) {
V2EltIdx0 = 4;
maskVT = MVT::v4i32;
for (unsigned j = 0; j < BytesPerElement; ++j)
ResultMask.push_back(DAG.getConstant(SrcElt*BytesPerElement+j,MVT::i8));
}
- // For half vectors padd the mask with zeros for the second half.
- // This is needed because mask is assumed to be full vector elsewhere in
- // the SPU backend.
- if(VecVT == MVT::v2i32 || VecVT == MVT::v2f32)
- for( unsigned i = 0; i < 2; ++i )
- {
- for (unsigned j = 0; j < BytesPerElement; ++j)
- ResultMask.push_back(DAG.getConstant(0,MVT::i8));
- }
-
SDValue VPermMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::v16i8,
&ResultMask[0], ResultMask.size());
return DAG.getNode(SPUISD::SHUFB, dl, V1.getValueType(), V1, V2, VPermMask);
case MVT::v4f32: n_copies = 4; VT = MVT::f32; break;
case MVT::v2i64: n_copies = 2; VT = MVT::i64; break;
case MVT::v2f64: n_copies = 2; VT = MVT::f64; break;
- case MVT::v2i32: n_copies = 2; VT = MVT::i32; break;
}
SDValue CValue = DAG.getConstant(CN->getZExtValue(), VT);
def v4f32: LoadDFormVec<v4f32>;
def v2f64: LoadDFormVec<v2f64>;
- def v2i32: LoadDFormVec<v2i32>;
- def v2f32: LoadDFormVec<v2f32>;
-
def r128: LoadDForm<GPRC>;
def r64: LoadDForm<R64C>;
def r32: LoadDForm<R32C>;
def v4f32: LoadAFormVec<v4f32>;
def v2f64: LoadAFormVec<v2f64>;
- def v2i32: LoadAFormVec<v2i32>;
- def v2f32: LoadAFormVec<v2f32>;
-
def r128: LoadAForm<GPRC>;
def r64: LoadAForm<R64C>;
def r32: LoadAForm<R32C>;
def v4f32: LoadXFormVec<v4f32>;
def v2f64: LoadXFormVec<v2f64>;
- def v2i32: LoadXFormVec<v2i32>;
- def v2f32: LoadXFormVec<v2f32>;
-
def r128: LoadXForm<GPRC>;
def r64: LoadXForm<R64C>;
def r32: LoadXForm<R32C>;
def v4f32: StoreDFormVec<v4f32>;
def v2f64: StoreDFormVec<v2f64>;
- def v2i32: StoreDFormVec<v2i32>;
- def v2f32: StoreDFormVec<v2f32>;
-
def r128: StoreDForm<GPRC>;
def r64: StoreDForm<R64C>;
def r32: StoreDForm<R32C>;
def v4f32: StoreAFormVec<v4f32>;
def v2f64: StoreAFormVec<v2f64>;
- def v2i32: StoreAFormVec<v2i32>;
- def v2f32: StoreAFormVec<v2f32>;
-
def r128: StoreAForm<GPRC>;
def r64: StoreAForm<R64C>;
def r32: StoreAForm<R32C>;
def v4f32: StoreXFormVec<v4f32>;
def v2f64: StoreXFormVec<v2f64>;
- def v2i32: StoreXFormVec<v2i32>;
- def v2f32: StoreXFormVec<v2f32>;
-
def r128: StoreXForm<GPRC>;
def r64: StoreXForm<R64C>;
def r32: StoreXForm<R32C>;
multiclass AddInstruction {
def v4i32: AVecInst<v4i32>;
def v16i8: AVecInst<v16i8>;
- def v2i32: AVecInst<v2i32>;
def r32: ARegInst<R32C>;
}
"sf\t$rT, $rA, $rB", IntegerOp,
[(set (v4i32 VECREG:$rT), (sub (v4i32 VECREG:$rB), (v4i32 VECREG:$rA)))]>;
-def SF2vec : RRForm<0b00000010000, (outs VECREG:$rT),
- (ins VECREG:$rA, VECREG:$rB),
- "sf\t$rT, $rA, $rB", IntegerOp,
- [(set (v2i32 VECREG:$rT), (sub (v2i32 VECREG:$rB), (v2i32 VECREG:$rA)))]>;
-
def SFr32 : RRForm<0b00000010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
"sf\t$rT, $rA, $rB", IntegerOp,
MPYUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
[/* no pattern */]>;
-def MPYUv2i32:
- MPYUInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- [/* no pattern */]>;
-
def MPYUr16:
MPYUInst<(outs R32C:$rT), (ins R16C:$rA, R16C:$rB),
[(set R32C:$rT, (mul (zext R16C:$rA), (zext R16C:$rB)))]>;
MPYHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
[/* no pattern */]>;
-def MPYHv2i32:
- MPYHInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB),
- [/* no pattern */]>;
-
def MPYHr32:
MPYHInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB),
[/* no pattern */]>;
def f32_v4f32: ORExtractElt<R32FP>;
def f64_v2f64: ORExtractElt<R64FP>;
- // half <-> full vector mappings
- def v2i32_v4i32: ORCvtVecVec;
- def v4i32_v2i32: ORCvtVecVec;
- def v2f32_v4f32: ORCvtVecVec;
- def v4f32_v2f32: ORCvtVecVec;
-
-
// Conversion from vector to GPRC
def i128_vec: ORCvtVecGPRC;
def : Pat<(v4i32 (SPUprefslot2vec R32C:$rA)),
(ORv4i32_i32 R32C:$rA)>;
-def : Pat<(v2i32 (SPUprefslot2vec R32C:$rA)),
- (ORv4i32_i32 R32C:$rA)>;
-
def : Pat<(v2i64 (SPUprefslot2vec R64C:$rA)),
(ORv2i64_i64 R64C:$rA)>;
def : Pat<(v4f32 (SPUprefslot2vec R32FP:$rA)),
(ORv4f32_f32 R32FP:$rA)>;
-def : Pat<(v2f32 (SPUprefslot2vec R32FP:$rA)),
- (ORv4f32_f32 R32FP:$rA)>;
-
def : Pat<(v2f64 (SPUprefslot2vec R64FP:$rA)),
(ORv2f64_f64 R64FP:$rA)>;
def : Pat<(SPUvec2prefslot (v4i32 VECREG:$rA)),
(ORi32_v4i32 VECREG:$rA)>;
-def : Pat<(SPUvec2prefslot (v2i32 VECREG:$rA)),
- (ORi32_v4i32 VECREG:$rA)>;
-
def : Pat<(SPUvec2prefslot (v2i64 VECREG:$rA)),
(ORi64_v2i64 VECREG:$rA)>;
def : Pat<(SPUvec2prefslot (v4f32 VECREG:$rA)),
(ORf32_v4f32 VECREG:$rA)>;
-def : Pat<(SPUvec2prefslot (v2f32 VECREG:$rA)),
- (ORf32_v4f32 VECREG:$rA)>;
-
def : Pat<(SPUvec2prefslot (v2f64 VECREG:$rA)),
(ORf64_v2f64 VECREG:$rA)>;
-// Conversions between 64 bit and 128 bit vectors.
-
-def : Pat<(v4i32 (SPUhalf2vec (v2i32 VECREG:$rA))),
- (ORv4i32_v2i32 (v2i32 VECREG:$rA))>;
-def : Pat<(v4f32 (SPUhalf2vec (v2f32 VECREG:$rA))),
- (ORv4f32_v2f32 (v2f32 VECREG:$rA))>;
-
-def : Pat<(v2i32 (SPUvec2half (v4i32 VECREG:$rA))),
- (ORv2i32_v4i32 VECREG:$rA)>;
-def : Pat<(v2f32 (SPUvec2half (v4f32 VECREG:$rA))),
- (ORv2f32_v4f32 VECREG:$rA)>;
-
// Load Register: This is an assembler alias for a bitwise OR of a register
// against itself. It's here because it brings some clarity to assembly
// language output.
def v8i16_m32 : SHUFBVecInst<v8i16, v4i32>;
def v4i32 : SHUFBVecInst<v4i32, v16i8>;
def v4i32_m32 : SHUFBVecInst<v4i32, v4i32>;
- def v2i32 : SHUFBVecInst<v2i32, v16i8>;
- def v2i32_m32 : SHUFBVecInst<v2i32, v4i32>;
def v2i64 : SHUFBVecInst<v2i64, v16i8>;
def v2i64_m32 : SHUFBVecInst<v2i64, v4i32>;
def v4f32 : SHUFBVecInst<v4f32, v16i8>;
def v4f32_m32 : SHUFBVecInst<v4f32, v4i32>;
- def v2f32 : SHUFBVecInst<v2f32, v16i8>;
- def v2f32_m32 : SHUFBVecInst<v2f32, v4i32>;
def v2f64 : SHUFBVecInst<v2f64, v16i8>;
def v2f64_m32 : SHUFBVecInst<v2f64, v4i32>;
multiclass SFPAdd
{
def v4f32: FAVecInst<v4f32>;
- def v2f32: FAVecInst<v2f32>;
def f32: FAInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
[(set R32FP:$rT, (fadd R32FP:$rA, R32FP:$rB))]>;
}
multiclass SFPSub
{
def v4f32: FSVecInst<v4f32>;
- def v2f32: FSVecInst<v2f32>;
def f32: FSInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
[(set R32FP:$rT, (fsub R32FP:$rA, R32FP:$rB))]>;
}
multiclass SFPMul
{
def v4f32: FMVecInst<v4f32>;
- def v2f32: FMVecInst<v2f32>;
def f32: FMInst<(outs R32FP:$rT), (ins R32FP:$rA, R32FP:$rB),
[(set R32FP:$rT, (fmul R32FP:$rA, R32FP:$rB))]>;
}
(FSMBIv8i16 0xcccc))>;
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
-// v4i32, v2i32, i32 multiply instruction sequence:
+// v4i32, i32 multiply instruction sequence:
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
def MPYv4i32:
(v4i32 (MPYHv4i32 VECREG:$rB, VECREG:$rA)))),
(v4i32 (MPYUv4i32 VECREG:$rA, VECREG:$rB)))>;
-def MPYv2i32:
- Pat<(mul (v2i32 VECREG:$rA), (v2i32 VECREG:$rB)),
- (Av2i32
- (v2i32 (Av2i32 (v2i32 (MPYHv2i32 VECREG:$rA, VECREG:$rB)),
- (v2i32 (MPYHv2i32 VECREG:$rB, VECREG:$rA)))),
- (v2i32 (MPYUv2i32 VECREG:$rA, VECREG:$rB)))>;
-
-
def MPYi32:
Pat<(mul R32C:$rA, R32C:$rB),
(Ar32
// The SPU's registers as vector registers:
def VECREG : RegisterClass<"SPU",
- [v16i8,v8i16,v2i32,v2f32,v4i32,v4f32,v2i64,v2f64],
+ [v16i8,v8i16,v4i32,v4f32,v2i64,v2f64],
128,
[
/* volatile register */
define ccc %paramstruct @test_return( i32 %param, %paramstruct %prm )
{
-;CHEKC: lqd $75, 80($sp)
+;CHECK: lqd $75, 80($sp)
;CHECK: lr $3, $4
ret %paramstruct %prm
}
define %vec @test_add(%vec %param)
{
-;CHECK: fa $3, $3, $3
+;CHECK: fa {{\$.}}, $3, $3
%1 = fadd %vec %param, %param
;CHECK: bi $lr
ret %vec %1
define %vec @test_sub(%vec %param)
{
-;CHECK: fs $3, $3, $3
+;CHECK: fs {{\$.}}, $3, $3
%1 = fsub %vec %param, %param
;CHECK: bi $lr
define %vec @test_mul(%vec %param)
{
-;CHECK: fm $3, $3, $3
+;CHECK: fm {{\$.}}, $3, $3
%1 = fmul %vec %param, %param
;CHECK: bi $lr
;CHECK: stqd
store %vec undef, %vec* null
-;CHECK: stqd $3, 0($4)
+;CHECK: stqd $3, 0(${{.}})
;CHECK: bi $lr
store %vec %val, %vec* %ptr
ret void
define %vec @test_add(%vec %param)
{
-;CHECK: a $3, $3, $3
+;CHECK: a {{\$.}}, $3, $3
%1 = add %vec %param, %param
;CHECK: bi $lr
ret %vec %1
define %vec @test_sub(%vec %param)
{
-;CHECK: sf $3, $4, $3
+;CHECK: sf {{\$.}}, $4, $3
%1 = sub %vec %param, <i32 1, i32 1>
;CHECK: bi $lr
{
;CHECK: mpyu
;CHECK: mpyh
-;CHECK: a
-;CHECK: a $3
+;CHECK: a {{\$., \$., \$.}}
+;CHECK: a {{\$., \$., \$.}}
%1 = mul %vec %param, %param
;CHECK: bi $lr
define void @test_store( %vec %val, %vec* %ptr)
{
-;CHECK: stqd $3, 0($4)
+;CHECK: stqd $3, 0(${{.}})
;CHECK: bi $lr
store %vec %val, %vec* %ptr
ret void