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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [opcodes/] [or32-dis.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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