return CCInfo.CheckReturn(Outs, RetCC);
}
+void VETargetLowering::initRegisterClasses() {
+ // Set up the register classes.
+ addRegisterClass(MVT::i32, &VE::I32RegClass);
+ addRegisterClass(MVT::i64, &VE::I64RegClass);
+ addRegisterClass(MVT::f32, &VE::F32RegClass);
+ addRegisterClass(MVT::f64, &VE::I64RegClass);
+ addRegisterClass(MVT::f128, &VE::F128RegClass);
+
+ addRegisterClass(MVT::v2i32, &VE::V64RegClass);
+ addRegisterClass(MVT::v4i32, &VE::V64RegClass);
+ addRegisterClass(MVT::v8i32, &VE::V64RegClass);
+ addRegisterClass(MVT::v16i32, &VE::V64RegClass);
+ addRegisterClass(MVT::v32i32, &VE::V64RegClass);
+ addRegisterClass(MVT::v64i32, &VE::V64RegClass);
+ addRegisterClass(MVT::v128i32, &VE::V64RegClass);
+ addRegisterClass(MVT::v256i32, &VE::V64RegClass);
+ addRegisterClass(MVT::v512i32, &VE::V64RegClass);
+
+ addRegisterClass(MVT::v2i64, &VE::V64RegClass);
+ addRegisterClass(MVT::v4i64, &VE::V64RegClass);
+ addRegisterClass(MVT::v8i64, &VE::V64RegClass);
+ addRegisterClass(MVT::v16i64, &VE::V64RegClass);
+ addRegisterClass(MVT::v32i64, &VE::V64RegClass);
+ addRegisterClass(MVT::v64i64, &VE::V64RegClass);
+ addRegisterClass(MVT::v128i64, &VE::V64RegClass);
+ addRegisterClass(MVT::v256i64, &VE::V64RegClass);
+
+ addRegisterClass(MVT::v2f32, &VE::V64RegClass);
+ addRegisterClass(MVT::v4f32, &VE::V64RegClass);
+ addRegisterClass(MVT::v8f32, &VE::V64RegClass);
+ addRegisterClass(MVT::v16f32, &VE::V64RegClass);
+ addRegisterClass(MVT::v32f32, &VE::V64RegClass);
+ addRegisterClass(MVT::v64f32, &VE::V64RegClass);
+ addRegisterClass(MVT::v128f32, &VE::V64RegClass);
+ addRegisterClass(MVT::v256f32, &VE::V64RegClass);
+ addRegisterClass(MVT::v512f32, &VE::V64RegClass);
+
+ addRegisterClass(MVT::v2f64, &VE::V64RegClass);
+ addRegisterClass(MVT::v4f64, &VE::V64RegClass);
+ addRegisterClass(MVT::v8f64, &VE::V64RegClass);
+ addRegisterClass(MVT::v16f64, &VE::V64RegClass);
+ addRegisterClass(MVT::v32f64, &VE::V64RegClass);
+ addRegisterClass(MVT::v64f64, &VE::V64RegClass);
+ addRegisterClass(MVT::v128f64, &VE::V64RegClass);
+ addRegisterClass(MVT::v256f64, &VE::V64RegClass);
+
+ addRegisterClass(MVT::v256i1, &VE::VMRegClass);
+ addRegisterClass(MVT::v512i1, &VE::VM512RegClass);
+}
+
+void VETargetLowering::initSPUActions() {
+ const auto &TM = getTargetMachine();
+ /// Load & Store {
+
+ // VE doesn't have i1 sign extending load.
+ for (MVT VT : MVT::integer_valuetypes()) {
+ setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
+ setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote);
+ setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote);
+ setTruncStoreAction(VT, MVT::i1, Expand);
+ }
+
+ // VE doesn't have floating point extload/truncstore, so expand them.
+ for (MVT FPVT : MVT::fp_valuetypes()) {
+ for (MVT OtherFPVT : MVT::fp_valuetypes()) {
+ setLoadExtAction(ISD::EXTLOAD, FPVT, OtherFPVT, Expand);
+ setTruncStoreAction(FPVT, OtherFPVT, Expand);
+ }
+ }
+
+ // VE doesn't have fp128 load/store, so expand them in custom lower.
+ setOperationAction(ISD::LOAD, MVT::f128, Custom);
+ setOperationAction(ISD::STORE, MVT::f128, Custom);
+
+ /// } Load & Store
+
+ // Custom legalize address nodes into LO/HI parts.
+ MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
+ setOperationAction(ISD::BlockAddress, PtrVT, Custom);
+ setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
+ setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom);
+ setOperationAction(ISD::ConstantPool, PtrVT, Custom);
+
+ /// VAARG handling {
+ setOperationAction(ISD::VASTART, MVT::Other, Custom);
+ // VAARG needs to be lowered to access with 8 bytes alignment.
+ setOperationAction(ISD::VAARG, MVT::Other, Custom);
+ // Use the default implementation.
+ setOperationAction(ISD::VACOPY, MVT::Other, Expand);
+ setOperationAction(ISD::VAEND, MVT::Other, Expand);
+ /// } VAARG handling
+
+ /// Stack {
+ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
+ setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
+ /// } Stack
+
+ /// Branch {
+
+ // VE doesn't have BRCOND
+ setOperationAction(ISD::BRCOND, MVT::Other, Expand);
+
+ // BRIND and BR_JT are not implemented yet.
+ // FIXME: Implement both for the scalar perforamnce.
+ setOperationAction(ISD::BRIND, MVT::Other, Expand);
+ setOperationAction(ISD::BR_JT, MVT::Other, Expand);
+
+ /// } Branch
+
+ /// Int Ops {
+ for (MVT IntVT : {MVT::i32, MVT::i64}) {
+ // VE has no REM or DIVREM operations.
+ setOperationAction(ISD::UREM, IntVT, Expand);
+ setOperationAction(ISD::SREM, IntVT, Expand);
+ setOperationAction(ISD::SDIVREM, IntVT, Expand);
+ setOperationAction(ISD::UDIVREM, IntVT, Expand);
+
+ // VE has no SHL_PARTS/SRA_PARTS/SRL_PARTS operations.
+ setOperationAction(ISD::SHL_PARTS, IntVT, Expand);
+ setOperationAction(ISD::SRA_PARTS, IntVT, Expand);
+ setOperationAction(ISD::SRL_PARTS, IntVT, Expand);
+
+ // VE has no MULHU/S or U/SMUL_LOHI operations.
+ // TODO: Use MPD instruction to implement SMUL_LOHI for i32 type.
+ setOperationAction(ISD::MULHU, IntVT, Expand);
+ setOperationAction(ISD::MULHS, IntVT, Expand);
+ setOperationAction(ISD::UMUL_LOHI, IntVT, Expand);
+ setOperationAction(ISD::SMUL_LOHI, IntVT, Expand);
+
+ // VE has no CTTZ, ROTL, ROTR operations.
+ setOperationAction(ISD::CTTZ, IntVT, Expand);
+ setOperationAction(ISD::ROTL, IntVT, Expand);
+ setOperationAction(ISD::ROTR, IntVT, Expand);
+
+ // VE has 64 bits instruction which works as i64 BSWAP operation. This
+ // instruction works fine as i32 BSWAP operation with an additional
+ // parameter. Use isel patterns to lower BSWAP.
+ setOperationAction(ISD::BSWAP, IntVT, Legal);
+
+ // VE has only 64 bits instructions which work as i64 BITREVERSE/CTLZ/CTPOP
+ // operations. Use isel patterns for i64, promote for i32.
+ LegalizeAction Act = (IntVT == MVT::i32) ? Promote : Legal;
+ setOperationAction(ISD::BITREVERSE, IntVT, Act);
+ setOperationAction(ISD::CTLZ, IntVT, Act);
+ setOperationAction(ISD::CTLZ_ZERO_UNDEF, IntVT, Act);
+ setOperationAction(ISD::CTPOP, IntVT, Act);
+
+ // VE has only 64 bits instructions which work as i64 AND/OR/XOR operations.
+ // Use isel patterns for i64, promote for i32.
+ setOperationAction(ISD::AND, IntVT, Act);
+ setOperationAction(ISD::OR, IntVT, Act);
+ setOperationAction(ISD::XOR, IntVT, Act);
+ }
+ /// } Int Ops
+
+ /// Conversion {
+ // VE doesn't have instructions for fp<->uint, so expand them by llvm
+ setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64
+ setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64
+ setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
+ setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
+
+ // fp16 not supported
+ for (MVT FPVT : MVT::fp_valuetypes()) {
+ setOperationAction(ISD::FP16_TO_FP, FPVT, Expand);
+ setOperationAction(ISD::FP_TO_FP16, FPVT, Expand);
+ }
+ /// } Conversion
+
+ /// Floating-point Ops {
+ /// Note: Floating-point operations are fneg, fadd, fsub, fmul, fdiv, frem,
+ /// and fcmp.
+
+ // VE doesn't have following floating point operations.
+ for (MVT VT : MVT::fp_valuetypes()) {
+ setOperationAction(ISD::FNEG, VT, Expand);
+ setOperationAction(ISD::FREM, VT, Expand);
+ }
+
+ // VE doesn't have fdiv of f128.
+ setOperationAction(ISD::FDIV, MVT::f128, Expand);
+
+ for (MVT FPVT : {MVT::f32, MVT::f64}) {
+ // f32 and f64 uses ConstantFP. f128 uses ConstantPool.
+ setOperationAction(ISD::ConstantFP, FPVT, Legal);
+ }
+ /// } Floating-point Ops
+
+ /// Floating-point math functions {
+
+ // VE doesn't have following floating point math functions.
+ for (MVT VT : MVT::fp_valuetypes()) {
+ setOperationAction(ISD::FABS, VT, Expand);
+ setOperationAction(ISD::FCOPYSIGN, VT, Expand);
+ setOperationAction(ISD::FCOS, VT, Expand);
+ setOperationAction(ISD::FSIN, VT, Expand);
+ setOperationAction(ISD::FSQRT, VT, Expand);
+ }
+
+ /// } Floating-point math functions
+
+ /// Atomic instructions {
+
+ setMaxAtomicSizeInBitsSupported(64);
+ setMinCmpXchgSizeInBits(32);
+ setSupportsUnalignedAtomics(false);
+
+ // Use custom inserter for ATOMIC_FENCE.
+ setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
+
+ /// } Atomic isntructions
+}
+
SDValue
VETargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
bool IsVarArg,
setBooleanContents(ZeroOrOneBooleanContent);
setBooleanVectorContents(ZeroOrOneBooleanContent);
- // Set up the register classes.
- addRegisterClass(MVT::i32, &VE::I32RegClass);
- addRegisterClass(MVT::i64, &VE::I64RegClass);
- addRegisterClass(MVT::f32, &VE::F32RegClass);
- addRegisterClass(MVT::f64, &VE::I64RegClass);
- addRegisterClass(MVT::f128, &VE::F128RegClass);
-
- addRegisterClass(MVT::v2i32, &VE::V64RegClass);
- addRegisterClass(MVT::v4i32, &VE::V64RegClass);
- addRegisterClass(MVT::v8i32, &VE::V64RegClass);
- addRegisterClass(MVT::v16i32, &VE::V64RegClass);
- addRegisterClass(MVT::v32i32, &VE::V64RegClass);
- addRegisterClass(MVT::v64i32, &VE::V64RegClass);
- addRegisterClass(MVT::v128i32, &VE::V64RegClass);
- addRegisterClass(MVT::v256i32, &VE::V64RegClass);
- addRegisterClass(MVT::v512i32, &VE::V64RegClass);
-
- addRegisterClass(MVT::v2i64, &VE::V64RegClass);
- addRegisterClass(MVT::v4i64, &VE::V64RegClass);
- addRegisterClass(MVT::v8i64, &VE::V64RegClass);
- addRegisterClass(MVT::v16i64, &VE::V64RegClass);
- addRegisterClass(MVT::v32i64, &VE::V64RegClass);
- addRegisterClass(MVT::v64i64, &VE::V64RegClass);
- addRegisterClass(MVT::v128i64, &VE::V64RegClass);
- addRegisterClass(MVT::v256i64, &VE::V64RegClass);
-
- addRegisterClass(MVT::v2f32, &VE::V64RegClass);
- addRegisterClass(MVT::v4f32, &VE::V64RegClass);
- addRegisterClass(MVT::v8f32, &VE::V64RegClass);
- addRegisterClass(MVT::v16f32, &VE::V64RegClass);
- addRegisterClass(MVT::v32f32, &VE::V64RegClass);
- addRegisterClass(MVT::v64f32, &VE::V64RegClass);
- addRegisterClass(MVT::v128f32, &VE::V64RegClass);
- addRegisterClass(MVT::v256f32, &VE::V64RegClass);
- addRegisterClass(MVT::v512f32, &VE::V64RegClass);
-
- addRegisterClass(MVT::v2f64, &VE::V64RegClass);
- addRegisterClass(MVT::v4f64, &VE::V64RegClass);
- addRegisterClass(MVT::v8f64, &VE::V64RegClass);
- addRegisterClass(MVT::v16f64, &VE::V64RegClass);
- addRegisterClass(MVT::v32f64, &VE::V64RegClass);
- addRegisterClass(MVT::v64f64, &VE::V64RegClass);
- addRegisterClass(MVT::v128f64, &VE::V64RegClass);
- addRegisterClass(MVT::v256f64, &VE::V64RegClass);
-
- addRegisterClass(MVT::v256i1, &VE::VMRegClass);
- addRegisterClass(MVT::v512i1, &VE::VM512RegClass);
-
- /// Load & Store {
-
- // VE doesn't have i1 sign extending load.
- for (MVT VT : MVT::integer_valuetypes()) {
- setLoadExtAction(ISD::SEXTLOAD, VT, MVT::i1, Promote);
- setLoadExtAction(ISD::ZEXTLOAD, VT, MVT::i1, Promote);
- setLoadExtAction(ISD::EXTLOAD, VT, MVT::i1, Promote);
- setTruncStoreAction(VT, MVT::i1, Expand);
- }
-
- // VE doesn't have floating point extload/truncstore, so expand them.
- for (MVT FPVT : MVT::fp_valuetypes()) {
- for (MVT OtherFPVT : MVT::fp_valuetypes()) {
- setLoadExtAction(ISD::EXTLOAD, FPVT, OtherFPVT, Expand);
- setTruncStoreAction(FPVT, OtherFPVT, Expand);
- }
- }
-
- // VE doesn't have fp128 load/store, so expand them in custom lower.
- setOperationAction(ISD::LOAD, MVT::f128, Custom);
- setOperationAction(ISD::STORE, MVT::f128, Custom);
-
- /// } Load & Store
-
- // Custom legalize address nodes into LO/HI parts.
- MVT PtrVT = MVT::getIntegerVT(TM.getPointerSizeInBits(0));
- setOperationAction(ISD::BlockAddress, PtrVT, Custom);
- setOperationAction(ISD::GlobalAddress, PtrVT, Custom);
- setOperationAction(ISD::GlobalTLSAddress, PtrVT, Custom);
- setOperationAction(ISD::ConstantPool, PtrVT, Custom);
-
- /// VAARG handling {
- setOperationAction(ISD::VASTART, MVT::Other, Custom);
- // VAARG needs to be lowered to access with 8 bytes alignment.
- setOperationAction(ISD::VAARG, MVT::Other, Custom);
- // Use the default implementation.
- setOperationAction(ISD::VACOPY, MVT::Other, Expand);
- setOperationAction(ISD::VAEND, MVT::Other, Expand);
- /// } VAARG handling
-
- /// Stack {
- setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom);
- setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Custom);
- /// } Stack
-
- /// Branch {
-
- // VE doesn't have BRCOND
- setOperationAction(ISD::BRCOND, MVT::Other, Expand);
-
- // BRIND and BR_JT are not implemented yet.
- // FIXME: Implement both for the scalar perforamnce.
- setOperationAction(ISD::BRIND, MVT::Other, Expand);
- setOperationAction(ISD::BR_JT, MVT::Other, Expand);
-
- /// } Branch
-
- /// Int Ops {
- for (MVT IntVT : {MVT::i32, MVT::i64}) {
- // VE has no REM or DIVREM operations.
- setOperationAction(ISD::UREM, IntVT, Expand);
- setOperationAction(ISD::SREM, IntVT, Expand);
- setOperationAction(ISD::SDIVREM, IntVT, Expand);
- setOperationAction(ISD::UDIVREM, IntVT, Expand);
-
- // VE has no SHL_PARTS/SRA_PARTS/SRL_PARTS operations.
- setOperationAction(ISD::SHL_PARTS, IntVT, Expand);
- setOperationAction(ISD::SRA_PARTS, IntVT, Expand);
- setOperationAction(ISD::SRL_PARTS, IntVT, Expand);
-
- // VE has no MULHU/S or U/SMUL_LOHI operations.
- // TODO: Use MPD instruction to implement SMUL_LOHI for i32 type.
- setOperationAction(ISD::MULHU, IntVT, Expand);
- setOperationAction(ISD::MULHS, IntVT, Expand);
- setOperationAction(ISD::UMUL_LOHI, IntVT, Expand);
- setOperationAction(ISD::SMUL_LOHI, IntVT, Expand);
-
- // VE has no CTTZ, ROTL, ROTR operations.
- setOperationAction(ISD::CTTZ, IntVT, Expand);
- setOperationAction(ISD::ROTL, IntVT, Expand);
- setOperationAction(ISD::ROTR, IntVT, Expand);
-
- // VE has 64 bits instruction which works as i64 BSWAP operation. This
- // instruction works fine as i32 BSWAP operation with an additional
- // parameter. Use isel patterns to lower BSWAP.
- setOperationAction(ISD::BSWAP, IntVT, Legal);
-
- // VE has only 64 bits instructions which work as i64 BITREVERSE/CTLZ/CTPOP
- // operations. Use isel patterns for i64, promote for i32.
- LegalizeAction Act = (IntVT == MVT::i32) ? Promote : Legal;
- setOperationAction(ISD::BITREVERSE, IntVT, Act);
- setOperationAction(ISD::CTLZ, IntVT, Act);
- setOperationAction(ISD::CTLZ_ZERO_UNDEF, IntVT, Act);
- setOperationAction(ISD::CTPOP, IntVT, Act);
-
- // VE has only 64 bits instructions which work as i64 AND/OR/XOR operations.
- // Use isel patterns for i64, promote for i32.
- setOperationAction(ISD::AND, IntVT, Act);
- setOperationAction(ISD::OR, IntVT, Act);
- setOperationAction(ISD::XOR, IntVT, Act);
- }
- /// } Int Ops
-
- /// Conversion {
- // VE doesn't have instructions for fp<->uint, so expand them by llvm
- setOperationAction(ISD::FP_TO_UINT, MVT::i32, Promote); // use i64
- setOperationAction(ISD::UINT_TO_FP, MVT::i32, Promote); // use i64
- setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand);
- setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
-
- // fp16 not supported
- for (MVT FPVT : MVT::fp_valuetypes()) {
- setOperationAction(ISD::FP16_TO_FP, FPVT, Expand);
- setOperationAction(ISD::FP_TO_FP16, FPVT, Expand);
- }
- /// } Conversion
-
- /// Floating-point Ops {
- /// Note: Floating-point operations are fneg, fadd, fsub, fmul, fdiv, frem,
- /// and fcmp.
-
- // VE doesn't have following floating point operations.
- for (MVT VT : MVT::fp_valuetypes()) {
- setOperationAction(ISD::FNEG, VT, Expand);
- setOperationAction(ISD::FREM, VT, Expand);
- }
-
- // VE doesn't have fdiv of f128.
- setOperationAction(ISD::FDIV, MVT::f128, Expand);
-
- for (MVT FPVT : {MVT::f32, MVT::f64}) {
- // f32 and f64 uses ConstantFP. f128 uses ConstantPool.
- setOperationAction(ISD::ConstantFP, FPVT, Legal);
- }
- /// } Floating-point Ops
-
- /// Floating-point math functions {
-
- // VE doesn't have following floating point math functions.
- for (MVT VT : MVT::fp_valuetypes()) {
- setOperationAction(ISD::FABS, VT, Expand);
- setOperationAction(ISD::FCOPYSIGN, VT, Expand);
- setOperationAction(ISD::FCOS, VT, Expand);
- setOperationAction(ISD::FSIN, VT, Expand);
- setOperationAction(ISD::FSQRT, VT, Expand);
- }
-
- /// } Floating-point math functions
-
- /// Atomic instructions {
-
- setMaxAtomicSizeInBitsSupported(64);
- setMinCmpXchgSizeInBits(32);
- setSupportsUnalignedAtomics(false);
-
- // Use custom inserter for ATOMIC_FENCE.
- setOperationAction(ISD::ATOMIC_FENCE, MVT::Other, Custom);
-
- /// } Atomic isntructions
+ initRegisterClasses();
+ initSPUActions();
+ // TODO initVPUActions();
setStackPointerRegisterToSaveRestore(VE::SX11);