Skip to content

Commit

Permalink
[ARM] Use table-gen'd assembly operand diags in ARM asm parser
Browse files Browse the repository at this point in the history
This switches the ARM AsmParser to use assembly operand diagnostics from
tablegen, rather than a switch statement on the ARMMatchResultTy. It
moves the existing diagnostic strings to tablegen, but adds no new ones,
so this is NFC except for one diagnostic string that had an off-by-1 error
in the hand-written switch statement.

Differential revision: https://reviews.llvm.org/D31607

llvm-svn: 314804
  • Loading branch information
ostannard committed Oct 3, 2017
1 parent 41dfac3 commit 0d5c792
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 98 deletions.
8 changes: 4 additions & 4 deletions llvm/lib/Target/ARM/ARMInstrFormats.td
Original file line number Diff line number Diff line change
Expand Up @@ -2573,18 +2573,18 @@ class N3VLaneCP8<bit op23, bits<2> op21_20, bit op6, bit op4,
}

// Operand types for complex instructions
class ComplexRotationOperand<int Angle, int Remainder, string Type>
class ComplexRotationOperand<int Angle, int Remainder, string Type, string Diag>
: AsmOperandClass {
let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";
let DiagnosticType = "InvalidComplexRotation" # Type;
let DiagnosticString = "complex rotation must be " # Diag;
let Name = "ComplexRotation" # Type;
}
def complexrotateop : Operand<i32> {
let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;
let ParserMatchClass = ComplexRotationOperand<90, 0, "Even", "0, 90, 180 or 270">;
let PrintMethod = "printComplexRotationOp<90, 0>";
}
def complexrotateopodd : Operand<i32> {
let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;
let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd", "90 or 270">;
let PrintMethod = "printComplexRotationOp<180, 90>";
}

Expand Down
32 changes: 17 additions & 15 deletions llvm/lib/Target/ARM/ARMInstrInfo.td
Original file line number Diff line number Diff line change
Expand Up @@ -460,12 +460,13 @@ def fsub_mlx : PatFrag<(ops node:$lhs, node:$rhs),(fsub node:$lhs, node:$rhs),[{
class ImmAsmOperand<int Low, int High> : AsmOperandClass {
let RenderMethod = "addImmOperands";
let PredicateMethod = "isImmediate<" # Low # "," # High # ">";
let DiagnosticType = "ImmRange" # Low # "_" # High;
let DiagnosticString = "immediate operand must be in the range [" # Low # "," # High # "]";
}

class ImmAsmOperandMinusOne<int Low, int High> : AsmOperandClass {
let PredicateMethod = "isImmediate<" # Low # "," # High # ">";
let DiagnosticType = "ImmRange" # Low # "_" # High;
let DiagnosticString = "immediate operand must be in the range [" # Low # "," # High # "]";
}

// Operands that are part of a memory addressing mode.
Expand Down Expand Up @@ -754,7 +755,6 @@ def imm1_31 : Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm < 32; }]> {
/// imm0_15 predicate - Immediate in the range [0,15].
def Imm0_15AsmOperand: ImmAsmOperand<0,15> {
let Name = "Imm0_15";
let DiagnosticType = "ImmRange0_15";
}
def imm0_15 : Operand<i32>, ImmLeaf<i32, [{
return Imm >= 0 && Imm < 16;
Expand Down Expand Up @@ -789,7 +789,6 @@ def imm0_63 : Operand<i32>, ImmLeaf<i32, [{
/// imm0_239 predicate - Immediate in the range [0,239].
def Imm0_239AsmOperand : ImmAsmOperand<0,239> {
let Name = "Imm0_239";
let DiagnosticType = "ImmRange0_239";
}
def imm0_239 : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 240; }]> {
let ParserMatchClass = Imm0_239AsmOperand;
Expand Down Expand Up @@ -836,7 +835,10 @@ def imm256_65535_expr : Operand<i32> {
}

/// imm24b - True if the 32-bit immediate is encodable in 24 bits.
def Imm24bitAsmOperand: ImmAsmOperand<0,0xffffff> { let Name = "Imm24bit"; }
def Imm24bitAsmOperand: ImmAsmOperand<0,0xffffff> {
let Name = "Imm24bit";
let DiagnosticString = "immediate operand must be in the range [0,0xffffff]";
}
def imm24b : Operand<i32>, ImmLeaf<i32, [{
return Imm >= 0 && Imm <= 0xffffff;
}]> {
Expand Down Expand Up @@ -1129,7 +1131,7 @@ class AddrMode6Align : MemOperand,
// VLD/VST instructions and checking the alignment is not specified.
def AddrMode6AlignNoneAsmOperand : AsmOperandClass {
let Name = "AlignedMemoryNone";
let DiagnosticType = "AlignedMemoryRequiresNone";
let DiagnosticString = "alignment must be omitted";
}
def addrmode6alignNone : AddrMode6Align {
// The alignment specifier can only be omitted.
Expand All @@ -1140,7 +1142,7 @@ def addrmode6alignNone : AddrMode6Align {
// VLD/VST instructions and checking the alignment value.
def AddrMode6Align16AsmOperand : AsmOperandClass {
let Name = "AlignedMemory16";
let DiagnosticType = "AlignedMemoryRequires16";
let DiagnosticString = "alignment must be 16 or omitted";
}
def addrmode6align16 : AddrMode6Align {
// The alignment specifier can only be 16 or omitted.
Expand All @@ -1151,7 +1153,7 @@ def addrmode6align16 : AddrMode6Align {
// VLD/VST instructions and checking the alignment value.
def AddrMode6Align32AsmOperand : AsmOperandClass {
let Name = "AlignedMemory32";
let DiagnosticType = "AlignedMemoryRequires32";
let DiagnosticString = "alignment must be 32 or omitted";
}
def addrmode6align32 : AddrMode6Align {
// The alignment specifier can only be 32 or omitted.
Expand All @@ -1162,7 +1164,7 @@ def addrmode6align32 : AddrMode6Align {
// VLD/VST instructions and checking the alignment value.
def AddrMode6Align64AsmOperand : AsmOperandClass {
let Name = "AlignedMemory64";
let DiagnosticType = "AlignedMemoryRequires64";
let DiagnosticString = "alignment must be 64 or omitted";
}
def addrmode6align64 : AddrMode6Align {
// The alignment specifier can only be 64 or omitted.
Expand All @@ -1173,7 +1175,7 @@ def addrmode6align64 : AddrMode6Align {
// for VLD/VST instructions and checking the alignment value.
def AddrMode6Align64or128AsmOperand : AsmOperandClass {
let Name = "AlignedMemory64or128";
let DiagnosticType = "AlignedMemoryRequires64or128";
let DiagnosticString = "alignment must be 64, 128 or omitted";
}
def addrmode6align64or128 : AddrMode6Align {
// The alignment specifier can only be 64, 128 or omitted.
Expand All @@ -1184,7 +1186,7 @@ def addrmode6align64or128 : AddrMode6Align {
// encoding for VLD/VST instructions and checking the alignment value.
def AddrMode6Align64or128or256AsmOperand : AsmOperandClass {
let Name = "AlignedMemory64or128or256";
let DiagnosticType = "AlignedMemoryRequires64or128or256";
let DiagnosticString = "alignment must be 64, 128, 256 or omitted";
}
def addrmode6align64or128or256 : AddrMode6Align {
// The alignment specifier can only be 64, 128, 256 or omitted.
Expand Down Expand Up @@ -1215,7 +1217,7 @@ class AddrMode6DupAlign : MemOperand,
// VLD-dup instruction and checking the alignment is not specified.
def AddrMode6dupAlignNoneAsmOperand : AsmOperandClass {
let Name = "DupAlignedMemoryNone";
let DiagnosticType = "DupAlignedMemoryRequiresNone";
let DiagnosticString = "alignment must be omitted";
}
def addrmode6dupalignNone : AddrMode6DupAlign {
// The alignment specifier can only be omitted.
Expand All @@ -1226,7 +1228,7 @@ def addrmode6dupalignNone : AddrMode6DupAlign {
// instruction and checking the alignment value.
def AddrMode6dupAlign16AsmOperand : AsmOperandClass {
let Name = "DupAlignedMemory16";
let DiagnosticType = "DupAlignedMemoryRequires16";
let DiagnosticString = "alignment must be 16 or omitted";
}
def addrmode6dupalign16 : AddrMode6DupAlign {
// The alignment specifier can only be 16 or omitted.
Expand All @@ -1237,7 +1239,7 @@ def addrmode6dupalign16 : AddrMode6DupAlign {
// instruction and checking the alignment value.
def AddrMode6dupAlign32AsmOperand : AsmOperandClass {
let Name = "DupAlignedMemory32";
let DiagnosticType = "DupAlignedMemoryRequires32";
let DiagnosticString = "alignment must be 32 or omitted";
}
def addrmode6dupalign32 : AddrMode6DupAlign {
// The alignment specifier can only be 32 or omitted.
Expand All @@ -1248,7 +1250,7 @@ def addrmode6dupalign32 : AddrMode6DupAlign {
// instructions and checking the alignment value.
def AddrMode6dupAlign64AsmOperand : AsmOperandClass {
let Name = "DupAlignedMemory64";
let DiagnosticType = "DupAlignedMemoryRequires64";
let DiagnosticString = "alignment must be 64 or omitted";
}
def addrmode6dupalign64 : AddrMode6DupAlign {
// The alignment specifier can only be 64 or omitted.
Expand All @@ -1259,7 +1261,7 @@ def addrmode6dupalign64 : AddrMode6DupAlign {
// for VLD instructions and checking the alignment value.
def AddrMode6dupAlign64or128AsmOperand : AsmOperandClass {
let Name = "DupAlignedMemory64or128";
let DiagnosticType = "DupAlignedMemoryRequires64or128";
let DiagnosticString = "alignment must be 64, 128 or omitted";
}
def addrmode6dupalign64or128 : AddrMode6DupAlign {
// The alignment specifier can only be 64, 128 or omitted.
Expand Down
77 changes: 1 addition & 76 deletions llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,6 @@ class ARMAsmParser : public MCTargetAsmParser {
SmallString<128> Message;
};

const char *getOperandMatchFailDiag(ARMMatchResultTy Error);
void FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
SmallVectorImpl<NearMissMessage> &NearMissesOut,
SMLoc IDLoc, OperandVector &Operands);
Expand Down Expand Up @@ -10095,80 +10094,6 @@ extern "C" void LLVMInitializeARMAsmParser() {
#define GET_MATCHER_IMPLEMENTATION
#include "ARMGenAsmMatcher.inc"

const char *ARMAsmParser::getOperandMatchFailDiag(ARMMatchResultTy Error) {
switch (Error) {
case Match_AlignedMemoryRequiresNone:
case Match_DupAlignedMemoryRequiresNone:
return "alignment must be omitted";
case Match_AlignedMemoryRequires16:
case Match_DupAlignedMemoryRequires16:
return "alignment must be 16 or omitted";
case Match_AlignedMemoryRequires32:
case Match_DupAlignedMemoryRequires32:
return "alignment must be 32 or omitted";
case Match_AlignedMemoryRequires64:
case Match_DupAlignedMemoryRequires64:
return "alignment must be 64 or omitted";
case Match_AlignedMemoryRequires64or128:
case Match_DupAlignedMemoryRequires64or128:
return "alignment must be 64, 128 or omitted";
case Match_AlignedMemoryRequires64or128or256:
return "alignment must be 64, 128, 256 or omitted";
case Match_ImmRange0_1:
return "immediate operand must be in the range [0,1]";
case Match_ImmRange0_3:
return "immediate operand must be in the range [0,3]";
case Match_ImmRange0_7:
return "immediate operand must be in the range [0,7]";
case Match_ImmRange0_15:
return "immediate operand must be in the range [0,15]";
case Match_ImmRange0_31:
return "immediate operand must be in the range [0,31]";
case Match_ImmRange0_32:
return "immediate operand must be in the range [0,32]";
case Match_ImmRange0_63:
return "immediate operand must be in the range [0,63]";
case Match_ImmRange0_239:
return "immediate operand must be in the range [0,239]";
case Match_ImmRange0_255:
return "immediate operand must be in the range [0,255]";
case Match_ImmRange0_4095:
return "immediate operand must be in the range [0,4095]";
case Match_ImmRange0_65535:
return "immediate operand must be in the range [0,65535]";
case Match_ImmRange1_7:
return "immediate operand must be in the range [1,7]";
case Match_ImmRange1_8:
return "immediate operand must be in the range [1,8]";
case Match_ImmRange1_15:
return "immediate operand must be in the range [1,15]";
case Match_ImmRange1_16:
return "immediate operand must be in the range [1,16]";
case Match_ImmRange1_31:
return "immediate operand must be in the range [1,31]";
case Match_ImmRange1_32:
return "immediate operand must be in the range [1,32]";
case Match_ImmRange1_64:
return "immediate operand must be in the range [1,64]";
case Match_ImmRange8_8:
return "immediate operand must be 8.";
case Match_ImmRange16_16:
return "immediate operand must be 16.";
case Match_ImmRange32_32:
return "immediate operand must be 32.";
case Match_ImmRange256_65535:
return "immediate operand must be in the range [255,65535]";
case Match_ImmRange0_16777215:
return "immediate operand must be in the range [0,0xffffff]";
case Match_InvalidComplexRotationEven:
return "complex rotation must be 0, 90, 180 or 270";
case Match_InvalidComplexRotationOdd:
return "complex rotation must be 90 or 270";
default:
return nullptr;
}
}

// Process the list of near-misses, throwing away ones we don't want to report
// to the user, and converting the rest to a source location and string that
// should be reported.
Expand Down Expand Up @@ -10199,7 +10124,7 @@ ARMAsmParser::FilterNearMisses(SmallVectorImpl<NearMissInfo> &NearMissesIn,
SMLoc OperandLoc =
((ARMOperand &)*Operands[I.getOperandIndex()]).getStartLoc();
const char *OperandDiag =
getOperandMatchFailDiag((ARMMatchResultTy)I.getOperandError());
getMatchKindDiag((ARMMatchResultTy)I.getOperandError());

// If we have already emitted a message for a superclass, don't also report
// the sub-class. We consider all operand classes that we don't have a
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/MC/ARM/lsl-zero-errors.s
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
// CHECK-NONARM-NEXT: mov r0, pc, lsl #0
// CHECK-NONARM: invalid operand for instruction
// CHECK-NONARM: invalid operand for instruction
// CHECK-NONARM: immediate operand must be in the range [255,65535]
// CHECK-NONARM: immediate operand must be in the range [256,65535]
// CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
// CHECK-NONARM-NEXT: mov pc, pc, lsl #0
// CHECK-NONARM: invalid operand for instruction
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/MC/ARM/t2-modified-immediate-fixup-error2.s
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@
@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK: note: instruction requires: arm-mode
@ CHECK: note: invalid operand for instruction
@ CHECK: note: immediate operand must be in the range [255,65535]
@ CHECK: note: immediate operand must be in the range [256,65535]
mov r0, :lower16: sym0
@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK: note: instruction requires: arm-mode
@ CHECK: note: invalid operand for instruction
@ CHECK: note: immediate operand must be in the range [255,65535]
@ CHECK: note: immediate operand must be in the range [256,65535]
.equ sym0, 0x01abcdef

0 comments on commit 0d5c792

Please sign in to comment.