123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- //===- AArch64SchedPredicates.td - AArch64 Sched Preds -----*- tablegen -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines scheduling predicate definitions that are used by the
- // AArch64 subtargets.
- //
- //===----------------------------------------------------------------------===//
- // Function mappers.
- // Check the extension type in arithmetic instructions.
- let FunctionMapper = "AArch64_AM::getArithExtendType" in {
- def CheckExtUXTB : CheckImmOperand_s<3, "AArch64_AM::UXTB">;
- def CheckExtUXTH : CheckImmOperand_s<3, "AArch64_AM::UXTH">;
- def CheckExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
- def CheckExtUXTX : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
- def CheckExtSXTB : CheckImmOperand_s<3, "AArch64_AM::SXTB">;
- def CheckExtSXTH : CheckImmOperand_s<3, "AArch64_AM::SXTH">;
- def CheckExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
- def CheckExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
- }
- // Check for shifting in extended arithmetic instructions.
- foreach I = {0-3} in {
- let FunctionMapper = "AArch64_AM::getArithShiftValue" in
- def CheckExtBy#I : CheckImmOperand<3, I>;
- }
- // Check the extension type in the register offset addressing mode.
- let FunctionMapper = "AArch64_AM::getMemExtendType" in {
- def CheckMemExtUXTW : CheckImmOperand_s<3, "AArch64_AM::UXTW">;
- def CheckMemExtLSL : CheckImmOperand_s<3, "AArch64_AM::UXTX">;
- def CheckMemExtSXTW : CheckImmOperand_s<3, "AArch64_AM::SXTW">;
- def CheckMemExtSXTX : CheckImmOperand_s<3, "AArch64_AM::SXTX">;
- }
- // Check for scaling in the register offset addressing mode.
- let FunctionMapper = "AArch64_AM::getMemDoShift" in
- def CheckMemScaled : CheckImmOperandSimple<4>;
- // Check the shifting type in arithmetic and logic instructions.
- let FunctionMapper = "AArch64_AM::getShiftType" in {
- def CheckShiftLSL : CheckImmOperand_s<3, "AArch64_AM::LSL">;
- def CheckShiftLSR : CheckImmOperand_s<3, "AArch64_AM::LSR">;
- def CheckShiftASR : CheckImmOperand_s<3, "AArch64_AM::ASR">;
- def CheckShiftROR : CheckImmOperand_s<3, "AArch64_AM::ROR">;
- def CheckShiftMSL : CheckImmOperand_s<3, "AArch64_AM::MSL">;
- }
- // Check for shifting in arithmetic and logic instructions.
- foreach I = {0-4, 8} in {
- let FunctionMapper = "AArch64_AM::getShiftValue" in
- def CheckShiftBy#I : CheckImmOperand<3, I>;
- }
- // Generic predicates.
- // Identify whether an instruction is NEON or floating point
- def CheckFpOrNEON : CheckFunctionPredicateWithTII<
- "AArch64_MC::isFpOrNEON",
- "AArch64InstrInfo::isFpOrNEON"
- >;
- // Identify whether an instruction is the 128-bit NEON form based on its result.
- def CheckQForm : CheckFunctionPredicateWithTII<
- "AArch64_MC::isQForm",
- "AArch64InstrInfo::isQForm"
- >;
- // Identify arithmetic instructions with extend.
- def IsArithExtOp : CheckOpcode<[ADDWrx, ADDXrx, ADDSWrx, ADDSXrx,
- SUBWrx, SUBXrx, SUBSWrx, SUBSXrx,
- ADDXrx64, ADDSXrx64,
- SUBXrx64, SUBSXrx64]>;
- // Identify arithmetic immediate instructions.
- def IsArithImmOp : CheckOpcode<[ADDWri, ADDXri, ADDSWri, ADDSXri,
- SUBWri, SUBXri, SUBSWri, SUBSXri]>;
- // Identify arithmetic instructions with shift.
- def IsArithShiftOp : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
- SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;
- // Identify arithmetic instructions without shift.
- def IsArithUnshiftOp : CheckOpcode<[ADDWrr, ADDXrr, ADDSWrr, ADDSXrr,
- SUBWrr, SUBXrr, SUBSWrr, SUBSXrr]>;
- // Identify logic immediate instructions.
- def IsLogicImmOp : CheckOpcode<[ANDWri, ANDXri,
- EORWri, EORXri,
- ORRWri, ORRXri]>;
- // Identify logic instructions with shift.
- def IsLogicShiftOp : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
- BICWrs, BICXrs, BICSWrs, BICSXrs,
- EONWrs, EONXrs,
- EORWrs, EORXrs,
- ORNWrs, ORNXrs,
- ORRWrs, ORRXrs]>;
- // Identify logic instructions without shift.
- def IsLogicUnshiftOp : CheckOpcode<[ANDWrr, ANDXrr, ANDSWrr, ANDSXrr,
- BICWrr, BICXrr, BICSWrr, BICSXrr,
- EONWrr, EONXrr,
- EORWrr, EORXrr,
- ORNWrr, ORNXrr,
- ORRWrr, ORRXrr]>;
- // Identify arithmetic and logic immediate instructions.
- def IsArithLogicImmOp : CheckOpcode<!listconcat(IsArithImmOp.ValidOpcodes,
- IsLogicImmOp.ValidOpcodes)>;
- // Identify arithmetic and logic instructions with shift.
- def IsArithLogicShiftOp : CheckOpcode<!listconcat(IsArithShiftOp.ValidOpcodes,
- IsLogicShiftOp.ValidOpcodes)>;
- // Identify arithmetic and logic instructions without shift.
- def IsArithLogicUnshiftOp : CheckOpcode<!listconcat(IsArithUnshiftOp.ValidOpcodes,
- IsLogicUnshiftOp.ValidOpcodes)>;
- // Identify whether an instruction is an ASIMD
- // load using the post index addressing mode.
- def IsLoadASIMDPostOp : CheckOpcode<[LD1Onev8b_POST, LD1Onev4h_POST, LD1Onev2s_POST, LD1Onev1d_POST,
- LD1Onev16b_POST, LD1Onev8h_POST, LD1Onev4s_POST, LD1Onev2d_POST,
- LD1Twov8b_POST, LD1Twov4h_POST, LD1Twov2s_POST, LD1Twov1d_POST,
- LD1Twov16b_POST, LD1Twov8h_POST, LD1Twov4s_POST, LD1Twov2d_POST,
- LD1Threev8b_POST, LD1Threev4h_POST, LD1Threev2s_POST, LD1Threev1d_POST,
- LD1Threev16b_POST, LD1Threev8h_POST, LD1Threev4s_POST, LD1Threev2d_POST,
- LD1Fourv8b_POST, LD1Fourv4h_POST, LD1Fourv2s_POST, LD1Fourv1d_POST,
- LD1Fourv16b_POST, LD1Fourv8h_POST, LD1Fourv4s_POST, LD1Fourv2d_POST,
- LD1i8_POST, LD1i16_POST, LD1i32_POST, LD1i64_POST,
- LD1Rv8b_POST, LD1Rv4h_POST, LD1Rv2s_POST, LD1Rv1d_POST,
- LD1Rv16b_POST, LD1Rv8h_POST, LD1Rv4s_POST, LD1Rv2d_POST,
- LD2Twov8b_POST, LD2Twov4h_POST, LD2Twov2s_POST,
- LD2Twov16b_POST, LD2Twov8h_POST, LD2Twov4s_POST, LD2Twov2d_POST,
- LD2i8_POST, LD2i16_POST, LD2i32_POST, LD2i64_POST,
- LD2Rv8b_POST, LD2Rv4h_POST, LD2Rv2s_POST, LD2Rv1d_POST,
- LD2Rv16b_POST, LD2Rv8h_POST, LD2Rv4s_POST, LD2Rv2d_POST,
- LD3Threev8b_POST, LD3Threev4h_POST, LD3Threev2s_POST,
- LD3Threev16b_POST, LD3Threev8h_POST, LD3Threev4s_POST, LD3Threev2d_POST,
- LD3i8_POST, LD3i16_POST, LD3i32_POST, LD3i64_POST,
- LD3Rv8b_POST, LD3Rv4h_POST, LD3Rv2s_POST, LD3Rv1d_POST,
- LD3Rv16b_POST, LD3Rv8h_POST, LD3Rv4s_POST, LD3Rv2d_POST,
- LD4Fourv8b_POST, LD4Fourv4h_POST, LD4Fourv2s_POST,
- LD4Fourv16b_POST, LD4Fourv8h_POST, LD4Fourv4s_POST, LD4Fourv2d_POST,
- LD4i8_POST, LD4i16_POST, LD4i32_POST, LD4i64_POST,
- LD4Rv8b_POST, LD4Rv4h_POST, LD4Rv2s_POST, LD4Rv1d_POST,
- LD4Rv16b_POST, LD4Rv8h_POST, LD4Rv4s_POST, LD4Rv2d_POST]>;
- // Identify whether an instruction is an ASIMD
- // store using the post index addressing mode.
- def IsStoreASIMDPostOp : CheckOpcode<[ST1Onev8b_POST, ST1Onev4h_POST, ST1Onev2s_POST, ST1Onev1d_POST,
- ST1Onev16b_POST, ST1Onev8h_POST, ST1Onev4s_POST, ST1Onev2d_POST,
- ST1Twov8b_POST, ST1Twov4h_POST, ST1Twov2s_POST, ST1Twov1d_POST,
- ST1Twov16b_POST, ST1Twov8h_POST, ST1Twov4s_POST, ST1Twov2d_POST,
- ST1Threev8b_POST, ST1Threev4h_POST, ST1Threev2s_POST, ST1Threev1d_POST,
- ST1Threev16b_POST, ST1Threev8h_POST, ST1Threev4s_POST, ST1Threev2d_POST,
- ST1Fourv8b_POST, ST1Fourv4h_POST, ST1Fourv2s_POST, ST1Fourv1d_POST,
- ST1Fourv16b_POST, ST1Fourv8h_POST, ST1Fourv4s_POST, ST1Fourv2d_POST,
- ST1i8_POST, ST1i16_POST, ST1i32_POST, ST1i64_POST,
- ST2Twov8b_POST, ST2Twov4h_POST, ST2Twov2s_POST,
- ST2Twov16b_POST, ST2Twov8h_POST, ST2Twov4s_POST, ST2Twov2d_POST,
- ST2i8_POST, ST2i16_POST, ST2i32_POST, ST2i64_POST,
- ST3Threev8b_POST, ST3Threev4h_POST, ST3Threev2s_POST,
- ST3Threev16b_POST, ST3Threev8h_POST, ST3Threev4s_POST, ST3Threev2d_POST,
- ST3i8_POST, ST3i16_POST, ST3i32_POST, ST3i64_POST,
- ST4Fourv8b_POST, ST4Fourv4h_POST, ST4Fourv2s_POST,
- ST4Fourv16b_POST, ST4Fourv8h_POST, ST4Fourv4s_POST, ST4Fourv2d_POST,
- ST4i8_POST, ST4i16_POST, ST4i32_POST, ST4i64_POST]>;
- // Identify whether an instruction is an ASIMD load
- // or store using the post index addressing mode.
- def IsLoadStoreASIMDPostOp : CheckOpcode<!listconcat(IsLoadASIMDPostOp.ValidOpcodes,
- IsStoreASIMDPostOp.ValidOpcodes)>;
- // Identify whether an instruction is a load
- // using the register offset addressing mode.
- def IsLoadRegOffsetOp : CheckOpcode<[PRFMroW, PRFMroX,
- LDRBBroW, LDRBBroX,
- LDRSBWroW, LDRSBWroX, LDRSBXroW, LDRSBXroX,
- LDRHHroW, LDRHHroX,
- LDRSHWroW, LDRSHWroX, LDRSHXroW, LDRSHXroX,
- LDRWroW, LDRWroX,
- LDRSWroW, LDRSWroX,
- LDRXroW, LDRXroX,
- LDRBroW, LDRBroX,
- LDRHroW, LDRHroX,
- LDRSroW, LDRSroX,
- LDRDroW, LDRDroX,
- LDRQroW, LDRQroX]>;
- // Identify whether an instruction is a store
- // using the register offset addressing mode.
- def IsStoreRegOffsetOp : CheckOpcode<[STRBBroW, STRBBroX,
- STRHHroW, STRHHroX,
- STRWroW, STRWroX,
- STRXroW, STRXroX,
- STRBroW, STRBroX,
- STRHroW, STRHroX,
- STRSroW, STRSroX,
- STRDroW, STRDroX,
- STRQroW, STRQroX]>;
- // Identify whether an instruction is a load or
- // store using the register offset addressing mode.
- def IsLoadStoreRegOffsetOp : CheckOpcode<!listconcat(IsLoadRegOffsetOp.ValidOpcodes,
- IsStoreRegOffsetOp.ValidOpcodes)>;
- // Target predicates.
- // Identify an instruction that effectively transfers a register to another.
- def IsCopyIdiomFn : TIIPredicate<"isCopyIdiom",
- MCOpcodeSwitchStatement<
- [// MOV {Rd, SP}, {SP, Rn} =>
- // ADD {Rd, SP}, {SP, Rn}, #0
- MCOpcodeSwitchCase<
- [ADDWri, ADDXri],
- MCReturnStatement<
- CheckAll<
- [CheckIsRegOperand<0>,
- CheckIsRegOperand<1>,
- CheckAny<
- [CheckRegOperand<0, WSP>,
- CheckRegOperand<0, SP>,
- CheckRegOperand<1, WSP>,
- CheckRegOperand<1, SP>]>,
- CheckZeroOperand<2>]>>>,
- // MOV Rd, Rm =>
- // ORR Rd, ZR, Rm, LSL #0
- MCOpcodeSwitchCase<
- [ORRWrs, ORRXrs],
- MCReturnStatement<
- CheckAll<
- [CheckIsRegOperand<1>,
- CheckIsRegOperand<2>,
- CheckAny<
- [CheckRegOperand<1, WZR>,
- CheckRegOperand<1, XZR>]>,
- CheckShiftBy0]>>>],
- MCReturnStatement<FalsePred>>>;
- def IsCopyIdiomPred : MCSchedPredicate<IsCopyIdiomFn>;
- // Identify arithmetic instructions with an extended register.
- def RegExtendedFn : TIIPredicate<"hasExtendedReg",
- MCOpcodeSwitchStatement<
- [MCOpcodeSwitchCase<
- IsArithExtOp.ValidOpcodes,
- MCReturnStatement<
- CheckNot<CheckZeroOperand<3>>>>],
- MCReturnStatement<FalsePred>>>;
- def RegExtendedPred : MCSchedPredicate<RegExtendedFn>;
- // Identify arithmetic and logic instructions with a shifted register.
- def RegShiftedFn : TIIPredicate<"hasShiftedReg",
- MCOpcodeSwitchStatement<
- [MCOpcodeSwitchCase<
- IsArithLogicShiftOp.ValidOpcodes,
- MCReturnStatement<
- CheckNot<CheckZeroOperand<3>>>>],
- MCReturnStatement<FalsePred>>>;
- def RegShiftedPred : MCSchedPredicate<RegShiftedFn>;
- // Identify a load or store using the register offset addressing mode
- // with an extended or scaled register.
- def ScaledIdxFn : TIIPredicate<"isScaledAddr",
- MCOpcodeSwitchStatement<
- [MCOpcodeSwitchCase<
- IsLoadStoreRegOffsetOp.ValidOpcodes,
- MCReturnStatement<
- CheckAny<[CheckNot<CheckMemExtLSL>,
- CheckMemScaled]>>>],
- MCReturnStatement<FalsePred>>>;
- def ScaledIdxPred : MCSchedPredicate<ScaledIdxFn>;
- // Identify an instruction that effectively resets a FP register to zero.
- def IsZeroFPIdiomFn : TIIPredicate<"isZeroFPIdiom",
- MCOpcodeSwitchStatement<
- [// MOVI Vd, #0
- MCOpcodeSwitchCase<
- [MOVIv8b_ns, MOVIv16b_ns,
- MOVID, MOVIv2d_ns],
- MCReturnStatement<CheckZeroOperand<1>>>,
- // MOVI Vd, #0, LSL #0
- MCOpcodeSwitchCase<
- [MOVIv4i16, MOVIv8i16,
- MOVIv2i32, MOVIv4i32],
- MCReturnStatement<
- CheckAll<
- [CheckZeroOperand<1>,
- CheckZeroOperand<2>]>>>],
- MCReturnStatement<FalsePred>>>;
- def IsZeroFPIdiomPred : MCSchedPredicate<IsZeroFPIdiomFn>;
- // Identify an instruction that effectively resets a GP register to zero.
- def IsZeroIdiomFn : TIIPredicate<"isZeroIdiom",
- MCOpcodeSwitchStatement<
- [// ORR Rd, ZR, #0
- MCOpcodeSwitchCase<
- [ORRWri, ORRXri],
- MCReturnStatement<
- CheckAll<
- [CheckIsRegOperand<1>,
- CheckAny<
- [CheckRegOperand<1, WZR>,
- CheckRegOperand<1, XZR>]>,
- CheckZeroOperand<2>]>>>],
- MCReturnStatement<FalsePred>>>;
- def IsZeroIdiomPred : MCSchedPredicate<IsZeroIdiomFn>;
|