summaryrefslogtreecommitdiff
path: root/opcodes/m10300-dis.c
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2003-07-10 02:53:27 +0000
committerAlexandre Oliva <aoliva@redhat.com>2003-07-10 02:53:27 +0000
commit40fa02078b63a5cbca3b8700ba4b37dd0a48ce2b (patch)
tree1e2eeacb08e53f3581accc61dfb443f99e264614 /opcodes/m10300-dis.c
parentb08fa4d3bf5914d746515f4f6ca560d7e900ec92 (diff)
downloadbinutils-gdb-40fa02078b63a5cbca3b8700ba4b37dd0a48ce2b.tar.gz
2000-05-25 Alexandre Oliva <aoliva@cygnus.com>
* m10300-dis.c (disassemble): Negate negative accumulator's shift. 2000-05-24 Alexandre Oliva <aoliva@cygnus.com> * m10300-dis.c (disassemble, case FSREG, FDREG): Don't assume 32-bit longs when sign-extending operands. 2000-04-20 Alexandre Oliva <aoliva@cygnus.com> * m10300-opc.c: Remove MN10300_OPERAND_RELAX from all FSREGs. * m10300-dis.c (HAVE_AM33_2): Define. (disassemble): Use it. (HAVE_AM33): Redefine. (print_insn_mn10300): Fix mask for 5-byte extended insns. 2000-04-01 Alexandre Oliva <aoliva@cygnus.com> * m10300-opc.c: Renamed AM332 to AM33_2. 2000-03-31 Alexandre Oliva <aoliva@cygnus.com> * m10300-opc.c: Defined AM33 2.0 register operands. Added support for AM33 2.0 `imm8,(abs16)' addressing mode for btst, bset and bclr. Implemented `fbCC', `flCC', `dcpf' and all FP insns. * m10300-dis.c (print_insn_mn10300): Recognize 5byte extended insn code of AM33 2.0. (disassemble): Recognize FMT_D3. Print out FP register names.
Diffstat (limited to 'opcodes/m10300-dis.c')
-rw-r--r--opcodes/m10300-dis.c83
1 files changed, 82 insertions, 1 deletions
diff --git a/opcodes/m10300-dis.c b/opcodes/m10300-dis.c
index a8d4b510dcd..1d3637c704d 100644
--- a/opcodes/m10300-dis.c
+++ b/opcodes/m10300-dis.c
@@ -26,7 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
static void disassemble PARAMS ((bfd_vma, struct disassemble_info *,
unsigned long insn, unsigned int));
-#define HAVE_AM33 (info->mach == AM33)
+#define HAVE_AM33_2 (info->mach == AM33_2)
+#define HAVE_AM33 (info->mach == AM33 || HAVE_AM33_2)
#define HAVE_AM30 (info->mach == AM30)
int
@@ -200,6 +201,9 @@ print_insn_mn10300 (memaddr, info)
insn = bfd_getb32 (buffer);
consume = 7;
+ /* Handle the 5-byte extended instruction codes. */
+ if ((insn & 0xfff80000) == 0xfe800000)
+ consume = 5;
}
disassemble (memaddr, info, insn, consume);
@@ -237,6 +241,8 @@ disassemble (memaddr, info, insn, size)
mysize = 5;
else if (op->format == FMT_D2)
mysize = 4;
+ else if (op->format == FMT_D3)
+ mysize = 5;
else if (op->format == FMT_D4)
mysize = 6;
else if (op->format == FMT_D6)
@@ -253,6 +259,7 @@ disassemble (memaddr, info, insn, size)
if ((op->mask & insn) == op->opcode
&& size == (unsigned int) mysize
&& (op->machine == 0
+ || (op->machine == AM33_2 && HAVE_AM33_2)
|| (op->machine == AM33 && HAVE_AM33)
|| (op->machine == AM30 && HAVE_AM30)))
{
@@ -343,6 +350,25 @@ disassemble (memaddr, info, insn, size)
insn |= (temp & 0xffffff00) >> 8;
extension = temp & 0xff;
}
+ else if (size == 5 && op->format == FMT_D3)
+ {
+ status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ insn &= 0xffff0000;
+ insn |= bfd_getl16 (buffer);
+
+ status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
+ if (status != 0)
+ {
+ (*info->memory_error_func) (status, memaddr, info);
+ return;
+ }
+ extension = *(unsigned char *) buffer;
+ }
else if (size == 5)
{
unsigned long temp = 0;
@@ -498,6 +524,52 @@ disassemble (memaddr, info, insn, size)
if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
}
+ else if ((operand->flags & (MN10300_OPERAND_FSREG
+ | MN10300_OPERAND_FDREG)))
+ {
+ /* See m10300-opc.c just before #define FSM0 for an
+ explanation of these variables. Note that
+ FMT-implied shifts are not taken into account for
+ FP registers. */
+ unsigned long mask_low, mask_high;
+ int shl_low, shr_high, shl_high;
+
+ switch (operand->bits)
+ {
+ case 5:
+ /* Handle regular FP registers. */
+ if (operand->shift >= 0)
+ {
+ /* This is an `m' register. */
+ shl_low = operand->shift;
+ shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
+ }
+ else
+ {
+ /* This is an `n' register. */
+ shl_low = -operand->shift;
+ shl_high = shl_low / 4;
+ }
+ mask_low = 0x0f;
+ mask_high = 0x10;
+ shr_high = 4;
+ break;
+
+ case 3:
+ /* Handle accumulators. */
+ shl_low = -operand->shift;
+ shl_high = 0;
+ mask_low = 0x03;
+ mask_high = 0x04;
+ shr_high = 2;
+ break;
+
+ default:
+ abort ();
+ }
+ value = ((((insn >> shl_high) << shr_high) & mask_high)
+ | ((insn >> shl_low) & mask_low));
+ }
else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
{
value = ((extension >> (operand->shift))
@@ -567,6 +639,15 @@ disassemble (memaddr, info, insn, size)
(*info->fprintf_func) (info->stream, "xr%d", (int) value);
}
+ else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
+ (*info->fprintf_func) (info->stream, "fs%d", (int) value);
+
+ else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
+ (*info->fprintf_func) (info->stream, "fd%d", (int) value);
+
+ else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
+ (*info->fprintf_func) (info->stream, "fpcr");
+
else if ((operand->flags & MN10300_OPERAND_USP) != 0)
(*info->fprintf_func) (info->stream, "usp");