summaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorThiemo Seufer <ths@networkno.de>2005-11-14 02:25:39 +0000
committerThiemo Seufer <ths@networkno.de>2005-11-14 02:25:39 +0000
commit0499d65b9bc3522c3275f1945beb3d40e6f7a1ca (patch)
tree2893f145182b936f85283320bd1c3989075cd3e4 /opcodes
parenteafa87ff3b0eadd6e13c1c42962cad9e92992c3c (diff)
downloadbinutils-0499d65b9bc3522c3275f1945beb3d40e6f7a1ca.tar.gz
binutils-0499d65b9bc3522c3275f1945beb3d40e6f7a1ca.tar.bz2
binutils-0499d65b9bc3522c3275f1945beb3d40e6f7a1ca.zip
* mips.h: Assign 'm'/'M' codes to MIPS16e save/restore
instructions. Define MIPS16_ALL_ARGS and MIPS16_ALL_STATICS for save/restore encoding of the args field. * mips16-opc.c: Add MIPS16e save/restore opcodes. * mips-dis.c (print_mips16_insn_arg): Handle printing of 'm'/'M' codes for save/restore. * config/tc-mips.c (mips16_ip): Add handling of 'm' and 'M' codes for the MIPS16e save/restore instructions. * gas/mips/mips.exp: Run new save/restore tests. * gas/testsuite/gas/mips/mips16e-save.s: New test for generating different styles of save/restore instructions. * gas/testsuite/gas/mips/mips16e-save.d: New.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog6
-rw-r--r--opcodes/mips-dis.c86
-rw-r--r--opcodes/mips16-opc.c2
3 files changed, 94 insertions, 0 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index aa14a3d125a..aebe716dc51 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,9 @@
+2005-11-14 David Ung <davidu@mips.com>
+
+ * mips16-opc.c: Add MIPS16e save/restore opcodes.
+ * mips-dis.c (print_mips16_insn_arg): Handle printing of 'm'/'M'
+ codes for save/restore.
+
2005-11-10 Andreas Schwab <schwab@suse.de>
* m68k-dis.c (print_insn_m68k): Only match FPU insns with
diff --git a/opcodes/mips-dis.c b/opcodes/mips-dis.c
index 21f20fb5035..9a48d86d2d1 100644
--- a/opcodes/mips-dis.c
+++ b/opcodes/mips-dis.c
@@ -1656,6 +1656,92 @@ print_mips16_insn_arg (char type,
}
break;
+ case 'm':
+ case 'M':
+ /* MIPS16e save/restore. */
+ {
+ int need_comma = 0;
+ int amask, args, statics;
+ int nsreg, smask;
+ int framesz;
+ int i, j;
+
+ l = l & 0x7f;
+ if (use_extend)
+ l |= extend << 16;
+
+ amask = (l >> 16) & 0xf;
+ if (amask == MIPS16_ALL_ARGS)
+ {
+ args = 4;
+ statics = 0;
+ }
+ else if (amask == MIPS16_ALL_STATICS)
+ {
+ args = 0;
+ statics = 4;
+ }
+ else
+ {
+ args = amask >> 2;
+ statics = amask & 3;
+ }
+
+ if (args > 0) {
+ (*info->fprintf_func) (info->stream, "%s", mips_gpr_names[4]);
+ if (args > 1)
+ (*info->fprintf_func) (info->stream, "-%s",
+ mips_gpr_names[4 + args - 1]);
+ need_comma = 1;
+ }
+
+ framesz = (((l >> 16) & 0xf0) | (l & 0x0f)) * 8;
+ if (framesz == 0 && !use_extend)
+ framesz = 128;
+
+ (*info->fprintf_func) (info->stream, "%s%d",
+ need_comma ? "," : "",
+ framesz);
+
+ if (l & 0x40) /* $ra */
+ (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[31]);
+
+ nsreg = (l >> 24) & 0x7;
+ smask = 0;
+ if (l & 0x20) /* $s0 */
+ smask |= 1 << 0;
+ if (l & 0x10) /* $s1 */
+ smask |= 1 << 1;
+ if (nsreg > 0) /* $s2-$s8 */
+ smask |= ((1 << nsreg) - 1) << 2;
+
+ /* Find first set static reg bit. */
+ for (i = 0; i < 9; i++)
+ {
+ if (smask & (1 << i))
+ {
+ (*info->fprintf_func) (info->stream, ",%s",
+ mips_gpr_names[i == 8 ? 30 : (16 + i)]);
+ /* Skip over string of set bits. */
+ for (j = i; smask & (2 << j); j++)
+ continue;
+ if (j > i)
+ (*info->fprintf_func) (info->stream, "-%s",
+ mips_gpr_names[j == 8 ? 30 : (16 + j)]);
+ i = j + 1;
+ }
+ }
+
+ /* Statics $ax - $a3. */
+ if (statics == 1)
+ (*info->fprintf_func) (info->stream, ",%s", mips_gpr_names[7]);
+ else if (statics > 0)
+ (*info->fprintf_func) (info->stream, ",%s-%s",
+ mips_gpr_names[7 - statics + 1],
+ mips_gpr_names[7]);
+ }
+ break;
+
default:
/* xgettext:c-format */
(*info->fprintf_func)
diff --git a/opcodes/mips16-opc.c b/opcodes/mips16-opc.c
index 0459582e20f..4e5ae44752f 100644
--- a/opcodes/mips16-opc.c
+++ b/opcodes/mips16-opc.c
@@ -226,6 +226,8 @@ const struct mips_opcode mips16_opcodes[] =
{"jalrc", "R,x", 0xe8c0, 0xf8ff, WR_31|RD_x|TRAP, 0, 0 },
{"jrc", "x", 0xe880, 0xf8ff, RD_x|TRAP, 0, 0 },
{"jrc", "R", 0xe8a0, 0xffff, RD_31|TRAP, 0, 0 },
+{"restore", "M", 0x6400, 0xff80, WR_31|RD_SP|WR_SP|TRAP, 0, 0 },
+{"save", "m", 0x6480, 0xff80, RD_31|RD_SP|WR_SP|TRAP, 0, 0 },
{"seb", "x", 0xe891, 0xf8ff, WR_x|RD_x, 0, 0 },
{"seh", "x", 0xe8b1, 0xf8ff, WR_x|RD_x, 0, 0 },
{"sew", "x", 0xe8d1, 0xf8ff, WR_x|RD_x, 0, I3 },