mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-10-10 16:24:04 +00:00
- 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:
parent
53dec47f3b
commit
ad2715e0d7
@ -243,15 +243,23 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM)
|
|||||||
|
|
||||||
setOperationAction(ISD::CTLZ , MVT::i32, Legal);
|
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::i1, Expand);
|
||||||
setOperationAction(ISD::SELECT, MVT::i8, Expand);
|
setOperationAction(ISD::SELECT, MVT::i8, Expand);
|
||||||
setOperationAction(ISD::SELECT, MVT::i16, Expand);
|
setOperationAction(ISD::SELECT, MVT::i16, Legal);
|
||||||
setOperationAction(ISD::SELECT, MVT::i32, Expand);
|
setOperationAction(ISD::SELECT, MVT::i32, Legal);
|
||||||
setOperationAction(ISD::SELECT, MVT::i64, Expand);
|
setOperationAction(ISD::SELECT, MVT::i64, Expand);
|
||||||
setOperationAction(ISD::SELECT, MVT::f32, Expand);
|
setOperationAction(ISD::SELECT, MVT::f32, Expand);
|
||||||
setOperationAction(ISD::SELECT, MVT::f64, 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
|
// Zero extension and sign extension for i64 have to be
|
||||||
// custom legalized
|
// custom legalized
|
||||||
setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
|
setOperationAction(ISD::ZERO_EXTEND, MVT::i64, Custom);
|
||||||
@ -838,7 +846,6 @@ LowerConstant(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
|
SDOperand T = DAG.getConstant(CN->getValue(), MVT::i64);
|
||||||
return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
|
return DAG.getNode(SPUISD::EXTRACT_ELT0, VT,
|
||||||
DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
|
DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
cerr << "LowerConstant: unhandled constant type "
|
cerr << "LowerConstant: unhandled constant type "
|
||||||
<< MVT::getValueTypeString(VT)
|
<< MVT::getValueTypeString(VT)
|
||||||
@ -981,6 +988,7 @@ LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, int &VarArgsFrameIndex)
|
|||||||
break;
|
break;
|
||||||
case MVT::v2f64:
|
case MVT::v2f64:
|
||||||
case MVT::v4f32:
|
case MVT::v4f32:
|
||||||
|
case MVT::v2i64:
|
||||||
case MVT::v4i32:
|
case MVT::v4i32:
|
||||||
case MVT::v8i16:
|
case MVT::v8i16:
|
||||||
case MVT::v16i8:
|
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,
|
SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
|
||||||
MVT::ValueType ValueType) {
|
MVT::ValueType ValueType) {
|
||||||
if (ConstantSDNode *CN = getVecImm(N)) {
|
if (ConstantSDNode *CN = getVecImm(N)) {
|
||||||
if (ValueType == MVT::i32) {
|
int64_t Value = CN->getSignExtended();
|
||||||
int Value = (int) CN->getValue();
|
if (Value >= -(1 << 15) && Value <= ((1 << 15) - 1)) {
|
||||||
int SExtValue = ((Value & 0xffff) << 16) >> 16;
|
return DAG.getConstant(Value, ValueType);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1389,9 +1382,8 @@ SDOperand SPU::get_vec_i16imm(SDNode *N, SelectionDAG &DAG,
|
|||||||
SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
|
SDOperand SPU::get_vec_i10imm(SDNode *N, SelectionDAG &DAG,
|
||||||
MVT::ValueType ValueType) {
|
MVT::ValueType ValueType) {
|
||||||
if (ConstantSDNode *CN = getVecImm(N)) {
|
if (ConstantSDNode *CN = getVecImm(N)) {
|
||||||
int Value = (int) CN->getValue();
|
int64_t Value = CN->getSignExtended();
|
||||||
if ((ValueType == MVT::i32 && isS10Constant(Value))
|
if (isS10Constant(Value))
|
||||||
|| (ValueType == MVT::i16 && isS10Constant((short) Value)))
|
|
||||||
return DAG.getConstant(Value, ValueType);
|
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 upper = uint32_t(val >> 32);
|
||||||
uint32_t lower = uint32_t(val);
|
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 LO32;
|
||||||
SDOperand HI32;
|
SDOperand HI32;
|
||||||
SmallVector<SDOperand, 16> ShufBytes;
|
SmallVector<SDOperand, 16> ShufBytes;
|
||||||
@ -1708,12 +1707,6 @@ static SDOperand LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
|
|||||||
return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
|
return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32,
|
||||||
DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
|
DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8,
|
||||||
&ShufBytes[0], ShufBytes.size()));
|
&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
@ -59,7 +59,7 @@ def SPUv4i32_binop: SDTypeProfile<1, 2, [
|
|||||||
// FSMBI type constraints: There are several variations for the various
|
// FSMBI type constraints: There are several variations for the various
|
||||||
// vector types (this avoids having to bit_convert all over the place.)
|
// vector types (this avoids having to bit_convert all over the place.)
|
||||||
def SPUfsmbi_type: SDTypeProfile<1, 1, [
|
def SPUfsmbi_type: SDTypeProfile<1, 1, [
|
||||||
SDTCisVT<1, i32>]>;
|
/* SDTCisVT<1, i32> */ SDTCisInt<1>]>;
|
||||||
|
|
||||||
// SELB type constraints:
|
// SELB type constraints:
|
||||||
def SPUselb_type: SDTypeProfile<1, 3, [
|
def SPUselb_type: SDTypeProfile<1, 3, [
|
||||||
|
@ -141,7 +141,7 @@ def imm18 : PatLeaf<(imm), [{
|
|||||||
}]>;
|
}]>;
|
||||||
|
|
||||||
def lo16 : 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:
|
// low order bits and is a 32-bit constant:
|
||||||
if (N->getValueType(0) == MVT::i32) {
|
if (N->getValueType(0) == MVT::i32) {
|
||||||
uint32_t val = N->getValue();
|
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
|
// hi16 predicate - returns true if the immediate has all zeros in the
|
||||||
// low order bits and is a 32-bit constant:
|
// low order bits and is a 32-bit constant:
|
||||||
if (N->getValueType(0) == MVT::i32) {
|
if (N->getValueType(0) == MVT::i32) {
|
||||||
uint32_t val = N->getValue();
|
uint32_t val = uint32_t(N->getValue());
|
||||||
return ((val & 0xffff0000) == val);
|
return ((val & 0xffff0000) == val);
|
||||||
|
} else if (N->getValueType(0) == MVT::i64) {
|
||||||
|
uint64_t val = N->getValue();
|
||||||
|
return ((val & 0xffff0000ULL) == val);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -503,6 +506,10 @@ def s16imm_f64: Operand<f64> {
|
|||||||
let PrintMethod = "printS16ImmOperand";
|
let PrintMethod = "printS16ImmOperand";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def u16imm_i64 : Operand<i64> {
|
||||||
|
let PrintMethod = "printU16ImmOperand";
|
||||||
|
}
|
||||||
|
|
||||||
def u16imm : Operand<i32> {
|
def u16imm : Operand<i32> {
|
||||||
let PrintMethod = "printU16ImmOperand";
|
let PrintMethod = "printU16ImmOperand";
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user