mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 19:23:23 +01:00
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. llvm-svn: 61829
This commit is contained in:
parent
b19f5073f9
commit
54f7f6d67f
@ -21,13 +21,14 @@ class CCIfSubtarget<string F, CCAction A>
|
||||
|
||||
// Return-value convention for Cell SPU: Everything can be passed back via $3:
|
||||
def RetCC_SPU : CallingConv<[
|
||||
CCIfType<[i8], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i16], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i32], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i64], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i128], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i8], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i16], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i32], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i64], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[i128], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[f32, f64], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[R3]>>
|
||||
CCIfType<[v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], CCAssignToReg<[R3]>>,
|
||||
CCIfType<[v2i32], CCAssignToReg<[R3]>>
|
||||
]>;
|
||||
|
||||
|
||||
|
@ -327,6 +327,9 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
|
||||
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);
|
||||
|
||||
for (unsigned i = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
|
||||
i <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++i) {
|
||||
MVT VT = (MVT::SimpleValueType)i;
|
||||
@ -417,7 +420,6 @@ SPUTargetLowering::getTargetNodeName(unsigned Opcode) const
|
||||
node_names[(unsigned) SPUISD::CARRY_GENERATE] = "SPUISD::CARRY_GENERATE";
|
||||
node_names[(unsigned) SPUISD::SUB_EXTENDED] = "SPUISD::SUB_EXTENDED";
|
||||
node_names[(unsigned) SPUISD::BORROW_GENERATE] = "SPUISD::BORROW_GENERATE";
|
||||
node_names[(unsigned) SPUISD::SEXT32TO64] = "SPUISD::SEXT32TO64";
|
||||
}
|
||||
|
||||
std::map<unsigned, const char *>::iterator i = node_names.find(Opcode);
|
||||
@ -1029,8 +1031,7 @@ static SDNode *isLSAAddress(SDValue Op, SelectionDAG &DAG) {
|
||||
return DAG.getConstant((int)C->getZExtValue() >> 2, MVT::i32).getNode();
|
||||
}
|
||||
|
||||
static
|
||||
SDValue
|
||||
static SDValue
|
||||
LowerCALL(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) {
|
||||
CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
|
||||
SDValue Chain = TheCall->getChain();
|
||||
@ -1618,6 +1619,11 @@ static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) {
|
||||
SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
|
||||
return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T, T, T);
|
||||
}
|
||||
case MVT::v2i32: {
|
||||
unsigned int Value = SplatBits;
|
||||
SDValue T = DAG.getConstant(Value, VT.getVectorElementType());
|
||||
return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T);
|
||||
}
|
||||
case MVT::v2i64: {
|
||||
uint64_t val = SplatBits;
|
||||
uint32_t upper = uint32_t(val >> 32);
|
||||
@ -2454,32 +2460,6 @@ static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) {
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
//! Lower ISD::SETCC
|
||||
/*!
|
||||
Lower i64 condition code handling.
|
||||
*/
|
||||
|
||||
static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) {
|
||||
MVT VT = Op.getValueType();
|
||||
SDValue lhs = Op.getOperand(0);
|
||||
SDValue rhs = Op.getOperand(1);
|
||||
SDValue condition = Op.getOperand(2);
|
||||
|
||||
if (VT == MVT::i32 && lhs.getValueType() == MVT::i64) {
|
||||
// Expand the i64 comparisons to what Cell can actually support,
|
||||
// which is eq, ugt and sgt:
|
||||
#if 0
|
||||
CondCodeSDNode *ccvalue = dyn_cast<CondCodeSDValue>(condition);
|
||||
|
||||
switch (ccvalue->get()) {
|
||||
case
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
}
|
||||
|
||||
//! Lower ISD::SELECT_CC
|
||||
/*!
|
||||
ISD::SELECT_CC can (generally) be implemented directly on the SPU using the
|
||||
@ -2647,9 +2627,6 @@ SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG)
|
||||
|
||||
case ISD::TRUNCATE:
|
||||
return LowerTRUNCATE(Op, DAG);
|
||||
|
||||
case ISD::SETCC:
|
||||
return LowerSETCC(Op, DAG);
|
||||
}
|
||||
|
||||
return SDValue();
|
||||
@ -2971,7 +2948,6 @@ SPUTargetLowering::computeMaskedBitsForTargetNode(const SDValue Op,
|
||||
case SPUISD::ROTBYTES_LEFT:
|
||||
case SPUISD::SELECT_MASK:
|
||||
case SPUISD::SELB:
|
||||
case SPUISD::SEXT32TO64:
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -52,12 +52,10 @@ namespace llvm {
|
||||
ROTBYTES_LEFT_BITS, ///< Rotate bytes left by bit shift count
|
||||
SELECT_MASK, ///< Select Mask (FSM, FSMB, FSMH, FSMBI)
|
||||
SELB, ///< Select bits -> (b & mask) | (a & ~mask)
|
||||
GATHER_BITS, ///< Gather bits from bytes/words/halfwords
|
||||
ADD_EXTENDED, ///< Add extended, with carry
|
||||
CARRY_GENERATE, ///< Carry generate for ADD_EXTENDED
|
||||
SUB_EXTENDED, ///< Subtract extended, with borrow
|
||||
BORROW_GENERATE, ///< Borrow generate for SUB_EXTENDED
|
||||
SEXT32TO64, ///< Sign-extended 32-bit const -> 64-bits
|
||||
LAST_SPUISD ///< Last user-defined instruction
|
||||
};
|
||||
}
|
||||
|
@ -71,6 +71,8 @@ let canFoldAsLoad = 1 in {
|
||||
def v4f32: LoadDFormVec<v4f32>;
|
||||
def v2f64: LoadDFormVec<v2f64>;
|
||||
|
||||
def v2i32: LoadDFormVec<v2i32>;
|
||||
|
||||
def r128: LoadDForm<GPRC>;
|
||||
def r64: LoadDForm<R64C>;
|
||||
def r32: LoadDForm<R32C>;
|
||||
@ -103,6 +105,8 @@ let canFoldAsLoad = 1 in {
|
||||
def v4f32: LoadAFormVec<v4f32>;
|
||||
def v2f64: LoadAFormVec<v2f64>;
|
||||
|
||||
def v2i32: LoadAFormVec<v2i32>;
|
||||
|
||||
def r128: LoadAForm<GPRC>;
|
||||
def r64: LoadAForm<R64C>;
|
||||
def r32: LoadAForm<R32C>;
|
||||
@ -135,6 +139,8 @@ let canFoldAsLoad = 1 in {
|
||||
def v4f32: LoadXFormVec<v4f32>;
|
||||
def v2f64: LoadXFormVec<v2f64>;
|
||||
|
||||
def v2i32: LoadXFormVec<v2i32>;
|
||||
|
||||
def r128: LoadXForm<GPRC>;
|
||||
def r64: LoadXForm<R64C>;
|
||||
def r32: LoadXForm<R32C>;
|
||||
@ -183,6 +189,8 @@ multiclass StoreDForms
|
||||
def v4f32: StoreDFormVec<v4f32>;
|
||||
def v2f64: StoreDFormVec<v2f64>;
|
||||
|
||||
def v2i32: StoreDFormVec<v2i32>;
|
||||
|
||||
def r128: StoreDForm<GPRC>;
|
||||
def r64: StoreDForm<R64C>;
|
||||
def r32: StoreDForm<R32C>;
|
||||
@ -213,6 +221,8 @@ multiclass StoreAForms
|
||||
def v4f32: StoreAFormVec<v4f32>;
|
||||
def v2f64: StoreAFormVec<v2f64>;
|
||||
|
||||
def v2i32: StoreAFormVec<v2i32>;
|
||||
|
||||
def r128: StoreAForm<GPRC>;
|
||||
def r64: StoreAForm<R64C>;
|
||||
def r32: StoreAForm<R32C>;
|
||||
@ -245,6 +255,8 @@ multiclass StoreXForms
|
||||
def v4f32: StoreXFormVec<v4f32>;
|
||||
def v2f64: StoreXFormVec<v2f64>;
|
||||
|
||||
def v2i32: StoreXFormVec<v2i32>;
|
||||
|
||||
def r128: StoreXForm<GPRC>;
|
||||
def r64: StoreXForm<R64C>;
|
||||
def r32: StoreXForm<R32C>;
|
||||
@ -1044,11 +1056,11 @@ class GBBInst<dag OOL, dag IOL, list<dag> pattern>:
|
||||
|
||||
class GBBRegInst<RegisterClass rclass, ValueType vectype>:
|
||||
GBBInst<(outs rclass:$rT), (ins VECREG:$rA),
|
||||
[(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
|
||||
[/* no pattern */]>;
|
||||
|
||||
class GBBVecInst<ValueType vectype>:
|
||||
GBBInst<(outs VECREG:$rT), (ins VECREG:$rA),
|
||||
[(set (vectype VECREG:$rT), (SPUgatherbits (vectype VECREG:$rA)))]>;
|
||||
[/* no pattern */]>;
|
||||
|
||||
multiclass GatherBitsFromBytes {
|
||||
def v16i8_r32: GBBRegInst<R32C, v16i8>;
|
||||
@ -1070,12 +1082,11 @@ class GBHInst<dag OOL, dag IOL, list<dag> pattern>:
|
||||
|
||||
class GBHRegInst<RegisterClass rclass, ValueType vectype>:
|
||||
GBHInst<(outs rclass:$rT), (ins VECREG:$rA),
|
||||
[(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
|
||||
[/* no pattern */]>;
|
||||
|
||||
class GBHVecInst<ValueType vectype>:
|
||||
GBHInst<(outs VECREG:$rT), (ins VECREG:$rA),
|
||||
[(set (vectype VECREG:$rT),
|
||||
(SPUgatherbits (vectype VECREG:$rA)))]>;
|
||||
[/* no pattern */]>;
|
||||
|
||||
multiclass GatherBitsHalfword {
|
||||
def v8i16_r32: GBHRegInst<R32C, v8i16>;
|
||||
@ -1097,12 +1108,11 @@ class GBInst<dag OOL, dag IOL, list<dag> pattern>:
|
||||
|
||||
class GBRegInst<RegisterClass rclass, ValueType vectype>:
|
||||
GBInst<(outs rclass:$rT), (ins VECREG:$rA),
|
||||
[(set rclass:$rT, (SPUgatherbits (vectype VECREG:$rA)))]>;
|
||||
[/* no pattern */]>;
|
||||
|
||||
class GBVecInst<ValueType vectype>:
|
||||
GBInst<(outs VECREG:$rT), (ins VECREG:$rA),
|
||||
[(set (vectype VECREG:$rT),
|
||||
(SPUgatherbits (vectype VECREG:$rA)))]>;
|
||||
[/* no pattern */]>;
|
||||
|
||||
multiclass GatherBitsWord {
|
||||
def v4i32_r32: GBRegInst<R32C, v4i32>;
|
||||
|
@ -61,13 +61,6 @@ def SPUselb_type: SDTypeProfile<1, 3, [
|
||||
def SPUvecshift_type: SDTypeProfile<1, 2, [
|
||||
SDTCisSameAs<0, 1>, SDTCisInt<2>]>;
|
||||
|
||||
// SPU gather bits:
|
||||
// This instruction looks at each vector (word|halfword|byte) slot's low bit
|
||||
// and forms a mask in the low order bits of the first word's preferred slot.
|
||||
def SPUgatherbits_type: SDTypeProfile<1, 1, [
|
||||
/* no type constraints defined */
|
||||
]>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Synthetic/pseudo-instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -115,9 +108,6 @@ def SPUselmask: SDNode<"SPUISD::SELECT_MASK", SPUselmask_type, []>;
|
||||
// SPU select bits instruction
|
||||
def SPUselb: SDNode<"SPUISD::SELB", SPUselb_type, []>;
|
||||
|
||||
// SPU gather bits instruction:
|
||||
def SPUgatherbits: SDNode<"SPUISD::GATHER_BITS", SPUgatherbits_type, []>;
|
||||
|
||||
def SDTprefslot2vec: SDTypeProfile<1, 1, []>;
|
||||
def SPUprefslot2vec: SDNode<"SPUISD::PREFSLOT2VEC", SDTprefslot2vec, []>;
|
||||
|
||||
|
@ -393,7 +393,9 @@ def R8C : RegisterClass<"SPU", [i8], 128,
|
||||
}
|
||||
|
||||
// The SPU's registers as vector registers:
|
||||
def VECREG : RegisterClass<"SPU", [v16i8,v8i16,v4i32,v4f32,v2i64,v2f64], 128,
|
||||
def VECREG : RegisterClass<"SPU",
|
||||
[v16i8,v8i16,v2i32,v4i32,v4f32,v2i64,v2f64],
|
||||
128,
|
||||
[
|
||||
/* volatile register */
|
||||
R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, R16,
|
||||
|
@ -85,7 +85,7 @@ namespace llvm {
|
||||
/// properties of this subtarget.
|
||||
const char *getTargetDataString() const {
|
||||
return "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128"
|
||||
"-i16:16:128-i8:8:128-i1:8:128-a:0:128-v128:128:128"
|
||||
"-i16:16:128-i8:8:128-i1:8:128-a:0:128-v64:128:128-v128:128:128"
|
||||
"-s:128:128";
|
||||
}
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user