This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ARM NEON vext bugs
- From: Paul Brook <paul at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Wed, 4 Apr 2007 20:21:27 +0100
- Subject: ARM NEON vext bugs
The patch below fixes a bug in the implementation of the ARM NEON vext
instruction. The shift count is expressed in elements, so the valid range
depends on both the register and element sizes.
Tested on arm-non-eabi.
Applied to CVS head.
Paul
2007-04-04 Paul Brook <paul@codesourcery.com>
gas/
* config/tc-arm.c (do_neon_ext): Enforce immediate range.
(insns): Use I15 for vext.
gas/testsute/
* gas/arm/neon-cov.s: Add new vext test.
* gas/arm/neon-cov.d: Ditto.
Index: gas/testsuite/gas/arm/neon-cov.d
===================================================================
--- gas/testsuite/gas/arm/neon-cov.d (revision 152532)
+++ gas/testsuite/gas/arm/neon-cov.d (revision 152533)
@@ -1338,6 +1338,7 @@ Disassembly of section \.text:
0[0-9a-f]+ <[^>]+> f2b00040 vext\.8 q0, q0, q0, #0
0[0-9a-f]+ <[^>]+> f2b00040 vext\.8 q0, q0, q0, #0
0[0-9a-f]+ <[^>]+> f2b00000 vext\.8 d0, d0, d0, #0
+0[0-9a-f]+ <[^>]+> f2b00840 vext\.8 q0, q0, q0, #8
0[0-9a-f]+ <[^>]+> f3b00040 vrev64\.8 q0, q0
0[0-9a-f]+ <[^>]+> f3b00040 vrev64\.8 q0, q0
0[0-9a-f]+ <[^>]+> f3b00000 vrev64\.8 d0, d0
Index: gas/testsuite/gas/arm/neon-cov.s
===================================================================
--- gas/testsuite/gas/arm/neon-cov.s (revision 152532)
+++ gas/testsuite/gas/arm/neon-cov.s (revision 152533)
@@ -561,6 +561,7 @@
vext.8 q0,q0,q0,0
vextq.8 q0,q0,q0,0
vext.8 d0,d0,d0,0
+ vext.8 q0,q0,q0,8
.macro revs op opq vtype
\op\vtype q0,q0
Index: gas/config/tc-arm.c
===================================================================
--- gas/config/tc-arm.c (revision 152532)
+++ gas/config/tc-arm.c (revision 152533)
@@ -12682,6 +12688,7 @@ do_neon_ext (void)
struct neon_type_el et = neon_check_type (3, rs,
N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
unsigned imm = (inst.operands[3].imm * et.size) / 8;
+ constraint (imm >= (neon_quad (rs) ? 16 : 8), _("shift out of range"));
inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
inst.instruction |= HI1 (inst.operands[0].reg) << 22;
inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
@@ -15782,8 +15789,8 @@ static const struct asm_opcode insns[] =
nUF(vmull, vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
/* Extract. Size 8. */
- NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I7), neon_ext),
- NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I7), neon_ext),
+ NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
+ NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
/* Two registers, miscellaneous. */
/* Reverse. Sizes 8 16 32 (must be < size in opcode). */