ARM NEON vext bugs
Paul Brook
paul@codesourcery.com
Wed Apr 4 19:21:00 GMT 2007
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). */
More information about the Binutils
mailing list