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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [opcodes/] [or32-dis.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* Instruction printing code for the OpenRISC 1000
2
   Copyright (C) 2002, 2005, 2007 Free Software Foundation, Inc.
3
   Contributed by Damjan Lampret <lampret@opencores.org>.
4
   Modified from a29k port.
5
 
6
   This file is part of the GNU opcodes library.
7
 
8 225 jeremybenn
   This library is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3, or (at your option)
11 24 jeremybenn
   any later version.
12
 
13 225 jeremybenn
   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.
17 24 jeremybenn
 
18 225 jeremybenn
   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.  */
22 24 jeremybenn
 
23 225 jeremybenn
#define DEBUG 0
24 24 jeremybenn
 
25
#include "dis-asm.h"
26
#include "opcode/or32.h"
27
#include "safe-ctype.h"
28
#include <string.h>
29
#include <stdlib.h>
30
 
31 673 yannv
#define EXTEND28(x) ((x) & 0x08000000UL ? ((x) | ~0x0fffffffUL) : ((x)))
32 24 jeremybenn
 
33 225 jeremybenn
/* Now find the four bytes of INSN_CH and put them in *INSN.  */
34 24 jeremybenn
 
35
static void
36 225 jeremybenn
find_bytes_big (unsigned char *insn_ch, unsigned long *insn)
37 24 jeremybenn
{
38
  *insn =
39
    ((unsigned long) insn_ch[0] << 24) +
40
    ((unsigned long) insn_ch[1] << 16) +
41
    ((unsigned long) insn_ch[2] << 8) +
42
    ((unsigned long) insn_ch[3]);
43 225 jeremybenn
#if DEBUG
44
  printf ("find_bytes_big3: %x\n", *insn);
45
#endif
46
}
47 24 jeremybenn
 
48
static void
49 225 jeremybenn
find_bytes_little (unsigned char *insn_ch, unsigned long *insn)
50 24 jeremybenn
{
51
  *insn =
52
    ((unsigned long) insn_ch[3] << 24) +
53
    ((unsigned long) insn_ch[2] << 16) +
54
    ((unsigned long) insn_ch[1] << 8) +
55
    ((unsigned long) insn_ch[0]);
56 225 jeremybenn
}
57 24 jeremybenn
 
58 225 jeremybenn
typedef void (*find_byte_func_type) (unsigned char *, unsigned long *);
59 24 jeremybenn
 
60
static unsigned long
61 225 jeremybenn
or32_extract (char param_ch, char *enc_initial, unsigned long insn)
62 24 jeremybenn
{
63 225 jeremybenn
  char *enc;
64
  unsigned long ret = 0;
65
  int opc_pos = 0;
66
  int param_pos = 0;
67 24 jeremybenn
 
68
  for (enc = enc_initial; *enc != '\0'; enc++)
69 225 jeremybenn
    if (*enc == param_ch)
70
      {
71
        if (enc - 2 >= enc_initial && (*(enc - 2) == '0') && (*(enc - 1) == 'x'))
72
          continue;
73
        else
74
          param_pos++;
75
      }
76 24 jeremybenn
 
77 225 jeremybenn
#if DEBUG
78
  printf ("or32_extract: %c %x ", param_ch, param_pos);
79
#endif
80 24 jeremybenn
  opc_pos = 32;
81
 
82
  for (enc = enc_initial; *enc != '\0'; )
83 225 jeremybenn
    if ((*enc == '0') && (*(enc + 1) == 'x'))
84
      {
85
        opc_pos -= 4;
86 24 jeremybenn
 
87 225 jeremybenn
        if ((param_ch == '0') || (param_ch == '1'))
88
          {
89
            unsigned long tmp = strtoul (enc, NULL, 16);
90
#if DEBUG
91
            printf (" enc=%s, tmp=%x ", enc, tmp);
92
#endif
93
            if (param_ch == '0')
94
              tmp = 15 - tmp;
95
            ret |= tmp << opc_pos;
96
          }
97
        enc += 3;
98
      }
99
    else if ((*enc == '0') || (*enc == '1'))
100
      {
101
        opc_pos--;
102
        if (param_ch == *enc)
103 673 yannv
          ret |= 1UL << opc_pos;
104 225 jeremybenn
        enc++;
105
      }
106
    else if (*enc == param_ch)
107
      {
108
        opc_pos--;
109
        param_pos--;
110
#if DEBUG
111
        printf ("\n  ret=%x opc_pos=%x, param_pos=%x\n", ret, opc_pos, param_pos);
112
#endif
113
        ret += ((insn >> opc_pos) & 0x1) << param_pos;
114 24 jeremybenn
 
115 225 jeremybenn
        if (!param_pos
116
            && letter_signed (param_ch)
117
            && ret >> (letter_range (param_ch) - 1))
118
          {
119
#if DEBUG
120
            printf ("\n  ret=%x opc_pos=%x, param_pos=%x\n",
121
                    ret, opc_pos, param_pos);
122
#endif
123 673 yannv
            ret |= -1L << letter_range(param_ch);
124 225 jeremybenn
#if DEBUG
125
            printf ("\n  after conversion to signed: ret=%x\n", ret);
126
#endif
127 24 jeremybenn
          }
128 225 jeremybenn
        enc++;
129
      }
130
    else if (ISALPHA (*enc))
131
      {
132
        opc_pos--;
133
        enc++;
134
      }
135
    else if (*enc == '-')
136
      {
137
        opc_pos--;
138
        enc++;
139
      }
140
    else
141
      enc++;
142 24 jeremybenn
 
143 225 jeremybenn
#if DEBUG
144
  printf ("ret=%x\n", ret);
145
#endif
146 24 jeremybenn
  return ret;
147 225 jeremybenn
}
148 24 jeremybenn
 
149
static int
150
or32_opcode_match (unsigned long insn, char *encoding)
151
{
152
  unsigned long ones, zeros;
153
 
154 225 jeremybenn
#if DEBUG
155
  printf ("or32_opcode_match: %.8lx\n", insn);
156
#endif    
157 24 jeremybenn
  ones  = or32_extract ('1', encoding, insn);
158
  zeros = or32_extract ('0', encoding, insn);
159 225 jeremybenn
 
160
#if DEBUG
161
  printf ("ones: %x \n", ones);
162
  printf ("zeros: %x \n", zeros);
163
#endif
164 24 jeremybenn
  if ((insn & ones) != ones)
165
    {
166 225 jeremybenn
#if DEBUG
167
      printf ("ret1\n");
168
#endif
169 24 jeremybenn
      return 0;
170
    }
171
 
172
  if ((~insn & zeros) != zeros)
173
    {
174 225 jeremybenn
#if DEBUG
175
      printf ("ret2\n");
176
#endif
177 24 jeremybenn
      return 0;
178
    }
179
 
180 225 jeremybenn
#if DEBUG
181
  printf ("ret3\n");
182
#endif
183 24 jeremybenn
  return 1;
184 225 jeremybenn
}
185 24 jeremybenn
 
186 225 jeremybenn
/* Print register to INFO->STREAM. Used only by print_insn.  */
187 24 jeremybenn
 
188
static void
189
or32_print_register (char param_ch,
190
                     char *encoding,
191
                     unsigned long insn,
192
                     struct disassemble_info *info)
193
{
194
  int regnum = or32_extract (param_ch, encoding, insn);
195
 
196 225 jeremybenn
#if DEBUG
197
  printf ("or32_print_register: %c, %s, %x\n", param_ch, encoding, insn);
198
#endif  
199
  if (param_ch == 'A')
200
    (*info->fprintf_func) (info->stream, "r%d", regnum);
201
  else if (param_ch == 'B')
202
    (*info->fprintf_func) (info->stream, "r%d", regnum);
203
  else if (param_ch == 'D')
204
    (*info->fprintf_func) (info->stream, "r%d", regnum);
205
  else if (regnum < 16)
206
    (*info->fprintf_func) (info->stream, "r%d", regnum);
207
  else if (regnum < 32)
208
    (*info->fprintf_func) (info->stream, "r%d", regnum-16);
209
  else
210
    (*info->fprintf_func) (info->stream, "X%d", regnum);
211
}
212 24 jeremybenn
 
213
/* Print immediate to INFO->STREAM. Used only by print_insn.  */
214
 
215
static void
216 225 jeremybenn
or32_print_immediate (char param_ch,
217
                      char *encoding,
218
                      unsigned long insn,
219 24 jeremybenn
                      struct disassemble_info *info)
220
{
221
  int imm = or32_extract(param_ch, encoding, insn);
222
 
223 225 jeremybenn
  if (letter_signed(param_ch))
224
    (*info->fprintf_func) (info->stream, "0x%x", imm);
225
/*    (*info->fprintf_func) (info->stream, "%d", imm); */
226 24 jeremybenn
  else
227 225 jeremybenn
    (*info->fprintf_func) (info->stream, "0x%x", imm);
228
}
229 24 jeremybenn
 
230 225 jeremybenn
/* Print one instruction from MEMADDR on INFO->STREAM.
231
   Return the size of the instruction (always 4 on or32).  */
232 24 jeremybenn
 
233
static int
234 225 jeremybenn
print_insn (bfd_vma memaddr, struct disassemble_info *info)
235 24 jeremybenn
{
236
  /* The raw instruction.  */
237
  unsigned char insn_ch[4];
238
  /* Address. Will be sign extened 27-bit.  */
239
  unsigned long addr;
240
  /* The four bytes of the instruction.  */
241
  unsigned long insn;
242
  find_byte_func_type find_byte_func = (find_byte_func_type) info->private_data;
243 225 jeremybenn
  struct or32_opcode const * opcode;
244 24 jeremybenn
 
245 225 jeremybenn
  {
246
    int status =
247
      (*info->read_memory_func) (memaddr, (bfd_byte *) &insn_ch[0], 4, info);
248 24 jeremybenn
 
249 225 jeremybenn
    if (status != 0)
250
      {
251
        (*info->memory_error_func) (status, memaddr, info);
252
        return -1;
253
      }
254
  }
255 24 jeremybenn
 
256
  (*find_byte_func) (&insn_ch[0], &insn);
257
 
258
  for (opcode = &or32_opcodes[0];
259
       opcode < &or32_opcodes[or32_num_opcodes];
260
       ++opcode)
261
    {
262
      if (or32_opcode_match (insn, opcode->encoding))
263
        {
264
          char *s;
265
 
266 225 jeremybenn
          (*info->fprintf_func) (info->stream, "%s ", opcode->name);
267 24 jeremybenn
 
268
          for (s = opcode->args; *s != '\0'; ++s)
269
            {
270
              switch (*s)
271
                {
272
                case '\0':
273
                  return 4;
274
 
275
                case 'r':
276
                  or32_print_register (*++s, opcode->encoding, insn, info);
277
                  break;
278
 
279 225 jeremybenn
                case 'N':
280
                  addr = or32_extract ('N', opcode->encoding, insn) << 2;
281 24 jeremybenn
 
282 225 jeremybenn
                  /* Calulate the correct address.  */
283
                  addr = memaddr + EXTEND28 (addr);
284 24 jeremybenn
 
285
                  (*info->print_address_func)
286
                    (addr, info);
287
                  break;
288
 
289
                default:
290
                  if (strchr (opcode->encoding, *s))
291 225 jeremybenn
                    or32_print_immediate (*s, opcode->encoding, insn, info);
292 24 jeremybenn
                  else
293 225 jeremybenn
                    (*info->fprintf_func) (info->stream, "%c", *s);
294
                }
295 24 jeremybenn
            }
296
 
297
          return 4;
298
        }
299
    }
300
 
301
  /* This used to be %8x for binutils.  */
302 225 jeremybenn
  (*info->fprintf_func)
303
    (info->stream, ".word 0x%08lx", insn);
304 24 jeremybenn
  return 4;
305 225 jeremybenn
}
306 24 jeremybenn
 
307 225 jeremybenn
/* Disassemble a big-endian or32 instruction.  */
308 24 jeremybenn
 
309
int
310 225 jeremybenn
print_insn_big_or32 (bfd_vma memaddr, struct disassemble_info *info)
311 24 jeremybenn
{
312
  info->private_data = find_bytes_big;
313
 
314
  return print_insn (memaddr, info);
315 225 jeremybenn
}
316 24 jeremybenn
 
317 225 jeremybenn
/* Disassemble a little-endian or32 instruction.  */
318 24 jeremybenn
 
319
int
320 225 jeremybenn
print_insn_little_or32 (bfd_vma memaddr, struct disassemble_info *info)
321 24 jeremybenn
{
322
  info->private_data = find_bytes_little;
323
  return print_insn (memaddr, info);
324 225 jeremybenn
}

powered by: WebSVN 2.1.0

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