blob: e7565fe43b3c3dc547576be2ebfa7cce96798e88 [file] [edit]
// RUN: llvm-tblgen -gen-asm-matcher -I %p/../../include %s | FileCheck %s
include "llvm/Target/Target.td"
def ArchInstrInfo : InstrInfo { }
def ArchAsmParser : AsmParser {
let EmitTokenDiagnosticTypes = true;
}
def Arch : Target {
let InstructionSet = ArchInstrInfo;
let AssemblyParsers = [ArchAsmParser];
}
def Reg : Register<"reg">;
def RegClass : RegisterClass<"foo", [i32], 0, (add Reg)>;
class ArchInstruction<string AsmStr, dag OutOperands, dag InOperands> : Instruction {
let OutOperandList = OutOperands;
let InOperandList = InOperands;
let AsmString = AsmStr;
}
def Instr1 : ArchInstruction<"Instr1 [$foo]", (outs RegClass:$foo), (ins)> {
bits<1> foo;
}
def Instr2 : ArchInstruction<"Instr2 shift $foo", (outs RegClass:$foo), (ins)> {
bits<1> foo;
}
// Ensure there are match class kinds for the tokens `[`, `]`, and `shift`
// CHECK-LABEL: enum MatchClassKind
// CHECK: OptionalMatchClass = 1,
// CHECK-NEXT: MCK__91_, // '['
// CHECK-NEXT: MCK__93_, // ']'
// CHECK-NEXT: MCK_shift, // 'shift'
// CHECK-NEXT: MCK_LAST_TOKEN = MCK_shift,
// Ensure there are diagnostic strings for Match_InvalidToken* failures
// CHECK-LABEL: getMatchKindDiag
// CHECK: (ArchAsmParser::ArchMatchResultTy MatchResult) {
// CHECK-NEXT: switch (MatchResult) {
// CHECK-NEXT: case ArchAsmParser::Match_InvalidToken_91_:
// CHECK-NEXT: return "expected '['";
// CHECK-NEXT: case ArchAsmParser::Match_InvalidToken_93_:
// CHECK-NEXT: return "expected ']'";
// CHECK-NEXT: case ArchAsmParser::Match_InvalidTokenshift:
// CHECK-NEXT: return "expected 'shift'";
// Ensure there are Match_InvalidToken* instances for each token kind
// CHECK-LABEL: getDiagKindFromTokenClass
// CHECK: (MatchClassKind Kind) {
// CHECK-NEXT: switch (Kind) {
// CHECK-NEXT: default:
// CHECK-NEXT: return MCTargetAsmParser::Match_InvalidOperand;
// CHECK-NEXT: case MCK__91_:
// CHECK-NEXT: return ArchAsmParser::Match_InvalidToken_91_;
// CHECK-NEXT: case MCK__93_:
// CHECK-NEXT: return ArchAsmParser::Match_InvalidToken_93_;
// CHECK-NEXT: case MCK_shift:
// CHECK-NEXT: return ArchAsmParser::Match_InvalidTokenshift;
// CHECK-NEXT: }
// CHECK-NEXT: }
// Ensure that we call `getDiagKindFromTokenClass` when a token is expected but not found
// CHECK-LABEL: validateOperandClass
// CHECK: (MCParsedAsmOperand &GOp, MatchClassKind Kind, const MCSubtargetInfo &STI) {
// CHECK-NEXT: ArchOperand &Operand = (ArchOperand &)GOp;
// CHECK-NEXT: if (Kind == InvalidMatchClass)
// CHECK-NEXT: return MCTargetAsmParser::Match_InvalidOperand;
// CHECK-EMPTY:
// CHECK-NEXT: if (Kind <= MCK_LAST_TOKEN) {
// CHECK-NEXT: if (Operand.isToken() &&
// CHECK-NEXT: isSubclass(matchTokenString(Operand.getToken()), Kind))
// CHECK-NEXT: return MCTargetAsmParser::Match_Success;
// CHECK-NEXT: return getDiagKindFromTokenClass(Kind);
// CHECK-NEXT: }