mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
[TableGen] Prevent invalid code generation when emitting AssemblerPredicate conditions.
Summary: The loop which emits AssemblerPredicate conditions also links them together by emitting a '&&'. If the 1st predicate is not an AssemblerPredicate, while the 2nd one is, nothing gets emitted for the 1st one, but we still emit the '&&' because of the 2nd predicate. This generated code looks like "( && Cond2)" and is invalid. Reviewers: dsanders Reviewed By: dsanders Subscribers: dsanders, llvm-commits Differential Revision: http://reviews.llvm.org/D8294 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234312 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
1fe7512627
commit
0e407e7bbf
31
test/TableGen/AsmPredicateCondsEmission.td
Normal file
31
test/TableGen/AsmPredicateCondsEmission.td
Normal file
@ -0,0 +1,31 @@
|
||||
// RUN: llvm-tblgen -gen-disassembler -I %p/../../include %s | FileCheck %s
|
||||
|
||||
// Check that we don't generate invalid code of the form "( && Cond2)" when
|
||||
// emitting AssemblerPredicate conditions. In the example below, the invalid
|
||||
// code would be: "return ( && (Bits & arch::AssemblerCondition2));".
|
||||
|
||||
include "llvm/Target/Target.td"
|
||||
|
||||
def archInstrInfo : InstrInfo { }
|
||||
|
||||
def arch : Target {
|
||||
let InstructionSet = archInstrInfo;
|
||||
}
|
||||
|
||||
def Pred1 : Predicate<"Condition1">;
|
||||
def Pred2 : Predicate<"Condition2">,
|
||||
AssemblerPredicate<"AssemblerCondition2">;
|
||||
|
||||
def foo : Instruction {
|
||||
let Size = 2;
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = (ins);
|
||||
field bits<16> Inst;
|
||||
let Inst = 0xAAAA;
|
||||
let AsmString = "foo";
|
||||
field bits<16> SoftFail = 0;
|
||||
// This is the important bit:
|
||||
let Predicates = [Pred1, Pred2];
|
||||
}
|
||||
|
||||
// CHECK: return ((Bits & arch::AssemblerCondition2));
|
@ -1112,6 +1112,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
|
||||
unsigned Opc) const {
|
||||
ListInit *Predicates =
|
||||
AllInstructions[Opc]->TheDef->getValueAsListInit("Predicates");
|
||||
bool IsFirstEmission = true;
|
||||
for (unsigned i = 0; i < Predicates->getSize(); ++i) {
|
||||
Record *Pred = Predicates->getElementAsRecord(i);
|
||||
if (!Pred->getValue("AssemblerMatcherPredicate"))
|
||||
@ -1122,7 +1123,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
|
||||
if (!P.length())
|
||||
continue;
|
||||
|
||||
if (i != 0)
|
||||
if (!IsFirstEmission)
|
||||
o << " && ";
|
||||
|
||||
StringRef SR(P);
|
||||
@ -1133,6 +1134,7 @@ bool FilterChooser::emitPredicateMatch(raw_ostream &o, unsigned &Indentation,
|
||||
pairs = pairs.second.split(',');
|
||||
}
|
||||
emitSinglePredicateMatch(o, pairs.first, Emitter->PredicateNamespace);
|
||||
IsFirstEmission = false;
|
||||
}
|
||||
return Predicates->getSize() > 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user