OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [opcodes/] [xtensa-dis.c] - Blame information for rev 18

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 khays
/* xtensa-dis.c.  Disassembly functions for Xtensa.
2
   Copyright 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
3
   Contributed by Bob Wilson at Tensilica, Inc. (bwilson@tensilica.com)
4
 
5
   This file is part of the GNU opcodes library.
6
 
7
   This library is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
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.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this file; see the file COPYING.  If not, write to the
19
   Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
20
   MA 02110-1301, USA.  */
21
 
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <sys/types.h>
25
#include <string.h>
26
#include "xtensa-isa.h"
27
#include "ansidecl.h"
28
#include "libiberty.h"
29
#include "sysdep.h"
30
#include "dis-asm.h"
31
 
32
#include <setjmp.h>
33
 
34
extern xtensa_isa xtensa_default_isa;
35
 
36
#ifndef MAX
37
#define MAX(a,b) (a > b ? a : b)
38
#endif
39
 
40
int show_raw_fields;
41
 
42
struct dis_private
43
{
44
  bfd_byte *byte_buf;
45
  jmp_buf bailout;
46
};
47
 
48
 
49
static int
50
fetch_data (struct disassemble_info *info, bfd_vma memaddr)
51
{
52
  int length, status = 0;
53
  struct dis_private *priv = (struct dis_private *) info->private_data;
54
  int insn_size = xtensa_isa_maxlength (xtensa_default_isa);
55
 
56
  /* Read the maximum instruction size, padding with zeros if we go past
57
     the end of the text section.  This code will automatically adjust
58
     length when we hit the end of the buffer.  */
59
 
60
  memset (priv->byte_buf, 0, insn_size);
61
  for (length = insn_size; length > 0; length--)
62
    {
63
      status = (*info->read_memory_func) (memaddr, priv->byte_buf, length,
64
                                          info);
65
      if (status == 0)
66
        return length;
67
    }
68
  (*info->memory_error_func) (status, memaddr, info);
69
  longjmp (priv->bailout, 1);
70
  /*NOTREACHED*/
71
}
72
 
73
 
74
static void
75
print_xtensa_operand (bfd_vma memaddr,
76
                      struct disassemble_info *info,
77
                      xtensa_opcode opc,
78
                      int opnd,
79
                      unsigned operand_val)
80
{
81
  xtensa_isa isa = xtensa_default_isa;
82
  int signed_operand_val;
83
 
84
  if (show_raw_fields)
85
    {
86
      if (operand_val < 0xa)
87
        (*info->fprintf_func) (info->stream, "%u", operand_val);
88
      else
89
        (*info->fprintf_func) (info->stream, "0x%x", operand_val);
90
      return;
91
    }
92
 
93
  (void) xtensa_operand_decode (isa, opc, opnd, &operand_val);
94
  signed_operand_val = (int) operand_val;
95
 
96
  if (xtensa_operand_is_register (isa, opc, opnd) == 0)
97
    {
98
      if (xtensa_operand_is_PCrelative (isa, opc, opnd) == 1)
99
        {
100
          (void) xtensa_operand_undo_reloc (isa, opc, opnd,
101
                                            &operand_val, memaddr);
102
          info->target = operand_val;
103
          (*info->print_address_func) (info->target, info);
104
        }
105
      else
106
        {
107
          if ((signed_operand_val > -256) && (signed_operand_val < 256))
108
            (*info->fprintf_func) (info->stream, "%d", signed_operand_val);
109
          else
110
            (*info->fprintf_func) (info->stream, "0x%x", signed_operand_val);
111
        }
112
    }
113
  else
114
    {
115
      int i = 1;
116
      xtensa_regfile opnd_rf = xtensa_operand_regfile (isa, opc, opnd);
117
      (*info->fprintf_func) (info->stream, "%s%u",
118
                             xtensa_regfile_shortname (isa, opnd_rf),
119
                             operand_val);
120
      while (i < xtensa_operand_num_regs (isa, opc, opnd))
121
        {
122
          operand_val++;
123
          (*info->fprintf_func) (info->stream, ":%s%u",
124
                                 xtensa_regfile_shortname (isa, opnd_rf),
125
                                 operand_val);
126
          i++;
127
        }
128
    }
129
}
130
 
131
 
132
/* Print the Xtensa instruction at address MEMADDR on info->stream.
133
   Returns length of the instruction in bytes.  */
134
 
135
int
136
print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info)
137
{
138
  unsigned operand_val;
139
  int bytes_fetched, size, maxsize, i, n, noperands, nslots;
140
  xtensa_isa isa;
141
  xtensa_opcode opc;
142
  xtensa_format fmt;
143
  struct dis_private priv;
144
  static bfd_byte *byte_buf = NULL;
145
  static xtensa_insnbuf insn_buffer = NULL;
146
  static xtensa_insnbuf slot_buffer = NULL;
147
  int first, first_slot, valid_insn;
148
 
149
  if (!xtensa_default_isa)
150
    xtensa_default_isa = xtensa_isa_init (0, 0);
151
 
152
  info->target = 0;
153
  maxsize = xtensa_isa_maxlength (xtensa_default_isa);
154
 
155
  /* Set bytes_per_line to control the amount of whitespace between the hex
156
     values and the opcode.  For Xtensa, we always print one "chunk" and we
157
     vary bytes_per_chunk to determine how many bytes to print.  (objdump
158
     would apparently prefer that we set bytes_per_chunk to 1 and vary
159
     bytes_per_line but that makes it hard to fit 64-bit instructions on
160
     an 80-column screen.)  The value of bytes_per_line here is not exactly
161
     right, because objdump adds an extra space for each chunk so that the
162
     amount of whitespace depends on the chunk size.  Oh well, it's good
163
     enough....  Note that we set the minimum size to 4 to accomodate
164
     literal pools.  */
165
  info->bytes_per_line = MAX (maxsize, 4);
166
 
167
  /* Allocate buffers the first time through.  */
168
  if (!insn_buffer)
169
    {
170
      insn_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
171
      slot_buffer = xtensa_insnbuf_alloc (xtensa_default_isa);
172
      byte_buf = (bfd_byte *) xmalloc (MAX (maxsize, 4));
173
    }
174
 
175
  priv.byte_buf = byte_buf;
176
 
177
  info->private_data = (void *) &priv;
178
  if (setjmp (priv.bailout) != 0)
179
      /* Error return.  */
180
      return -1;
181
 
182
  /* Don't set "isa" before the setjmp to keep the compiler from griping.  */
183
  isa = xtensa_default_isa;
184
  size = 0;
185
  nslots = 0;
186
 
187
  /* Fetch the maximum size instruction.  */
188
  bytes_fetched = fetch_data (info, memaddr);
189
 
190
  /* Copy the bytes into the decode buffer.  */
191
  memset (insn_buffer, 0, (xtensa_insnbuf_size (isa) *
192
                           sizeof (xtensa_insnbuf_word)));
193
  xtensa_insnbuf_from_chars (isa, insn_buffer, priv.byte_buf, bytes_fetched);
194
 
195
  fmt = xtensa_format_decode (isa, insn_buffer);
196
  if (fmt == XTENSA_UNDEFINED
197
      || ((size = xtensa_format_length (isa, fmt)) > bytes_fetched))
198
    valid_insn = 0;
199
  else
200
    {
201
      /* Make sure all the opcodes are valid.  */
202
      valid_insn = 1;
203
      nslots = xtensa_format_num_slots (isa, fmt);
204
      for (n = 0; n < nslots; n++)
205
        {
206
          xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
207
          if (xtensa_opcode_decode (isa, fmt, n, slot_buffer)
208
              == XTENSA_UNDEFINED)
209
            {
210
              valid_insn = 0;
211
              break;
212
            }
213
        }
214
    }
215
 
216
  if (!valid_insn)
217
    {
218
      (*info->fprintf_func) (info->stream, ".byte %#02x", priv.byte_buf[0]);
219
      return 1;
220
    }
221
 
222
  if (nslots > 1)
223
    (*info->fprintf_func) (info->stream, "{ ");
224
 
225
  first_slot = 1;
226
  for (n = 0; n < nslots; n++)
227
    {
228
      if (first_slot)
229
        first_slot = 0;
230
      else
231
        (*info->fprintf_func) (info->stream, "; ");
232
 
233
      xtensa_format_get_slot (isa, fmt, n, insn_buffer, slot_buffer);
234
      opc = xtensa_opcode_decode (isa, fmt, n, slot_buffer);
235
      (*info->fprintf_func) (info->stream, "%s",
236
                             xtensa_opcode_name (isa, opc));
237
 
238
      /* Print the operands (if any).  */
239
      noperands = xtensa_opcode_num_operands (isa, opc);
240
      first = 1;
241
      for (i = 0; i < noperands; i++)
242
        {
243
          if (xtensa_operand_is_visible (isa, opc, i) == 0)
244
            continue;
245
          if (first)
246
            {
247
              (*info->fprintf_func) (info->stream, "\t");
248
              first = 0;
249
            }
250
          else
251
            (*info->fprintf_func) (info->stream, ", ");
252
          (void) xtensa_operand_get_field (isa, opc, i, fmt, n,
253
                                           slot_buffer, &operand_val);
254
 
255
          print_xtensa_operand (memaddr, info, opc, i, operand_val);
256
        }
257
    }
258
 
259
  if (nslots > 1)
260
    (*info->fprintf_func) (info->stream, " }");
261
 
262
  info->bytes_per_chunk = size;
263
  info->display_endian = info->endian;
264
 
265
  return size;
266
}
267
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.