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

Subversion Repositories open8_urisc

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

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

Line No. Rev Author Line
1 163 khays
/* Disassembler code for Renesas RL78.
2
   Copyright 2011 Free Software Foundation, Inc.
3
   Contributed by Red Hat.
4
   Written by DJ Delorie.
5
 
6
   This file is part of the GNU opcodes library.
7
 
8
   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
   any later version.
12
 
13
   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
 
18
   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
 
23
#include <stdio.h>
24
 
25
#include "bfd.h"
26
#include "dis-asm.h"
27
#include "opcode/rl78.h"
28
 
29
#define DEBUG_SEMANTICS 0
30
 
31
typedef struct
32
{
33
  bfd_vma pc;
34
  disassemble_info * dis;
35
} RL78_Data;
36
 
37
static int
38
rl78_get_byte (void * vdata)
39
{
40
  bfd_byte buf[1];
41
  RL78_Data *rl78_data = (RL78_Data *) vdata;
42
 
43
  rl78_data->dis->read_memory_func (rl78_data->pc,
44
                                  buf,
45
                                  1,
46
                                  rl78_data->dis);
47
 
48
  rl78_data->pc ++;
49
  return buf[0];
50
}
51
 
52
static char const *
53
register_names[] =
54
{
55
  "",
56
  "x", "a", "c", "b", "e", "d", "l", "h",
57
  "ax", "bc", "de", "hl",
58
  "sp", "psw", "cs", "es", "pmc", "mem"
59
};
60
 
61
static char const *
62
condition_names[] =
63
{
64
  "t", "f", "c", "nc", "h", "nh", "z", "nz"
65
};
66
 
67
static int
68
indirect_type (int t)
69
{
70
  switch (t)
71
    {
72
    case RL78_Operand_Indirect:
73
    case RL78_Operand_BitIndirect:
74
    case RL78_Operand_PostInc:
75
    case RL78_Operand_PreDec:
76
      return 1;
77
    default:
78
      return 0;
79
    }
80
}
81
 
82
int
83
print_insn_rl78 (bfd_vma addr, disassemble_info * dis)
84
{
85
  int rv;
86
  RL78_Data rl78_data;
87
  RL78_Opcode_Decoded opcode;
88
  const char * s;
89
#if DEBUG_SEMANTICS
90
  static char buf[200];
91
#endif
92
 
93
  rl78_data.pc = addr;
94
  rl78_data.dis = dis;
95
 
96
  rv = rl78_decode_opcode (addr, &opcode, rl78_get_byte, &rl78_data);
97
 
98
  dis->bytes_per_line = 10;
99
 
100
#define PR (dis->fprintf_func)
101
#define PS (dis->stream)
102
#define PC(c) PR (PS, "%c", c)
103
 
104
  s = opcode.syntax;
105
 
106
#if DEBUG_SEMANTICS
107
 
108
  switch (opcode.id)
109
    {
110
    case RLO_unknown: s = "uknown"; break;
111
    case RLO_add: s = "add: %e0%0 += %e1%1"; break;
112
    case RLO_addc: s = "addc: %e0%0 += %e1%1 + CY"; break;
113
    case RLO_and: s = "and: %e0%0 &= %e1%1"; break;
114
    case RLO_branch: s = "branch: pc = %e0%0"; break;
115
    case RLO_branch_cond: s = "branch_cond: pc = %e0%0 if %c1 / %e1%1"; break;
116
    case RLO_branch_cond_clear: s = "branch_cond_clear: pc = %e0%0 if %c1 / %e1%1, %e1%1 = 0"; break;
117
    case RLO_call: s = "call: pc = %e1%0"; break;
118
    case RLO_cmp: s = "cmp: %e0%0 - %e1%1"; break;
119
    case RLO_mov: s = "mov: %e0%0 = %e1%1"; break;
120
    case RLO_or: s = "or: %e0%0 |= %e1%1"; break;
121
    case RLO_rol: s = "rol: %e0%0 <<= %e1%1"; break;
122
    case RLO_rolc: s = "rol: %e0%0 <<= %e1%1,CY"; break;
123
    case RLO_ror: s = "ror: %e0%0 >>= %e1%1"; break;
124
    case RLO_rorc: s = "ror: %e0%0 >>= %e1%1,CY"; break;
125
    case RLO_sar: s = "sar: %e0%0 >>= %e1%1 signed"; break;
126
    case RLO_sel: s = "sel: rb = %1"; break;
127
    case RLO_shr: s = "shr: %e0%0 >>= %e1%1 unsigned"; break;
128
    case RLO_shl: s = "shl: %e0%0 <<= %e1%1"; break;
129
    case RLO_skip: s = "skip: if %c1"; break;
130
    case RLO_sub: s = "sub: %e0%0 -= %e1%1"; break;
131
    case RLO_subc: s = "subc: %e0%0 -= %e1%1 - CY"; break;
132
    case RLO_xch: s = "xch: %e0%0 <-> %e1%1"; break;
133
    case RLO_xor: s = "xor: %e0%0 ^= %e1%1"; break;
134
    }
135
 
136
  sprintf(buf, "%s%%W%%f\t\033[32m%s\033[0m", s, opcode.syntax);
137
  s = buf;
138
 
139
#endif
140
 
141
  for (; *s; s++)
142
    {
143
      if (*s != '%')
144
        {
145
          PC (*s);
146
        }
147
      else
148
        {
149
          RL78_Opcode_Operand * oper;
150
          int do_hex = 0;
151
          int do_addr = 0;
152
          int do_es = 0;
153
          int do_sfr = 0;
154
          int do_cond = 0;
155
          int do_bang = 0;
156
 
157
          s ++;
158
 
159
          if (*s == 'x')
160
            {
161
              do_hex = 1;
162
              s++;
163
            }
164
          if (*s == '!')
165
            {
166
              do_bang = 1;
167
              s++;
168
            }
169
          if (*s == 'e')
170
            {
171
              do_es = 1;
172
              s++;
173
            }
174
          if (*s == 'a')
175
            {
176
              do_addr = 1;
177
              s++;
178
            }
179
          if (*s == 's')
180
            {
181
              do_sfr = 1;
182
              s++;
183
            }
184
          if (*s == 'c')
185
            {
186
              do_cond = 1;
187
              s++;
188
            }
189
 
190
          switch (*s)
191
            {
192
            case '%':
193
              PC ('%');
194
              break;
195
 
196
#if DEBUG_SEMANTICS
197
 
198
            case 'W':
199
              if (opcode.size == RL78_Word)
200
                PR (PS, " \033[33mW\033[0m");
201
              break;
202
 
203
            case 'f':
204
              if (opcode.flags)
205
                {
206
                  char *comma = "";
207
                  PR (PS, "  \033[35m");
208
 
209
                  if (opcode.flags & RL78_PSW_Z)
210
                    { PR (PS, "Z"); comma = ","; }
211
                  if (opcode.flags & RL78_PSW_AC)
212
                    { PR (PS, "%sAC", comma); comma = ","; }
213
                  if (opcode.flags & RL78_PSW_CY)
214
                    { PR (PS, "%sCY", comma); comma = ","; }
215
                  PR (PS, "\033[0m");
216
                }
217
              break;
218
 
219
#endif
220
 
221
            case '0':
222
            case '1':
223
              oper = opcode.op + *s - '0';
224
              if (do_bang)
225
                PC ('!');
226
 
227
              if (do_es)
228
                {
229
                  if (oper->use_es && indirect_type (oper->type))
230
                    PR (PS, "es:");
231
                }
232
 
233
              else if (do_cond)
234
                {
235
                  PR (PS, "%s", condition_names[oper->condition]);
236
                }
237
 
238
              else
239
                switch (oper->type)
240
                  {
241
                  case RL78_Operand_Immediate:
242
                    if (do_addr)
243
                      dis->print_address_func (oper->addend, dis);
244
                    else if (do_hex
245
                             || oper->addend > 999
246
                             || oper->addend < -999)
247
                      PR (PS, "%#x", oper->addend);
248
                    else
249
                      PR (PS, "%d", oper->addend);
250
                    break;
251
 
252
                  case RL78_Operand_Register:
253
                    PR (PS, "%s", register_names[oper->reg]);
254
                    break;
255
 
256
                  case RL78_Operand_Bit:
257
                    PR (PS, "%s.%d", register_names[oper->reg], oper->bit_number);
258
                    break;
259
 
260
                  case RL78_Operand_Indirect:
261
                  case RL78_Operand_BitIndirect:
262
                    switch (oper->reg)
263
                      {
264
                      case RL78_Reg_None:
265
                        if (oper->addend == 0xffffa && do_sfr && opcode.size == RL78_Byte)
266
                          PR (PS, "psw");
267
                        else if (oper->addend == 0xffff8 && do_sfr && opcode.size == RL78_Word)
268
                          PR (PS, "sp");
269
                        else if (oper->addend >= 0xffe20)
270
                          PR (PS, "%#x", oper->addend);
271
                        else
272
                          dis->print_address_func (oper->addend, dis);
273
                        break;
274
 
275
                      case RL78_Reg_B:
276
                      case RL78_Reg_C:
277
                      case RL78_Reg_BC:
278
                        PR (PS, "%d[%s]", oper->addend, register_names[oper->reg]);
279
                        break;
280
 
281
                      default:
282
                        PR (PS, "[%s", register_names[oper->reg]);
283
                        if (oper->reg2 != RL78_Reg_None)
284
                          PR (PS, "+%s", register_names[oper->reg2]);
285
                        if (oper->addend)
286
                          PR (PS, "+%d", oper->addend);
287
                        PC (']');
288
                        break;
289
 
290
                      }
291
                    if (oper->type == RL78_Operand_BitIndirect)
292
                      PR (PS, ".%d", oper->bit_number);
293
                    break;
294
 
295
#if DEBUG_SEMANTICS
296
                    /* Shouldn't happen - push and pop don't print
297
                       [SP] directly.  But we *do* use them for
298
                       semantic debugging.  */
299
                  case RL78_Operand_PostInc:
300
                    PR (PS, "[%s++]", register_names[oper->reg]);
301
                    break;
302
                  case RL78_Operand_PreDec:
303
                    PR (PS, "[--%s]", register_names[oper->reg]);
304
                    break;
305
#endif
306
 
307
                  default:
308
                    /* If we ever print this, that means the
309
                       programmer tried to print an operand with a
310
                       type we don't expect.  Print the line and
311
                       operand number from rl78-decode.opc for
312
                       them.  */
313
                    PR (PS, "???%d.%d", opcode.lineno, *s - '0');
314
                    break;
315
                  }
316
            }
317
        }
318
    }
319
 
320
#if DEBUG_SEMANTICS
321
 
322
  PR (PS, "\t\033[34m(line %d)\033[0m", opcode.lineno);
323
 
324
#endif
325
 
326
  return rv;
327
}

powered by: WebSVN 2.1.0

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