[ARM][TableGen][MC] Change the ARM mnemonic operands to be optional for ASM parsing (#83436)

This changs the way the assembly matcher works for Aarch32 parsing.
Previously there was a pile of hacks which dictated whether the CC,
CCOut, and VCC operands should be present which de-facto chose if the
wide/narrow (or thumb1/thumb2/arm) instruction version were chosen.

This meant much of the TableGen machinery present for the assembly
matching was effectively being bypassed and worked around.

This patch makes the CC and CCOut operands optional which allows the ASM
matcher operate as it was designed and means we can avoid doing some of
the hacks done previously. This also adds the option for the target to
allow the prioritizing the smaller instruction encodings as is required
for Aarch32.
This commit is contained in:
Alfie Richards 2024-03-18 11:25:13 +00:00 committed by GitHub
parent 3e6db60291
commit 295cdd5c3d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 1340 additions and 1132 deletions

View File

@ -947,8 +947,6 @@ class AsmOperandClass {
/// instruction if it hasn't matched all the operands yet. However, this
/// error will be suppressed if all of the remaining unmatched operands are
/// marked as IsOptional.
///
/// Optional arguments must be at the end of the operand list.
bit IsOptional = false;
/// The name of the method on the target specific asm parser that returns the

View File

@ -1742,6 +1742,7 @@ def ARMAsmWriter : AsmWriter {
def ARMAsmParser : AsmParser {
bit ReportMultipleNearMisses = 1;
let PreferSmallerInstructions = true;
}
def ARMAsmParserVariant : AsmParserVariant {

View File

@ -155,7 +155,11 @@ def iflags_op : Operand<i32> {
// ARM Predicate operand. Default to 14 = always (AL). Second part is CC
// register whose default is 0 (no register).
def CondCodeOperand : AsmOperandClass { let Name = "CondCode"; }
def CondCodeOperand : AsmOperandClass {
let Name = "CondCode";
let DefaultMethod = "defaultCondCodeOp";
let IsOptional = true;
}
def pred : PredicateOperand<OtherVT, (ops i32imm, i32imm),
(ops (i32 14), (i32 zero_reg))> {
let PrintMethod = "printPredicateOperand";
@ -174,7 +178,11 @@ def cmovpred : Operand<i32>, PredicateOp,
}
// Conditional code result for instructions whose 's' bit is set, e.g. subs.
def CCOutOperand : AsmOperandClass { let Name = "CCOut"; }
def CCOutOperand : AsmOperandClass {
let Name = "CCOut";
let DefaultMethod = "defaultCCOutOp";
let IsOptional = true;
}
def cc_out : OptionalDefOperand<OtherVT, (ops CCR), (ops (i32 zero_reg))> {
let EncoderMethod = "getCCOutOpValue";
let PrintMethod = "printSBitModifierOperand";
@ -202,10 +210,14 @@ def inv_cond_XFORM : SDNodeXForm<imm, [{
def VPTPredNOperand : AsmOperandClass {
let Name = "VPTPredN";
let PredicateMethod = "isVPTPred";
let DefaultMethod = "defaultVPTPredOp";
let IsOptional = true;
}
def VPTPredROperand : AsmOperandClass {
let Name = "VPTPredR";
let PredicateMethod = "isVPTPred";
let DefaultMethod = "defaultVPTPredOp";
let IsOptional = true;
}
// Operand classes for the cluster of MC operands describing a
@ -468,7 +480,7 @@ class InstThumb<AddrMode am, int sz, IndexMode im,
// These are aliases that require C++ handling to convert to the target
// instruction, while InstAliases can be handled directly by tblgen.
class AsmPseudoInst<string asm, dag iops, dag oops = (outs)>
: InstTemplate<AddrModeNone, 0, IndexModeNone, Pseudo, GenericDomain,
: InstTemplate<AddrModeNone, 4, IndexModeNone, Pseudo, GenericDomain,
"", NoItinerary> {
let OutOperandList = oops;
let InOperandList = iops;

View File

@ -1210,7 +1210,7 @@ def tMOVi8 : T1sI<(outs tGPR:$Rd), (ins imm0_255_expr:$imm8), IIC_iMOVi,
// Because we have an explicit tMOVSr below, we need an alias to handle
// the immediate "movs" form here. Blech.
def : tInstAlias <"movs $Rdn, $imm8",
(tMOVi8 tGPR:$Rdn, CPSR, imm0_255_expr:$imm8, 14, 0)>;
(tMOVi8 tGPR:$Rdn, CPSR, imm0_255_expr:$imm8, 14, zero_reg)>;
// A7-73: MOV(2) - mov setting flag.
@ -1768,7 +1768,7 @@ let isBranch = 1, isTerminator = 1, isBarrier = 1, isIndirectBranch = 1 in {
// In Thumb1, "nop" is encoded as a "mov r8, r8". Technically, the bf00
// encoding is available on ARMv6K, but we don't differentiate that finely.
def : InstAlias<"nop", (tMOVr R8, R8, 14, 0), 0>, Requires<[IsThumb, IsThumb1Only]>;
def : InstAlias<"nop", (tMOVr R8, R8, 14, zero_reg), 0>, Requires<[IsThumb, IsThumb1Only]>;
// "neg" is and alias for "rsb rd, rn, #0"

View File

@ -5092,14 +5092,14 @@ def : InstAlias<"dmb${p}.w", (t2DMB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"dsb${p}.w\t$opt", (t2DSB memb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"dsb${p}", (t2DSB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"dsb${p}.w", (t2DSB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}.w\t$opt", (t2ISB memb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}.w\t$opt", (t2ISB instsyncb_opt:$opt, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}", (t2ISB 0xf, pred:$p), 0>, Requires<[HasDB]>;
def : InstAlias<"isb${p}.w", (t2ISB 0xf, pred:$p), 0>, Requires<[HasDB]>;
// Non-predicable aliases of a predicable DSB: the predicate is (14, 0) where
// 14 = AL (always execute) and 0 = "instruction doesn't read the CPSR".
def : InstAlias<"ssbb", (t2DSB 0x0, 14, 0), 1>, Requires<[HasDB, IsThumb2]>;
def : InstAlias<"pssbb", (t2DSB 0x4, 14, 0), 1>, Requires<[HasDB, IsThumb2]>;
// Non-predicable aliases of a predicable DSB: the predicate is (14, zero_reg) where
// 14 = AL (always execute) and zero_reg = "instruction doesn't read the CPSR".
def : InstAlias<"ssbb", (t2DSB 0x0, 14, zero_reg), 1>, Requires<[HasDB, IsThumb2]>;
def : InstAlias<"pssbb", (t2DSB 0x4, 14, zero_reg), 1>, Requires<[HasDB, IsThumb2]>;
// Armv8-R 'Data Full Barrier'
def : InstAlias<"dfb${p}", (t2DSB 0xc, pred:$p), 1>, Requires<[HasDFB]>;

File diff suppressed because it is too large Load Diff

View File

@ -10,13 +10,13 @@
@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK: b #2
@ CHECK: note: instruction requires: thumb
@ CHECK: note: invalid operand for instruction
@ CHECK: note: instruction requires: thumb
@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK: bl #2
@ CHECK: note: instruction requires: thumb
@ CHECK: note: invalid operand for instruction
@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK: beq #2
@ CHECK: note: instruction requires: thumb
@ CHECK: note: invalid operand for instruction
@ CHECK: note: instruction requires: thumb

View File

@ -65,7 +65,13 @@
@ CHECK-THUMB: wfe @ encoding: [0x20,0xbf]
@ CHECK-THUMB: wfi @ encoding: [0x30,0xbf]
@ CHECK-THUMB: sev @ encoding: [0x40,0xbf]
@ CHECK-ERROR-THUMB: error: instruction requires: v7 clrex
@ CHECK-ERROR-THUMB: error: invalid instruction, any one of the following would fix this:
@ CHECK-ERROR-THUMB: clrex
@ CHECK-ERROR-THUMB: ^
@ CHECK-ERROR-THUMB: note: instruction requires: v7 clrex
@ CHECK-ERROR-THUMB: clrex
@ CHECK-ERROR-THUMB: ^
@ CHECK-ERROR-THUMB: note: instruction requires: arm-mode
@ CHECK-ERROR-THUMB: clrex
@ CHECK-ERROR-THUMB: ^

View File

@ -12,7 +12,7 @@ ittt eq
vcx1a p1, s7, #2047
// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: instructions in IT block must be predicable
vcx2 p0, d0, d15, #0
// ERROR-FP: [[@LINE+2]]:{{[0-9]+}}: error: invalid instruction
// ERROR-FP: [[@LINE+2]]:{{[0-9]+}}: error: instruction requires: mve
// ERROR-MVE: [[@LINE+1]]:{{[0-9]+}}: error: instructions in IT block must be predicable
vcx3 p0, q0, q7, q0, #12
nop
@ -33,12 +33,15 @@ vcx1a p1, d3, #2047
// ERROR-FP: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this:
vcx1 p0, q1, #1234
// CHECK-MVE-NEXT: vcx1a p1, q5, #4095 @ encoding: [0x2f,0xfd,0xff,0xa1]
// ERROR-FP: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
// ERROR-FP: [[@LINE+1]]:{{[0-9]+}}: error: instruction requires: mve
vcx1a p1, q5, #4095
// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
vcx1a p1, s7, s7, #2047
// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,2047]
// ERROR-FP: [[@LINE+4]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,2047]
// ERROR-MVE: [[@LINE+3]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this
// ERROR-MVE: [[@LINE+2]]:{{[0-9]+}}: note: operand must be a register in range [q0, q7]
// ERROR-MVE: [[@LINE+1]]:{{[0-9]+}}: note: operand must be an immediate in the range [0,2047]
vcx1 p0, d0, #2048
// ERROR-FP: [[@LINE+1]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,2047]
vcx1a p1, s0, #2048
@ -51,10 +54,13 @@ vcx1 p8, d0, #1234
vcx1 p0, d16, #1234
// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: invalid instruction
vcx1 p0, s32, #1234
// ERROR-FP: [[@LINE+4]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this:
// ERROR-FP: [[@LINE+3]]:{{[0-9]+}}: note: operand must be a register in range [s0, s31]
// ERROR-FP: [[@LINE+2]]:{{[0-9]+}}: note: operand must be a register in range [d0, d15]
// ERROR-MVE: [[@LINE+1]]:{{[0-9]+}}: error: operand must be a register in range [q0, q7]
// ERROR-FP: [[@LINE+7]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this:
// ERROR-FP: [[@LINE+6]]:{{[0-9]+}}: note: operand must be a register in range [s0, s31]
// ERROR-FP: [[@LINE+5]]:{{[0-9]+}}: note: operand must be a register in range [d0, d15]
// ERROR-MVE: [[@LINE+4]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this:
// ERROR-MVE: [[@LINE+3]]:{{[0-9]+}}: note: operand must be a register in range [q0, q7]
// ERROR-MVE: [[@LINE+2]]:{{[0-9]+}}: note: operand must be a register in range [s0, s31]
// ERROR-MVE: [[@LINE+1]]:{{[0-9]+}}: note: operand must be a register in range [d0, d15]
vcx1 p0, q8, #1234
// ERROR: [[@LINE+3]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this:
// ERROR: [[@LINE+2]]:{{[0-9]+}}: note: operand must be a register in range [s0, s31]
@ -116,7 +122,7 @@ vcx3a p1, d1, d11, d12, #8
// ERROR-MVE: [[@LINE+2]]:{{[0-9]+}}: error: operand must be an immediate in the range [0,15]
// ERROR-FP: error: invalid instruction
vcx3a p1, q1, q2, q3, #16
// ERROR-MVE: [[@LINE+2]]:{{[0-9]+}}: error: invalid instruction
// ERROR-MVE: [[@LINE+2]]:{{[0-9]+}}: error: operand must be a register in range [d0, d15]
// ERROR-FP: [[@LINE+1]]:{{[0-9]+}}: error: operand must be a register in range [d0, d15]
vcx3 p0, d0, q0, d7, #1
// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: operand must be a register in range [s0, s31]

View File

@ -19,7 +19,7 @@ vcx3at p1, q3, q7, q6, #15
vcx3e p0, q0, q2, q0, #12
vpt.i8 eq, q0, q0
// ERROR: [[@LINE+1]]:{{[0-9]+}}: error: incorrect predication in VPT block; got 'none', but expected 't'
// ERROR: error: incorrect predication in VPT block; got 'none', but expected 't'
vcx1 p0, q1, #1234
vpt.i8 eq, q0, q0

View File

@ -26,6 +26,6 @@
@ V6-ERRORS: note: too many operands for instruction
@ V6-ERRORS: error: invalid instruction, any one of the following would fix this:
@ V6-ERRORS: cps #0
@ V6-ERRORS: note: too few operands for instruction
@ V6-ERRORS: note: instruction requires: arm-mode
@ V6-ERRORS: note: instruction requires: thumb2
@ V6-ERRORS: note: too few operands for instruction

View File

@ -288,7 +288,7 @@
@ CHECK-ERRORS: error: 'asr' shift amount must be in range [1,32]
@ CHECK-ERRORS: ssat r8, #1, r10, asr #33
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: shift operator 'asr' or 'lsl' expected
@ CHECK-ERRORS: error: operand must be a register in range [r0, r14]
@ CHECK-ERRORS: ssat r8, #1, r10, lsr #5
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: '#' expected

View File

@ -10,15 +10,16 @@
.syntax unified
.arch_extension crypto
@ CHECK-V7: error: architectural extension 'crypto' is not allowed for the current base architecture
@ CHECK-V7: architectural extension 'crypto' is not allowed for the current base architecture
@ CHECK-V7-NEXT: .arch_extension crypto
@ CHECK-V7-NEXT: ^
.type crypto,%function
crypto:
vmull.p64 q0, d0, d1
@ CHECK-V7: error: instruction requires: aes armv8
@ CHECK-V7: error: invalid instruction, any one of the following would fix this:
@ CHECK-V7: note: invalid operand for instruction
@ CHECK-V7: note: instruction requires: aes armv8
aesd.8 q0, q1
@ CHECK-V7: error: instruction requires: aes armv8
aese.8 q0, q1
@ -51,14 +52,18 @@ crypto:
@ CHECK-V7: error: instruction requires: sha2 armv8
.arch_extension nocrypto
@ CHECK-V7: error: architectural extension 'sha2' is not allowed for the current base architecture
@ CHECK-V7: error: architectural extension 'aes' is not allowed for the current base architecture
@ CHECK-V7: error: architectural extension 'crypto' is not allowed for the current base architecture
@ CHECK-V7-NEXT: .arch_extension nocrypto
@ CHECK-V7-NEXT: .arch_extension nocrypto
@ CHECK-V7-NEXT: ^
.type nocrypto,%function
nocrypto:
vmull.p64 q0, d0, d1
@ CHECK-V7: error: instruction requires: aes armv8
@ CHECK-V7: error: invalid instruction, any one of the following
@ CHECK-V7: note: invalid operand for instruction
@ CHECK-V7: note: instruction requires: aes armv8
@ CHECK-V8: error: instruction requires: aes
aesd.8 q0, q1

View File

@ -88,6 +88,8 @@ vrinta.f64.f64 s3, q0
vrintn.f32.f32 d3, d0
@ V8: error: instruction requires: NEON
vrintp.f32 q3, q0
@ V8: error: instruction requires: NEON
@ V8: error: invalid instruction, any one of the following would fix this:
@ V8: note: instruction requires: mve.fp
@ V8: note: instruction requires: NEON
vrintmlt.f32 q3, q0
@ V8: error: instruction 'vrintm' is not predicable, but condition code specified

View File

@ -55,22 +55,22 @@
// CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
// CHECK-NONARM-NEXT: mov pc, r0, lsl #0
// CHECK-NONARM: note: operand must be a register in range [r0, r15]
// CHECK-THUMBV7: note: operand must be a register in range [r0, r12] or r14
// CHECK-THUMBV8: note: operand must be a register in range [r0, r14]
// CHECK-NONARM: note: operand must be a register in range [r0, r15]
// CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
// CHECK-NONARM-NEXT: mov r0, pc, lsl #0
// CHECK-NONARM: note: operand must be a register in range [r0, r15]
// CHECK-NONARM: note: invalid operand for instruction
// CHECK-NONARM: note: invalid operand for instruction
// CHECK-NONARM: note: operand must be an immediate in the range [256,65535]
// CHECK-NONARM: note: operand must be a register in range [r0, r15]
// CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
// CHECK-NONARM-NEXT: mov pc, pc, lsl #0
// CHECK-NONARM: note: operand must be a register in range [r0, r15]
// CHECK-THUMBV7: note: operand must be a register in range [r0, r12] or r14
// CHECK-THUMBV8: note: operand must be a register in range [r0, r14]
// CHECK-NONARM: note: operand must be a register in range [r0, r15]
// CHECK-NONARM: error: invalid instruction, any one of the following would fix this:
// CHECK-NONARM-NEXT: movs pc, r0, lsl #0
@ -134,8 +134,8 @@
// FIXME: We should consistently have the "requires ARMv8" error here
// CHECK-THUMBV7: error: invalid instruction, any one of the following would fix this:
// CHECK-THUMBV7-NEXT: mov sp, sp, lsl #0
// CHECK-THUMBV7: note: operand must be a register in range [r0, r15]
// CHECK-THUMBV7: note: operand must be a register in range [r0, r12] or r14
// CHECK-THUMBV7: note: operand must be a register in range [r0, r15]
// CHECK-THUMBV7: error: invalid instruction, any one of the following would fix this:
// CHECK-THUMBV7-NEXT: movs sp, sp, lsl #0

File diff suppressed because it is too large Load Diff

View File

@ -7,63 +7,63 @@
# RUN: FileCheck --check-prefix=ERROR-NOMVE < %t %s
# CHECK: vpsel q0, q5, q2 @ encoding: [0x3b,0xfe,0x05,0x0f]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
vpsel q0, q5, q2
# CHECK: vpnot @ encoding: [0x31,0xfe,0x4d,0x0f]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
vpnot
# CHECK: wlstp.8 lr, r0, #1668 @ encoding: [0x00,0xf0,0x43,0xc3]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r0, #1668
# CHECK: wlstp.16 lr, r0, #1668 @ encoding: [0x10,0xf0,0x43,0xc3]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.16 lr, r0, #1668
# CHECK: wlstp.32 lr, r4, #2706 @ encoding: [0x24,0xf0,0x49,0xcd]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.32 lr, r4, #2706
# CHECK: wlstp.64 lr, lr, #3026 @ encoding: [0x3e,0xf0,0xe9,0xcd]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.64 lr, lr, #3026
# CHECK: wlstp.8 lr, r5, #3436 @ encoding: [0x05,0xf0,0xb7,0xc6]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r5, #3436
# CHECK: wlstp.16 lr, r1, #1060 @ encoding: [0x11,0xf0,0x13,0xc2]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.16 lr, r1, #1060
# CHECK: wlstp.32 lr, r7, #4036 @ encoding: [0x27,0xf0,0xe3,0xc7]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.32 lr, r7, #4036
# CHECK: wlstp.8 lr, r1, #538 @ encoding: [0x01,0xf0,0x0d,0xc9]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r1, #538
# CHECK: wlstp.8 lr, r10, #1404 @ encoding: [0x0a,0xf0,0xbf,0xc2]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r10, #1404
# CHECK: wlstp.8 lr, r10, #1408 @ encoding: [0x0a,0xf0,0xc1,0xc2]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r10, #1408
# CHECK: wlstp.8 lr, r10, #2358 @ encoding: [0x0a,0xf0,0x9b,0xcc]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r10, #2358
# CHECK: wlstp.8 lr, r10, #4086 @ encoding: [0x0a,0xf0,0xfb,0xcf]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r10, #4086
# CHECK: wlstp.8 lr, r11, #1442 @ encoding: [0x0b,0xf0,0xd1,0xca]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r11, #1442
# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: loop end is out of range or not a positive multiple of 2
@ -87,39 +87,39 @@ wlstp.16 lr, sp, #1442
wlstp.32 r10, r11, #1442
# CHECK: wlstp.8 lr, r1, .Lendloop @ encoding: [0x01'A',0xf0'A',0x01'A',0xc0'A']
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.8 lr, r1, .Lendloop
# CHECK: wlstp.16 lr, r2, .Lendloop @ encoding: [0x12'A',0xf0'A',0x01'A',0xc0'A']
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.16 lr, r2, .Lendloop
# CHECK: wlstp.32 lr, r3, .Lendloop @ encoding: [0x23'A',0xf0'A',0x01'A',0xc0'A']
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.32 lr, r3, .Lendloop
# CHECK: wlstp.64 lr, r5, .Lendloop @ encoding: [0x35'A',0xf0'A',0x01'A',0xc0'A']
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.64 lr, r5, .Lendloop
# CHECK: wlstp.64 lr, r5, #0 @ encoding: [0x35,0xf0,0x01,0xc0]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
wlstp.64 lr, r5, #0
# CHECK: dlstp.8 lr, r5 @ encoding: [0x05,0xf0,0x01,0xe0]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
dlstp.8 lr, r5
# CHECK: dlstp.16 lr, r5 @ encoding: [0x15,0xf0,0x01,0xe0]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
dlstp.16 lr, r5
# CHECK: dlstp.32 lr, r7 @ encoding: [0x27,0xf0,0x01,0xe0]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
dlstp.32 lr, r7
# CHECK: dlstp.64 lr, r2 @ encoding: [0x32,0xf0,0x01,0xe0]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
dlstp.64 lr, r2
# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: operand must be a register in range [r0, r12] or r14
@ -135,15 +135,15 @@ dlstp.64 r10, r0
dlstp.64 lr, pc
# CHECK: letp lr, #-2 @ encoding: [0x1f,0xf0,0x01,0xc8]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
letp lr, #-2
# CHECK: letp lr, #-8 @ encoding: [0x1f,0xf0,0x05,0xc0]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
letp lr, #-8
# CHECK: letp lr, #-4094 @ encoding: [0x1f,0xf0,0xff,0xcf]
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
letp lr, #-4094
# ERROR: [[@LINE+2]]:{{[0-9]+}}: {{error|note}}: invalid operand for instruction
@ -159,7 +159,7 @@ letp lr, #8
letp lr, #-4096
# CHECK: letp lr, .Lstartloop @ encoding: [0x1f'A',0xf0'A',0x01'A',0xc0'A']
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
letp lr, .Lstartloop
# CHECK: lctp @ encoding: [0x0f,0xf0,0x01,0xe0]
@ -172,8 +172,11 @@ it eq
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
lctpeq
# ERROR-NOMVE: [[@LINE+1]]:1: error: instruction requires: mve
vpste
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
vpselt.s16 q0, q1, q2
# ERROR-NOMVE: [[@LINE+1]]:1: error: invalid instruction
vpsele.i32 q0, q1, q2
# CHECK: vpste @ encoding: [0x71,0xfe,0x4d,0x8f]
# CHECK: vpselt q0, q1, q2 @ encoding: [0x33,0xfe,0x05,0x0f]

View File

@ -29,8 +29,10 @@
// FP16-ARM: vcmla.f16 q0, q1, q2, #0 @ encoding: [0x44,0x08,0x22,0xfc]
// FP16-THUMB: vcmla.f16 q0, q1, q2, #0 @ encoding: [0x22,0xfc,0x44,0x08]
// NO-FP16-STDERR: :[[@LINE-3]]:{{[0-9]*}}: note: instruction requires: full half-float
// V82A: :[[@LINE-4]]:{{[0-9]*}}: error: instruction requires: armv8.3a
// NO-NEON_STDERR: :[[@LINE-5]]:{{[0-9]*}}: error: instruction requires: NEON
// V82A: :[[@LINE-4]]:{{[0-9]*}}: error: invalid instruction, any one of the following would fix this:
// V82A: :[[@LINE-5]]:{{[0-9]*}}: note: instruction requires: mve.fp
// V82A: :[[@LINE-6]]:{{[0-9]*}}: note: instruction requires: armv8.3a
// NO-NEON_STDERR: :[[@LINE-7]]:{{[0-9]*}}: error: instruction requires: NEON
vcmla.f32 d0, d1, d2, #0
// ARM: vcmla.f32 d0, d1, d2, #0 @ encoding: [0x02,0x08,0x31,0xfc]
// THUMB: vcmla.f32 d0, d1, d2, #0 @ encoding: [0x31,0xfc,0x02,0x08]
@ -39,8 +41,10 @@
vcmla.f32 q0, q1, q2, #0
// ARM: vcmla.f32 q0, q1, q2, #0 @ encoding: [0x44,0x08,0x32,0xfc]
// THUMB: vcmla.f32 q0, q1, q2, #0 @ encoding: [0x32,0xfc,0x44,0x08]
// V82A: :[[@LINE-3]]:{{[0-9]*}}: error: instruction requires: armv8.3a
// NO-NEON_STDERR: :[[@LINE-4]]:{{[0-9]*}}: error: instruction requires: NEON
// V82A: :[[@LINE-3]]:{{[0-9]*}}: error: invalid instruction, any one of the following would fix this:
// V82A: :[[@LINE-4]]:{{[0-9]*}}: note: instruction requires: mve.fp
// V82A: :[[@LINE-5]]:{{[0-9]*}}: note: instruction requires: armv8.3a
// NO-NEON_STDERR: :[[@LINE-6]]:{{[0-9]*}}: error: instruction requires: NEON
// Valid rotations
vcmla.f32 d0, d1, d2, #90
@ -83,8 +87,10 @@
// FP16-ARM: vcadd.f16 q0, q1, q2, #90 @ encoding: [0x44,0x08,0x82,0xfc]
// FP16-THUMB: vcadd.f16 q0, q1, q2, #90 @ encoding: [0x82,0xfc,0x44,0x08]
// NO-FP16-STDERR: :[[@LINE-3]]:{{[0-9]*}}: note: instruction requires: full half-float
// V82A: :[[@LINE-4]]:{{[0-9]*}}: error: instruction requires: armv8.3a
// NO-NEON_STDERR: :[[@LINE-5]]:{{[0-9]*}}: error: instruction requires: NEON
// V82A: :[[@LINE-4]]:{{[0-9]*}}: error: invalid instruction, any one of the following would fix this:
// V82A: :[[@LINE-5]]:{{[0-9]*}}: note: instruction requires: mve.fp
// V82A: :[[@LINE-6]]:{{[0-9]*}}: note: instruction requires: armv8.3a
// NO-NEON_STDERR: :[[@LINE-7]]:{{[0-9]*}}: error: instruction requires: NEON
vcadd.f32 d0, d1, d2, #90
// ARM: vcadd.f32 d0, d1, d2, #90 @ encoding: [0x02,0x08,0x91,0xfc]
// THUMB: vcadd.f32 d0, d1, d2, #90 @ encoding: [0x91,0xfc,0x02,0x08]
@ -93,8 +99,10 @@
vcadd.f32 q0, q1, q2, #90
// ARM: vcadd.f32 q0, q1, q2, #90 @ encoding: [0x44,0x08,0x92,0xfc]
// THUMB: vcadd.f32 q0, q1, q2, #90 @ encoding: [0x92,0xfc,0x44,0x08]
// V82A: :[[@LINE-3]]:{{[0-9]*}}: error: instruction requires: armv8.3a
// NO-NEON_STDERR: :[[@LINE-4]]:{{[0-9]*}}: error: instruction requires: NEON
// V82A: :[[@LINE-3]]:{{[0-9]*}}: error: invalid instruction, any one of the following would fix this:
// V82A: :[[@LINE-4]]:{{[0-9]*}}: note: instruction requires: mve.fp
// V82A: :[[@LINE-5]]:{{[0-9]*}}: note: instruction requires: armv8.3a
// NO-NEON_STDERR: :[[@LINE-6]]:{{[0-9]*}}: error: instruction requires: NEON
// Valid rotations
vcadd.f32 d0, d1, d2, #270

View File

@ -4,13 +4,13 @@
# RUN: FileCheck --check-prefix=CHECK-MVE < %t %s
# CHECK-MVE: instruction requires: mve.fp
# CHECK: invalid instruction
# CHECK: instruction requires: mve.fp
vcadd.f32 q1, q2, q3, #270
# CHECK-MVE: instruction requires: mve.fp
# CHECK: invalid instruction
# CHECK: instruction requires: mve.fp
vadd.f32 q1, q2, q3
# CHECK-MVE: vadd.i16 q1, q2, q3 @ encoding: [0x14,0xef,0x46,0x28]
# CHECK: invalid instruction
# CHECK: instruction requires: mve
vadd.i16 q1, q2, q3

View File

@ -1,13 +1,21 @@
@ RUN: not llvm-mc < %s -triple armv4-unknown-unknown -show-encoding 2>&1 | FileCheck %s
@ PR18524
@ CHECK: instruction requires: armv5t
@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK: note: instruction requires: armv5t
@ CHECK: note: instruction requires: thumb2
clz r4,r9
@ CHECK: instruction requires: armv6t2
@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK: note: instruction requires: armv6t2
@ CHECK: note: instruction requires: thumb2
rbit r4,r9
@ CHECK: error: instruction requires: armv6t2
movw r4,#0x1234
@ CHECK: error: instruction requires: armv6t2
@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK: note: invalid operand for instruction
@ CHECK: note: operand must be a register in range [r0, r15]
@ CHECK: note: instruction requires: armv6t2
mov r4,#0x1234

View File

@ -3,6 +3,9 @@
// CHECK: error: invalid instruction, any one of the following would fix this:
// CHECK-NEXT: add sp, r0, #4
// CHECK-NEXT: ^
// CHECK-NEXT: note: operand must be a register in range [r0, r7]
// CHECK-NEXT: add sp, r0, #4
// CHECK-NEXT: ^
// CHECK-NEXT: note: operand must be a register sp
// CHECK-NEXT: add sp, r0, #4
// CHECK-NEXT: ^

View File

@ -1,6 +1,7 @@
@ REQUIRES: asserts
@ RUN: llvm-mc --triple=thumbv8 --debug %s 2>&1 | FileCheck %s --match-full-lines
@ RUN: llvm-mc --triple=thumbv8 %s --show-encoding 2>&1 | FileCheck %s --match-full-lines
@ CHECK: Changed to: <MCInst #{{[0-9]+}} tMOVSr <MCOperand Reg:{{[0-9]+}}> <MCOperand Reg:{{[0-9]+}}>>
// Note this makes sure the narrow instruciton is selected
@ CHECK: movs r2, r3 @ encoding: [0x1a,0x00]
.text
movs r2, r3

View File

@ -28,9 +28,12 @@
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction variant requires Thumb2
@ CHECK-ERRORS: note: operand must be a register sp
@ CHECK-ERRORS-V5: error: instruction variant requires ARMv6 or later
@ CHECK-ERRORS-V5: error: invalid instruction, any one of the following would fix this:
@ CHECK-ERRORS-V5: mov r2, r3
@ CHECK-ERRORS-V5: ^
@ CHECK-ERRORS-V5: note: instruction requires: arm-mode
@ CHECK-ERRORS-V5: note: operand must be an immediate in the range [0,255] or a relocatable expression
@ CHECK-ERRORS-V5: note: instruction variant requires ARMv6 or later
@ Immediates where registers were expected
adds #0, r1, r2
@ -225,10 +228,11 @@
@ Mismatched source/destination operands for MUL instruction.
muls r1, r2, r3
@ CHECK-ERRORS: error: destination register must match source register
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
@ CHECK-ERRORS: muls r1, r2, r3
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: destination register must match a source register
@ CHECK-ERRORS: note: too many operands for instruction
@ Out of range immediates for STR instruction.
str r2, [r7, #-1]
@ -274,30 +278,33 @@
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
@ CHECK-ERRORS: add sp, #-1
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
@ CHECK-ERRORS: add sp, #-1
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
@ CHECK-ERRORS: add sp, #-1
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: invalid operand for instruction
@ CHECK-ERRORS: add sp, #-1
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
@ CHECK-ERRORS: add sp, #-1
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
@ CHECK-ERRORS: add sp, #3
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
@ CHECK-ERRORS: add sp, #3
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
@ CHECK-ERRORS: add sp, #3
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: invalid operand for instruction
@ CHECK-ERRORS: add sp, #3
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
@ CHECK-ERRORS: add sp, #3
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
@ CHECK-ERRORS: add sp, sp, #512
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
@ CHECK-ERRORS: add sp, sp, #512
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
@ CHECK-ERRORS: add sp, sp, #512
@ CHECK-ERRORS: ^
@ -305,9 +312,6 @@
@ CHECK-ERRORS: add sp, sp, #512
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: note: instruction requires: thumb2
@ CHECK-ERRORS: add sp, sp, #512
@ CHECK-ERRORS: ^
@ CHECK-ERRORS: error: instruction requires: thumb2
@ CHECK-ERRORS: add r2, sp, #1024
@ CHECK-ERRORS: ^
add r2, sp, ip
@ -407,7 +411,8 @@
adds
adds r0
@ CHECK-ERRORS: error: too few operands for instruction
@ CHECK-ERRORS: error: too few operands for instruction
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
@ CHECK-ERRORS: note: too few operands for instruction
@------------------------------------------------------------------------------
@ Out of range width for SBFX/UBFX

View File

@ -58,10 +58,16 @@
movs sp, r0
movs r0, sp
movs sp, sp
// CHECK-V7: error: instruction variant requires ARMv8 or later
// CHECK-V7: error: invalid instruction, any one of the following would fix this:
// CHECK-V7-NEXT: movs sp, r0
// CHECK-V7: instruction variant requires ARMv8 or later
// CHECK-V7: note: instruction variant requires ARMv8 or later
// CHECK-V7: note: operand must be a register in range [r0, r7]
// CHECK-V7: error: invalid instruction, any one of the following would fix this:
// CHECK-V7-NEXT: movs r0, sp
// CHECK-V7: note: instruction variant requires ARMv8 or later
// CHECK-V7: note: invalid operand for instruction
// CHECK-V7: note: operand must be an immediate in the range [0,255] or a relocatable expression
// CHECK-V7: note: operand must be a register in range [r0, r7]
// CHECK-V7: error: instruction variant requires ARMv8 or later
// CHECK-V7-NEXT: movs sp, sp
// CHECK-V8: movs.w sp, r0 @ encoding: [0x5f,0xea,0x00,0x0d]
@ -69,8 +75,9 @@
// CHECK-V8: movs.w sp, sp @ encoding: [0x5f,0xea,0x0d,0x0d]
mov.w sp, sp
// CHECK-V7: error: instruction variant requires ARMv8 or later
// CHECK-V7: error: invalid instruction, any one of the following would fix this:
// CHECK-V7-NEXT: mov.w sp, sp
// CHECK-V7: note: instruction variant requires ARMv8 or later
// CHECK-V8: mov.w sp, sp @ encoding: [0x4f,0xea,0x0d,0x0d]
movs.w sp, r0
@ -78,8 +85,9 @@
movs.w sp, sp
// CHECK-V7: error: instruction variant requires ARMv8 or later
// CHECK-V7-NEXT: movs.w sp, r0
// CHECK-V7: instruction variant requires ARMv8 or later
// CHECK-V7: error: invalid instruction, any one of the following would fix this:
// CHECK-V7-NEXT: movs.w r0, sp
// CHECK-V7: note: instruction variant requires ARMv8 or later
// CHECK-V7: error: instruction variant requires ARMv8 or later
// CHECK-V7-NEXT: movs.w sp, sp
// CHECK-V8: movs.w sp, r0 @ encoding: [0x5f,0xea,0x00,0x0d]

View File

@ -156,7 +156,9 @@ foo2:
adds
adds r0
@ CHECK-ERRORS: error: too few operands for instruction
@ CHECK-ERRORS: error: too few operands for instruction
@ CHECK-ERRORS: error: invalid instruction, any one of the following would fix this:
@ CHECK-ERRORS: note: too few operands for instruction
@ CHECK-ERRORS: note: operand must be a register in range [r0, r15]
tst sp, #3
tst sp, r5

View File

@ -23,7 +23,7 @@ vfma.f32 d16, d18, d17
@ ARM: vfma.f32 q2, q4, q0 @ encoding: [0x50,0x4c,0x08,0xf2]
@ THUMB: vfma.f32 q2, q4, q0 @ encoding: [0x08,0xef,0x50,0x4c]
@ THUMB_V7EM-ERRORS: error: invalid instruction
@ THUMB_V7EM-ERRORS: error: instruction requires: mve.fp
@ THUMB_V7EM-ERRORS-NEXT: vfma.f32 q2, q4, q0
vfma.f32 q2, q4, q0
@ -57,7 +57,7 @@ vfms.f32 d16, d18, d17
@ ARM: vfms.f32 q2, q4, q0 @ encoding: [0x50,0x4c,0x28,0xf2]
@ THUMB: vfms.f32 q2, q4, q0 @ encoding: [0x28,0xef,0x50,0x4c]
@ THUMB_V7EM-ERRORS: error: invalid instruction
@ THUMB_V7EM-ERRORS: error: instruction requires: mve.fp
@ THUMB_V7EM-ERRORS-NEXT: vfms.f32 q2, q4, q0
vfms.f32 q2, q4, q0

View File

@ -1023,7 +1023,7 @@
# CHECK-NEXT: 2 2 1.00 blxne r2
# CHECK-NEXT: 2 1 1.00 U blx #32424576
# CHECK-NEXT: 2 1 1.00 U blx #16212288
# CHECK-NEXT: 1 1 1.00 U bx r2
# CHECK-NEXT: 1 1 1.00 bx r2
# CHECK-NEXT: 1 1 1.00 U bxne r2
# CHECK-NEXT: 1 1 1.00 U bxj r2
# CHECK-NEXT: 1 1 1.00 U bxjne r2

View File

@ -107,6 +107,7 @@
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@ -3752,6 +3753,9 @@ void AsmMatcherEmitter::run(raw_ostream &OS) {
OS << " } else {\n";
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 << " }\n";
OS << " }\n";
OS << " continue;\n";
} else {