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