summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64SchedPredicates.td
blob: 3468d18e949ad9a3245706ad71ba0a884cee88c8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
//===- AArch64SchedPredicates.td - AArch64 Sched Preds -----*- tablegen -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines scheduling predicate definitions that are used by the
// AArch64 subtargets.
//
//===----------------------------------------------------------------------===//

// Function mappers.

// 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<3>;

// Generic predicates.

// Identify arithmetic instructions with extend.
def IsArithExtPred        : CheckOpcode<[ADDWrx, ADDXrx, ADDXrx64, ADDSWrx, ADDSXrx, ADDSXrx64,
                                         SUBWrx, SUBXrx, SUBXrx64, SUBSWrx, SUBSXrx, SUBSXrx64]>;

// Identify arithmetic instructions with shift.
def IsArithShiftPred      : CheckOpcode<[ADDWrs, ADDXrs, ADDSWrs, ADDSXrs,
                                         SUBWrs, SUBXrs, SUBSWrs, SUBSXrs]>;

// Identify logic instructions with shift.
def IsLogicShiftPred      : CheckOpcode<[ANDWrs, ANDXrs, ANDSWrs, ANDSXrs,
                                         BICWrs, BICXrs, BICSWrs, BICSXrs,
                                         EONWrs, EONXrs,
                                         EORWrs, EORXrs,
                                         ORNWrs, ORNXrs,
                                         ORRWrs, ORRXrs]>;

// Identify arithmetic and logic instructions with shift.
def IsArithLogicShiftPred : CheckAny<[IsArithShiftPred, IsLogicShiftPred]>;

// Identify whether an instruction is a load
// using the register offset addressing mode.
def IsLoadRegOffsetPred   : 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]>;

// Identify whether an instruction is a load
// using the register offset addressing mode.
def IsStoreRegOffsetPred  : CheckOpcode<[STRBBroW, STRBBroX,
                                         STRHHroW, STRHHroX,
                                         STRWroW, STRWroX,
                                         STRXroW, STRXroX,
                                         STRBroW, STRBroX,
                                         STRHroW, STRHroX,
                                         STRSroW, STRSroX,
                                         STRDroW, STRDroX]>;

// Target predicates.

// Identify arithmetic instructions with an extended register.
def RegExtendedFn   : TIIPredicate<"hasExtendedReg",
                                   MCOpcodeSwitchStatement<
                                     [MCOpcodeSwitchCase<
                                       IsArithExtPred.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<
                                        !listconcat(IsArithShiftPred.ValidOpcodes,
                                                    IsLogicShiftPred.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<
                                        !listconcat(IsLoadRegOffsetPred.ValidOpcodes,
                                                    IsStoreRegOffsetPred.ValidOpcodes),
                                        MCReturnStatement<
                                          CheckAny<[CheckNot<CheckMemExtLSL>,
                                                    CheckMemScaled]>>>],
                                     MCReturnStatement<FalsePred>>>;
def ScaledIdxPred   : MCSchedPredicate<ScaledIdxFn>;
OpenPOWER on IntegriCloud