diff --git a/llvm/lib/Target/VE/VEISelLowering.h b/llvm/lib/Target/VE/VEISelLowering.h --- a/llvm/lib/Target/VE/VEISelLowering.h +++ b/llvm/lib/Target/VE/VEISelLowering.h @@ -43,6 +43,10 @@ class VETargetLowering : public TargetLowering { const VESubtarget *Subtarget; + void initRegisterClasses(); + void initSPUActions(); + // TODO void initVPUActions(); + public: VETargetLowering(const TargetMachine &TM, const VESubtarget &STI); diff --git a/llvm/lib/Target/VE/VEISelLowering.cpp b/llvm/lib/Target/VE/VEISelLowering.cpp --- a/llvm/lib/Target/VE/VEISelLowering.cpp +++ b/llvm/lib/Target/VE/VEISelLowering.cpp @@ -49,6 +49,219 @@ 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, @@ -627,213 +840,9 @@ 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);