195140023SAndrea Di Biagio //===--------------------- PredicateExpander.cpp --------------------------===//
295140023SAndrea Di Biagio //
395140023SAndrea Di Biagio //                     The LLVM Compiler Infrastructure
495140023SAndrea Di Biagio //
595140023SAndrea Di Biagio // This file is distributed under the University of Illinois Open Source
695140023SAndrea Di Biagio // License. See LICENSE.TXT for details.
795140023SAndrea Di Biagio //
895140023SAndrea Di Biagio //===----------------------------------------------------------------------===//
995140023SAndrea Di Biagio /// \file
1095140023SAndrea Di Biagio /// Functionalities used by the Tablegen backends to expand machine predicates.
1195140023SAndrea Di Biagio //
1295140023SAndrea Di Biagio //===----------------------------------------------------------------------===//
1395140023SAndrea Di Biagio 
1495140023SAndrea Di Biagio #include "PredicateExpander.h"
1595140023SAndrea Di Biagio 
1695140023SAndrea Di Biagio namespace llvm {
1795140023SAndrea Di Biagio 
1895140023SAndrea Di Biagio void PredicateExpander::expandTrue(formatted_raw_ostream &OS) { OS << "true"; }
1995140023SAndrea Di Biagio void PredicateExpander::expandFalse(formatted_raw_ostream &OS) {
2095140023SAndrea Di Biagio   OS << "false";
2195140023SAndrea Di Biagio }
2295140023SAndrea Di Biagio 
2395140023SAndrea Di Biagio void PredicateExpander::expandCheckImmOperand(formatted_raw_ostream &OS,
2495140023SAndrea Di Biagio                                               int OpIndex, int ImmVal) {
25*ad0293caSAndrea Di Biagio   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
26*ad0293caSAndrea Di Biagio      << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
2795140023SAndrea Di Biagio }
2895140023SAndrea Di Biagio 
2995140023SAndrea Di Biagio void PredicateExpander::expandCheckImmOperand(formatted_raw_ostream &OS,
3095140023SAndrea Di Biagio                                               int OpIndex, StringRef ImmVal) {
31*ad0293caSAndrea Di Biagio   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
32*ad0293caSAndrea Di Biagio      << ").getImm() " << (shouldNegate() ? "!= " : "== ") << ImmVal;
3395140023SAndrea Di Biagio }
3495140023SAndrea Di Biagio 
3595140023SAndrea Di Biagio void PredicateExpander::expandCheckRegOperand(formatted_raw_ostream &OS,
3695140023SAndrea Di Biagio                                               int OpIndex, const Record *Reg) {
3795140023SAndrea Di Biagio   assert(Reg->isSubClassOf("Register") && "Expected a register Record!");
3895140023SAndrea Di Biagio 
3995140023SAndrea Di Biagio   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << OpIndex
4095140023SAndrea Di Biagio      << ").getReg() " << (shouldNegate() ? "!= " : "== ");
4195140023SAndrea Di Biagio   const StringRef Str = Reg->getValueAsString("Namespace");
4295140023SAndrea Di Biagio   if (!Str.empty())
4395140023SAndrea Di Biagio     OS << Str << "::";
4495140023SAndrea Di Biagio   OS << Reg->getName();
4595140023SAndrea Di Biagio }
4695140023SAndrea Di Biagio 
4795140023SAndrea Di Biagio void PredicateExpander::expandCheckSameRegOperand(formatted_raw_ostream &OS,
4895140023SAndrea Di Biagio                                                   int First, int Second) {
4995140023SAndrea Di Biagio   OS << "MI" << (isByRef() ? "." : "->") << "getOperand(" << First
5095140023SAndrea Di Biagio      << ").getReg() " << (shouldNegate() ? "!=" : "==") << " MI"
5195140023SAndrea Di Biagio      << (isByRef() ? "." : "->") << "getOperand(" << Second << ").getReg()";
5295140023SAndrea Di Biagio }
5395140023SAndrea Di Biagio 
5495140023SAndrea Di Biagio void PredicateExpander::expandCheckNumOperands(formatted_raw_ostream &OS,
5595140023SAndrea Di Biagio                                                int NumOps) {
5695140023SAndrea Di Biagio   OS << "MI" << (isByRef() ? "." : "->") << "getNumOperands() "
5795140023SAndrea Di Biagio      << (shouldNegate() ? "!= " : "== ") << NumOps;
5895140023SAndrea Di Biagio }
5995140023SAndrea Di Biagio 
6095140023SAndrea Di Biagio void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
6195140023SAndrea Di Biagio                                           const Record *Inst) {
6295140023SAndrea Di Biagio   OS << "MI" << (isByRef() ? "." : "->") << "getOpcode() "
6395140023SAndrea Di Biagio      << (shouldNegate() ? "!= " : "== ") << Inst->getValueAsString("Namespace")
6495140023SAndrea Di Biagio      << "::" << Inst->getName();
6595140023SAndrea Di Biagio }
6695140023SAndrea Di Biagio 
6795140023SAndrea Di Biagio void PredicateExpander::expandCheckOpcode(formatted_raw_ostream &OS,
6895140023SAndrea Di Biagio                                           const RecVec &Opcodes) {
6995140023SAndrea Di Biagio   assert(!Opcodes.empty() && "Expected at least one opcode to check!");
7095140023SAndrea Di Biagio   bool First = true;
7195140023SAndrea Di Biagio 
7295140023SAndrea Di Biagio   if (Opcodes.size() == 1) {
7395140023SAndrea Di Biagio     OS << "( ";
7495140023SAndrea Di Biagio     expandCheckOpcode(OS, Opcodes[0]);
7595140023SAndrea Di Biagio     OS << " )";
7695140023SAndrea Di Biagio     return;
7795140023SAndrea Di Biagio   }
7895140023SAndrea Di Biagio 
7995140023SAndrea Di Biagio   OS << '(';
8095140023SAndrea Di Biagio   increaseIndentLevel();
8195140023SAndrea Di Biagio   for (const Record *Rec : Opcodes) {
8295140023SAndrea Di Biagio     OS << '\n';
8395140023SAndrea Di Biagio     OS.PadToColumn(getIndentLevel() * 2);
8495140023SAndrea Di Biagio     if (!First)
8595140023SAndrea Di Biagio       OS << (shouldNegate() ? "&& " : "|| ");
8695140023SAndrea Di Biagio 
8795140023SAndrea Di Biagio     expandCheckOpcode(OS, Rec);
8895140023SAndrea Di Biagio     First = false;
8995140023SAndrea Di Biagio   }
9095140023SAndrea Di Biagio 
9195140023SAndrea Di Biagio   OS << '\n';
9295140023SAndrea Di Biagio   decreaseIndentLevel();
9395140023SAndrea Di Biagio   OS.PadToColumn(getIndentLevel() * 2);
9495140023SAndrea Di Biagio   OS << ')';
9595140023SAndrea Di Biagio }
9695140023SAndrea Di Biagio 
9795140023SAndrea Di Biagio void PredicateExpander::expandCheckPseudo(formatted_raw_ostream &OS,
9895140023SAndrea Di Biagio                                           const RecVec &Opcodes) {
9995140023SAndrea Di Biagio   if (shouldExpandForMC())
10095140023SAndrea Di Biagio     expandFalse(OS);
10195140023SAndrea Di Biagio   else
10295140023SAndrea Di Biagio     expandCheckOpcode(OS, Opcodes);
10395140023SAndrea Di Biagio }
10495140023SAndrea Di Biagio 
10595140023SAndrea Di Biagio void PredicateExpander::expandPredicateSequence(formatted_raw_ostream &OS,
10695140023SAndrea Di Biagio                                                 const RecVec &Sequence,
10795140023SAndrea Di Biagio                                                 bool IsCheckAll) {
10895140023SAndrea Di Biagio   assert(!Sequence.empty() && "Found an invalid empty predicate set!");
10995140023SAndrea Di Biagio   if (Sequence.size() == 1)
11095140023SAndrea Di Biagio     return expandPredicate(OS, Sequence[0]);
11195140023SAndrea Di Biagio 
11295140023SAndrea Di Biagio   // Okay, there is more than one predicate in the set.
11395140023SAndrea Di Biagio   bool First = true;
11495140023SAndrea Di Biagio   OS << (shouldNegate() ? "!(" : "(");
11595140023SAndrea Di Biagio   increaseIndentLevel();
11695140023SAndrea Di Biagio 
11795140023SAndrea Di Biagio   bool OldValue = shouldNegate();
11895140023SAndrea Di Biagio   setNegatePredicate(false);
11995140023SAndrea Di Biagio   for (const Record *Rec : Sequence) {
12095140023SAndrea Di Biagio     OS << '\n';
12195140023SAndrea Di Biagio     OS.PadToColumn(getIndentLevel() * 2);
12295140023SAndrea Di Biagio     if (!First)
12395140023SAndrea Di Biagio       OS << (IsCheckAll ? "&& " : "|| ");
12495140023SAndrea Di Biagio     expandPredicate(OS, Rec);
12595140023SAndrea Di Biagio     First = false;
12695140023SAndrea Di Biagio   }
12795140023SAndrea Di Biagio   OS << '\n';
12895140023SAndrea Di Biagio   decreaseIndentLevel();
12995140023SAndrea Di Biagio   OS.PadToColumn(getIndentLevel() * 2);
13095140023SAndrea Di Biagio   OS << ')';
13195140023SAndrea Di Biagio   setNegatePredicate(OldValue);
13295140023SAndrea Di Biagio }
13395140023SAndrea Di Biagio 
13495140023SAndrea Di Biagio void PredicateExpander::expandTIIFunctionCall(formatted_raw_ostream &OS,
13595140023SAndrea Di Biagio                                               StringRef TargetName,
13695140023SAndrea Di Biagio                                               StringRef MethodName) {
13795140023SAndrea Di Biagio   OS << (shouldNegate() ? "!" : "");
13895140023SAndrea Di Biagio   if (shouldExpandForMC())
13995140023SAndrea Di Biagio     OS << TargetName << "_MC::";
14095140023SAndrea Di Biagio   else
14195140023SAndrea Di Biagio     OS << TargetName << "Gen"
14295140023SAndrea Di Biagio        << "InstrInfo::";
14395140023SAndrea Di Biagio   OS << MethodName << (isByRef() ? "(MI)" : "(*MI)");
14495140023SAndrea Di Biagio }
14595140023SAndrea Di Biagio 
14695140023SAndrea Di Biagio void PredicateExpander::expandCheckIsRegOperand(formatted_raw_ostream &OS,
14795140023SAndrea Di Biagio                                                 int OpIndex) {
14895140023SAndrea Di Biagio   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
14995140023SAndrea Di Biagio      << "getOperand(" << OpIndex << ").isReg() ";
15095140023SAndrea Di Biagio }
15195140023SAndrea Di Biagio 
15295140023SAndrea Di Biagio void PredicateExpander::expandCheckIsImmOperand(formatted_raw_ostream &OS,
15395140023SAndrea Di Biagio                                                 int OpIndex) {
15495140023SAndrea Di Biagio   OS << (shouldNegate() ? "!" : "") << "MI" << (isByRef() ? "." : "->")
15595140023SAndrea Di Biagio      << "getOperand(" << OpIndex << ").isImm() ";
15695140023SAndrea Di Biagio }
15795140023SAndrea Di Biagio 
15895140023SAndrea Di Biagio void PredicateExpander::expandCheckFunctionPredicate(formatted_raw_ostream &OS,
15995140023SAndrea Di Biagio                                                      StringRef MCInstFn,
16095140023SAndrea Di Biagio                                                      StringRef MachineInstrFn) {
16195140023SAndrea Di Biagio   OS << (shouldExpandForMC() ? MCInstFn : MachineInstrFn)
16295140023SAndrea Di Biagio      << (isByRef() ? "(MI)" : "(*MI)");
16395140023SAndrea Di Biagio }
16495140023SAndrea Di Biagio 
16595140023SAndrea Di Biagio void PredicateExpander::expandCheckNonPortable(formatted_raw_ostream &OS,
16695140023SAndrea Di Biagio                                                StringRef Code) {
16795140023SAndrea Di Biagio   if (shouldExpandForMC())
16895140023SAndrea Di Biagio     return expandFalse(OS);
16995140023SAndrea Di Biagio 
17095140023SAndrea Di Biagio   OS << '(' << Code << ')';
17195140023SAndrea Di Biagio }
17295140023SAndrea Di Biagio 
17395140023SAndrea Di Biagio void PredicateExpander::expandPredicate(formatted_raw_ostream &OS,
17495140023SAndrea Di Biagio                                         const Record *Rec) {
17595140023SAndrea Di Biagio   OS.flush();
17695140023SAndrea Di Biagio   unsigned ColNum = getIndentLevel() * 2;
17795140023SAndrea Di Biagio   if (OS.getColumn() < ColNum)
17895140023SAndrea Di Biagio     OS.PadToColumn(ColNum);
17995140023SAndrea Di Biagio 
18095140023SAndrea Di Biagio   if (Rec->isSubClassOf("MCTrue")) {
18195140023SAndrea Di Biagio     if (shouldNegate())
18295140023SAndrea Di Biagio       return expandFalse(OS);
18395140023SAndrea Di Biagio     return expandTrue(OS);
18495140023SAndrea Di Biagio   }
18595140023SAndrea Di Biagio 
18695140023SAndrea Di Biagio   if (Rec->isSubClassOf("MCFalse")) {
18795140023SAndrea Di Biagio     if (shouldNegate())
18895140023SAndrea Di Biagio       return expandTrue(OS);
18995140023SAndrea Di Biagio     return expandFalse(OS);
19095140023SAndrea Di Biagio   }
19195140023SAndrea Di Biagio 
19295140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckNot")) {
19395140023SAndrea Di Biagio     flipNegatePredicate();
19495140023SAndrea Di Biagio     expandPredicate(OS, Rec->getValueAsDef("Pred"));
19595140023SAndrea Di Biagio     flipNegatePredicate();
19695140023SAndrea Di Biagio     return;
19795140023SAndrea Di Biagio   }
19895140023SAndrea Di Biagio 
19995140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckIsRegOperand"))
20095140023SAndrea Di Biagio     return expandCheckIsRegOperand(OS, Rec->getValueAsInt("OpIndex"));
20195140023SAndrea Di Biagio 
20295140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckIsImmOperand"))
20395140023SAndrea Di Biagio     return expandCheckIsImmOperand(OS, Rec->getValueAsInt("OpIndex"));
20495140023SAndrea Di Biagio 
20595140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckRegOperand"))
20695140023SAndrea Di Biagio     return expandCheckRegOperand(OS, Rec->getValueAsInt("OpIndex"),
20795140023SAndrea Di Biagio                                  Rec->getValueAsDef("Reg"));
20895140023SAndrea Di Biagio 
20995140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckImmOperand"))
21095140023SAndrea Di Biagio     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
21195140023SAndrea Di Biagio                                  Rec->getValueAsInt("ImmVal"));
21295140023SAndrea Di Biagio 
21395140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckImmOperand_s"))
21495140023SAndrea Di Biagio     return expandCheckImmOperand(OS, Rec->getValueAsInt("OpIndex"),
21595140023SAndrea Di Biagio                                  Rec->getValueAsString("ImmVal"));
21695140023SAndrea Di Biagio 
21795140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckSameRegOperand"))
21895140023SAndrea Di Biagio     return expandCheckSameRegOperand(OS, Rec->getValueAsInt("FirstIndex"),
21995140023SAndrea Di Biagio                                      Rec->getValueAsInt("SecondIndex"));
22095140023SAndrea Di Biagio 
22195140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckNumOperands"))
22295140023SAndrea Di Biagio     return expandCheckNumOperands(OS, Rec->getValueAsInt("NumOps"));
22395140023SAndrea Di Biagio 
22495140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckPseudo"))
22595140023SAndrea Di Biagio     return expandCheckPseudo(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
22695140023SAndrea Di Biagio 
22795140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckOpcode"))
22895140023SAndrea Di Biagio     return expandCheckOpcode(OS, Rec->getValueAsListOfDefs("ValidOpcodes"));
22995140023SAndrea Di Biagio 
23095140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckAll"))
23195140023SAndrea Di Biagio     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
23295140023SAndrea Di Biagio                                    /* AllOf */ true);
23395140023SAndrea Di Biagio 
23495140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckAny"))
23595140023SAndrea Di Biagio     return expandPredicateSequence(OS, Rec->getValueAsListOfDefs("Predicates"),
23695140023SAndrea Di Biagio                                    /* AllOf */ false);
23795140023SAndrea Di Biagio 
23895140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckFunctionPredicate"))
23995140023SAndrea Di Biagio     return expandCheckFunctionPredicate(
24095140023SAndrea Di Biagio         OS, Rec->getValueAsString("MCInstFnName"),
24195140023SAndrea Di Biagio         Rec->getValueAsString("MachineInstrFnName"));
24295140023SAndrea Di Biagio 
24395140023SAndrea Di Biagio   if (Rec->isSubClassOf("CheckNonPortable"))
24495140023SAndrea Di Biagio     return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock"));
24595140023SAndrea Di Biagio 
24695140023SAndrea Di Biagio   if (Rec->isSubClassOf("TIIPredicate"))
24795140023SAndrea Di Biagio     return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"),
24895140023SAndrea Di Biagio                                  Rec->getValueAsString("FunctionName"));
24995140023SAndrea Di Biagio 
25095140023SAndrea Di Biagio   llvm_unreachable("No known rules to expand this MCInstPredicate");
25195140023SAndrea Di Biagio }
25295140023SAndrea Di Biagio 
25395140023SAndrea Di Biagio } // namespace llvm
254