PR 14072
[deliverable/binutils-gdb.git] / opcodes / pj-dis.c
CommitLineData
1e608f98 1/* pj-dis.c -- Disassemble picoJava instructions.
df7b86aa
NC
2 Copyright 1999, 2000, 2001, 2002, 2005, 2007, 2012
3 Free Software Foundation, Inc.
1e608f98
ILT
4 Contributed by Steve Chamberlain, of Transmeta (sac@pobox.com).
5
9b201bb5
NC
6 This file is part of the GNU opcodes library.
7
8 This library is free software; you can redistribute it and/or modify
47b0e7ad 9 it under the terms of the GNU General Public License as published by
9b201bb5
NC
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
1e608f98 12
9b201bb5
NC
13 It is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
16 License for more details.
1e608f98 17
47b0e7ad
NC
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
1e608f98 22
0d8dfecf 23#include "sysdep.h"
df7b86aa 24#include <stdio.h>
1e608f98
ILT
25#include "opcode/pj.h"
26#include "dis-asm.h"
27
28extern const pj_opc_info_t pj_opc_info[512];
29
ec22bdda 30static int
47b0e7ad 31get_int (bfd_vma memaddr, int *iptr, struct disassemble_info *info)
1e608f98
ILT
32{
33 unsigned char ival[4];
1e608f98
ILT
34 int status = info->read_memory_func (memaddr, ival, 4, info);
35
7f6621cd
KH
36 *iptr = (ival[0] << 24)
37 | (ival[1] << 16)
38 | (ival[2] << 8)
39 | (ival[3] << 0);
1e608f98
ILT
40
41 return status;
42}
43
44int
47b0e7ad 45print_insn_pj (bfd_vma addr, struct disassemble_info *info)
1e608f98
ILT
46{
47 fprintf_ftype fprintf_fn = info->fprintf_func;
48 void *stream = info->stream;
49 unsigned char opcode;
50 int status;
51
52 if ((status = info->read_memory_func (addr, &opcode, 1, info)))
53 goto fail;
54
55 if (opcode == 0xff)
56 {
57 unsigned char byte_2;
47b0e7ad 58
1e608f98
ILT
59 if ((status = info->read_memory_func (addr + 1, &byte_2, 1, info)))
60 goto fail;
0e073f4c 61 fprintf_fn (stream, "%s\t", pj_opc_info[opcode + byte_2].u.name);
1e608f98
ILT
62 return 2;
63 }
64 else
65 {
66 char *sep = "\t";
67 int insn_start = addr;
68 const pj_opc_info_t *op = &pj_opc_info[opcode];
69 int a;
47b0e7ad 70
1e608f98 71 addr++;
0e073f4c 72 fprintf_fn (stream, "%s", op->u.name);
1e608f98
ILT
73
74 /* The tableswitch instruction is followed by the default
7f6621cd 75 address, low value, high value and the destinations. */
1e608f98 76
0e073f4c 77 if (strcmp (op->u.name, "tableswitch") == 0)
1e608f98
ILT
78 {
79 int lowval;
80 int highval;
81 int val;
82
83 addr = (addr + 3) & ~3;
84 if ((status = get_int (addr, &val, info)))
85 goto fail;
86
ec22bdda 87 fprintf_fn (stream, " default: ");
1e608f98
ILT
88 (*info->print_address_func) (val + insn_start, info);
89 addr += 4;
90
91 if ((status = get_int (addr, &lowval, info)))
92 goto fail;
93 addr += 4;
94
95 if ((status = get_int (addr, &highval, info)))
96 goto fail;
97 addr += 4;
98
ec22bdda
KH
99 while (lowval <= highval)
100 {
101 if ((status = get_int (addr, &val, info)))
102 goto fail;
103 fprintf_fn (stream, " %d:[", lowval);
104 (*info->print_address_func) (val + insn_start, info);
105 fprintf_fn (stream, " ]");
106 addr += 4;
107 lowval++;
108 }
1e608f98
ILT
109 return addr - insn_start;
110 }
111
112 /* The lookupswitch instruction is followed by the default
113 address, element count and pairs of values and
7f6621cd 114 addresses. */
0e073f4c 115 if (strcmp (op->u.name, "lookupswitch") == 0)
1e608f98
ILT
116 {
117 int count;
118 int val;
119
120 addr = (addr + 3) & ~3;
121 if ((status = get_int (addr, &val, info)))
122 goto fail;
123 addr += 4;
124
ec22bdda 125 fprintf_fn (stream, " default: ");
1e608f98
ILT
126 (*info->print_address_func) (val + insn_start, info);
127
128 if ((status = get_int (addr, &count, info)))
129 goto fail;
130 addr += 4;
131
ec22bdda
KH
132 while (count--)
133 {
134 if ((status = get_int (addr, &val, info)))
135 goto fail;
136 addr += 4;
137 fprintf_fn (stream, " %d:[", val);
1e608f98 138
ec22bdda
KH
139 if ((status = get_int (addr, &val, info)))
140 goto fail;
141 addr += 4;
1e608f98 142
ec22bdda
KH
143 (*info->print_address_func) (val + insn_start, info);
144 fprintf_fn (stream, " ]");
145 }
1e608f98
ILT
146 return addr - insn_start;
147 }
47b0e7ad 148
1e608f98
ILT
149 for (a = 0; op->arg[a]; a++)
150 {
151 unsigned char data[4];
152 int val = 0;
153 int i;
154 int size = ASIZE (op->arg[a]);
155
156 if ((status = info->read_memory_func (addr, data, size, info)))
157 goto fail;
158
159 val = (UNS (op->arg[0]) || ((data[0] & 0x80) == 0)) ? 0 : -1;
160
161 for (i = 0; i < size; i++)
162 val = (val << 8) | (data[i] & 0xff);
163
164 if (PCREL (op->arg[a]))
165 (*info->print_address_func) (val + insn_start, info);
166 else
167 fprintf_fn (stream, "%s%d", sep, val);
168
169 sep = ",";
170 addr += size;
171 }
172 return op->len;
173 }
174
175 fail:
176 info->memory_error_func (status, addr, info);
177 return -1;
178}
This page took 0.535071 seconds and 4 git commands to generate.