This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH, ARM] Fix encoding for VSHL/VQSHL by register
- From: Julian Brown <julian at codesourcery dot com>
- To: binutils at sources dot redhat dot com
- Cc: Richard Earnshaw <Richard dot Earnshaw at arm dot com>, Paul Brook <paul at codesourcery dot com>
- Date: Wed, 03 Jan 2007 17:07:36 +0000
- Subject: [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"},