Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 1 | //===--------------------- PredicateExpander.cpp --------------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | /// \file |
| 10 | /// Functionalities used by the Tablegen backends to expand machine predicates. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "PredicateExpander.h" |
Andrea Di Biagio | a9c15c1 | 2018-09-19 15:57:45 +0000 | [diff] [blame] | 15 | #include "CodeGenSchedule.h" // Definition of STIPredicateFunction. |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 16 | |
| 17 | namespace llvm { |
| 18 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 19 | void PredicateExpander::expandTrue(raw_ostream &OS) { OS << "true"; } |
| 20 | void PredicateExpander::expandFalse(raw_ostream &OS) { OS << "false"; } |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 21 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 22 | void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 23 | int ImmVal, |
| 24 | StringRef FunctionMapper) { |
| 25 | if (!FunctionMapper.empty()) |
| 26 | OS << FunctionMapper << "("; |
Andrea Di Biagio | 1885077 | 2018-07-17 16:11:37 +0000 | [diff] [blame] | 27 | OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 28 | << ").getImm()"; |
Evandro Menezes | 5f1a766 | 2018-11-30 21:03:24 +0000 | [diff] [blame] | 29 | if (!FunctionMapper.empty()) |
| 30 | OS << ")"; |
| 31 | OS << (shouldNegate() ? " != " : " == ") << ImmVal; |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 32 | } |
| 33 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 34 | void PredicateExpander::expandCheckImmOperand(raw_ostream &OS, int OpIndex, |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 35 | StringRef ImmVal, |
| 36 | StringRef FunctionMapper) { |
Evandro Menezes | 5f1a766 | 2018-11-30 21:03:24 +0000 | [diff] [blame] | 37 | if (ImmVal.empty()) |
| 38 | expandCheckImmOperandSimple(OS, OpIndex, FunctionMapper); |
| 39 | |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 40 | if (!FunctionMapper.empty()) |
| 41 | OS << FunctionMapper << "("; |
Andrea Di Biagio | 1885077 | 2018-07-17 16:11:37 +0000 | [diff] [blame] | 42 | OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 43 | << ").getImm()"; |
Evandro Menezes | 5f1a766 | 2018-11-30 21:03:24 +0000 | [diff] [blame] | 44 | if (!FunctionMapper.empty()) |
| 45 | OS << ")"; |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 46 | OS << (shouldNegate() ? " != " : " == ") << ImmVal; |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 47 | } |
| 48 | |
Evandro Menezes | 5f1a766 | 2018-11-30 21:03:24 +0000 | [diff] [blame] | 49 | void PredicateExpander::expandCheckImmOperandSimple(raw_ostream &OS, |
| 50 | int OpIndex, |
| 51 | StringRef FunctionMapper) { |
| 52 | if (shouldNegate()) |
| 53 | OS << "!"; |
| 54 | if (!FunctionMapper.empty()) |
| 55 | OS << FunctionMapper << "("; |
| 56 | OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex |
| 57 | << ").getImm()"; |
| 58 | if (!FunctionMapper.empty()) |
| 59 | OS << ")"; |
| 60 | } |
| 61 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 62 | void PredicateExpander::expandCheckRegOperand(raw_ostream &OS, int OpIndex, |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 63 | const Record *Reg, |
| 64 | StringRef FunctionMapper) { |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 65 | assert(Reg->isSubClassOf("Register") && "Expected a register Record!"); |
| 66 | |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 67 | if (!FunctionMapper.empty()) |
| 68 | OS << FunctionMapper << "("; |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 69 | OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 70 | << ").getReg()"; |
Evandro Menezes | 5f1a766 | 2018-11-30 21:03:24 +0000 | [diff] [blame] | 71 | if (!FunctionMapper.empty()) |
| 72 | OS << ")"; |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 73 | OS << (shouldNegate() ? " != " : " == "); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 74 | const StringRef Str = Reg->getValueAsString("Namespace"); |
| 75 | if (!Str.empty()) |
| 76 | OS << Str << "::"; |
| 77 | OS << Reg->getName(); |
| 78 | } |
| 79 | |
Evandro Menezes | 5f1a766 | 2018-11-30 21:03:24 +0000 | [diff] [blame] | 80 | |
| 81 | void PredicateExpander::expandCheckRegOperandSimple(raw_ostream &OS, |
| 82 | int OpIndex, |
| 83 | StringRef FunctionMapper) { |
| 84 | if (shouldNegate()) |
| 85 | OS << "!"; |
| 86 | if (!FunctionMapper.empty()) |
| 87 | OS << FunctionMapper << "("; |
| 88 | OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex |
| 89 | << ").getReg()"; |
| 90 | if (!FunctionMapper.empty()) |
| 91 | OS << ")"; |
| 92 | } |
| 93 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 94 | void PredicateExpander::expandCheckInvalidRegOperand(raw_ostream &OS, |
Andrea Di Biagio | 3ac65c4 | 2018-07-18 11:03:22 +0000 | [diff] [blame] | 95 | int OpIndex) { |
| 96 | OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex |
| 97 | << ").getReg() " << (shouldNegate() ? "!= " : "== ") << "0"; |
| 98 | } |
| 99 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 100 | void PredicateExpander::expandCheckSameRegOperand(raw_ostream &OS, int First, |
| 101 | int Second) { |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 102 | OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First |
| 103 | << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI" |
| 104 | << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()"; |
| 105 | } |
| 106 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 107 | void PredicateExpander::expandCheckNumOperands(raw_ostream &OS, int NumOps) { |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 108 | OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() " |
| 109 | << (shouldNegate() ? "!= " : "== ") << NumOps; |
| 110 | } |
| 111 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 112 | void PredicateExpander::expandCheckOpcode(raw_ostream &OS, const Record *Inst) { |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 113 | OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() " |
| 114 | << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace") |
| 115 | << "::" << Inst->getName(); |
| 116 | } |
| 117 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 118 | void PredicateExpander::expandCheckOpcode(raw_ostream &OS, |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 119 | const RecVec &Opcodes) { |
| 120 | assert(!Opcodes.empty() && "Expected at least one opcode to check!"); |
| 121 | bool First = true; |
| 122 | |
| 123 | if (Opcodes.size() == 1) { |
| 124 | OS << "( "; |
| 125 | expandCheckOpcode(OS, Opcodes[0]); |
| 126 | OS << " )"; |
| 127 | return; |
| 128 | } |
| 129 | |
| 130 | OS << '('; |
| 131 | increaseIndentLevel(); |
| 132 | for (const Record *Rec : Opcodes) { |
| 133 | OS << '\n'; |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 134 | OS.indent(getIndentLevel() * 2); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 135 | if (!First) |
| 136 | OS << (shouldNegate() ? "&& " : "|| "); |
| 137 | |
| 138 | expandCheckOpcode(OS, Rec); |
| 139 | First = false; |
| 140 | } |
| 141 | |
| 142 | OS << '\n'; |
| 143 | decreaseIndentLevel(); |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 144 | OS.indent(getIndentLevel() * 2); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 145 | OS << ')'; |
| 146 | } |
| 147 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 148 | void PredicateExpander::expandCheckPseudo(raw_ostream &OS, |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 149 | const RecVec &Opcodes) { |
| 150 | if (shouldExpandForMC()) |
| 151 | expandFalse(OS); |
| 152 | else |
| 153 | expandCheckOpcode(OS, Opcodes); |
| 154 | } |
| 155 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 156 | void PredicateExpander::expandPredicateSequence(raw_ostream &OS, |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 157 | const RecVec &Sequence, |
| 158 | bool IsCheckAll) { |
| 159 | assert(!Sequence.empty() && "Found an invalid empty predicate set!"); |
| 160 | if (Sequence.size() == 1) |
| 161 | return expandPredicate(OS, Sequence[0]); |
| 162 | |
| 163 | // Okay, there is more than one predicate in the set. |
| 164 | bool First = true; |
| 165 | OS << (shouldNegate() ? "!(" : "("); |
| 166 | increaseIndentLevel(); |
| 167 | |
| 168 | bool OldValue = shouldNegate(); |
| 169 | setNegatePredicate(false); |
| 170 | for (const Record *Rec : Sequence) { |
| 171 | OS << '\n'; |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 172 | OS.indent(getIndentLevel() * 2); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 173 | if (!First) |
| 174 | OS << (IsCheckAll ? "&& " : "|| "); |
| 175 | expandPredicate(OS, Rec); |
| 176 | First = false; |
| 177 | } |
| 178 | OS << '\n'; |
| 179 | decreaseIndentLevel(); |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 180 | OS.indent(getIndentLevel() * 2); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 181 | OS << ')'; |
| 182 | setNegatePredicate(OldValue); |
| 183 | } |
| 184 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 185 | void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS, |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 186 | StringRef MethodName) { |
| 187 | OS << (shouldNegate() ? "!" : ""); |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 188 | OS << TargetName << (shouldExpandForMC() ? "_MC::" : "InstrInfo::"); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 189 | OS << MethodName << (isByRef() ? "(MI)" : "(*MI)"); |
| 190 | } |
| 191 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 192 | void PredicateExpander::expandCheckIsRegOperand(raw_ostream &OS, int OpIndex) { |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 193 | OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") |
| 194 | << "getOperand(" << OpIndex << ").isReg() "; |
| 195 | } |
| 196 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 197 | void PredicateExpander::expandCheckIsImmOperand(raw_ostream &OS, int OpIndex) { |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 198 | OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->") |
| 199 | << "getOperand(" << OpIndex << ").isImm() "; |
| 200 | } |
| 201 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 202 | void PredicateExpander::expandCheckFunctionPredicate(raw_ostream &OS, |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 203 | StringRef MCInstFn, |
| 204 | StringRef MachineInstrFn) { |
| 205 | OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn) |
| 206 | << (isByRef() ? "(MI)" : "(*MI)"); |
| 207 | } |
| 208 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 209 | void PredicateExpander::expandCheckNonPortable(raw_ostream &OS, |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 210 | StringRef Code) { |
| 211 | if (shouldExpandForMC()) |
| 212 | return expandFalse(OS); |
| 213 | |
| 214 | OS << '(' << Code << ')'; |
| 215 | } |
| 216 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 217 | void PredicateExpander::expandReturnStatement(raw_ostream &OS, |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 218 | const Record *Rec) { |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 219 | std::string Buffer; |
| 220 | raw_string_ostream SS(Buffer); |
| 221 | |
| 222 | SS << "return "; |
| 223 | expandPredicate(SS, Rec); |
| 224 | SS << ";"; |
| 225 | SS.flush(); |
| 226 | OS << Buffer; |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 227 | } |
| 228 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 229 | void PredicateExpander::expandOpcodeSwitchCase(raw_ostream &OS, |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 230 | const Record *Rec) { |
| 231 | const RecVec &Opcodes = Rec->getValueAsListOfDefs("Opcodes"); |
| 232 | for (const Record *Opcode : Opcodes) { |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 233 | OS.indent(getIndentLevel() * 2); |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 234 | OS << "case " << Opcode->getValueAsString("Namespace") |
Evandro Menezes | e41f778 | 2018-11-27 20:59:01 +0000 | [diff] [blame] | 235 | << "::" << Opcode->getName() << ":\n"; |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 236 | } |
| 237 | |
| 238 | increaseIndentLevel(); |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 239 | OS.indent(getIndentLevel() * 2); |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 240 | expandStatement(OS, Rec->getValueAsDef("CaseStmt")); |
| 241 | decreaseIndentLevel(); |
| 242 | } |
| 243 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 244 | void PredicateExpander::expandOpcodeSwitchStatement(raw_ostream &OS, |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 245 | const RecVec &Cases, |
| 246 | const Record *Default) { |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 247 | std::string Buffer; |
| 248 | raw_string_ostream SS(Buffer); |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 249 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 250 | SS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 251 | for (const Record *Rec : Cases) { |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 252 | expandOpcodeSwitchCase(SS, Rec); |
| 253 | SS << '\n'; |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 254 | } |
| 255 | |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 256 | // Expand the default case. |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 257 | SS.indent(getIndentLevel() * 2); |
Evandro Menezes | e41f778 | 2018-11-27 20:59:01 +0000 | [diff] [blame] | 258 | SS << "default:\n"; |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 259 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 260 | increaseIndentLevel(); |
| 261 | SS.indent(getIndentLevel() * 2); |
| 262 | expandStatement(SS, Default); |
| 263 | decreaseIndentLevel(); |
| 264 | SS << '\n'; |
| 265 | |
| 266 | SS.indent(getIndentLevel() * 2); |
| 267 | SS << "} // end of switch-stmt"; |
| 268 | SS.flush(); |
| 269 | OS << Buffer; |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 270 | } |
| 271 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 272 | void PredicateExpander::expandStatement(raw_ostream &OS, const Record *Rec) { |
| 273 | // Assume that padding has been added by the caller. |
Andrea Di Biagio | d99d657 | 2018-08-09 15:32:48 +0000 | [diff] [blame] | 274 | if (Rec->isSubClassOf("MCOpcodeSwitchStatement")) { |
| 275 | expandOpcodeSwitchStatement(OS, Rec->getValueAsListOfDefs("Cases"), |
| 276 | Rec->getValueAsDef("DefaultCase")); |
| 277 | return; |
| 278 | } |
| 279 | |
| 280 | if (Rec->isSubClassOf("MCReturnStatement")) { |
| 281 | expandReturnStatement(OS, Rec->getValueAsDef("Pred")); |
| 282 | return; |
| 283 | } |
| 284 | |
| 285 | llvm_unreachable("No known rules to expand this MCStatement"); |
| 286 | } |
| 287 | |
Andrea Di Biagio | 87972c4 | 2018-08-13 15:13:35 +0000 | [diff] [blame] | 288 | void PredicateExpander::expandPredicate(raw_ostream &OS, const Record *Rec) { |
| 289 | // Assume that padding has been added by the caller. |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 290 | if (Rec->isSubClassOf("MCTrue")) { |
| 291 | if (shouldNegate()) |
| 292 | return expandFalse(OS); |
| 293 | return expandTrue(OS); |
| 294 | } |
| 295 | |
| 296 | if (Rec->isSubClassOf("MCFalse")) { |
| 297 | if (shouldNegate()) |
| 298 | return expandTrue(OS); |
| 299 | return expandFalse(OS); |
| 300 | } |
| 301 | |
| 302 | if (Rec->isSubClassOf("CheckNot")) { |
| 303 | flipNegatePredicate(); |
| 304 | expandPredicate(OS, Rec->getValueAsDef("Pred")); |
| 305 | flipNegatePredicate(); |
| 306 | return; |
| 307 | } |
| 308 | |
| 309 | if (Rec->isSubClassOf("CheckIsRegOperand")) |
| 310 | return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex")); |
| 311 | |
| 312 | if (Rec->isSubClassOf("CheckIsImmOperand")) |
| 313 | return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex")); |
| 314 | |
| 315 | if (Rec->isSubClassOf("CheckRegOperand")) |
| 316 | return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"), |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 317 | Rec->getValueAsDef("Reg"), |
| 318 | Rec->getValueAsString("FunctionMapper")); |
| 319 | |
| 320 | if (Rec->isSubClassOf("CheckRegOperandSimple")) |
Evandro Menezes | 5f1a766 | 2018-11-30 21:03:24 +0000 | [diff] [blame] | 321 | return expandCheckRegOperandSimple(OS, Rec->getValueAsInt("OpIndex"), |
| 322 | Rec->getValueAsString("FunctionMapper")); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 323 | |
Andrea Di Biagio | 3ac65c4 | 2018-07-18 11:03:22 +0000 | [diff] [blame] | 324 | if (Rec->isSubClassOf("CheckInvalidRegOperand")) |
| 325 | return expandCheckInvalidRegOperand(OS, Rec->getValueAsInt("OpIndex")); |
| 326 | |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 327 | if (Rec->isSubClassOf("CheckImmOperand")) |
| 328 | return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 329 | Rec->getValueAsInt("ImmVal"), |
| 330 | Rec->getValueAsString("FunctionMapper")); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 331 | |
| 332 | if (Rec->isSubClassOf("CheckImmOperand_s")) |
| 333 | return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"), |
Andrea Di Biagio | cf7570b | 2018-10-31 12:28:05 +0000 | [diff] [blame] | 334 | Rec->getValueAsString("ImmVal"), |
| 335 | Rec->getValueAsString("FunctionMapper")); |
| 336 | |
| 337 | if (Rec->isSubClassOf("CheckImmOperandSimple")) |
Evandro Menezes | 5f1a766 | 2018-11-30 21:03:24 +0000 | [diff] [blame] | 338 | return expandCheckImmOperandSimple(OS, Rec->getValueAsInt("OpIndex"), |
| 339 | Rec->getValueAsString("FunctionMapper")); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 340 | |
| 341 | if (Rec->isSubClassOf("CheckSameRegOperand")) |
| 342 | return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"), |
| 343 | Rec->getValueAsInt("SecondIndex")); |
| 344 | |
| 345 | if (Rec->isSubClassOf("CheckNumOperands")) |
| 346 | return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps")); |
| 347 | |
| 348 | if (Rec->isSubClassOf("CheckPseudo")) |
| 349 | return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); |
| 350 | |
| 351 | if (Rec->isSubClassOf("CheckOpcode")) |
| 352 | return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes")); |
| 353 | |
| 354 | if (Rec->isSubClassOf("CheckAll")) |
| 355 | return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), |
| 356 | /* AllOf */ true); |
| 357 | |
| 358 | if (Rec->isSubClassOf("CheckAny")) |
| 359 | return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"), |
| 360 | /* AllOf */ false); |
| 361 | |
| 362 | if (Rec->isSubClassOf("CheckFunctionPredicate")) |
| 363 | return expandCheckFunctionPredicate( |
| 364 | OS, Rec->getValueAsString("MCInstFnName"), |
| 365 | Rec->getValueAsString("MachineInstrFnName")); |
| 366 | |
| 367 | if (Rec->isSubClassOf("CheckNonPortable")) |
| 368 | return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); |
| 369 | |
| 370 | if (Rec->isSubClassOf("TIIPredicate")) |
Andrea Di Biagio | e9759dd | 2018-08-14 18:36:54 +0000 | [diff] [blame] | 371 | return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName")); |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 372 | |
| 373 | llvm_unreachable("No known rules to expand this MCInstPredicate"); |
| 374 | } |
| 375 | |
Andrea Di Biagio | a9c15c1 | 2018-09-19 15:57:45 +0000 | [diff] [blame] | 376 | void STIPredicateExpander::expandHeader(raw_ostream &OS, |
| 377 | const STIPredicateFunction &Fn) { |
| 378 | const Record *Rec = Fn.getDeclaration(); |
| 379 | StringRef FunctionName = Rec->getValueAsString("Name"); |
| 380 | |
| 381 | OS.indent(getIndentLevel() * 2); |
| 382 | OS << "bool "; |
| 383 | if (shouldExpandDefinition()) |
| 384 | OS << getClassPrefix() << "::"; |
| 385 | OS << FunctionName << "("; |
| 386 | if (shouldExpandForMC()) |
| 387 | OS << "const MCInst " << (isByRef() ? "&" : "*") << "MI"; |
| 388 | else |
| 389 | OS << "const MachineInstr " << (isByRef() ? "&" : "*") << "MI"; |
| 390 | if (Rec->getValueAsBit("UpdatesOpcodeMask")) |
| 391 | OS << ", APInt &Mask"; |
| 392 | OS << (shouldExpandForMC() ? ", unsigned ProcessorID) const " : ") const "); |
| 393 | if (shouldExpandDefinition()) { |
| 394 | OS << "{\n"; |
| 395 | return; |
| 396 | } |
| 397 | |
| 398 | if (Rec->getValueAsBit("OverridesBaseClassMember")) |
| 399 | OS << "override"; |
| 400 | OS << ";\n"; |
| 401 | } |
| 402 | |
| 403 | void STIPredicateExpander::expandPrologue(raw_ostream &OS, |
| 404 | const STIPredicateFunction &Fn) { |
| 405 | RecVec Delegates = Fn.getDeclaration()->getValueAsListOfDefs("Delegates"); |
| 406 | bool UpdatesOpcodeMask = |
| 407 | Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); |
| 408 | |
| 409 | increaseIndentLevel(); |
| 410 | unsigned IndentLevel = getIndentLevel(); |
| 411 | for (const Record *Delegate : Delegates) { |
| 412 | OS.indent(IndentLevel * 2); |
| 413 | OS << "if (" << Delegate->getValueAsString("Name") << "(MI"; |
| 414 | if (UpdatesOpcodeMask) |
| 415 | OS << ", Mask"; |
| 416 | if (shouldExpandForMC()) |
| 417 | OS << ", ProcessorID"; |
| 418 | OS << "))\n"; |
| 419 | OS.indent((1 + IndentLevel) * 2); |
| 420 | OS << "return true;\n\n"; |
| 421 | } |
| 422 | |
| 423 | if (shouldExpandForMC()) |
| 424 | return; |
| 425 | |
| 426 | OS.indent(IndentLevel * 2); |
| 427 | OS << "unsigned ProcessorID = getSchedModel().getProcessorID();\n"; |
| 428 | } |
| 429 | |
| 430 | void STIPredicateExpander::expandOpcodeGroup(raw_ostream &OS, const OpcodeGroup &Group, |
| 431 | bool ShouldUpdateOpcodeMask) { |
| 432 | const OpcodeInfo &OI = Group.getOpcodeInfo(); |
| 433 | for (const PredicateInfo &PI : OI.getPredicates()) { |
| 434 | const APInt &ProcModelMask = PI.ProcModelMask; |
| 435 | bool FirstProcID = true; |
| 436 | for (unsigned I = 0, E = ProcModelMask.getActiveBits(); I < E; ++I) { |
| 437 | if (!ProcModelMask[I]) |
| 438 | continue; |
| 439 | |
| 440 | if (FirstProcID) { |
| 441 | OS.indent(getIndentLevel() * 2); |
| 442 | OS << "if (ProcessorID == " << I; |
| 443 | } else { |
| 444 | OS << " || ProcessorID == " << I; |
| 445 | } |
| 446 | FirstProcID = false; |
| 447 | } |
| 448 | |
| 449 | OS << ") {\n"; |
| 450 | |
| 451 | increaseIndentLevel(); |
| 452 | OS.indent(getIndentLevel() * 2); |
| 453 | if (ShouldUpdateOpcodeMask) { |
| 454 | if (PI.OperandMask.isNullValue()) |
| 455 | OS << "Mask.clearAllBits();\n"; |
| 456 | else |
| 457 | OS << "Mask = " << PI.OperandMask << ";\n"; |
| 458 | OS.indent(getIndentLevel() * 2); |
| 459 | } |
| 460 | OS << "return "; |
| 461 | expandPredicate(OS, PI.Predicate); |
| 462 | OS << ";\n"; |
| 463 | decreaseIndentLevel(); |
| 464 | OS.indent(getIndentLevel() * 2); |
| 465 | OS << "}\n"; |
| 466 | } |
| 467 | } |
| 468 | |
| 469 | void STIPredicateExpander::expandBody(raw_ostream &OS, |
| 470 | const STIPredicateFunction &Fn) { |
| 471 | bool UpdatesOpcodeMask = |
| 472 | Fn.getDeclaration()->getValueAsBit("UpdatesOpcodeMask"); |
| 473 | |
| 474 | unsigned IndentLevel = getIndentLevel(); |
| 475 | OS.indent(IndentLevel * 2); |
| 476 | OS << "switch(MI" << (isByRef() ? "." : "->") << "getOpcode()) {\n"; |
| 477 | OS.indent(IndentLevel * 2); |
| 478 | OS << "default:\n"; |
| 479 | OS.indent(IndentLevel * 2); |
| 480 | OS << " break;"; |
| 481 | |
| 482 | for (const OpcodeGroup &Group : Fn.getGroups()) { |
| 483 | for (const Record *Opcode : Group.getOpcodes()) { |
| 484 | OS << '\n'; |
| 485 | OS.indent(IndentLevel * 2); |
| 486 | OS << "case " << getTargetName() << "::" << Opcode->getName() << ":"; |
| 487 | } |
| 488 | |
| 489 | OS << '\n'; |
| 490 | increaseIndentLevel(); |
| 491 | expandOpcodeGroup(OS, Group, UpdatesOpcodeMask); |
| 492 | |
| 493 | OS.indent(getIndentLevel() * 2); |
| 494 | OS << "break;\n"; |
| 495 | decreaseIndentLevel(); |
| 496 | } |
| 497 | |
| 498 | OS.indent(IndentLevel * 2); |
| 499 | OS << "}\n"; |
| 500 | } |
| 501 | |
| 502 | void STIPredicateExpander::expandEpilogue(raw_ostream &OS, |
| 503 | const STIPredicateFunction &Fn) { |
| 504 | OS << '\n'; |
| 505 | OS.indent(getIndentLevel() * 2); |
| 506 | OS << "return "; |
| 507 | expandPredicate(OS, Fn.getDefaultReturnPredicate()); |
| 508 | OS << ";\n"; |
| 509 | |
| 510 | decreaseIndentLevel(); |
| 511 | OS.indent(getIndentLevel() * 2); |
| 512 | StringRef FunctionName = Fn.getDeclaration()->getValueAsString("Name"); |
| 513 | OS << "} // " << ClassPrefix << "::" << FunctionName << "\n\n"; |
| 514 | } |
| 515 | |
| 516 | void STIPredicateExpander::expandSTIPredicate(raw_ostream &OS, |
| 517 | const STIPredicateFunction &Fn) { |
| 518 | const Record *Rec = Fn.getDeclaration(); |
| 519 | if (shouldExpandForMC() && !Rec->getValueAsBit("ExpandForMC")) |
| 520 | return; |
| 521 | |
| 522 | expandHeader(OS, Fn); |
| 523 | if (shouldExpandDefinition()) { |
| 524 | expandPrologue(OS, Fn); |
| 525 | expandBody(OS, Fn); |
| 526 | expandEpilogue(OS, Fn); |
| 527 | } |
| 528 | } |
| 529 | |
Andrea Di Biagio | e68d92b | 2018-05-25 15:55:37 +0000 | [diff] [blame] | 530 | } // namespace llvm |