source: branches/libc-0.6/src/binutils/opcodes/pj-dis.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

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