This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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).  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]