- Fix support for "special" i64 immediates that can be loaded

using IL, ILA, et. al. v2i64 and i64 are now supported by
  the select bits (SELB) instruction.

- Add missing comparison operations (testcase forthcoming)

- More multiclass refactoring.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47973 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Scott Michel 2008-03-05 23:02:02 +00:00
parent 53dec47f3b
commit ad2715e0d7
4 changed files with 363 additions and 649 deletions

View File

@ -243,15 +243,23 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
setOperationAction(ISD::CTLZ , MVT::i32, Legal);
// SPU does not have select or setcc
// SPU has a version of select
setOperationAction(ISD::SELECT, MVT::i1, Expand);
setOperationAction(ISD::SELECT, MVT::i8, Expand);
setOperationAction(ISD::SELECT, MVT::i16, Expand);
setOperationAction(ISD::SELECT, MVT::i32, Expand);
setOperationAction(ISD::SELECT, MVT::i16, Legal);
setOperationAction(ISD::SELECT, MVT::i32, Legal);
setOperationAction(ISD::SELECT, MVT::i64, Expand);
setOperationAction(ISD::SELECT, MVT::f32, Expand);
setOperationAction(ISD::SELECT, MVT::f64, Expand);
setOperationAction(ISD::SETCC, MVT::i1, Expand);
setOperationAction(ISD::SETCC, MVT::i8, Expand);
setOperationAction(ISD::SETCC, MVT::i16, Legal);
setOperationAction(ISD::SETCC, MVT::i32, Legal);
setOperationAction(ISD::SETCC, MVT::i64, Expand);
setOperationAction(ISD::SETCC, MVT::f32, Expand);
setOperationAction(ISD::SETCC, MVT::f64, Expand);
// Zero extension and sign extension for i64 have to be
// custom legalized
setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
@ -838,7 +846,6 @@ LowerConstant(SDOperand Op, SelectionDAG &DAG) {
SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
} else {
cerr << "LowerConstant: unhandled constant type "
<< MVT::getValueTypeString(VT)
@ -981,6 +988,7 @@ LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
break;
case MVT::v2f64:
case MVT::v4f32:
case MVT::v2i64:
case MVT::v4i32:
case MVT::v8i16:
case MVT::v16i8:
@ -1359,24 +1367,9 @@ SDOperand SPU::get_vec_u18imm(SDNode *N, SelectionDAG &DAG,
SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
MVT::ValueType ValueType) {
if (ConstantSDNode *CN = getVecImm(N)) {
if (ValueType == MVT::i32) {
int Value = (int) CN->getValue();
int SExtValue = ((Value & 0xffff) << 16) >> 16;
if (Value == SExtValue)
return DAG.getConstant(Value, ValueType);
} else if (ValueType == MVT::i16) {
short Value = (short) CN->getValue();
int SExtValue = ((int) Value << 16) >> 16;
if (Value == (short) SExtValue)
return DAG.getConstant(Value, ValueType);
} else if (ValueType == MVT::i64) {
int64_t Value = CN->getValue();
int64_t SExtValue = ((Value & 0xffff) << (64 - 16)) >> (64 - 16);
if (Value == SExtValue)
return DAG.getConstant(Value, ValueType);
int64_t Value = CN->getSignExtended();
if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
return DAG.getConstant(Value, ValueType);
}
}
@ -1389,9 +1382,8 @@ SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
MVT::ValueType ValueType) {
if (ConstantSDNode *CN = getVecImm(N)) {
int Value = (int) CN->getValue();
if ((ValueType == MVT::i32 && isS10Constant(Value))
|| (ValueType == MVT::i16 && isS10Constant((short) Value)))
int64_t Value = CN->getSignExtended();
if (isS10Constant(Value))
return DAG.getConstant(Value, ValueType);
}
@ -1634,7 +1626,14 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
uint32_t upper = uint32_t(val >> 32);
uint32_t lower = uint32_t(val);
if (val != 0) {
if (val == 0) {
SDOperand Zero = DAG.getTargetConstant(0, MVT::i64);
return DAG.getNode(ISD::BUILD_VECTOR, VT, Zero, Zero);
} else if (val == 0xffffffffffffffffULL) {
// For -1, this and has a chance of matching immAllOnesV.
SDOperand NegOne = DAG.getTargetConstant(-1, MVT::i64);
return DAG.getNode(ISD::BUILD_VECTOR, VT, NegOne, NegOne);
} else {
SDOperand LO32;
SDOperand HI32;
SmallVector<SDOperand, 16> ShufBytes;
@ -1708,12 +1707,6 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
&ShufBytes[0], ShufBytes.size()));
} else {
// For zero, this can be lowered efficiently via v4i32 BUILD_VECTOR
SDOperand Zero = DAG.getConstant(0, MVT::i32);
return DAG.getNode(ISD::BIT_CONVERT, VT,
DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32,
Zero, Zero, Zero, Zero));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,7 @@ def SPUv4i32_binop: SDTypeProfile<1, 2, [
// FSMBI type constraints: There are several variations for the various
// vector types (this avoids having to bit_convert all over the place.)
def SPUfsmbi_type: SDTypeProfile<1, 1, [
SDTCisVT<1, i32>]>;
/* SDTCisVT<1, i32> */ SDTCisInt<1>]>;
// SELB type constraints:
def SPUselb_type: SDTypeProfile<1, 3, [

View File

@ -141,7 +141,7 @@ def imm18 : PatLeaf<(imm), [{
}]>;
def lo16 : PatLeaf<(imm), [{
// hi16 predicate - returns true if the immediate has all zeros in the
// lo16 predicate - returns true if the immediate has all zeros in the
// low order bits and is a 32-bit constant:
if (N->getValueType(0) == MVT::i32) {
uint32_t val = N->getValue();
@ -155,8 +155,11 @@ def hi16 : PatLeaf<(imm), [{
// hi16 predicate - returns true if the immediate has all zeros in the
// low order bits and is a 32-bit constant:
if (N->getValueType(0) == MVT::i32) {
uint32_t val = N->getValue();
uint32_t val = uint32_t(N->getValue());
return ((val & 0xffff0000) == val);
} else if (N->getValueType(0) == MVT::i64) {
uint64_t val = N->getValue();
return ((val & 0xffff0000ULL) == val);
}
return false;
@ -503,6 +506,10 @@ def s16imm_f64: Operand<f64> {
let PrintMethod = "printS16ImmOperand";
}
def u16imm_i64 : Operand<i64> {
let PrintMethod = "printU16ImmOperand";
}
def u16imm : Operand<i32> {
let PrintMethod = "printU16ImmOperand";
}