summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog13
-rw-r--r--gas/NEWS6
-rw-r--r--gas/config/tc-sh.c361
-rw-r--r--gas/doc/c-sh.texi9
-rw-r--r--gas/doc/c-sh64.texi8
-rw-r--r--gas/testsuite/gas/sh/basic.exp8
-rw-r--r--gas/testsuite/gas/sh/err-sh4a-fp.s15
-rw-r--r--gas/testsuite/gas/sh/err-sh4a.s29
-rw-r--r--gas/testsuite/gas/sh/err-sh4al-dsp.s20
-rw-r--r--gas/testsuite/gas/sh/sh4a-dsp.d40
-rw-r--r--gas/testsuite/gas/sh/sh4a-dsp.s42
-rw-r--r--gas/testsuite/gas/sh/sh4a-fp.d15
-rw-r--r--gas/testsuite/gas/sh/sh4a-fp.s11
-rw-r--r--gas/testsuite/gas/sh/sh4a.d27
-rw-r--r--gas/testsuite/gas/sh/sh4a.s28
-rw-r--r--gas/testsuite/gas/sh/sh4al-dsp.d104
-rw-r--r--gas/testsuite/gas/sh/sh4al-dsp.s104
17 files changed, 822 insertions, 18 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index fe8ec76537..7785fa843e 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,16 @@
+2003-12-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * config/tc-sh.c: Add support for sh4a and no-fpu variants,
+ with appropriate additions to md_show_usage.
+ * testsuite/gas/sh/basic.exp: Call tests for sh4a.
+ * testsuite/gas/sh/{err-sh4a-fp.s, err-sh4a.s,
+ err-sh4al-dsp.s, sh4a-dsp.d, sh4a-dsp.s, sh4a-fp.d,
+ sh4a-fp.s, sh4a.d, sh4a.s, sh4al-dsp.d, sh4al-dsp.s:
+ New files, tests for sh4a and related variants.
+ * doc/c-sh.texi: Document new -isa options.
+ * doc/c-sh64.texi: Ditto.
+ * NEWS: Mention new support for sh4a.
+
2003-12-03 H.J. Lu <hongjiu.lu@intel.com>
* config/tc-alpha.c (s_alpha_end): Don't crash if there is no
diff --git a/gas/NEWS b/gas/NEWS
index 7df8a45ef8..1f704d2a35 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,9 +1,11 @@
-*- text -*-
+* Added support for sh4a and variants.
+
* Support for Renesas M32R2 added.
-* Limited support for Mapping Symbols as specified in the ARM ELF specification
- has been added to the arm assembler.
+* Limited support for Mapping Symbols as specified in the ARM ELF
+ specification has been added to the arm assembler.
* On ARM architectures, added a new gas directive ".unreq" that undoes
definitions created by ".req".
diff --git a/gas/config/tc-sh.c b/gas/config/tc-sh.c
index c49949185c..2b8f918fdb 100644
--- a/gas/config/tc-sh.c
+++ b/gas/config/tc-sh.c
@@ -1400,13 +1400,13 @@ parse_at (char *src, sh_operand_info *op)
|| (l0 == 'i' && (l1 == 'x' || l1 == 's')))
{
src += 2;
- op->type = A_PMOD_N;
+ op->type = AX_PMOD_N;
}
else if ( (l0 == 'r' && l1 == '9')
|| (l0 == 'i' && l1 == 'y'))
{
src += 2;
- op->type = A_PMODY_N;
+ op->type = AY_PMOD_N;
}
else
op->type = A_INC_N;
@@ -1579,8 +1579,6 @@ get_specific (sh_opcode_info *opcode, sh_operand_info *operands)
case V_REG_N:
case FPUL_N:
case FPSCR_N:
- case A_PMOD_N:
- case A_PMODY_N:
case DSP_REG_N:
/* Opcode needs rn */
if (user->type != arg)
@@ -1626,6 +1624,237 @@ get_specific (sh_opcode_info *opcode, sh_operand_info *operands)
reg_m = user->reg;
break;
+ case AS_DEC_N:
+ if (user->type != A_DEC_N)
+ goto fail;
+ if (user->reg < 2 || user->reg > 5)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AS_INC_N:
+ if (user->type != A_INC_N)
+ goto fail;
+ if (user->reg < 2 || user->reg > 5)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AS_IND_N:
+ if (user->type != A_IND_N)
+ goto fail;
+ if (user->reg < 2 || user->reg > 5)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AS_PMOD_N:
+ if (user->type != AX_PMOD_N)
+ goto fail;
+ if (user->reg < 2 || user->reg > 5)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AX_INC_N:
+ if (user->type != A_INC_N)
+ goto fail;
+ if (user->reg < 4 || user->reg > 5)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AX_IND_N:
+ if (user->type != A_IND_N)
+ goto fail;
+ if (user->reg < 4 || user->reg > 5)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AX_PMOD_N:
+ if (user->type != AX_PMOD_N)
+ goto fail;
+ if (user->reg < 4 || user->reg > 5)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AXY_INC_N:
+ if (user->type != A_INC_N)
+ goto fail;
+ if ((user->reg < 4 || user->reg > 5)
+ && (user->reg < 0 || user->reg > 1))
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AXY_IND_N:
+ if (user->type != A_IND_N)
+ goto fail;
+ if ((user->reg < 4 || user->reg > 5)
+ && (user->reg < 0 || user->reg > 1))
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AXY_PMOD_N:
+ if (user->type != AX_PMOD_N)
+ goto fail;
+ if ((user->reg < 4 || user->reg > 5)
+ && (user->reg < 0 || user->reg > 1))
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AY_INC_N:
+ if (user->type != A_INC_N)
+ goto fail;
+ if (user->reg < 6 || user->reg > 7)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AY_IND_N:
+ if (user->type != A_IND_N)
+ goto fail;
+ if (user->reg < 6 || user->reg > 7)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AY_PMOD_N:
+ if (user->type != AY_PMOD_N)
+ goto fail;
+ if (user->reg < 6 || user->reg > 7)
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AYX_INC_N:
+ if (user->type != A_INC_N)
+ goto fail;
+ if ((user->reg < 6 || user->reg > 7)
+ && (user->reg < 2 || user->reg > 3))
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AYX_IND_N:
+ if (user->type != A_IND_N)
+ goto fail;
+ if ((user->reg < 6 || user->reg > 7)
+ && (user->reg < 2 || user->reg > 3))
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case AYX_PMOD_N:
+ if (user->type != AY_PMOD_N)
+ goto fail;
+ if ((user->reg < 6 || user->reg > 7)
+ && (user->reg < 2 || user->reg > 3))
+ goto fail;
+ reg_n = user->reg;
+ break;
+
+ case DSP_REG_A_M:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ if (user->reg != A_A0_NUM
+ && user->reg != A_A1_NUM)
+ goto fail;
+ reg_m = user->reg;
+ break;
+
+ case DSP_REG_AX:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_A0_NUM:
+ reg_x = 0;
+ break;
+ case A_A1_NUM:
+ reg_x = 2;
+ break;
+ case A_X0_NUM:
+ reg_x = 1;
+ break;
+ case A_X1_NUM:
+ reg_x = 3;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
+ case DSP_REG_XY:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_X0_NUM:
+ reg_x = 0;
+ break;
+ case A_X1_NUM:
+ reg_x = 2;
+ break;
+ case A_Y0_NUM:
+ reg_x = 1;
+ break;
+ case A_Y1_NUM:
+ reg_x = 3;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
+ case DSP_REG_AY:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_A0_NUM:
+ reg_y = 0;
+ break;
+ case A_A1_NUM:
+ reg_y = 1;
+ break;
+ case A_Y0_NUM:
+ reg_y = 2;
+ break;
+ case A_Y1_NUM:
+ reg_y = 3;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
+ case DSP_REG_YX:
+ if (user->type != DSP_REG_N)
+ goto fail;
+ switch (user->reg)
+ {
+ case A_Y0_NUM:
+ reg_y = 0;
+ break;
+ case A_Y1_NUM:
+ reg_y = 1;
+ break;
+ case A_X0_NUM:
+ reg_y = 2;
+ break;
+ case A_X1_NUM:
+ reg_y = 3;
+ break;
+ default:
+ goto fail;
+ }
+ break;
+
case DSP_REG_X:
if (user->type != DSP_REG_N)
goto fail;
@@ -2069,6 +2298,7 @@ assemble_ppi (char *op_end, sh_opcode_info *opcode)
if (opcode->arg[0] != A_END)
op_end = get_operands (opcode, op_end, operand);
+ try_another_opcode:
opcode = get_specific (opcode, operand);
if (opcode == 0)
{
@@ -2099,9 +2329,43 @@ assemble_ppi (char *op_end, sh_opcode_info *opcode)
movy = DDT_BASE;
break;
+ case MOVX_NOPY:
+ if (movx)
+ as_bad (_("multiple movx specifications"));
+ if ((reg_n < 4 || reg_n > 5)
+ && (reg_n < 0 || reg_n > 1))
+ as_bad (_("invalid movx address register"));
+ if (movy && movy != DDT_BASE)
+ as_bad (_("insn cannot be combined with non-nopy"));
+ movx = ((((reg_n & 1) != 0) << 9)
+ + (((reg_n & 4) == 0) << 8)
+ + (reg_x << 6)
+ + (opcode->nibbles[2] << 4)
+ + opcode->nibbles[3]
+ + DDT_BASE);
+ break;
+
+ case MOVY_NOPX:
+ if (movy)
+ as_bad (_("multiple movy specifications"));
+ if ((reg_n < 6 || reg_n > 7)
+ && (reg_n < 2 || reg_n > 3))
+ as_bad (_("invalid movy address register"));
+ if (movx && movx != DDT_BASE)
+ as_bad (_("insn cannot be combined with non-nopx"));
+ movy = ((((reg_n & 1) != 0) << 8)
+ + (((reg_n & 4) == 0) << 9)
+ + (reg_y << 6)
+ + (opcode->nibbles[2] << 4)
+ + opcode->nibbles[3]
+ + DDT_BASE);
+ break;
+
case MOVX:
if (movx)
as_bad (_("multiple movx specifications"));
+ if (movy & 0x2ac)
+ as_bad (_("previous movy requires nopx"));
if (reg_n < 4 || reg_n > 5)
as_bad (_("invalid movx address register"));
if (opcode->nibbles[2] & 8)
@@ -2123,6 +2387,8 @@ assemble_ppi (char *op_end, sh_opcode_info *opcode)
case MOVY:
if (movy)
as_bad (_("multiple movy specifications"));
+ if (movx & 0x153)
+ as_bad (_("previous movx requires nopy"));
if (opcode->nibbles[2] & 8)
{
/* Bit 3 in nibbles[2] is intended for bit 4 of the opcode,
@@ -2151,11 +2417,31 @@ assemble_ppi (char *op_end, sh_opcode_info *opcode)
| (operand[0].immediate.X_add_number & 127) << 4
| reg_n);
break;
+ case PPI3NC:
+ if (cond)
+ {
+ opcode++;
+ goto try_another_opcode;
+ }
+ /* Fall through. */
case PPI3:
if (field_b)
as_bad (_("multiple parallel processing specifications"));
field_b = ((opcode->nibbles[2] << 12) + (opcode->nibbles[3] << 8)
+ (reg_x << 6) + (reg_y << 4) + reg_n);
+ switch (opcode->nibbles[4])
+ {
+ case HEX_0:
+ case HEX_XX00:
+ case HEX_00YY:
+ break;
+ case HEX_1:
+ case HEX_4:
+ field_b += opcode->nibbles[4] << 4;
+ break;
+ default:
+ abort ();
+ }
break;
case PDC:
if (cond)
@@ -2170,13 +2456,34 @@ assemble_ppi (char *op_end, sh_opcode_info *opcode)
field_b = ((opcode->nibbles[2] << 12) + (opcode->nibbles[3] << 8)
+ cond + (reg_x << 6) + (reg_y << 4) + reg_n);
cond = 0;
+ switch (opcode->nibbles[4])
+ {
+ case HEX_0:
+ case HEX_XX00:
+ case HEX_00YY:
+ break;
+ case HEX_1:
+ case HEX_4:
+ field_b += opcode->nibbles[4] << 4;
+ break;
+ default:
+ abort ();
+ }
break;
case PMUL:
if (field_b)
{
- if ((field_b & 0xef00) != 0xa100)
+ if ((field_b & 0xef00) == 0xa100)
+ field_b -= 0x8100;
+ /* pclr Dz pmuls Se,Sf,Dg */
+ else if ((field_b & 0xff00) == 0x8d00
+ && (valid_arch & arch_sh4al_dsp_up))
+ {
+ valid_arch &= arch_sh4al_dsp_up;
+ field_b -= 0x8cf0;
+ }
+ else
as_bad (_("insn cannot be combined with pmuls"));
- field_b -= 0x8100;
switch (field_b & 0xf)
{
case A_X0_NUM:
@@ -2192,7 +2499,7 @@ assemble_ppi (char *op_end, sh_opcode_info *opcode)
field_b += 3 - A_A1_NUM;
break;
default:
- as_bad (_("bad padd / psub pmuls output operand"));
+ as_bad (_("bad combined pmuls output operand"));
}
/* Generate warning if the destination register for padd / psub
and pmuls is the same ( only for A0 or A1 ).
@@ -2578,12 +2885,18 @@ md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
break;
case OPTION_DSP:
- preset_target_arch = arch_sh1_up & ~arch_sh3e_up;
+ preset_target_arch = arch_sh1_up & ~arch_sh2e_up;
break;
case OPTION_ISA:
if (strcasecmp (arg, "sh4") == 0)
preset_target_arch = arch_sh4;
+ else if (strcasecmp (arg, "sh4a") == 0)
+ preset_target_arch = arch_sh4a;
+ else if (strcasecmp (arg, "dsp") == 0)
+ preset_target_arch = arch_sh1_up & ~arch_sh2e_up;
+ else if (strcasecmp (arg, "fp") == 0)
+ preset_target_arch = arch_sh2e_up;
else if (strcasecmp (arg, "any") == 0)
preset_target_arch = arch_sh1_up;
#ifdef HAVE_SH64
@@ -2659,13 +2972,23 @@ SH options:\n\
-big generate big endian code\n\
-relax alter jump instructions for long displacements\n\
-small align sections to 4 byte boundaries, not 16\n\
--dsp enable sh-dsp insns, and disable sh2e/sh3e/sh4 insns.\n"));
+-dsp enable sh-dsp insns, and disable floating-point ISAs.\n"));
+ fprintf (stream, _("\
+-isa=[sh4\n\
+ | sh4a\n\
+ | dsp same as '-dsp'\n\
+ | fp\n"
+#ifdef HAVE_SH64
+"\
+ | shmedia set default instruction set for SH64\n\
+ | SHmedia\n\
+ | shcompact\n\
+ | SHcompact\n"
+#endif
+"\
+ | any]\n"));
#ifdef HAVE_SH64
fprintf (stream, _("\
--isa=[shmedia set default instruction set for SH64\n\
- | SHmedia\n\
- | shcompact\n\
- | SHcompact]\n\
-abi=[32|64] set size of expanded SHmedia operands and object\n\
file type\n\
-shcompact-const-crange emit code-range descriptors for constants in\n\
@@ -3212,7 +3535,7 @@ sh_elf_final_processing (void)
int val;
/* Set file-specific flags to indicate if this code needs
- a processor with the sh-dsp / sh3e ISA to execute. */
+ a processor with the sh-dsp / sh2e ISA to execute. */
#ifdef HAVE_SH64
/* SH5 and above don't know about the valid_arch arch_sh* bits defined
in sh-opc.h, so check SH64 mode before checking valid_arch. */
@@ -3231,11 +3554,19 @@ sh_elf_final_processing (void)
else if (valid_arch & arch_sh3)
val = EF_SH3;
else if (valid_arch & arch_sh3_dsp)
- val = EF_SH_DSP;
+ val = EF_SH3_DSP;
else if (valid_arch & arch_sh3e)
val = EF_SH3E;
+ else if (valid_arch & arch_sh4_nofpu)
+ val = EF_SH4_NOFPU;
else if (valid_arch & arch_sh4)
val = EF_SH4;
+ else if (valid_arch & arch_sh4a_nofpu)
+ val = EF_SH4A_NOFPU;
+ else if (valid_arch & arch_sh4a)
+ val = EF_SH4A;
+ else if (valid_arch & arch_sh4al_dsp)
+ val = EF_SH4AL_DSP;
else
abort ();
diff --git a/gas/doc/c-sh.texi b/gas/doc/c-sh.texi
index 7925530469..e19959b724 100644
--- a/gas/doc/c-sh.texi
+++ b/gas/doc/c-sh.texi
@@ -45,6 +45,15 @@ Align sections to 4 byte boundaries, not 16.
@item -dsp
Enable sh-dsp insns, and disable sh3e / sh4 insns.
+@item -isa=sh4 | sh4a
+Specify the sh4 or sh4a instruction set.
+@item -isa=dsp
+Enable sh-dsp insns, and disable sh3e / sh4 insns.
+@item -isa=fp
+Enable sh2e, sh3e, sh4, and sh4a insn sets.
+@item -isa=all
+Enable sh1, sh2, sh2e, sh3, sh3e, sh4, sh4a, and sh-dsp insn sets.
+
@end table
@node SH Syntax
diff --git a/gas/doc/c-sh64.texi b/gas/doc/c-sh64.texi
index f9e901af93..60681ee920 100644
--- a/gas/doc/c-sh64.texi
+++ b/gas/doc/c-sh64.texi
@@ -22,6 +22,14 @@
@cindex SH64 ISA options
@cindex ISA options, SH64
+@item -isa=sh4 | sh4a
+Specify the sh4 or sh4a instruction set.
+@item -isa=dsp
+Enable sh-dsp insns, and disable sh3e / sh4 insns.
+@item -isa=fp
+Enable sh2e, sh3e, sh4, and sh4a insn sets.
+@item -isa=all
+Enable sh1, sh2, sh2e, sh3, sh3e, sh4, sh4a, and sh-dsp insn sets.
@item -isa=shmedia | -isa=shcompact
Specify the default instruction set. @code{SHmedia} specifies the
32-bit opcodes, and @code{SHcompact} specifies the 16-bit opcodes
diff --git a/gas/testsuite/gas/sh/basic.exp b/gas/testsuite/gas/sh/basic.exp
index cbb1bb9d01..1fab0cc4b1 100644
--- a/gas/testsuite/gas/sh/basic.exp
+++ b/gas/testsuite/gas/sh/basic.exp
@@ -1,4 +1,4 @@
-# Copyright (C) 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
+# Copyright (C) 1995, 1996, 1997, 2002, 2003 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -140,6 +140,12 @@ if [istarget sh*-*-*] then {
}
if {[istarget sh*-*elf] || [istarget sh*-linux*]} then {
+ run_dump_test "sh4a"
+ run_dump_test "sh4a-fp"
+
+ run_dump_test "sh4a-dsp"
+ run_dump_test "sh4al-dsp"
+
run_dump_test "pic"
# Test TLS.
diff --git a/gas/testsuite/gas/sh/err-sh4a-fp.s b/gas/testsuite/gas/sh/err-sh4a-fp.s
new file mode 100644
index 0000000000..d15736c78b
--- /dev/null
+++ b/gas/testsuite/gas/sh/err-sh4a-fp.s
@@ -0,0 +1,15 @@
+! { dg-do assemble }
+
+ .text
+ .p2align 2
+
+ fpchg fpul ! { dg-error "excess operands" }
+
+ fsrra fr1, fr2 ! { dg-error "excess operands" }
+ fsrra ! { dg-error "invalid operands|missing operand" }
+ fsrra fpul ! { dg-error "invalid operands" }
+ fsrra dr0, dr2 ! { dg-error "invalid operands" }
+
+ fsca dr0, fpul ! { dg-error "invalid operands" }
+ fsca fpul, fr0 ! { dg-error "invalid operands" }
+ fsca fpul ! { dg-error "invalid operands|missing operand" }
diff --git a/gas/testsuite/gas/sh/err-sh4a.s b/gas/testsuite/gas/sh/err-sh4a.s
new file mode 100644
index 0000000000..6e5965d753
--- /dev/null
+++ b/gas/testsuite/gas/sh/err-sh4a.s
@@ -0,0 +1,29 @@
+! { dg-do assemble }
+
+ .text
+ .p2align 2
+
+ movli.l @r7,r13 ! { dg-error "invalid operands" }
+ movco.l r1,@r0 ! { dg-error "invalid operands" }
+
+ movli.l r0,@r0 ! { dg-error "invalid operands" }
+ movco.l @r0,r0 ! { dg-error "invalid operands" }
+
+ movli.l r1 ! { dg-error "invalid operands|missing operand" }
+ movco.l r0 ! { dg-error "invalid operands|missing operand" }
+
+ movli.l @r1,r0,r2 ! { dg-error "excess operands" }
+ movco.l r0,@r1,r2 ! { dg-error "excess operands" }
+
+ movua.l @r0,r1 ! { dg-error "invalid operands" }
+ movua.l @r0,r1,r2 ! { dg-error "invalid operands" }
+ movua.l @r1+ ! { dg-error "invalid operands|missing operand" }
+ movua.l r0,@r1 ! { dg-error "invalid operands" }
+ movua.l @(r0,r1),r2 ! { dg-error "invalid operands" }
+ movua.l @-r5,r1 ! { dg-error "invalid operands" }
+
+ icbi r0 ! { dg-error "invalid operands" }
+
+ prefi r7 ! { dg-error "invalid operands" }
+
+ synco r0 ! { dg-error "excess operands" }
diff --git a/gas/testsuite/gas/sh/err-sh4al-dsp.s b/gas/testsuite/gas/sh/err-sh4al-dsp.s
new file mode 100644
index 0000000000..ec2338a4bc
--- /dev/null
+++ b/gas/testsuite/gas/sh/err-sh4al-dsp.s
@@ -0,0 +1,20 @@
+! { dg-do assemble }
+! { dg-options "-dsp" }
+
+ .text
+ .p2align 2
+
+ ldrc a0 ! { dg-error "invalid operand" }
+
+ movx.w @r3,x0 ! { dg-error "invalid operand" }
+ movx.w @r0,x0 movy.w a0,@r7+ ! { dg-error "requires nopy" }
+ movy.w a0,@r2+ movx.w @r4,x0 ! { dg-error "requires nopx" }
+ movx.w @r4,x0 movy.w a0,@r3+ ! { dg-error "combined with non-nopx" }
+ movy.w a0,@r6+ movx.w @r1,x0 ! { dg-error "combined with non-nopy" }
+ movx.l @r5,x1 movx.w @r0,x0 ! { dg-error "multiple movx" }
+ movx.l @r1+,y0 nopx ! { dg-error "multiple movx" }
+ movy.w @r7,y1 movy.l @r2,y0 ! { dg-error "multiple movy" }
+ movy.l @r3+,x0 nopy ! { dg-error "multiple movy" }
+
+ dct pclr x0 pmuls a1,x0,m0 ! { dg-error "combined with pmuls" }
+ pclr a0 pmuls x1,y1,a0 ! { dg-warning "register is same" }
diff --git a/gas/testsuite/gas/sh/sh4a-dsp.d b/gas/testsuite/gas/sh/sh4a-dsp.d
new file mode 100644
index 0000000000..73d7e8d76b
--- /dev/null
+++ b/gas/testsuite/gas/sh/sh4a-dsp.d
@@ -0,0 +1,40 @@
+#as: -dsp
+#objdump: -fdr --prefix-addresses --show-raw-insn
+#name: SH4al-dsp constructs shared with sh4a (and sh4)
+
+.*: file format elf.*sh.*
+architecture: sh4a-nofpu, flags 0x00000010:
+HAS_SYMS
+start address 0x00000000
+
+Disassembly of section \.text:
+0x00000000 01 63 movli\.l @r1,r0
+0x00000002 00 73 movco\.l r0,@r0
+0x00000004 06 63 movli\.l @r6,r0
+0x00000006 03 73 movco\.l r0,@r3
+0x00000008 0a 63 movli\.l @r10,r0
+0x0000000a 0c 73 movco\.l r0,@r12
+0x0000000c 40 a9 movua\.l @r0,r0
+0x0000000e 4d a9 movua\.l @r13,r0
+0x00000010 47 a9 movua\.l @r7,r0
+0x00000012 45 e9 movua\.l @r5\+,r0
+0x00000014 42 e9 movua\.l @r2\+,r0
+0x00000016 4b e9 movua\.l @r11\+,r0
+0x00000018 04 e3 icbi @r4
+0x0000001a 0f e3 icbi @r15
+0x0000001c 02 e3 icbi @r2
+0x0000001e 05 d3 prefi @r5
+0x00000020 0a d3 prefi @r10
+0x00000022 00 ab synco
+0x00000024 45 fa ldc r5,dbr
+0x00000026 4a f6 ldc.l @r10\+,dbr
+0x00000028 0b 3a stc sgr,r11
+0x0000002a 49 32 stc.l sgr,@-r9
+0x0000002c 02 fa stc dbr,r2
+0x0000002e 46 f2 stc.l dbr,@-r6
+0x00000030 03 c3 movca.l r0,@r3
+0x00000032 0c 93 ocbi @r12
+0x00000034 07 a3 ocbp @r7
+0x00000036 0d b3 ocbwb @r13
+0x00000038 0e 83 pref @r14
+0x0000003a 00 09 nop
diff --git a/gas/testsuite/gas/sh/sh4a-dsp.s b/gas/testsuite/gas/sh/sh4a-dsp.s
new file mode 100644
index 0000000000..b884c4bc72
--- /dev/null
+++ b/gas/testsuite/gas/sh/sh4a-dsp.s
@@ -0,0 +1,42 @@
+ .text
+ .p2align 2
+
+ movli.l @r1,r0
+ movco.l r0,@r0
+
+ movli.l @r6,r0
+ movco.l r0,@r3
+
+ movli.l @r10,r0
+ movco.l r0,@r12
+
+ movua.l @r0,r0
+ movua.l @r13,r0
+ movua.l @r7,r0
+
+ movua.l @r5+,r0
+ movua.l @r2+,r0
+ movua.l @r11+,r0
+
+ icbi @r4
+ icbi @r15
+ icbi @r2
+
+ prefi @r5
+ prefi @r10
+
+ synco
+
+# Instructions present in SH4 but not in SH3-DSP
+ ldc r5,dbr
+ ldc.l @r10+,dbr
+ stc sgr,r11
+ stc.l sgr,@-r9
+ stc dbr,r2
+ stc.l dbr,@-r6
+
+ movca.l r0,@r3
+ ocbi @r12
+ ocbp @r7
+ ocbwb @r13
+ pref @r14
diff --git a/gas/testsuite/gas/sh/sh4a-fp.d b/gas/testsuite/gas/sh/sh4a-fp.d
new file mode 100644
index 0000000000..0605553200
--- /dev/null
+++ b/gas/testsuite/gas/sh/sh4a-fp.d
@@ -0,0 +1,15 @@
+#objdump: -fdr --prefix-addresses --show-raw-insn
+#name: SH4a FP constructs
+
+.*: file format elf.*sh.*
+architecture: sh4a, flags 0x00000010:
+HAS_SYMS
+start address 0x00000000
+
+Disassembly of section \.text:
+0x00000000 f7 fd fpchg
+0x00000002 f1 7d fsrra fr1
+0x00000004 f9 7d fsrra fr9
+0x00000006 f6 7d fsrra fr6
+0x00000008 f2 fd fsca fpul,dr2
+0x0000000a fc fd fsca fpul,dr12
diff --git a/gas/testsuite/gas/sh/sh4a-fp.s b/gas/testsuite/gas/sh/sh4a-fp.s
new file mode 100644
index 0000000000..f2c96829bc
--- /dev/null
+++ b/gas/testsuite/gas/sh/sh4a-fp.s
@@ -0,0 +1,11 @@
+ .text
+ .p2align 2
+
+ fpchg
+
+ fsrra fr1
+ fsrra fr9
+ fsrra fr6
+
+ fsca fpul, dr2
+ fsca fpul, dr12
diff --git a/gas/testsuite/gas/sh/sh4a.d b/gas/testsuite/gas/sh/sh4a.d
new file mode 100644
index 0000000000..0cdbf330da
--- /dev/null
+++ b/gas/testsuite/gas/sh/sh4a.d
@@ -0,0 +1,27 @@
+#objdump: -fdr --prefix-addresses --show-raw-insn
+#name: SH4a non-FP constructs
+
+.*: file format elf.*sh.*
+architecture: sh4a-nofpu, flags 0x00000010:
+HAS_SYMS
+start address 0x00000000
+
+Disassembly of section \.text:
+0x00000000 01 63 movli\.l @r1,r0
+0x00000002 00 73 movco\.l r0,@r0
+0x00000004 06 63 movli\.l @r6,r0
+0x00000006 03 73 movco\.l r0,@r3
+0x00000008 0a 63 movli\.l @r10,r0
+0x0000000a 0c 73 movco\.l r0,@r12
+0x0000000c 40 a9 movua\.l @r0,r0
+0x0000000e 4d a9 movua\.l @r13,r0
+0x00000010 47 a9 movua\.l @r7,r0
+0x00000012 45 e9 movua\.l @r5\+,r0
+0x00000014 42 e9 movua\.l @r2\+,r0
+0x00000016 4b e9 movua\.l @r11\+,r0
+0x00000018 04 e3 icbi @r4
+0x0000001a 0f e3 icbi @r15
+0x0000001c 02 e3 icbi @r2
+0x0000001e 05 d3 prefi @r5
+0x00000020 0a d3 prefi @r10
+0x00000022 00 ab synco
diff --git a/gas/testsuite/gas/sh/sh4a.s b/gas/testsuite/gas/sh/sh4a.s
new file mode 100644
index 0000000000..51c2382e3a
--- /dev/null
+++ b/gas/testsuite/gas/sh/sh4a.s
@@ -0,0 +1,28 @@
+ .text
+ .p2align 2
+
+ movli.l @r1,r0
+ movco.l r0,@r0
+
+ movli.l @r6,r0
+ movco.l r0,@r3
+
+ movli.l @r10,r0
+ movco.l r0,@r12
+
+ movua.l @r0,r0
+ movua.l @r13,r0
+ movua.l @r7,r0
+
+ movua.l @r5+,r0
+ movua.l @r2+,r0
+ movua.l @r11+,r0
+
+ icbi @r4
+ icbi @r15
+ icbi @r2
+
+ prefi @r5
+ prefi @r10
+
+ synco
diff --git a/gas/testsuite/gas/sh/sh4al-dsp.d b/gas/testsuite/gas/sh/sh4al-dsp.d
new file mode 100644
index 0000000000..d49abd2514
--- /dev/null
+++ b/gas/testsuite/gas/sh/sh4al-dsp.d
@@ -0,0 +1,104 @@
+#as: -dsp
+#objdump: -fdr --prefix-addresses --show-raw-insn
+#name: SH4al DSP constructs
+
+.*: file format elf.*sh.*
+architecture: sh4al-dsp, flags 0x00000010:
+HAS_SYMS
+start address 0x00000000
+
+Disassembly of section \.text:
+0x00000000 43 34 ldrc r3
+0x00000002 4c 34 ldrc r12
+0x00000004 8c 0a ldrc #10
+0x00000006 8c f3 ldrc #-13
+0x00000008 00 c8 setdmx
+0x0000000a 00 98 setdmy
+0x0000000c 00 88 clrdmxy
+
+0x0000000e f1 16 movx\.w @r4,x0 movy\.w a0,@r7\+
+0x00000010 f1 84 movx\.w @r0,x1
+0x00000012 f3 48 movx\.w @r1\+,y0
+0x00000014 f2 cc movx\.w @r5\+r8,y1
+0x00000016 f2 94 movx\.l @r5,x1
+0x00000018 f1 14 movx\.l @r0,x0
+0x0000001a f3 58 movx\.l @r1\+,y0
+0x0000001c f0 dc movx\.l @r4\+r8,y1
+
+0x0000001e f0 2b movx\.w a0,@r4\+ movy\.w @r6\+r9,y0
+0x00000020 f3 64 movx\.w x0,@r1
+0x00000022 f1 a8 movx\.w a1,@r0\+
+0x00000024 f2 ec movx\.w x1,@r5\+r8
+0x00000026 f2 34 movx\.l a0,@r5
+0x00000028 f1 74 movx\.l x0,@r0
+0x0000002a f3 f8 movx\.l x1,@r1\+
+0x0000002c f0 bc movx\.l a1,@r4\+r8
+
+0x0000002e f1 ed movx\.w a1,@r4\+r8 movy\.w @r7,y1
+0x00000030 f3 01 movy\.w @r3,y0
+0x00000032 f2 c2 movy\.w @r2\+,x1
+0x00000034 f0 83 movy\.w @r6\+r9,x0
+0x00000036 f0 61 movy\.l @r6,y1
+0x00000038 f2 21 movy\.l @r2,y0
+0x0000003a f3 a2 movy\.l @r3\+,x0
+0x0000003c f1 e3 movy\.l @r7\+r9,x1
+
+0x0000003e f2 de movx\.w @r5\+r8,x1 movy\.w a1,@r6\+
+0x00000040 f2 d1 movy\.w y1,@r2
+0x00000042 f3 12 movy\.w a0,@r3\+
+0x00000044 f1 93 movy\.w y0,@r7\+r9
+0x00000046 f1 71 movy\.l a1,@r7
+0x00000048 f3 b1 movy\.l y0,@r3
+0x0000004a f2 f2 movy\.l y1,@r2\+
+0x0000004c f0 33 movy\.l a0,@r6\+r9
+
+0x0000004e f8 00 88 47 pabs x1,a0
+0x00000052 f8 00 a8 0e pabs y0,m1
+0x00000056 f8 00 8a dc dct pabs a1,m0
+0x0000005a f8 00 8a 19 dct pabs x0,x1
+0x0000005e f8 00 8b 9b dcf pabs a0,y1
+0x00000062 f8 00 8b 57 dcf pabs x1,a0
+0x00000066 f8 00 aa 58 dct pabs y1,x0
+0x0000006a f8 00 aa 6e dct pabs m0,m1
+0x0000006e f8 00 ab 7a dcf pabs m1,y0
+0x00000072 f8 00 ab 45 dcf pabs y0,a1
+0x00000076 f8 00 4e 00 pmuls a1,x0,m0
+0x0000007a f8 00 4b 04 pmuls y0,a1,m1
+0x0000007e f8 00 8d 07 pclr a0
+0x00000082 f8 00 8e 05 dct pclr a1
+0x00000086 f8 00 4e 10 pclr x0 pmuls a1,x0,m0
+0x0000008a f8 00 40 1b pclr a1 pmuls x0,y0,a0
+0x0000008e f8 00 45 1e pclr a0 pmuls x1,y1,a1
+0x00000092 f8 00 4b 15 pclr y0 pmuls y0,a1,m1
+0x00000096 f8 00 a1 a8 psub a0,m0,x0
+0x0000009a f8 00 85 79 psub m1,x1,x1
+0x0000009e f8 00 85 8a psub y0,a0,y0
+0x000000a2 f8 00 a2 db dct psub a1,y1,y1
+0x000000a6 f8 00 86 67 dct psub m0,x1,a0
+0x000000aa f8 00 86 95 dct psub y1,a0,a1
+0x000000ae f8 00 a3 7c dcf psub x1,m1,m0
+0x000000b2 f8 00 87 4e dcf psub y0,x1,m1
+0x000000b6 f8 00 87 b5 dcf psub m1,a0,a1
+0x000000ba f8 00 9d de pswap a1,m1
+0x000000be f8 00 9d 17 pswap x0,a0
+0x000000c2 f8 00 bd 7a pswap m1,y0
+0x000000c6 f8 00 bd 49 pswap y0,x1
+0x000000ca f8 00 9e 9b dct pswap a0,y1
+0x000000ce f8 00 9e 58 dct pswap x1,x0
+0x000000d2 f8 00 be 55 dct pswap y1,a1
+0x000000d6 f8 00 be 6c dct pswap m0,m0
+0x000000da f8 00 9f 97 dcf pswap a0,a0
+0x000000de f8 00 9f 5e dcf pswap x1,m1
+0x000000e2 f8 00 bf 78 dcf pswap m1,x0
+0x000000e6 f8 00 bf 4b dcf pswap y0,y1
+0x000000ea f8 00 98 85 prnd a0,a1
+0x000000ee f8 00 b8 1c prnd y1,m0
+0x000000f2 f8 00 9a d8 dct prnd a1,x0
+0x000000f6 f8 00 9a 1b dct prnd x0,y1
+0x000000fa f8 00 ba 77 dct prnd m1,a0
+0x000000fe f8 00 ba 49 dct prnd y0,x1
+0x00000102 f8 00 9b 9a dcf prnd a0,y0
+0x00000106 f8 00 9b 5e dcf prnd x1,m1
+0x0000010a f8 00 bb 57 dcf prnd y1,a0
+0x0000010e f8 00 bb 65 dcf prnd m0,a1
+0x00000112 00 09 nop
diff --git a/gas/testsuite/gas/sh/sh4al-dsp.s b/gas/testsuite/gas/sh/sh4al-dsp.s
new file mode 100644
index 0000000000..4a326ea02f
--- /dev/null
+++ b/gas/testsuite/gas/sh/sh4al-dsp.s
@@ -0,0 +1,104 @@
+ .text
+ .p2align 2
+
+ ldrc r3
+ ldrc r12
+ ldrc #10
+ ldrc #243
+ setdmx
+ setdmy
+ clrdmxy
+
+ movx.w @r4,x0 movy.w a0,@r7+
+ movx.w @r0,x1
+ movx.w @r1+,y0 nopy
+nopy movx.w @r5+r8,y1
+
+ movx.l @r5,x1
+ movx.l @r0,x0
+ movx.l @r1+,y0 nopy
+nopy movx.l @r4+r8,y1
+
+ movx.w a0,@r4+ movy.w @r6+r9,y0
+ movx.w x0,@r1
+ movx.w a1,@r0+ nopy
+nopy movx.w x1,@r5+r8
+
+ movx.l a0,@r5
+ movx.l x0,@r0
+ movx.l x1,@r1+ nopy
+nopy movx.l a1,@r4+r8
+
+ movy.w @r7,y1 movx.w a1,@r4+r8
+ movy.w @r3,y0
+ movy.w @r2+,x1 nopx
+nopx movy.w @r6+r9,x0
+
+ movy.l @r6,y1
+ movy.l @r2,y0
+ movy.l @r3+,x0 nopx
+nopx movy.l @r7+r9,x1
+
+ movy.w a1,@r6+ movx.w @r5+r8,x1
+ movy.w y1,@r2
+ movy.w a0,@r3+ nopx
+nopx movy.w y0,@r7+r9
+
+ movy.l a1,@r7
+ movy.l y0,@r3
+ movy.l y1,@r2+ nopx
+nopx movy.l a0,@r6+r9
+
+ pabs x1,a0
+ pabs y0,m1
+ dct pabs a1,m0
+ dct pabs x0,x1
+ dcf pabs a0,y1
+ dcf pabs x1,a0
+ dct pabs y1,x0
+ dct pabs m0,m1
+ dcf pabs m1,y0
+ dcf pabs y0,a1
+
+ pmuls a1,x0,m0
+ pmuls y0,a1,m1
+ pclr a0
+ dct pclr a1
+ pclr x0 pmuls a1,x0,m0
+ pclr a1 pmuls x0,y0,a0
+ pclr a0 pmuls x1,y1,a1
+ pclr y0 pmuls y0,a1,m1
+
+ psub a0,m0,x0
+ psub m1,x1,x1
+ psub y0,a0,y0
+ dct psub a1,y1,y1
+ dct psub m0,x1,a0
+ dct psub y1,a0,a1
+ dcf psub x1,m1,m0
+ dcf psub y0,x1,m1
+ dcf psub m1,a0,a1
+
+ pswap a1,m1
+ pswap x0,a0
+ pswap m1,y0
+ pswap y0,x1
+ dct pswap a0,y1
+ dct pswap x1,x0
+ dct pswap y1,a1
+ dct pswap m0,m0
+ dcf pswap a0,a0
+ dcf pswap x1,m1
+ dcf pswap m1,x0
+ dcf pswap y0,y1
+
+ prnd a0,a1
+ prnd y1,m0
+ dct prnd a1,x0
+ dct prnd x0,y1
+ dct prnd m1,a0
+ dct prnd y0,x1
+ dcf prnd a0,y0
+ dcf prnd x1,m1
+ dcf prnd y1,a0
+ dcf prnd m0,a1