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