[PATCH] D44460: [ARM] Fix a check in vmov/vmvn immediate parsing
Mikhail Maltsev via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 16 05:50:02 PDT 2018
This revision was automatically updated to reflect the committed changes.
Closed by commit rL327704: [ARM] Fix a check in vmov/vmvn immediate parsing (authored by miyuki, committed by ).
Changed prior to commit:
https://reviews.llvm.org/D44460?vs=138317&id=138685#toc
Repository:
rL LLVM
https://reviews.llvm.org/D44460
Files:
llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s
Index: llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s
===================================================================
--- llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s
+++ llvm/trunk/test/MC/ARM/vmov-vmvn-illegal-cases.s
@@ -10,6 +10,10 @@
@ CHECK: note: operand must be a register in range [q0, q15]
@ CHECK: note: invalid operand for instruction
@ CHECK: error: invalid instruction, any one of the following would fix this:
+@ CHECK-NEXT: vmov.i32 d2, #0x00a500a6
+@ CHECK: note: operand must be a register in range [d0, d31]
+@ CHECK: note: invalid operand for instruction
+@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK-NEXT: vmov.i16 q2, #0xffab
@ CHECK: note: operand must be a register in range [q0, q15]
@ CHECK: note: invalid operand for instruction
@@ -27,6 +31,10 @@
@ CHECK: note: operand must be a register in range [q0, q15]
@ CHECK: note: invalid operand for instruction
@ CHECK: error: invalid instruction, any one of the following would fix this:
+@ CHECK-NEXT: vmvn.i32 d2, #0x00a500a6
+@ CHECK: note: operand must be a register in range [d0, d31]
+@ CHECK: note: invalid operand for instruction
+@ CHECK: error: invalid instruction, any one of the following would fix this:
@ CHECK-NEXT: vmvn.i16 q2, #0xffab
@ CHECK: note: operand must be a register in range [q0, q15]
@ CHECK: note: invalid operand for instruction
@@ -37,10 +45,12 @@
vmov.i32 d2, #0xffffffab
vmov.i32 q2, #0xffffffab
+ vmov.i32 d2, #0x00a500a6
vmov.i16 q2, #0xffab
vmov.i16 q2, #0xffab
vmvn.i32 d2, #0xffffffab
vmvn.i32 q2, #0xffffffab
+ vmvn.i32 d2, #0x00a500a6
vmvn.i16 q2, #0xffab
vmvn.i16 q2, #0xffab
Index: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -1880,6 +1880,17 @@
bool isNEONi16ByteReplicate() const { return isNEONByteReplicate(2); }
bool isNEONi32ByteReplicate() const { return isNEONByteReplicate(4); }
+ static bool isValidNEONi32vmovImm(int64_t Value) {
+ // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
+ // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
+ return ((Value & 0xffffffffffffff00) == 0) ||
+ ((Value & 0xffffffffffff00ff) == 0) ||
+ ((Value & 0xffffffffff00ffff) == 0) ||
+ ((Value & 0xffffffff00ffffff) == 0) ||
+ ((Value & 0xffffffffffff00ff) == 0xff) ||
+ ((Value & 0xffffffffff00ffff) == 0xffff);
+ }
+
bool isNEONi32vmov() const {
if (isNEONByteReplicate(4))
return false; // Let it to be classified as byte-replicate case.
@@ -1889,33 +1900,15 @@
// Must be a constant.
if (!CE)
return false;
- int64_t Value = CE->getValue();
- // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
- // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
- // FIXME: This is probably wrong and a copy and paste from previous example
- return (Value >= 0 && Value < 256) ||
- (Value >= 0x0100 && Value <= 0xff00) ||
- (Value >= 0x010000 && Value <= 0xff0000) ||
- (Value >= 0x01000000 && Value <= 0xff000000) ||
- (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
- (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
+ return isValidNEONi32vmovImm(CE->getValue());
}
bool isNEONi32vmovNeg() const {
if (!isImm()) return false;
const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
// Must be a constant.
if (!CE) return false;
- int64_t Value = ~CE->getValue();
- // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
- // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
- // FIXME: This is probably wrong and a copy and paste from previous example
- return (Value >= 0 && Value < 256) ||
- (Value >= 0x0100 && Value <= 0xff00) ||
- (Value >= 0x010000 && Value <= 0xff0000) ||
- (Value >= 0x01000000 && Value <= 0xff000000) ||
- (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
- (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
+ return isValidNEONi32vmovImm(~CE->getValue());
}
bool isNEONi64splat() const {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D44460.138685.patch
Type: text/x-patch
Size: 4537 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180316/6ba0f83b/attachment.bin>
More information about the llvm-commits
mailing list