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]

[PATCH, ARM] Fix encoding for VSHL/VQSHL by register


Hi,

This patch fixes the encoding for the ARM Neon extension's vshl/vqshl instructions. The order of registers for these instructions is:

V{Q}SHL rD, rM, rN

Rather than the previously-used:

V{Q}SHL rD, rN, rM

This is (obviously) a silent code-generation error. Both the assembler and disassembler were at fault.

Tested with no regressions with cross to arm-none-eabi. OK for mainline?

Cheers,

Julian

ChangeLogs

    gas/
    * config/tc-arm.c (do_neon_shl_imm): Swap rN, rM.
    (do_neon_qshl_imm): Likewise.
    (do_neon_rshl): New function. Handle rounding variants of
    v{q}shl-by-register.
    (insns): Use do_neon_rshl for vrshl, vqrshl.

    gas/testsuite/
    * gas/arm/neon-omit.d: Fix expected encodings for vshl, vqshl.

    opcodes/
    * arm-dis.c (neon_opcode): Fix disassembly for vshl, vqshl, vrshl,
    vqrshl instructions.
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.250.2.46
diff -c -p -r1.250.2.46 tc-arm.c
*** gas/config/tc-arm.c	13 Dec 2006 16:07:32 -0000	1.250.2.46
--- gas/config/tc-arm.c	3 Jan 2007 16:38:44 -0000
*************** do_neon_shl_imm (void)
*** 11390,11395 ****
--- 11390,11406 ----
        enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
        struct neon_type_el et = neon_check_type (3, rs,
          N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
+       unsigned int tmp;
+       /* VSHL/VQSHL 3-register variants have syntax such as:
+            vshl.xx Dd, Dm, Dn
+          whereas other 3-register operations encoded by neon_three_same have
+          syntax like:
+            vadd.xx Dd, Dn, Dm
+          (i.e. with Dn & Dm reversed). Swap operands[1].reg and operands[2].reg
+          here.  */
+       tmp = inst.operands[2].reg;
+       inst.operands[2].reg = inst.operands[1].reg;
+       inst.operands[1].reg = tmp;
        inst.instruction = NEON_ENC_INTEGER (inst.instruction);
        neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
      }
*************** do_neon_qshl_imm (void)
*** 11411,11421 ****
--- 11422,11450 ----
        enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
        struct neon_type_el et = neon_check_type (3, rs,
          N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
+       unsigned int tmp;
+       /* See note in do_neon_shl_imm.  */
+       tmp = inst.operands[2].reg;
+       inst.operands[2].reg = inst.operands[1].reg;
+       inst.operands[1].reg = tmp;
        inst.instruction = NEON_ENC_INTEGER (inst.instruction);
        neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
      }
  }
  
+ static void
+ do_neon_rshl (void)
+ {
+   enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
+   struct neon_type_el et = neon_check_type (3, rs,
+     N_EQK, N_EQK, N_SU_ALL | N_KEY);
+   unsigned int tmp;
+   tmp = inst.operands[2].reg;
+   inst.operands[2].reg = inst.operands[1].reg;
+   inst.operands[1].reg = tmp;
+   neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
+ }
+ 
  static int
  neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
  {
*************** static const struct asm_opcode insns[] =
*** 15639,15648 ****
   NUF(vqaddq,    0000010, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
   NUF(vqsub,     0000210, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
   NUF(vqsubq,    0000210, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
!  NUF(vrshl,     0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
!  NUF(vrshlq,    0000500, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
!  NUF(vqrshl,    0000510, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
!  NUF(vqrshlq,   0000510, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
    /* If not immediate, fall back to neon_dyadic_i64_su.
       shl_imm should accept I8 I16 I32 I64,
       qshl_imm should accept S8 S16 S32 S64 U8 U16 U32 U64.  */
--- 15668,15677 ----
   NUF(vqaddq,    0000010, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
   NUF(vqsub,     0000210, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
   NUF(vqsubq,    0000210, 3, (RNQ,  oRNQ,  RNQ),  neon_dyadic_i64_su),
!  NUF(vrshl,     0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
!  NUF(vrshlq,    0000500, 3, (RNQ,  oRNQ,  RNQ),  neon_rshl),
!  NUF(vqrshl,    0000510, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
!  NUF(vqrshlq,   0000510, 3, (RNQ,  oRNQ,  RNQ),  neon_rshl),
    /* If not immediate, fall back to neon_dyadic_i64_su.
       shl_imm should accept I8 I16 I32 I64,
       qshl_imm should accept S8 S16 S32 S64 U8 U16 U32 U64.  */
Index: gas/testsuite/gas/arm/neon-omit.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/neon-omit.d,v
retrieving revision 1.1.2.3
diff -c -p -r1.1.2.3 neon-omit.d
*** gas/testsuite/gas/arm/neon-omit.d	6 Sep 2006 16:35:22 -0000	1.1.2.3
--- gas/testsuite/gas/arm/neon-omit.d	3 Jan 2007 16:38:44 -0000
*************** Disassembly of section .text:
*** 9,16 ****
  0[0-9a-f]+ <[^>]+> f26cc0c6 	vhadd\.s32	q14, q14, q3
  0[0-9a-f]+ <[^>]+> f2222144 	vrhadd\.s32	q1, q1, q2
  0[0-9a-f]+ <[^>]+> f22aa24e 	vhsub\.s32	q5, q5, q7
! 0[0-9a-f]+ <[^>]+> f3166448 	vshl\.u16	q3, q3, q4
! 0[0-9a-f]+ <[^>]+> f32aa45c 	vqshl\.u32	q5, q5, q6
  0[0-9a-f]+ <[^>]+> f20ee170 	vand	q7, q7, q8
  0[0-9a-f]+ <[^>]+> f30ee170 	veor	q7, q7, q8
  0[0-9a-f]+ <[^>]+> f3b5a14a 	vceq\.i16	q5, q5, #0
--- 9,16 ----
  0[0-9a-f]+ <[^>]+> f26cc0c6 	vhadd\.s32	q14, q14, q3
  0[0-9a-f]+ <[^>]+> f2222144 	vrhadd\.s32	q1, q1, q2
  0[0-9a-f]+ <[^>]+> f22aa24e 	vhsub\.s32	q5, q5, q7
! 0[0-9a-f]+ <[^>]+> f3186446 	vshl\.u16	q3, q3, q4
! 0[0-9a-f]+ <[^>]+> f32ca45a 	vqshl\.u32	q5, q5, q6
  0[0-9a-f]+ <[^>]+> f20ee170 	vand	q7, q7, q8
  0[0-9a-f]+ <[^>]+> f30ee170 	veor	q7, q7, q8
  0[0-9a-f]+ <[^>]+> f3b5a14a 	vceq\.i16	q5, q5, #0
*************** Disassembly of section .text:
*** 55,62 ****
  0[0-9a-f]+ <[^>]+> f262c0c6 	vhadd\.s32	q14, q9, q3
  0[0-9a-f]+ <[^>]+> f22a2144 	vrhadd\.s32	q1, q5, q2
  0[0-9a-f]+ <[^>]+> f220a2ce 	vhsub\.s32	q5, q8, q7
! 0[0-9a-f]+ <[^>]+> f318644a 	vshl\.u16	q3, q4, q5
! 0[0-9a-f]+ <[^>]+> f32ca452 	vqshl\.u32	q5, q6, q1
  0[0-9a-f]+ <[^>]+> f200e1dc 	vand	q7, q8, q6
  0[0-9a-f]+ <[^>]+> f300e1dc 	veor	q7, q8, q6
  0[0-9a-f]+ <[^>]+> f3b5a146 	vceq\.i16	q5, q3, #0
--- 55,62 ----
  0[0-9a-f]+ <[^>]+> f262c0c6 	vhadd\.s32	q14, q9, q3
  0[0-9a-f]+ <[^>]+> f22a2144 	vrhadd\.s32	q1, q5, q2
  0[0-9a-f]+ <[^>]+> f220a2ce 	vhsub\.s32	q5, q8, q7
! 0[0-9a-f]+ <[^>]+> f31a6448 	vshl\.u16	q3, q4, q5
! 0[0-9a-f]+ <[^>]+> f322a45c 	vqshl\.u32	q5, q6, q1
  0[0-9a-f]+ <[^>]+> f200e1dc 	vand	q7, q8, q6
  0[0-9a-f]+ <[^>]+> f300e1dc 	veor	q7, q8, q6
  0[0-9a-f]+ <[^>]+> f3b5a146 	vceq\.i16	q5, q3, #0
Index: opcodes/arm-dis.c
===================================================================
RCS file: /cvs/src/src/opcodes/arm-dis.c,v
retrieving revision 1.62.2.11
diff -c -p -r1.62.2.11 arm-dis.c
*** opcodes/arm-dis.c	26 Oct 2006 19:41:54 -0000	1.62.2.11
--- opcodes/arm-dis.c	3 Jan 2007 16:38:44 -0000
*************** static const struct opcode32 neon_opcode
*** 576,585 ****
    {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
!   {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
!   {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
!   {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
!   {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
--- 576,585 ----
    {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
!   {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
!   {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
!   {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
!   {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
    {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
    {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},

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