llvm.org GIT mirror llvm / c96f2d4
[ARM] Fix a check in vmov/vmvn immediate parsing Summary: Currently the check is incorrect and the following invalid instruction is accepted and incorrectly assembled: vmov.i32 d2, #0x00a500a6 This patch fixes the issue. Reviewers: olista01, rengolin Reviewed By: rengolin Subscribers: SjoerdMeijer, javed.absar, rogfer01, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D44460 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327704 91177308-0d34-0410-b5e6-96231b3b80d8 Mikhail Maltsev 2 years ago
2 changed file(s) with 23 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
18791879 bool isNEONi16ByteReplicate() const { return isNEONByteReplicate(2); }
18801880 bool isNEONi32ByteReplicate() const { return isNEONByteReplicate(4); }
18811881
1882 static bool isValidNEONi32vmovImm(int64_t Value) {
1883 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
1884 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
1885 return ((Value & 0xffffffffffffff00) == 0) ||
1886 ((Value & 0xffffffffffff00ff) == 0) ||
1887 ((Value & 0xffffffffff00ffff) == 0) ||
1888 ((Value & 0xffffffff00ffffff) == 0) ||
1889 ((Value & 0xffffffffffff00ff) == 0xff) ||
1890 ((Value & 0xffffffffff00ffff) == 0xffff);
1891 }
1892
18821893 bool isNEONi32vmov() const {
18831894 if (isNEONByteReplicate(4))
18841895 return false; // Let it to be classified as byte-replicate case.
18881899 // Must be a constant.
18891900 if (!CE)
18901901 return false;
1891 int64_t Value = CE->getValue();
1892 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
1893 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
1894 // FIXME: This is probably wrong and a copy and paste from previous example
1895 return (Value >= 0 && Value < 256) ||
1896 (Value >= 0x0100 && Value <= 0xff00) ||
1897 (Value >= 0x010000 && Value <= 0xff0000) ||
1898 (Value >= 0x01000000 && Value <= 0xff000000) ||
1899 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
1900 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
1902 return isValidNEONi32vmovImm(CE->getValue());
19011903 }
19021904
19031905 bool isNEONi32vmovNeg() const {
19051907 const MCConstantExpr *CE = dyn_cast(getImm());
19061908 // Must be a constant.
19071909 if (!CE) return false;
1908 int64_t Value = ~CE->getValue();
1909 // i32 value with set bits only in one byte X000, 0X00, 00X0, or 000X,
1910 // for VMOV/VMVN only, 00Xf or 0Xff are also accepted.
1911 // FIXME: This is probably wrong and a copy and paste from previous example
1912 return (Value >= 0 && Value < 256) ||
1913 (Value >= 0x0100 && Value <= 0xff00) ||
1914 (Value >= 0x010000 && Value <= 0xff0000) ||
1915 (Value >= 0x01000000 && Value <= 0xff000000) ||
1916 (Value >= 0x01ff && Value <= 0xffff && (Value & 0xff) == 0xff) ||
1917 (Value >= 0x01ffff && Value <= 0xffffff && (Value & 0xffff) == 0xffff);
1910 return isValidNEONi32vmovImm(~CE->getValue());
19181911 }
19191912
19201913 bool isNEONi64splat() const {
77 @ CHECK: error: invalid instruction, any one of the following would fix this:
88 @ CHECK-NEXT: vmov.i32 q2, #0xffffffab
99 @ CHECK: note: operand must be a register in range [q0, q15]
10 @ CHECK: note: invalid operand for instruction
11 @ CHECK: error: invalid instruction, any one of the following would fix this:
12 @ CHECK-NEXT: vmov.i32 d2, #0x00a500a6
13 @ CHECK: note: operand must be a register in range [d0, d31]
1014 @ CHECK: note: invalid operand for instruction
1115 @ CHECK: error: invalid instruction, any one of the following would fix this:
1216 @ CHECK-NEXT: vmov.i16 q2, #0xffab
2630 @ CHECK: note: operand must be a register in range [q0, q15]
2731 @ CHECK: note: invalid operand for instruction
2832 @ CHECK: error: invalid instruction, any one of the following would fix this:
33 @ CHECK-NEXT: vmvn.i32 d2, #0x00a500a6
34 @ CHECK: note: operand must be a register in range [d0, d31]
35 @ CHECK: note: invalid operand for instruction
36 @ CHECK: error: invalid instruction, any one of the following would fix this:
2937 @ CHECK-NEXT: vmvn.i16 q2, #0xffab
3038 @ CHECK: note: operand must be a register in range [q0, q15]
3139 @ CHECK: note: invalid operand for instruction
3644
3745 vmov.i32 d2, #0xffffffab
3846 vmov.i32 q2, #0xffffffab
47 vmov.i32 d2, #0x00a500a6
3948 vmov.i16 q2, #0xffab
4049 vmov.i16 q2, #0xffab
4150
4251 vmvn.i32 d2, #0xffffffab
4352 vmvn.i32 q2, #0xffffffab
53 vmvn.i32 d2, #0x00a500a6
4454 vmvn.i16 q2, #0xffab
4555 vmvn.i16 q2, #0xffab