Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Target/ARM/ARMISelLowering.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | void ARMTargetLowering::addDRTypeForNEON(MVT VT) { | ||||
addTypeForNEON(VT, MVT::f64, MVT::v2i32); | addTypeForNEON(VT, MVT::f64, MVT::v2i32); | ||||
} | } | ||||
void ARMTargetLowering::addQRTypeForNEON(MVT VT) { | void ARMTargetLowering::addQRTypeForNEON(MVT VT) { | ||||
addRegisterClass(VT, &ARM::DPairRegClass); | addRegisterClass(VT, &ARM::DPairRegClass); | ||||
addTypeForNEON(VT, MVT::v2f64, MVT::v4i32); | addTypeForNEON(VT, MVT::v2f64, MVT::v4i32); | ||||
} | } | ||||
void ARMTargetLowering::addMVEVectorTypes() { | |||||
// We 'support' these types up to bitcast/load/store level, regardless of | |||||
// MVE integer-only / float support. Only doing FP data processing on the FP | |||||
// vector types is inhibited at integer-only level. | |||||
const MVT VecTypes[] = { | |||||
MVT::v2i64, MVT::v4i32, MVT::v8i16, MVT::v16i8, | |||||
MVT::v2f64, MVT::v4f32, MVT::v8f16, | |||||
}; | |||||
for (auto VT : VecTypes) { | |||||
addRegisterClass(VT, &ARM::QPRRegClass); | |||||
for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc) | |||||
setOperationAction(Opc, VT, Expand); | |||||
setOperationAction(ISD::BITCAST, VT, Legal); | |||||
setOperationAction(ISD::LOAD, VT, Legal); | |||||
setOperationAction(ISD::STORE, VT, Legal); | |||||
} | |||||
} | |||||
ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, | ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, | ||||
const ARMSubtarget &STI) | const ARMSubtarget &STI) | ||||
: TargetLowering(TM), Subtarget(&STI) { | : TargetLowering(TM), Subtarget(&STI) { | ||||
RegInfo = Subtarget->getRegisterInfo(); | RegInfo = Subtarget->getRegisterInfo(); | ||||
Itins = Subtarget->getInstrItineraryData(); | Itins = Subtarget->getInstrItineraryData(); | ||||
setBooleanContents(ZeroOrOneBooleanContent); | setBooleanContents(ZeroOrOneBooleanContent); | ||||
setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); | setBooleanVectorContents(ZeroOrNegativeOneBooleanContent); | ||||
▲ Show 20 Lines • Show All 273 Lines • ▼ Show 20 Lines | if (Subtarget->isTargetAEABI()) { | ||||
} | } | ||||
} | } | ||||
if (Subtarget->isThumb1Only()) | if (Subtarget->isThumb1Only()) | ||||
addRegisterClass(MVT::i32, &ARM::tGPRRegClass); | addRegisterClass(MVT::i32, &ARM::tGPRRegClass); | ||||
else | else | ||||
addRegisterClass(MVT::i32, &ARM::GPRRegClass); | addRegisterClass(MVT::i32, &ARM::GPRRegClass); | ||||
if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() && | if (!Subtarget->useSoftFloat() && Subtarget->hasFPRegs() && | ||||
!Subtarget->isThumb1Only()) { | !Subtarget->isThumb1Only()) { | ||||
addRegisterClass(MVT::f32, &ARM::SPRRegClass); | addRegisterClass(MVT::f32, &ARM::SPRRegClass); | ||||
addRegisterClass(MVT::f64, &ARM::DPRRegClass); | addRegisterClass(MVT::f64, &ARM::DPRRegClass); | ||||
} | } | ||||
if (Subtarget->hasFullFP16()) { | if (Subtarget->hasFullFP16()) { | ||||
addRegisterClass(MVT::f16, &ARM::HPRRegClass); | addRegisterClass(MVT::f16, &ARM::HPRRegClass); | ||||
setOperationAction(ISD::BITCAST, MVT::i16, Custom); | setOperationAction(ISD::BITCAST, MVT::i16, Custom); | ||||
Show All 21 Lines | ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, | ||||
} | } | ||||
setOperationAction(ISD::ConstantFP, MVT::f32, Custom); | setOperationAction(ISD::ConstantFP, MVT::f32, Custom); | ||||
setOperationAction(ISD::ConstantFP, MVT::f64, Custom); | setOperationAction(ISD::ConstantFP, MVT::f64, Custom); | ||||
setOperationAction(ISD::READ_REGISTER, MVT::i64, Custom); | setOperationAction(ISD::READ_REGISTER, MVT::i64, Custom); | ||||
setOperationAction(ISD::WRITE_REGISTER, MVT::i64, Custom); | setOperationAction(ISD::WRITE_REGISTER, MVT::i64, Custom); | ||||
if (Subtarget->hasMVEIntegerOps()) | |||||
addMVEVectorTypes(); | |||||
if (Subtarget->hasNEON()) { | if (Subtarget->hasNEON()) { | ||||
addDRTypeForNEON(MVT::v2f32); | addDRTypeForNEON(MVT::v2f32); | ||||
addDRTypeForNEON(MVT::v8i8); | addDRTypeForNEON(MVT::v8i8); | ||||
addDRTypeForNEON(MVT::v4i16); | addDRTypeForNEON(MVT::v4i16); | ||||
addDRTypeForNEON(MVT::v2i32); | addDRTypeForNEON(MVT::v2i32); | ||||
addDRTypeForNEON(MVT::v1i64); | addDRTypeForNEON(MVT::v1i64); | ||||
addQRTypeForNEON(MVT::v4f32); | addQRTypeForNEON(MVT::v4f32); | ||||
addQRTypeForNEON(MVT::v2f64); | addQRTypeForNEON(MVT::v2f64); | ||||
addQRTypeForNEON(MVT::v16i8); | addQRTypeForNEON(MVT::v16i8); | ||||
addQRTypeForNEON(MVT::v8i16); | addQRTypeForNEON(MVT::v8i16); | ||||
addQRTypeForNEON(MVT::v4i32); | addQRTypeForNEON(MVT::v4i32); | ||||
addQRTypeForNEON(MVT::v2i64); | addQRTypeForNEON(MVT::v2i64); | ||||
if (Subtarget->hasFullFP16()) { | if (Subtarget->hasFullFP16()) { | ||||
addQRTypeForNEON(MVT::v8f16); | addQRTypeForNEON(MVT::v8f16); | ||||
addDRTypeForNEON(MVT::v4f16); | addDRTypeForNEON(MVT::v4f16); | ||||
} | } | ||||
} | |||||
if (Subtarget->hasMVEIntegerOps() || Subtarget->hasNEON()) { | |||||
// v2f64 is legal so that QR subregs can be extracted as f64 elements, but | // v2f64 is legal so that QR subregs can be extracted as f64 elements, but | ||||
// neither Neon nor VFP support any arithmetic operations on it. | // none of Neon, MVE or VFP supports any arithmetic operations on it. | ||||
// The same with v4f32. But keep in mind that vadd, vsub, vmul are natively | |||||
// supported for v4f32. | |||||
setOperationAction(ISD::FADD, MVT::v2f64, Expand); | setOperationAction(ISD::FADD, MVT::v2f64, Expand); | ||||
setOperationAction(ISD::FSUB, MVT::v2f64, Expand); | setOperationAction(ISD::FSUB, MVT::v2f64, Expand); | ||||
setOperationAction(ISD::FMUL, MVT::v2f64, Expand); | setOperationAction(ISD::FMUL, MVT::v2f64, Expand); | ||||
// FIXME: Code duplication: FDIV and FREM are expanded always, see | // FIXME: Code duplication: FDIV and FREM are expanded always, see | ||||
// ARMTargetLowering::addTypeForNEON method for details. | // ARMTargetLowering::addTypeForNEON method for details. | ||||
setOperationAction(ISD::FDIV, MVT::v2f64, Expand); | setOperationAction(ISD::FDIV, MVT::v2f64, Expand); | ||||
setOperationAction(ISD::FREM, MVT::v2f64, Expand); | setOperationAction(ISD::FREM, MVT::v2f64, Expand); | ||||
// FIXME: Create unittest. | // FIXME: Create unittest. | ||||
Show All 17 Lines | if (Subtarget->hasMVEIntegerOps() || Subtarget->hasNEON()) { | ||||
setOperationAction(ISD::FEXP2, MVT::v2f64, Expand); | setOperationAction(ISD::FEXP2, MVT::v2f64, Expand); | ||||
// FIXME: Create unittest for FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR. | // FIXME: Create unittest for FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR. | ||||
setOperationAction(ISD::FCEIL, MVT::v2f64, Expand); | setOperationAction(ISD::FCEIL, MVT::v2f64, Expand); | ||||
setOperationAction(ISD::FTRUNC, MVT::v2f64, Expand); | setOperationAction(ISD::FTRUNC, MVT::v2f64, Expand); | ||||
setOperationAction(ISD::FRINT, MVT::v2f64, Expand); | setOperationAction(ISD::FRINT, MVT::v2f64, Expand); | ||||
setOperationAction(ISD::FNEARBYINT, MVT::v2f64, Expand); | setOperationAction(ISD::FNEARBYINT, MVT::v2f64, Expand); | ||||
setOperationAction(ISD::FFLOOR, MVT::v2f64, Expand); | setOperationAction(ISD::FFLOOR, MVT::v2f64, Expand); | ||||
setOperationAction(ISD::FMA, MVT::v2f64, Expand); | setOperationAction(ISD::FMA, MVT::v2f64, Expand); | ||||
} | |||||
if (Subtarget->hasNEON()) { | |||||
// The same with v4f32. But keep in mind that vadd, vsub, vmul are natively | |||||
// supported for v4f32. | |||||
setOperationAction(ISD::FSQRT, MVT::v4f32, Expand); | setOperationAction(ISD::FSQRT, MVT::v4f32, Expand); | ||||
setOperationAction(ISD::FSIN, MVT::v4f32, Expand); | setOperationAction(ISD::FSIN, MVT::v4f32, Expand); | ||||
setOperationAction(ISD::FCOS, MVT::v4f32, Expand); | setOperationAction(ISD::FCOS, MVT::v4f32, Expand); | ||||
setOperationAction(ISD::FPOW, MVT::v4f32, Expand); | setOperationAction(ISD::FPOW, MVT::v4f32, Expand); | ||||
setOperationAction(ISD::FLOG, MVT::v4f32, Expand); | setOperationAction(ISD::FLOG, MVT::v4f32, Expand); | ||||
setOperationAction(ISD::FLOG2, MVT::v4f32, Expand); | setOperationAction(ISD::FLOG2, MVT::v4f32, Expand); | ||||
setOperationAction(ISD::FLOG10, MVT::v4f32, Expand); | setOperationAction(ISD::FLOG10, MVT::v4f32, Expand); | ||||
setOperationAction(ISD::FEXP, MVT::v4f32, Expand); | setOperationAction(ISD::FEXP, MVT::v4f32, Expand); | ||||
▲ Show 20 Lines • Show All 419 Lines • ▼ Show 20 Lines | ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, | ||||
// Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes. | // Requires SXTB/SXTH, available on v6 and up in both ARM and Thumb modes. | ||||
if (!Subtarget->hasV6Ops()) { | if (!Subtarget->hasV6Ops()) { | ||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); | setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); | ||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand); | setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8, Expand); | ||||
} | } | ||||
setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); | setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); | ||||
if (!Subtarget->useSoftFloat() && Subtarget->hasVFP2Base() && | if (!Subtarget->useSoftFloat() && Subtarget->hasFPRegs() && | ||||
!Subtarget->isThumb1Only()) { | !Subtarget->isThumb1Only()) { | ||||
// Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR | // Turn f64->i64 into VMOVRRD, i64 -> f64 to VMOVDRR | ||||
// iff target supports vfp2. | // iff target supports vfp2. | ||||
setOperationAction(ISD::BITCAST, MVT::i64, Custom); | setOperationAction(ISD::BITCAST, MVT::i64, Custom); | ||||
setOperationAction(ISD::FLT_ROUNDS_, MVT::i32, Custom); | setOperationAction(ISD::FLT_ROUNDS_, MVT::i32, Custom); | ||||
} | } | ||||
// We want to custom lower some of our intrinsics. | // We want to custom lower some of our intrinsics. | ||||
▲ Show 20 Lines • Show All 14,377 Lines • Show Last 20 Lines |