[TableGen][AsmMatcher] Fix optional operand mask indexing when HasMnemonicFirst is false (#176868)
### Summary Fix optional operand mask indexing in the generated asm matcher when HasMnemonicFirst is false.
This commit is contained in:
parent
f5de33dbf5
commit
170ad2335e
64
llvm/test/TableGen/NotFirstMnemonic.td
Normal file
64
llvm/test/TableGen/NotFirstMnemonic.td
Normal file
@ -0,0 +1,64 @@
|
||||
// RUN: llvm-tblgen -gen-asm-matcher -I %p/../../include %s | FileCheck %s
|
||||
|
||||
// Check that specifying AsmVariant works correctly
|
||||
|
||||
include "llvm/Target/Target.td"
|
||||
|
||||
def ArchParser : AsmParser {
|
||||
let HasMnemonicFirst = 0;
|
||||
}
|
||||
|
||||
def Arch : Target {
|
||||
let AssemblyParsers = [ArchParser];
|
||||
}
|
||||
|
||||
def Reg : Register<"reg">;
|
||||
|
||||
def RegClass : RegisterClass<"foo", [i32], 0, (add Reg)>;
|
||||
|
||||
def OptinalAsmOperand :AsmOperandClass {
|
||||
let Name = "OptinalAsmOperand";
|
||||
let RenderMethod = "addOptinalAsmOperand";
|
||||
let IsOptional = 1;
|
||||
}
|
||||
|
||||
def OptinalOperand : Operand<i32> {
|
||||
let OperandNamespace = "Arch";
|
||||
let OperandType = "OPERAND_INPUT_MODS";
|
||||
let PrintMethod = "printOptinalOperand";
|
||||
let ParserMatchClass = OptinalAsmOperand;
|
||||
}
|
||||
|
||||
class InstCommonBase {
|
||||
field bits<64> Inst;
|
||||
}
|
||||
|
||||
def foo : Instruction, InstCommonBase {
|
||||
bits<32> optinalOp;
|
||||
|
||||
let Size = 2;
|
||||
let OutOperandList = (outs);
|
||||
let InOperandList = (ins OptinalOperand:$optinalOp);
|
||||
let AsmString = "$optinalOp\tfoo";
|
||||
let Namespace = "Arch";
|
||||
|
||||
let Inst{22 - 10} = optinalOp{12 - 0};
|
||||
}
|
||||
|
||||
// CHECK: if (OptionalOperandsMask[*(p + 1)]) {
|
||||
|
||||
// CHECK: SmallBitVector OptionalOperandsMask(2);
|
||||
|
||||
// CHECK: OptionalOperandsMask.reset(0, 2);
|
||||
|
||||
// CHECK: if (Formal == InvalidMatchClass) {
|
||||
// CHECK-NEXT: OptionalOperandsMask.set(FormalIdx, 2);
|
||||
// CHECK: if (isSubclass(Formal, OptionalMatchClass)) {
|
||||
// CHECK-NEXT: OptionalOperandsMask.set(FormalIdx);
|
||||
// CHECK: if (Diag == Match_InvalidOperand && isSubclass(Formal, OptionalMatchClass)) {
|
||||
// CHECK-NEXT: OptionalOperandsMask.set(FormalIdx);
|
||||
|
||||
// CHECK: for (unsigned i = 0, NumDefaults = 0; i < 2; ++i) {
|
||||
// CHECK-NEXT: NumDefaults += (OptionalOperandsMask[i] ? 1 : 0);
|
||||
// CHECK-NEXT: DefaultsOffset[i + 1] = NumDefaults;
|
||||
// CHECK-NEXT: }
|
||||
@ -2183,7 +2183,7 @@ emitConvertFuncs(CodeGenTarget &Target, StringRef ClassName,
|
||||
// If optional operand is not present in actual instruction then we
|
||||
// should call its DefaultMethod before RenderMethod
|
||||
assert(HasOptionalOperands);
|
||||
CvtOS << " if (OptionalOperandsMask[*(p + 1) - 1]) {\n"
|
||||
CvtOS << " if (OptionalOperandsMask[*(p + 1)]) {\n"
|
||||
<< " " << Op.Class->DefaultMethod << "()"
|
||||
<< "->" << Op.Class->RenderMethod << "(Inst, "
|
||||
<< OpInfo.MINumOperands << ");\n"
|
||||
@ -3733,7 +3733,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
}
|
||||
|
||||
if (HasOptionalOperands)
|
||||
OS << " SmallBitVector OptionalOperandsMask(" << MaxNumOperands << ");\n";
|
||||
OS << " SmallBitVector OptionalOperandsMask("
|
||||
<< MaxNumOperands + HasMnemonicFirst << ");\n";
|
||||
|
||||
// Emit code to search the table.
|
||||
OS << " // Find the appropriate table for this asm variant.\n";
|
||||
@ -3802,7 +3803,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
if (!ReportMultipleNearMisses)
|
||||
OS << " bool OperandsValid = true;\n";
|
||||
if (HasOptionalOperands)
|
||||
OS << " OptionalOperandsMask.reset(0, " << MaxNumOperands << ");\n";
|
||||
OS << " OptionalOperandsMask.reset(0, "
|
||||
<< MaxNumOperands + HasMnemonicFirst << ");\n";
|
||||
OS << " for (unsigned FormalIdx = " << (HasMnemonicFirst ? "0" : "SIndex")
|
||||
<< ", ActualIdx = " << (HasMnemonicFirst ? "1" : "SIndex")
|
||||
<< "; FormalIdx != " << MaxNumOperands << "; ++FormalIdx) {\n";
|
||||
@ -3850,21 +3852,24 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"but formal "
|
||||
"operand not required\\n\");\n";
|
||||
OS << " if (isSubclass(Formal, OptionalMatchClass)) {\n";
|
||||
OS << " OptionalOperandsMask.set(FormalIdx);\n";
|
||||
OS << " OptionalOperandsMask.set("
|
||||
<< (HasMnemonicFirst ? "FormalIdx + 1" : "FormalIdx") << ");\n";
|
||||
OS << " }\n";
|
||||
OS << " }\n";
|
||||
OS << " continue;\n";
|
||||
} else {
|
||||
OS << " if (Formal == InvalidMatchClass) {\n";
|
||||
if (HasOptionalOperands) {
|
||||
OS << " OptionalOperandsMask.set(FormalIdx, " << MaxNumOperands
|
||||
<< ");\n";
|
||||
OS << " OptionalOperandsMask.set("
|
||||
<< (HasMnemonicFirst ? "FormalIdx + 1, " : "FormalIdx, ")
|
||||
<< MaxNumOperands + HasMnemonicFirst << ");\n";
|
||||
}
|
||||
OS << " break;\n";
|
||||
OS << " }\n";
|
||||
OS << " if (isSubclass(Formal, OptionalMatchClass)) {\n";
|
||||
if (HasOptionalOperands)
|
||||
OS << " OptionalOperandsMask.set(FormalIdx);\n";
|
||||
OS << " OptionalOperandsMask.set("
|
||||
<< (HasMnemonicFirst ? "FormalIdx + 1" : "FormalIdx") << ");\n";
|
||||
OS << " continue;\n";
|
||||
OS << " }\n";
|
||||
OS << " OperandsValid = false;\n";
|
||||
@ -3904,7 +3909,8 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
OS << " if (Diag == Match_InvalidOperand "
|
||||
<< "&& isSubclass(Formal, OptionalMatchClass)) {\n";
|
||||
if (HasOptionalOperands)
|
||||
OS << " OptionalOperandsMask.set(FormalIdx);\n";
|
||||
OS << " OptionalOperandsMask.set("
|
||||
<< (HasMnemonicFirst ? "FormalIdx + 1" : "FormalIdx") << ");\n";
|
||||
OS << " DEBUG_WITH_TYPE(\"asm-matcher\", dbgs() << \"ignoring "
|
||||
"optional operand\\n\");\n";
|
||||
OS << " continue;\n";
|
||||
@ -4059,12 +4065,12 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
|
||||
if (HasOptionalOperands) {
|
||||
OS << " unsigned DefaultsOffset[" << (MaxNumOperands + 1)
|
||||
<< "] = { 0 };\n";
|
||||
OS << " assert(OptionalOperandsMask.size() == " << (MaxNumOperands)
|
||||
<< ");\n";
|
||||
OS << " assert(OptionalOperandsMask.size() == "
|
||||
<< (MaxNumOperands + HasMnemonicFirst) << ");\n";
|
||||
OS << " for (unsigned i = 0, NumDefaults = 0; i < " << (MaxNumOperands)
|
||||
<< "; ++i) {\n";
|
||||
OS << " DefaultsOffset[i + 1] = NumDefaults;\n";
|
||||
OS << " NumDefaults += (OptionalOperandsMask[i] ? 1 : 0);\n";
|
||||
OS << " DefaultsOffset[i + 1] = NumDefaults;\n";
|
||||
OS << " }\n\n";
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user