diff --git a/lib/Target/CellSPU/SPUISelLowering.cpp b/lib/Target/CellSPU/SPUISelLowering.cpp index 99243d3a62b..de1fff0ccae 100644 --- a/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/lib/Target/CellSPU/SPUISelLowering.cpp @@ -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 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)); } } } diff --git a/lib/Target/CellSPU/SPUInstrInfo.td b/lib/Target/CellSPU/SPUInstrInfo.td index cfe47c6d32c..b76e03dc345 100644 --- a/lib/Target/CellSPU/SPUInstrInfo.td +++ b/lib/Target/CellSPU/SPUInstrInfo.td @@ -196,15 +196,13 @@ class StoreAFormVec : RI16Form<0b0010010, (outs), (ins VECREG:$rT, addr256k:$src), "stqa\t$rT, $src", LoadStore, - [(store (vectype VECREG:$rT), aform_addr:$src)]> -{ } + [(store (vectype VECREG:$rT), aform_addr:$src)]>; class StoreAForm : RI16Form<0b001001, (outs), (ins rclass:$rT, addr256k:$src), "stqa\t$rT, $src", LoadStore, - [(store rclass:$rT, aform_addr:$src)]> -{ } + [(store rclass:$rT, aform_addr:$src)]>; multiclass StoreAForms { @@ -326,87 +324,89 @@ def ILHr8: [(set R8C:$rT, immSExt8:$val)]>; // IL does sign extension! -def ILr64: - RI16Form<0b100000010, (outs R64C:$rT), (ins s16imm_i64:$val), - "il\t$rT, $val", ImmLoad, - [(set R64C:$rT, immSExt16:$val)]>; -def ILv2i64: - RI16Form<0b100000010, (outs VECREG:$rT), (ins s16imm_i64:$val), - "il\t$rT, $val", ImmLoad, - [(set VECREG:$rT, (v2i64 v2i64SExt16Imm:$val))]>; +class ILInst pattern>: + RI16Form<0b100000010, OOL, IOL, "il\t$rT, $val", + ImmLoad, pattern>; -def ILv4i32: - RI16Form<0b100000010, (outs VECREG:$rT), (ins s16imm:$val), - "il\t$rT, $val", ImmLoad, - [(set VECREG:$rT, (v4i32 v4i32SExt16Imm:$val))]>; +class ILVecInst: + ILInst<(outs VECREG:$rT), (ins immtype:$val), + [(set (vectype VECREG:$rT), (vectype xform:$val))]>; -def ILr32: - RI16Form<0b100000010, (outs R32C:$rT), (ins s16imm_i32:$val), - "il\t$rT, $val", ImmLoad, - [(set R32C:$rT, immSExt16:$val)]>; +class ILRegInst: + ILInst<(outs rclass:$rT), (ins immtype:$val), + [(set rclass:$rT, xform:$val)]>; -def ILf32: - RI16Form<0b100000010, (outs R32FP:$rT), (ins s16imm_f32:$val), - "il\t$rT, $val", ImmLoad, - [(set R32FP:$rT, fpimmSExt16:$val)]>; +multiclass ImmediateLoad +{ + def v2i64: ILVecInst; + def v4i32: ILVecInst; -def ILf64: - RI16Form<0b100000010, (outs R64FP:$rT), (ins s16imm_f64:$val), - "il\t$rT, $val", ImmLoad, - [(set R64FP:$rT, fpimmSExt16:$val)]>; + // TODO: Need v2f64, v4f32 -def ILHUv4i32: - RI16Form<0b010000010, (outs VECREG:$rT), (ins u16imm:$val), - "ilhu\t$rT, $val", ImmLoad, - [(set VECREG:$rT, (v4i32 immILHUvec:$val))]>; + def r64: ILRegInst; + def r32: ILRegInst; + def f32: ILRegInst; + def f64: ILRegInst; +} -def ILHUr32: - RI16Form<0b010000010, (outs R32C:$rT), (ins u16imm:$val), - "ilhu\t$rT, $val", ImmLoad, - [(set R32C:$rT, hi16:$val)]>; +defm IL : ImmediateLoad; -// ILHUf32: Used to custom lower float constant loads -def ILHUf32: - RI16Form<0b010000010, (outs R32FP:$rT), (ins f16imm:$val), - "ilhu\t$rT, $val", ImmLoad, - [(set R32FP:$rT, hi16_f32:$val)]>; +class ILHUInst pattern>: + RI16Form<0b010000010, OOL, IOL, "ilhu\t$rT, $val", + ImmLoad, pattern>; -// ILHUhi: Used for loading high portion of an address. Note the symbolHi -// printer used for the operand. -def ILHUhi: - RI16Form<0b010000010, (outs R32C:$rT), (ins symbolHi:$val), - "ilhu\t$rT, $val", ImmLoad, - [(set R32C:$rT, hi16:$val)]>; +class ILHUVecInst: + ILHUInst<(outs VECREG:$rT), (ins immtype:$val), + [(set (vectype VECREG:$rT), (vectype xform:$val))]>; + +class ILHURegInst: + ILHUInst<(outs rclass:$rT), (ins immtype:$val), + [(set rclass:$rT, xform:$val)]>; + +multiclass ImmLoadHalfwordUpper +{ + def v2i64: ILHUVecInst; + def v4i32: ILHUVecInst; + + def r64: ILHURegInst; + def r32: ILHURegInst; + + // Loads the high portion of an address + def hi: ILHURegInst; + + // Used in custom lowering constant SFP loads: + def f32: ILHURegInst; +} + +defm ILHU : ImmLoadHalfwordUpper; // Immediate load address (can also be used to load 18-bit unsigned constants, // see the zext 16->32 pattern) + class ILAInst pattern>: RI18Form<0b1000010, OOL, IOL, "ila\t$rT, $val", LoadNOP, pattern>; +class ILAVecInst: + ILAInst<(outs VECREG:$rT), (ins immtype:$val), + [(set (vectype VECREG:$rT), (vectype xform:$val))]>; + +class ILARegInst: + ILAInst<(outs rclass:$rT), (ins immtype:$val), + [(set rclass:$rT, xform:$val)]>; + multiclass ImmLoadAddress { - def v2i64: ILAInst<(outs VECREG:$rT), (ins u18imm:$val), - [(set (v2i64 VECREG:$rT), v2i64Uns18Imm:$val)]>; + def v2i64: ILAVecInst; + def v4i32: ILAVecInst; - def v4i32: ILAInst<(outs VECREG:$rT), (ins u18imm:$val), - [(set (v4i32 VECREG:$rT), v4i32Uns18Imm:$val)]>; + def r64: ILARegInst; + def r32: ILARegInst; + def f32: ILARegInst; + def f64: ILARegInst; - def r64: ILAInst<(outs R64C:$rT), (ins u18imm_i64:$val), - [(set R64C:$rT, imm18:$val)]>; - - def r32: ILAInst<(outs R32C:$rT), (ins u18imm:$val), - [(set R32C:$rT, imm18:$val)]>; - - def f32: ILAInst<(outs R32FP:$rT), (ins f18imm:$val), - [(set R32FP:$rT, fpimm18:$val)]>; - - def f64: ILAInst<(outs R64FP:$rT), (ins f18imm_f64:$val), - [(set R64FP:$rT, fpimm18:$val)]>; - - def lo: ILAInst<(outs R32C:$rT), (ins symbolLo:$val), - [(set R32C:$rT, imm18:$val)]>; + def lo: ILARegInst; def lsa: ILAInst<(outs R32C:$rT), (ins symbolLSA:$val), [/* no pattern */]>; @@ -419,43 +419,41 @@ defm ILA : ImmLoadAddress; // Note that these are really two operand instructions, but they're encoded // as three operands with the first two arguments tied-to each other. -def IOHLvec: - RI16Form<0b100000110, (outs VECREG:$rT), (ins VECREG:$rS, u16imm:$val), - "iohl\t$rT, $val", ImmLoad, - [/* insert intrinsic here */]>, - RegConstraint<"$rS = $rT">, - NoEncode<"$rS">; +class IOHLInst pattern>: + RI16Form<0b100000110, OOL, IOL, "iohl\t$rT, $val", + ImmLoad, pattern>, + RegConstraint<"$rS = $rT">, + NoEncode<"$rS">; -def IOHLr32: - RI16Form<0b100000110, (outs R32C:$rT), (ins R32C:$rS, i32imm:$val), - "iohl\t$rT, $val", ImmLoad, - [/* insert intrinsic here */]>, - RegConstraint<"$rS = $rT">, - NoEncode<"$rS">; +class IOHLVecInst: + IOHLInst<(outs VECREG:$rT), (ins VECREG:$rS, immtype:$val), + [/* no pattern */]>; -def IOHLf32: - RI16Form<0b100000110, (outs R32FP:$rT), (ins R32FP:$rS, f32imm:$val), - "iohl\t$rT, $val", ImmLoad, - [/* insert intrinsic here */]>, - RegConstraint<"$rS = $rT">, - NoEncode<"$rS">; +class IOHLRegInst: + IOHLInst<(outs rclass:$rT), (ins rclass:$rS, immtype:$val), + [/* no pattern */]>; -def IOHLlo: - RI16Form<0b100000110, (outs R32C:$rT), (ins R32C:$rS, symbolLo:$val), - "iohl\t$rT, $val", ImmLoad, - [/* no pattern */]>, - RegConstraint<"$rS = $rT">, - NoEncode<"$rS">; +multiclass ImmOrHalfwordLower +{ + def v2i64: IOHLVecInst; + def v4i32: IOHLVecInst; + + def r32: IOHLRegInst; + def f32: IOHLRegInst; + + def lo: IOHLRegInst; +} + +defm IOHL: ImmOrHalfwordLower; // Form select mask for bytes using immediate, used in conjunction with the // SELB instruction: -class FSMBIVec - : RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val), - "fsmbi\t$rT, $val", - SelectOp, - [(set (vectype VECREG:$rT), (SPUfsmbi immU16:$val))]> -{ } +class FSMBIVec: + RI16Form<0b101001100, (outs VECREG:$rT), (ins u16imm:$val), + "fsmbi\t$rT, $val", + SelectOp, + [(set (vectype VECREG:$rT), (SPUfsmbi (i32 immU16:$val)))]>; multiclass FormSelectMaskBytesImm { @@ -470,22 +468,22 @@ defm FSMBI : FormSelectMaskBytesImm; // fsmb: Form select mask for bytes. N.B. Input operand, $rA, is 16-bits def FSMB: RRForm_1<0b01101101100, (outs VECREG:$rT), (ins R16C:$rA), - "fsmb\t$rT, $rA", SelectOp, - []>; + "fsmb\t$rT, $rA", SelectOp, + [(set (v16i8 VECREG:$rT), (SPUfsmbi R16C:$rA))]>; // fsmh: Form select mask for halfwords. N.B., Input operand, $rA, is // only 8-bits wide (even though it's input as 16-bits here) def FSMH: RRForm_1<0b10101101100, (outs VECREG:$rT), (ins R16C:$rA), "fsmh\t$rT, $rA", SelectOp, - []>; + [(set (v8i16 VECREG:$rT), (SPUfsmbi R16C:$rA))]>; // fsm: Form select mask for words. Like the other fsm* instructions, // only the lower 4 bits of $rA are significant. def FSM: RRForm_1<0b00101101100, (outs VECREG:$rT), (ins R16C:$rA), "fsm\t$rT, $rA", SelectOp, - []>; + [(set (v4i32 VECREG:$rT), (SPUfsmbi R16C:$rA))]>; //===----------------------------------------------------------------------===// // Integer and Logical Operations: @@ -926,6 +924,10 @@ class ANDVecInst: [(set (vectype VECREG:$rT), (and (vectype VECREG:$rA), (vectype VECREG:$rB)))]>; +class ANDRegInst: + ANDInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), + [(set rclass:$rT, (and rclass:$rA, rclass:$rB))]>; + multiclass BitwiseAnd { def v16i8: ANDVecInst; @@ -933,17 +935,11 @@ multiclass BitwiseAnd def v4i32: ANDVecInst; def v2i64: ANDVecInst; - def r64: ANDInst<(outs R64C:$rT), (ins R64C:$rA, R64C:$rB), - [(set R64C:$rT, (and R64C:$rA, R64C:$rB))]>; - - def r32: ANDInst<(outs R32C:$rT), (ins R32C:$rA, R32C:$rB), - [(set R32C:$rT, (and R32C:$rA, R32C:$rB))]>; - - def r16: ANDInst<(outs R16C:$rT), (ins R16C:$rA, R16C:$rB), - [(set R16C:$rT, (and R16C:$rA, R16C:$rB))]>; - - def r8: ANDInst<(outs R8C:$rT), (ins R8C:$rA, R8C:$rB), - [(set R8C:$rT, (and R8C:$rA, R8C:$rB))]>; + def r128: ANDRegInst; + def r64: ANDRegInst; + def r32: ANDRegInst; + def r16: ANDRegInst; + def r8: ANDRegInst; //===--------------------------------------------- // Special instructions to perform the fabs instruction @@ -1323,61 +1319,49 @@ def ORXv4i32: []>; // XOR: -def XORv16i8: - RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [(set (v16i8 VECREG:$rT), (xor (v16i8 VECREG:$rA), (v16i8 VECREG:$rB)))]>; -def XORv8i16: - RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [(set (v8i16 VECREG:$rT), (xor (v8i16 VECREG:$rA), (v8i16 VECREG:$rB)))]>; +class XORInst pattern> : + RRForm<0b10010010000, OOL, IOL, "xor\t$rT, $rA, $rB", + IntegerOp, pattern>; -def XORv4i32: - RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [(set (v4i32 VECREG:$rT), (xor (v4i32 VECREG:$rA), (v4i32 VECREG:$rB)))]>; +class XORVecInst: + XORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + [(set (vectype VECREG:$rT), (xor (vectype VECREG:$rA), + (vectype VECREG:$rB)))]>; -def XORr32: - RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [(set R32C:$rT, (xor R32C:$rA, R32C:$rB))]>; +class XORRegInst: + XORInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), + [(set rclass:$rT, (xor rclass:$rA, rclass:$rB))]>; + +multiclass BitwiseExclusiveOr +{ + def v16i8: XORVecInst; + def v8i16: XORVecInst; + def v4i32: XORVecInst; + def v2i64: XORVecInst; + + def r128: XORRegInst; + def r64: XORRegInst; + def r32: XORRegInst; + def r16: XORRegInst; + def r8: XORRegInst; + + // Special forms for floating point instructions. + // fneg and fabs require bitwise logical ops to manipulate the sign bit. + + def fneg32: XORInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB), + [/* no pattern */]>; + + def fneg64: XORInst<(outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB), + [/* no pattern */]>; + + def fnegvec: XORInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + [/* no pattern, see fneg{32,64} */]>; +} + +defm XOR : BitwiseExclusiveOr; //==---------------------------------------------------------- -// Special forms for floating point instructions. -// Bitwise ORs and ANDs don't make sense for normal floating -// point numbers. These operations (fneg and fabs), however, -// require bitwise logical ops to manipulate the sign bit. -def XORfneg32: - RRForm<0b10010010000, (outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [/* Intentionally does not match a pattern, see fneg32 */]>; - -// KLUDGY! Better way to do this without a VECREG? bitconvert? -// VECREG is assumed to contain two identical 64-bit masks, so -// it doesn't matter which word we select for the xor -def XORfneg64: - RRForm<0b10010010000, (outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [/* Intentionally does not match a pattern, see fneg64 */]>; - -// Could use XORv4i32, but will use this for clarity -def XORfnegvec: - RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [/* Intentionally does not match a pattern, see fneg{32,64} */]>; - -//==---------------------------------------------------------- - -def XORr16: - RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [(set R16C:$rT, (xor R16C:$rA, R16C:$rB))]>; - -def XORr8: - RRForm<0b10010010000, (outs R8C:$rT), (ins R8C:$rA, R8C:$rB), - "xor\t$rT, $rA, $rB", IntegerOp, - [(set R8C:$rT, (xor R8C:$rA, R8C:$rB))]>; class XORBIInst pattern>: RI10Form<0b01100000, OOL, IOL, "xorbi\t$rT, $rA, $val", @@ -1486,433 +1470,156 @@ def NORr8: "nor\t$rT, $rA, $rB", IntegerOp, [(set R8C:$rT, (not (or R8C:$rA, R8C:$rB)))]>; -// EQV: Equivalence (1 for each same bit, otherwise 0) -def EQVv16i8: - RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "eqv\t$rT, $rA, $rB", IntegerOp, - [(set (v16i8 VECREG:$rT), (or (and (v16i8 VECREG:$rA), - (v16i8 VECREG:$rB)), - (and (vnot (v16i8 VECREG:$rA)), - (vnot (v16i8 VECREG:$rB)))))]>; - -def : Pat<(xor (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rB))), - (EQVv16i8 VECREG:$rA, VECREG:$rB)>; - -def : Pat<(xor (vnot (v16i8 VECREG:$rA)), (v16i8 VECREG:$rB)), - (EQVv16i8 VECREG:$rA, VECREG:$rB)>; - -def EQVv8i16: - RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "eqv\t$rT, $rA, $rB", IntegerOp, - [(set (v8i16 VECREG:$rT), (or (and (v8i16 VECREG:$rA), - (v8i16 VECREG:$rB)), - (and (vnot (v8i16 VECREG:$rA)), - (vnot (v8i16 VECREG:$rB)))))]>; - -def : Pat<(xor (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rB))), - (EQVv8i16 VECREG:$rA, VECREG:$rB)>; - -def : Pat<(xor (vnot (v8i16 VECREG:$rA)), (v8i16 VECREG:$rB)), - (EQVv8i16 VECREG:$rA, VECREG:$rB)>; - -def EQVv4i32: - RRForm<0b10010010000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), - "eqv\t$rT, $rA, $rB", IntegerOp, - [(set (v4i32 VECREG:$rT), (or (and (v4i32 VECREG:$rA), - (v4i32 VECREG:$rB)), - (and (vnot (v4i32 VECREG:$rA)), - (vnot (v4i32 VECREG:$rB)))))]>; - -def : Pat<(xor (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rB))), - (EQVv4i32 VECREG:$rA, VECREG:$rB)>; - -def : Pat<(xor (vnot (v4i32 VECREG:$rA)), (v4i32 VECREG:$rB)), - (EQVv4i32 VECREG:$rA, VECREG:$rB)>; - -def EQVr32: - RRForm<0b10010010000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB), - "eqv\t$rT, $rA, $rB", IntegerOp, - [(set R32C:$rT, (or (and R32C:$rA, R32C:$rB), - (and (not R32C:$rA), (not R32C:$rB))))]>; - -def : Pat<(xor R32C:$rA, (not R32C:$rB)), - (EQVr32 R32C:$rA, R32C:$rB)>; - -def : Pat<(xor (not R32C:$rA), R32C:$rB), - (EQVr32 R32C:$rA, R32C:$rB)>; - -def EQVr16: - RRForm<0b10010010000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB), - "eqv\t$rT, $rA, $rB", IntegerOp, - [(set R16C:$rT, (or (and R16C:$rA, R16C:$rB), - (and (not R16C:$rA), (not R16C:$rB))))]>; - -def : Pat<(xor R16C:$rA, (not R16C:$rB)), - (EQVr16 R16C:$rA, R16C:$rB)>; - -def : Pat<(xor (not R16C:$rA), R16C:$rB), - (EQVr16 R16C:$rA, R16C:$rB)>; - -def EQVr8: - RRForm<0b10010010000, (outs R8C:$rT), (ins R8C:$rA, R8C:$rB), - "eqv\t$rT, $rA, $rB", IntegerOp, - [(set R8C:$rT, (or (and R8C:$rA, R8C:$rB), - (and (not R8C:$rA), (not R8C:$rB))))]>; - -def : Pat<(xor R8C:$rA, (not R8C:$rB)), - (EQVr8 R8C:$rA, R8C:$rB)>; - -def : Pat<(xor (not R8C:$rA), R8C:$rB), - (EQVr8 R8C:$rA, R8C:$rB)>; - -// gcc optimizes (p & q) | (~p & ~q) -> ~(p | q) | (p & q), so match that -// pattern also: -def : Pat<(or (vnot (or (v16i8 VECREG:$rA), (v16i8 VECREG:$rB))), - (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rB))), - (EQVv16i8 VECREG:$rA, VECREG:$rB)>; - -def : Pat<(or (vnot (or (v8i16 VECREG:$rA), (v8i16 VECREG:$rB))), - (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rB))), - (EQVv8i16 VECREG:$rA, VECREG:$rB)>; - -def : Pat<(or (vnot (or (v4i32 VECREG:$rA), (v4i32 VECREG:$rB))), - (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rB))), - (EQVv4i32 VECREG:$rA, VECREG:$rB)>; - -def : Pat<(or (not (or R32C:$rA, R32C:$rB)), (and R32C:$rA, R32C:$rB)), - (EQVr32 R32C:$rA, R32C:$rB)>; - -def : Pat<(or (not (or R16C:$rA, R16C:$rB)), (and R16C:$rA, R16C:$rB)), - (EQVr16 R16C:$rA, R16C:$rB)>; - -def : Pat<(or (not (or R8C:$rA, R8C:$rB)), (and R8C:$rA, R8C:$rB)), - (EQVr8 R8C:$rA, R8C:$rB)>; - // Select bits: -def SELBv16i8: - RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), - "selb\t$rT, $rA, $rB, $rC", IntegerOp, - [(set (v16i8 VECREG:$rT), - (SPUselb (v16i8 VECREG:$rA), (v16i8 VECREG:$rB), - (v16i8 VECREG:$rC)))]>; - -def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)), - (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)), - (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)), - (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)), - (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))), - (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))), - (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)), - (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)), - (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)), - (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)), - (and (v16i8 VECREG:$rB), (vnot (v16i8 VECREG:$rC)))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rA), (v16i8 VECREG:$rC)), - (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rA)), - (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rB))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))), - (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v16i8 VECREG:$rA), (vnot (v16i8 VECREG:$rC))), - (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)), - (and (v16i8 VECREG:$rB), (v16i8 VECREG:$rC))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v16i8 VECREG:$rC)), (v16i8 VECREG:$rA)), - (and (v16i8 VECREG:$rC), (v16i8 VECREG:$rB))), - (SELBv16i8 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def SELBv8i16: - RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), - "selb\t$rT, $rA, $rB, $rC", IntegerOp, - [(set (v8i16 VECREG:$rT), - (SPUselb (v8i16 VECREG:$rA), (v8i16 VECREG:$rB), - (v8i16 VECREG:$rC)))]>; - -def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)), - (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)), - (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)), - (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)), - (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))), - (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))), - (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)), - (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)), - (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)), - (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)), - (and (v8i16 VECREG:$rB), (vnot (v8i16 VECREG:$rC)))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rA), (v8i16 VECREG:$rC)), - (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rA)), - (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rB))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))), - (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v8i16 VECREG:$rA), (vnot (v8i16 VECREG:$rC))), - (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)), - (and (v8i16 VECREG:$rB), (v8i16 VECREG:$rC))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v8i16 VECREG:$rC)), (v8i16 VECREG:$rA)), - (and (v8i16 VECREG:$rC), (v8i16 VECREG:$rB))), - (SELBv8i16 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def SELBv4i32: - RRRForm<0b1000, (outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), - "selb\t$rT, $rA, $rB, $rC", IntegerOp, - [(set (v4i32 VECREG:$rT), - (SPUselb (v4i32 VECREG:$rA), (v4i32 VECREG:$rB), - (v4i32 VECREG:$rC)))]>; - -def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)), - (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)), - (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)), - (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)), - (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))), - (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))), - (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)), - (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)), - (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)), - (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)), - (and (v4i32 VECREG:$rB), (vnot (v4i32 VECREG:$rC)))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rA), (v4i32 VECREG:$rC)), - (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rA)), - (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rB))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))), - (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (v4i32 VECREG:$rA), (vnot (v4i32 VECREG:$rC))), - (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)), - (and (v4i32 VECREG:$rB), (v4i32 VECREG:$rC))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def : Pat<(or (and (vnot (v4i32 VECREG:$rC)), (v4i32 VECREG:$rA)), - (and (v4i32 VECREG:$rC), (v4i32 VECREG:$rB))), - (SELBv4i32 VECREG:$rA, VECREG:$rB, VECREG:$rC)>; - -def SELBr32: - RRRForm<0b1000, (outs R32C:$rT), (ins R32C:$rA, R32C:$rB, R32C:$rC), - "selb\t$rT, $rA, $rB, $rC", IntegerOp, - []>; - -// And the various patterns that can be matched... (all 8 of them :-) -def : Pat<(or (and R32C:$rA, R32C:$rC), - (and R32C:$rB, (not R32C:$rC))), - (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; - -def : Pat<(or (and R32C:$rC, R32C:$rA), - (and R32C:$rB, (not R32C:$rC))), - (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; - -def : Pat<(or (and R32C:$rA, R32C:$rC), - (and (not R32C:$rC), R32C:$rB)), - (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; - -def : Pat<(or (and R32C:$rC, R32C:$rA), - (and (not R32C:$rC), R32C:$rB)), - (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; - -def : Pat<(or (and R32C:$rA, (not R32C:$rC)), - (and R32C:$rB, R32C:$rC)), - (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; - -def : Pat<(or (and R32C:$rA, (not R32C:$rC)), - (and R32C:$rC, R32C:$rB)), - (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; - -def : Pat<(or (and (not R32C:$rC), R32C:$rA), - (and R32C:$rB, R32C:$rC)), - (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; - -def : Pat<(or (and (not R32C:$rC), R32C:$rA), - (and R32C:$rC, R32C:$rB)), - (SELBr32 R32C:$rA, R32C:$rB, R32C:$rC)>; - -def SELBr16: - RRRForm<0b1000, (outs R16C:$rT), (ins R16C:$rA, R16C:$rB, R16C:$rC), - "selb\t$rT, $rA, $rB, $rC", IntegerOp, - []>; - -def : Pat<(or (and R16C:$rA, R16C:$rC), - (and R16C:$rB, (not R16C:$rC))), - (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; - -def : Pat<(or (and R16C:$rC, R16C:$rA), - (and R16C:$rB, (not R16C:$rC))), - (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; - -def : Pat<(or (and R16C:$rA, R16C:$rC), - (and (not R16C:$rC), R16C:$rB)), - (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; - -def : Pat<(or (and R16C:$rC, R16C:$rA), - (and (not R16C:$rC), R16C:$rB)), - (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; - -def : Pat<(or (and R16C:$rA, (not R16C:$rC)), - (and R16C:$rB, R16C:$rC)), - (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; - -def : Pat<(or (and R16C:$rA, (not R16C:$rC)), - (and R16C:$rC, R16C:$rB)), - (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; - -def : Pat<(or (and (not R16C:$rC), R16C:$rA), - (and R16C:$rB, R16C:$rC)), - (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; - -def : Pat<(or (and (not R16C:$rC), R16C:$rA), - (and R16C:$rC, R16C:$rB)), - (SELBr16 R16C:$rA, R16C:$rB, R16C:$rC)>; - -def SELBr8: - RRRForm<0b1000, (outs R8C:$rT), (ins R8C:$rA, R8C:$rB, R8C:$rC), - "selb\t$rT, $rA, $rB, $rC", IntegerOp, - []>; - -def : Pat<(or (and R8C:$rA, R8C:$rC), - (and R8C:$rB, (not R8C:$rC))), - (SELBr8 R8C:$rA, R8C:$rB, R8C:$rC)>; - -def : Pat<(or (and R8C:$rC, R8C:$rA), - (and R8C:$rB, (not R8C:$rC))), - (SELBr8 R8C:$rA, R8C:$rB, R8C:$rC)>; - -def : Pat<(or (and R8C:$rA, R8C:$rC), - (and (not R8C:$rC), R8C:$rB)), - (SELBr8 R8C:$rA, R8C:$rB, R8C:$rC)>; - -def : Pat<(or (and R8C:$rC, R8C:$rA), - (and (not R8C:$rC), R8C:$rB)), - (SELBr8 R8C:$rA, R8C:$rB, R8C:$rC)>; - -def : Pat<(or (and R8C:$rA, (not R8C:$rC)), - (and R8C:$rB, R8C:$rC)), - (SELBr8 R8C:$rA, R8C:$rB, R8C:$rC)>; - -def : Pat<(or (and R8C:$rA, (not R8C:$rC)), - (and R8C:$rC, R8C:$rB)), - (SELBr8 R8C:$rA, R8C:$rB, R8C:$rC)>; - -def : Pat<(or (and (not R8C:$rC), R8C:$rA), - (and R8C:$rB, R8C:$rC)), - (SELBr8 R8C:$rA, R8C:$rB, R8C:$rC)>; - -def : Pat<(or (and (not R8C:$rC), R8C:$rA), - (and R8C:$rC, R8C:$rB)), - (SELBr8 R8C:$rA, R8C:$rB, R8C:$rC)>; +class SELBInst pattern>: + RRRForm<0b1000, OOL, IOL, "selb\t$rT, $rA, $rB, $rC", + IntegerOp, pattern>; + +class SELBVecInst: + SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + [(set (vectype VECREG:$rT), + (or (and (vectype VECREG:$rC), (vectype VECREG:$rB)), + (and (vnot (vectype VECREG:$rC)), + (vectype VECREG:$rA))))]>; + +class SELBRegInst: + SELBInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB, rclass:$rC), + [(set rclass:$rT, + (or (and rclass:$rA, rclass:$rC), + (and rclass:$rB, (not rclass:$rC))))]>; + +multiclass SelectBits +{ + def v16i8: SELBVecInst; + def v8i16: SELBVecInst; + def v4i32: SELBVecInst; + def v2i64: SELBVecInst; + + def r128: SELBRegInst; + def r64: SELBRegInst; + def r32: SELBRegInst; + def r16: SELBRegInst; + def r8: SELBRegInst; +} + +defm SELB : SelectBits; + +class SPUselbPat: + Pat<(SPUselb (vectype VECREG:$rA), (vectype VECREG:$rB), (vectype VECREG:$rC)), + (inst VECREG:$rA, VECREG:$rB, VECREG:$rC)>; + +def : SPUselbPat; +def : SPUselbPat; +def : SPUselbPat; +def : SPUselbPat; + +class SelectConditional: + Pat<(select rclass:$rCond, rclass:$rTrue, rclass:$rFalse), + (inst rclass:$rCond, rclass:$rFalse, rclass:$rTrue)>; + +def : SelectConditional; +def : SelectConditional; +def : SelectConditional; + +// EQV: Equivalence (1 for each same bit, otherwise 0) +// +// Note: There are a lot of ways to match this bit operator and these patterns +// attempt to be as exhaustive as possible. + +class EQVInst pattern>: + RRForm<0b10010010000, OOL, IOL, "eqv\t$rT, $rA, $rB", + IntegerOp, pattern>; + +class EQVVecInst: + EQVInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + [(set (vectype VECREG:$rT), + (or (and (vectype VECREG:$rA), (vectype VECREG:$rB)), + (and (vnot (vectype VECREG:$rA)), + (vnot (vectype VECREG:$rB)))))]>; + +class EQVRegInst: + EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), + [(set rclass:$rT, (or (and rclass:$rA, rclass:$rB), + (and (not rclass:$rA), (not rclass:$rB))))]>; + +class EQVVecPattern1: + EQVInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + [(set (vectype VECREG:$rT), + (xor (vectype VECREG:$rA), (vnot (vectype VECREG:$rB))))]>; + +class EQVRegPattern1: + EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), + [(set rclass:$rT, (xor rclass:$rA, (not rclass:$rB)))]>; + +class EQVVecPattern2: + EQVInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + [(set (vectype VECREG:$rT), + (or (and (vectype VECREG:$rA), (vectype VECREG:$rB)), + (vnot (or (vectype VECREG:$rA), (vectype VECREG:$rB)))))]>; + +class EQVRegPattern2: + EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), + [(set rclass:$rT, + (or (and rclass:$rA, rclass:$rB), + (not (or rclass:$rA, rclass:$rB))))]>; + +class EQVVecPattern3: + EQVInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), + [(set (vectype VECREG:$rT), + (not (xor (vectype VECREG:$rA), (vectype VECREG:$rB))))]>; + +class EQVRegPattern3: + EQVInst<(outs rclass:$rT), (ins rclass:$rA, rclass:$rB), + [(set rclass:$rT, (not (xor rclass:$rA, rclass:$rB)))]>; + +multiclass BitEquivalence +{ + def v16i8: EQVVecInst; + def v8i16: EQVVecInst; + def v4i32: EQVVecInst; + def v2i64: EQVVecInst; + + def v16i8_1: EQVVecPattern1; + def v8i16_1: EQVVecPattern1; + def v4i32_1: EQVVecPattern1; + def v2i64_1: EQVVecPattern1; + + def v16i8_2: EQVVecPattern2; + def v8i16_2: EQVVecPattern2; + def v4i32_2: EQVVecPattern2; + def v2i64_2: EQVVecPattern2; + + def v16i8_3: EQVVecPattern3; + def v8i16_3: EQVVecPattern3; + def v4i32_3: EQVVecPattern3; + def v2i64_3: EQVVecPattern3; + + def r128: EQVRegInst; + def r64: EQVRegInst; + def r32: EQVRegInst; + def r16: EQVRegInst; + def r8: EQVRegInst; + + def r128_1: EQVRegPattern1; + def r64_1: EQVRegPattern1; + def r32_1: EQVRegPattern1; + def r16_1: EQVRegPattern1; + def r8_1: EQVRegPattern1; + + def r128_2: EQVRegPattern2; + def r64_2: EQVRegPattern2; + def r32_2: EQVRegPattern2; + def r16_2: EQVRegPattern2; + def r8_2: EQVRegPattern2; + + def r128_3: EQVRegPattern3; + def r64_3: EQVRegPattern3; + def r32_3: EQVRegPattern3; + def r16_3: EQVRegPattern3; + def r8_3: EQVRegPattern3; +} + +defm EQV: BitEquivalence; //===----------------------------------------------------------------------===// // Vector shuffle... @@ -3062,7 +2769,7 @@ multiclass CmpGtrWordImm } class CLGTBInst pattern> : - RRForm<0b00001011010, OOL, IOL, "cgtb\t$rT, $rA, $rB", + RRForm<0b00001011010, OOL, IOL, "clgtb\t$rT, $rA, $rB", ByteOp, pattern>; multiclass CmpLGtrByte @@ -3078,7 +2785,7 @@ multiclass CmpLGtrByte } class CLGTBIInst pattern> : - RI10Form<0b01111010, OOL, IOL, "cgtbi\t$rT, $rA, $val", + RI10Form<0b01111010, OOL, IOL, "clgtbi\t$rT, $rA, $val", ByteOp, pattern>; multiclass CmpLGtrByteImm @@ -3093,7 +2800,7 @@ multiclass CmpLGtrByteImm } class CLGTHInst pattern> : - RRForm<0b00010011010, OOL, IOL, "cgth\t$rT, $rA, $rB", + RRForm<0b00010011010, OOL, IOL, "clgth\t$rT, $rA, $rB", ByteOp, pattern>; multiclass CmpLGtrHalfword @@ -3107,7 +2814,7 @@ multiclass CmpLGtrHalfword } class CLGTHIInst pattern> : - RI10Form<0b10111010, OOL, IOL, "cgthi\t$rT, $rA, $val", + RI10Form<0b10111010, OOL, IOL, "clgthi\t$rT, $rA, $val", ByteOp, pattern>; multiclass CmpLGtrHalfwordImm @@ -3121,7 +2828,7 @@ multiclass CmpLGtrHalfwordImm } class CLGTInst pattern> : - RRForm<0b00000011010, OOL, IOL, "cgt\t$rT, $rA, $rB", + RRForm<0b00000011010, OOL, IOL, "clgt\t$rT, $rA, $rB", ByteOp, pattern>; multiclass CmpLGtrWord @@ -3135,7 +2842,7 @@ multiclass CmpLGtrWord } class CLGTIInst pattern> : - RI10Form<0b00111010, OOL, IOL, "cgti\t$rT, $rA, $val", + RI10Form<0b00111010, OOL, IOL, "clgti\t$rT, $rA, $val", ByteOp, pattern>; multiclass CmpLGtrWordImm @@ -3146,7 +2853,7 @@ multiclass CmpLGtrWordImm (v4i32 v4i32SExt16Imm:$val)))]>; def r32: CLGTIInst<(outs R32C:$rT), (ins R32C:$rA, s10imm_i32:$val), - [(set R32C:$rT, (setugt R32C:$rA, i32ImmSExt10:$val))]>; + [(set R32C:$rT, (setugt R32C:$rA, i32ImmSExt10:$val))]>; } defm CEQB : CmpEqualByte; @@ -3193,25 +2900,28 @@ def CGTEQBIr8: SETCCBinOpImm; def CLTBr8: SETCCBinOpReg; def CLTBIr8: SETCCBinOpImm; def CLTEQr8: Pat<(setle R8C:$rA, R8C:$rB), - (XORBIr8 (CGTBIr8 R8C:$rA, R8C:$rB), 0xff)>; + (XORBIr8 (CGTBr8 R8C:$rA, R8C:$rB), 0xff)>; def CLTEQIr8: Pat<(setle R8C:$rA, immU8:$imm), (XORBIr8 (CGTBIr8 R8C:$rA, immU8:$imm), 0xff)>; -def CGTEQHr16: SETCCBinOpReg; +def CGTEQHr16: SETCCBinOpReg; def CGTEQHIr16: SETCCBinOpImm; +def CLTHr16: SETCCBinOpReg; +def CLTHIr16: SETCCBinOpImm; def CLTEQr16: Pat<(setle R16C:$rA, R16C:$rB), - (XORHIr16 (CGTHIr16 R16C:$rA, R16C:$rB), 0xffff)>; -def CLTEQIr16: Pat<(setle R16C:$rA, i16ImmUns10:$imm), + (XORHIr16 (CGTHr16 R16C:$rA, R16C:$rB), 0xffff)>; +def CLTEQIr16: Pat<(setle R16C:$rA, i16ImmSExt10:$imm), (XORHIr16 (CGTHIr16 R16C:$rA, i16ImmSExt10:$imm), 0xffff)>; - -def CGTEQHr32: SETCCBinOpReg; -def CGTEQHIr32: SETCCBinOpImm; +def CGTEQHIr32: SETCCBinOpImm; +def CLTr32: SETCCBinOpReg; +def CLTIr32: SETCCBinOpImm; def CLTEQr32: Pat<(setle R32C:$rA, R32C:$rB), - (XORIr32 (CGTIr32 R32C:$rA, R32C:$rB), 0xffffffff)>; -def CLTEQIr32: Pat<(setle R32C:$rA, i32ImmUns10:$imm), + (XORIr32 (CGTr32 R32C:$rA, R32C:$rB), 0xffffffff)>; +def CLTEQIr32: Pat<(setle R32C:$rA, i32ImmSExt10:$imm), (XORIr32 (CGTIr32 R32C:$rA, i32ImmSExt10:$imm), 0xffffffff)>; def CLGTEQBr8: SETCCBinOpReg; @@ -3219,26 +2929,30 @@ def CLGTEQBIr8: SETCCBinOpImm; def CLLTBIr8: SETCCBinOpImm; def CLLTEQr8: Pat<(setule R8C:$rA, R8C:$rB), - (XORBIr8 (CLGTBIr8 R8C:$rA, R8C:$rB), 0xff)>; + (XORBIr8 (CLGTBr8 R8C:$rA, R8C:$rB), 0xff)>; def CLLTEQIr8: Pat<(setule R8C:$rA, immU8:$imm), (XORBIr8 (CLGTBIr8 R8C:$rA, immU8:$imm), 0xff)>; -def CLGTEQHr16: SETCCBinOpReg; +def CLGTEQHr16: SETCCBinOpReg; def CLGTEQHIr16: SETCCBinOpImm; + ORr16, CLGTHIr16, CEQHIr16>; +def CLLTHr16: SETCCBinOpReg; +def CLLTHIr16: SETCCBinOpImm; def CLLTEQr16: Pat<(setule R16C:$rA, R16C:$rB), - (XORHIr16 (CLGTHIr16 R16C:$rA, R16C:$rB), 0xffff)>; + (XORHIr16 (CLGTHr16 R16C:$rA, R16C:$rB), 0xffff)>; def CLLTEQIr16: Pat<(setule R16C:$rA, i16ImmUns10:$imm), - (XORHIr16 (CLGTHIr16 R16C:$rA, i16ImmSExt10:$imm), 0xffff)>; + (XORHIr16 (CLGTHIr16 R16C:$rA, i16ImmSExt10:$imm), 0xffff)>; -def CLGTEQHr32: SETCCBinOpReg; +def CLGTEQHr32: SETCCBinOpReg; def CLGTEQHIr32: SETCCBinOpImm; + ORr32, CLGTIr32, CEQIr32>; +def CLLTr32: SETCCBinOpReg; +def CLLTIr32: SETCCBinOpImm; def CLLTEQr32: Pat<(setule R32C:$rA, R32C:$rB), - (XORIr32 (CLGTIr32 R32C:$rA, R32C:$rB), 0xffffffff)>; -def CLLTEQIr32: Pat<(setule R32C:$rA, i32ImmUns10:$imm), - (XORIr32 (CLGTIr32 R32C:$rA, i32ImmSExt10:$imm), 0xffffffff)>; + (XORIr32 (CLGTr32 R32C:$rA, R32C:$rB), 0xffffffff)>; +def CLLTEQIr32: Pat<(setule R32C:$rA, i32ImmSExt10:$imm), + (XORIr32 (CLGTIr32 R32C:$rA, i32ImmSExt10:$imm), 0xffffffff)>; //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ @@ -3959,8 +3673,8 @@ def : Pat<(f32 fpimm:$imm), // General constant 32-bit vectors def : Pat<(v4i32 v4i32Imm:$imm), - (IOHLvec (v4i32 (ILHUv4i32 (HI16_vec v4i32Imm:$imm))), - (LO16_vec v4i32Imm:$imm))>; + (IOHLv4i32 (v4i32 (ILHUv4i32 (HI16_vec v4i32Imm:$imm))), + (LO16_vec v4i32Imm:$imm))>; // 8-bit constants def : Pat<(i8 imm:$imm), diff --git a/lib/Target/CellSPU/SPUNodes.td b/lib/Target/CellSPU/SPUNodes.td index c2db66783e6..e390345ae2c 100644 --- a/lib/Target/CellSPU/SPUNodes.td +++ b/lib/Target/CellSPU/SPUNodes.td @@ -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, [ diff --git a/lib/Target/CellSPU/SPUOperands.td b/lib/Target/CellSPU/SPUOperands.td index 94271428c85..da4b0f2efce 100644 --- a/lib/Target/CellSPU/SPUOperands.td +++ b/lib/Target/CellSPU/SPUOperands.td @@ -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 { let PrintMethod = "printS16ImmOperand"; } +def u16imm_i64 : Operand { + let PrintMethod = "printU16ImmOperand"; +} + def u16imm : Operand { let PrintMethod = "printU16ImmOperand"; }