From: Tim Northover Date: Mon, 28 Apr 2014 11:27:43 +0000 (+0000) Subject: ARM64: diagnose use of v16-v31 in certain indexed NEON instructions. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=16aac4387f3ff3e8e8702b09ac23a0b320b3b1d3;p=oota-llvm.git ARM64: diagnose use of v16-v31 in certain indexed NEON instructions. Someone couldn't bear to have a completely orthogonal set of floating-point registers, so we've got some instructions that only accept v0-v15 (coming in ARMv9, V128_prime: you're allowed v2, v3, v5, v7, ...). Anyway, we were permitting even the out of range registers during assembly (CodeGen handled it correctly). This adds a diagnostic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@207412 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/ARM64/ARM64RegisterInfo.td b/lib/Target/ARM64/ARM64RegisterInfo.td index 514ba07bb0a..3a8e969a01f 100644 --- a/lib/Target/ARM64/ARM64RegisterInfo.td +++ b/lib/Target/ARM64/ARM64RegisterInfo.td @@ -431,7 +431,11 @@ def VectorRegAsmOperand : AsmOperandClass { let Name = "VectorReg"; } let ParserMatchClass = VectorRegAsmOperand in { def V64 : RegisterOperand; def V128 : RegisterOperand; -def V128_lo : RegisterOperand; +} + +def VectorRegLoAsmOperand : AsmOperandClass { let Name = "VectorRegLo"; } +def V128_lo : RegisterOperand { + let ParserMatchClass = VectorRegLoAsmOperand; } class TypedVecListAsmOperand diff --git a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp index 5fe0acc59da..71cf100daf9 100644 --- a/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp +++ b/lib/Target/ARM64/AsmParser/ARM64AsmParser.cpp @@ -688,6 +688,10 @@ public: } bool isReg() const { return Kind == k_Register && !Reg.isVector; } bool isVectorReg() const { return Kind == k_Register && Reg.isVector; } + bool isVectorRegLo() const { + return Kind == k_Register && Reg.isVector && + ARM64MCRegisterClasses[ARM64::FPR128_loRegClassID].contains(Reg.RegNum); + } /// Is this a vector list with the type implicit (presumably attached to the /// instruction itself)? @@ -1059,6 +1063,11 @@ public: Inst.addOperand(MCOperand::CreateReg(getReg())); } + void addVectorRegLoOperands(MCInst &Inst, unsigned N) const { + assert(N == 1 && "Invalid number of operands!"); + Inst.addOperand(MCOperand::CreateReg(getReg())); + } + template void addVectorList64Operands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); diff --git a/test/MC/ARM64/v128_lo-diagnostics.s b/test/MC/ARM64/v128_lo-diagnostics.s new file mode 100644 index 00000000000..ffe29cfbed3 --- /dev/null +++ b/test/MC/ARM64/v128_lo-diagnostics.s @@ -0,0 +1,11 @@ +// RUN: not llvm-mc -triple arm64 -mattr=neon %s 2> %t > /dev/null +// RUN: FileCheck %s < %t + + sqrdmulh v0.8h, v1.8h, v16.h[0] +// CHECK: error: invalid operand for instruction + + sqrdmulh h0, h1, v16.h[0] +// CHECK: error: invalid operand for instruction + + sqdmull2 v0.4h, v1.8h, v16.h[0] +// CHECK: error: invalid operand for instruction