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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [opcodes/] [m68hc11-dis.c] - Blame information for rev 247

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

Line No. Rev Author Line
1 205 julius
/* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly
2
   Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007
3
   Free Software Foundation, Inc.
4
   Written by Stephane Carrez (stcarrez@nerim.fr)
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 "ansidecl.h"
26
#include "opcode/m68hc11.h"
27
#include "dis-asm.h"
28
 
29
#define PC_REGNUM 3
30
 
31
static const char *const reg_name[] = {
32
  "X", "Y", "SP", "PC"
33
};
34
 
35
static const char *const reg_src_table[] = {
36
  "A", "B", "CCR", "TMP3", "D", "X", "Y", "SP"
37
};
38
 
39
static const char *const reg_dst_table[] = {
40
  "A", "B", "CCR", "TMP2", "D", "X", "Y", "SP"
41
};
42
 
43
#define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4)
44
 
45
/* Prototypes for local functions.  */
46
static int read_memory (bfd_vma, bfd_byte *, int, struct disassemble_info *);
47
static int print_indexed_operand (bfd_vma, struct disassemble_info *,
48
                                  int*, int, int, bfd_vma);
49
static int print_insn (bfd_vma, struct disassemble_info *, int);
50
 
51
static int
52
read_memory (bfd_vma memaddr, bfd_byte* buffer, int size,
53
             struct disassemble_info* info)
54
{
55
  int status;
56
 
57
  /* Get first byte.  Only one at a time because we don't know the
58
     size of the insn.  */
59
  status = (*info->read_memory_func) (memaddr, buffer, size, info);
60
  if (status != 0)
61
    {
62
      (*info->memory_error_func) (status, memaddr, info);
63
      return -1;
64
    }
65
  return 0;
66
}
67
 
68
 
69
/* Read the 68HC12 indexed operand byte and print the corresponding mode.
70
   Returns the number of bytes read or -1 if failure.  */
71
static int
72
print_indexed_operand (bfd_vma memaddr, struct disassemble_info* info,
73
                       int* indirect, int mov_insn, int pc_offset,
74
                       bfd_vma endaddr)
75
{
76
  bfd_byte buffer[4];
77
  int reg;
78
  int status;
79
  short sval;
80
  int pos = 1;
81
 
82
  if (indirect)
83
    *indirect = 0;
84
 
85
  status = read_memory (memaddr, &buffer[0], 1, info);
86
  if (status != 0)
87
    {
88
      return status;
89
    }
90
 
91
  /* n,r with 5-bits signed constant.  */
92
  if ((buffer[0] & 0x20) == 0)
93
    {
94
      reg = (buffer[0] >> 6) & 3;
95
      sval = (buffer[0] & 0x1f);
96
      if (sval & 0x10)
97
        sval |= 0xfff0;
98
      /* 68HC12 requires an adjustment for movb/movw pc relative modes.  */
99
      if (reg == PC_REGNUM && info->mach == bfd_mach_m6812 && mov_insn)
100
        sval += pc_offset;
101
      (*info->fprintf_func) (info->stream, "%d,%s",
102
                             (int) sval, reg_name[reg]);
103
 
104
      if (reg == PC_REGNUM)
105
        {
106
          (* info->fprintf_func) (info->stream, " {");
107
          (* info->print_address_func) (endaddr + sval, info);
108
          (* info->fprintf_func) (info->stream, "}");
109
        }
110
    }
111
 
112
  /* Auto pre/post increment/decrement.  */
113
  else if ((buffer[0] & 0xc0) != 0xc0)
114
    {
115
      const char *mode;
116
 
117
      reg = (buffer[0] >> 6) & 3;
118
      sval = (buffer[0] & 0x0f);
119
      if (sval & 0x8)
120
        {
121
          sval |= 0xfff0;
122
          sval = -sval;
123
          mode = "-";
124
        }
125
      else
126
        {
127
          sval = sval + 1;
128
          mode = "+";
129
        }
130
      (*info->fprintf_func) (info->stream, "%d,%s%s%s",
131
                             (int) sval,
132
                             (buffer[0] & 0x10 ? "" : mode),
133
                             reg_name[reg], (buffer[0] & 0x10 ? mode : ""));
134
    }
135
 
136
  /* [n,r] 16-bits offset indexed indirect.  */
137
  else if ((buffer[0] & 0x07) == 3)
138
    {
139
      if (mov_insn)
140
        {
141
          (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>",
142
                                 buffer[0] & 0x0ff);
143
          return 0;
144
        }
145
      reg = (buffer[0] >> 3) & 0x03;
146
      status = read_memory (memaddr + pos, &buffer[0], 2, info);
147
      if (status != 0)
148
        {
149
          return status;
150
        }
151
 
152
      pos += 2;
153
      sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
154
      (*info->fprintf_func) (info->stream, "[%u,%s]",
155
                             sval & 0x0ffff, reg_name[reg]);
156
      if (indirect)
157
        *indirect = 1;
158
    }
159
 
160
  /* n,r with 9 and 16 bit signed constant.  */
161
  else if ((buffer[0] & 0x4) == 0)
162
    {
163
      if (mov_insn)
164
        {
165
          (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>",
166
                                 buffer[0] & 0x0ff);
167
          return 0;
168
        }
169
      reg = (buffer[0] >> 3) & 0x03;
170
      status = read_memory (memaddr + pos,
171
                            &buffer[1], (buffer[0] & 0x2 ? 2 : 1), info);
172
      if (status != 0)
173
        {
174
          return status;
175
        }
176
      if (buffer[0] & 2)
177
        {
178
          sval = ((buffer[1] << 8) | (buffer[2] & 0x0FF));
179
          sval &= 0x0FFFF;
180
          pos += 2;
181
          endaddr += 2;
182
        }
183
      else
184
        {
185
          sval = buffer[1] & 0x00ff;
186
          if (buffer[0] & 0x01)
187
            sval |= 0xff00;
188
          pos++;
189
          endaddr++;
190
        }
191
      (*info->fprintf_func) (info->stream, "%d,%s",
192
                             (int) sval, reg_name[reg]);
193
      if (reg == PC_REGNUM)
194
        {
195
          (* info->fprintf_func) (info->stream, " {");
196
          (* info->print_address_func) (endaddr + sval, info);
197
          (* info->fprintf_func) (info->stream, "}");
198
        }
199
    }
200
  else
201
    {
202
      reg = (buffer[0] >> 3) & 0x03;
203
      switch (buffer[0] & 3)
204
        {
205
        case 0:
206
          (*info->fprintf_func) (info->stream, "A,%s", reg_name[reg]);
207
          break;
208
        case 1:
209
          (*info->fprintf_func) (info->stream, "B,%s", reg_name[reg]);
210
          break;
211
        case 2:
212
          (*info->fprintf_func) (info->stream, "D,%s", reg_name[reg]);
213
          break;
214
        case 3:
215
        default:
216
          (*info->fprintf_func) (info->stream, "[D,%s]", reg_name[reg]);
217
          if (indirect)
218
            *indirect = 1;
219
          break;
220
        }
221
    }
222
 
223
  return pos;
224
}
225
 
226
/* Disassemble one instruction at address 'memaddr'.  Returns the number
227
   of bytes used by that instruction.  */
228
static int
229
print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch)
230
{
231
  int status;
232
  bfd_byte buffer[4];
233
  unsigned char code;
234
  long format, pos, i;
235
  short sval;
236
  const struct m68hc11_opcode *opcode;
237
 
238
  /* Get first byte.  Only one at a time because we don't know the
239
     size of the insn.  */
240
  status = read_memory (memaddr, buffer, 1, info);
241
  if (status != 0)
242
    {
243
      return status;
244
    }
245
 
246
  format = 0;
247
  code = buffer[0];
248
  pos = 0;
249
 
250
  /* Look for page2,3,4 opcodes.  */
251
  if (code == M6811_OPCODE_PAGE2)
252
    {
253
      pos++;
254
      format = M6811_OP_PAGE2;
255
    }
256
  else if (code == M6811_OPCODE_PAGE3 && arch == cpu6811)
257
    {
258
      pos++;
259
      format = M6811_OP_PAGE3;
260
    }
261
  else if (code == M6811_OPCODE_PAGE4 && arch == cpu6811)
262
    {
263
      pos++;
264
      format = M6811_OP_PAGE4;
265
    }
266
 
267
  /* We are in page2,3,4; get the real opcode.  */
268
  if (pos == 1)
269
    {
270
      status = read_memory (memaddr + pos, &buffer[1], 1, info);
271
      if (status != 0)
272
        {
273
          return status;
274
        }
275
      code = buffer[1];
276
    }
277
 
278
 
279
  /* Look first for a 68HC12 alias.  All of them are 2-bytes long and
280
     in page 1.  There is no operand to print.  We read the second byte
281
     only when we have a possible match.  */
282
  if ((arch & cpu6812) && format == 0)
283
    {
284
      int must_read = 1;
285
 
286
      /* Walk the alias table to find a code1+code2 match.  */
287
      for (i = 0; i < m68hc12_num_alias; i++)
288
        {
289
          if (m68hc12_alias[i].code1 == code)
290
            {
291
              if (must_read)
292
                {
293
                  status = read_memory (memaddr + pos + 1,
294
                                        &buffer[1], 1, info);
295
                  if (status != 0)
296
                    break;
297
 
298
                  must_read = 1;
299
                }
300
              if (m68hc12_alias[i].code2 == (unsigned char) buffer[1])
301
                {
302
                  (*info->fprintf_func) (info->stream, "%s",
303
                                         m68hc12_alias[i].name);
304
                  return 2;
305
                }
306
            }
307
        }
308
    }
309
 
310
  pos++;
311
 
312
  /* Scan the opcode table until we find the opcode
313
     with the corresponding page.  */
314
  opcode = m68hc11_opcodes;
315
  for (i = 0; i < m68hc11_num_opcodes; i++, opcode++)
316
    {
317
      int offset;
318
      int pc_src_offset;
319
      int pc_dst_offset = 0;
320
 
321
      if ((opcode->arch & arch) == 0)
322
        continue;
323
      if (opcode->opcode != code)
324
        continue;
325
      if ((opcode->format & OP_PAGE_MASK) != format)
326
        continue;
327
 
328
      if (opcode->format & M6812_OP_REG)
329
        {
330
          int j;
331
          int is_jump;
332
 
333
          if (opcode->format & M6811_OP_JUMP_REL)
334
            is_jump = 1;
335
          else
336
            is_jump = 0;
337
 
338
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
339
          if (status != 0)
340
            {
341
              return status;
342
            }
343
          for (j = 0; i + j < m68hc11_num_opcodes; j++)
344
            {
345
              if ((opcode[j].arch & arch) == 0)
346
                continue;
347
              if (opcode[j].opcode != code)
348
                continue;
349
              if (is_jump)
350
                {
351
                  if (!(opcode[j].format & M6811_OP_JUMP_REL))
352
                    continue;
353
 
354
                  if ((opcode[j].format & M6812_OP_IBCC_MARKER)
355
                      && (buffer[0] & 0xc0) != 0x80)
356
                    continue;
357
                  if ((opcode[j].format & M6812_OP_TBCC_MARKER)
358
                      && (buffer[0] & 0xc0) != 0x40)
359
                    continue;
360
                  if ((opcode[j].format & M6812_OP_DBCC_MARKER)
361
                      && (buffer[0] & 0xc0) != 0)
362
                    continue;
363
                  if ((opcode[j].format & M6812_OP_EQ_MARKER)
364
                      && (buffer[0] & 0x20) == 0)
365
                    break;
366
                  if (!(opcode[j].format & M6812_OP_EQ_MARKER)
367
                      && (buffer[0] & 0x20) != 0)
368
                    break;
369
                  continue;
370
                }
371
              if (opcode[j].format & M6812_OP_EXG_MARKER && buffer[0] & 0x80)
372
                break;
373
              if ((opcode[j].format & M6812_OP_SEX_MARKER)
374
                  && (((buffer[0] & 0x07) >= 3 && (buffer[0] & 7) <= 7))
375
                  && ((buffer[0] & 0x0f0) <= 0x20))
376
                break;
377
              if (opcode[j].format & M6812_OP_TFR_MARKER
378
                  && !(buffer[0] & 0x80))
379
                break;
380
            }
381
          if (i + j < m68hc11_num_opcodes)
382
            opcode = &opcode[j];
383
        }
384
 
385
      /* We have found the opcode.  Extract the operand and print it.  */
386
      (*info->fprintf_func) (info->stream, "%s", opcode->name);
387
 
388
      format = opcode->format;
389
      if (format & (M6811_OP_MASK | M6811_OP_BITMASK
390
                    | M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16))
391
        {
392
          (*info->fprintf_func) (info->stream, "\t");
393
        }
394
 
395
      /* The movb and movw must be handled in a special way...
396
         The source constant 'ii' is not always at the same place.
397
         This is the same for the destination for the post-indexed byte.
398
         The 'offset' is used to do the appropriate correction.
399
 
400
                                   offset          offset
401
                              for constant     for destination
402
         movb   18 OB ii hh ll       0          0
403
                18 08 xb ii          1          -1
404
                18 0C hh ll hh ll    0          0
405
                18 09 xb hh ll       1          -1
406
                18 0D xb hh ll       0          0
407
                18 0A xb xb          0          0
408
 
409
         movw   18 03 jj kk hh ll    0          0
410
                18 00 xb jj kk       1          -1
411
                18 04 hh ll hh ll    0          0
412
                18 01 xb hh ll       1          -1
413
                18 05 xb hh ll       0          0
414
                18 02 xb xb          0          0
415
 
416
         After the source operand is read, the position 'pos' is incremented
417
         this explains the negative offset for destination.
418
 
419
         movb/movw above are the only instructions with this matching
420
         format.  */
421
      offset = ((format & M6812_OP_IDX_P2)
422
                && (format & (M6811_OP_IMM8 | M6811_OP_IMM16 |
423
                              M6811_OP_IND16)));
424
 
425
      /* Operand with one more byte: - immediate, offset,
426
         direct-low address.  */
427
      if (format &
428
          (M6811_OP_IMM8 | M6811_OP_IX | M6811_OP_IY | M6811_OP_DIRECT))
429
        {
430
          status = read_memory (memaddr + pos + offset, &buffer[0], 1, info);
431
          if (status != 0)
432
            {
433
              return status;
434
            }
435
 
436
          pos++;
437
 
438
          /* This movb/movw is special (see above).  */
439
          offset = -offset;
440
 
441
          pc_dst_offset = 2;
442
          if (format & M6811_OP_IMM8)
443
            {
444
              (*info->fprintf_func) (info->stream, "#%d", (int) buffer[0]);
445
              format &= ~M6811_OP_IMM8;
446
              /* Set PC destination offset.  */
447
              pc_dst_offset = 1;
448
            }
449
          else if (format & M6811_OP_IX)
450
            {
451
              /* Offsets are in range 0..255, print them unsigned.  */
452
              (*info->fprintf_func) (info->stream, "%u,x", buffer[0] & 0x0FF);
453
              format &= ~M6811_OP_IX;
454
            }
455
          else if (format & M6811_OP_IY)
456
            {
457
              (*info->fprintf_func) (info->stream, "%u,y", buffer[0] & 0x0FF);
458
              format &= ~M6811_OP_IY;
459
            }
460
          else if (format & M6811_OP_DIRECT)
461
            {
462
              (*info->fprintf_func) (info->stream, "*");
463
              (*info->print_address_func) (buffer[0] & 0x0FF, info);
464
              format &= ~M6811_OP_DIRECT;
465
            }
466
        }
467
 
468
#define M6812_DST_MOVE  (M6812_OP_IND16_P2 | M6812_OP_IDX_P2)
469
#define M6812_INDEXED_FLAGS (M6812_OP_IDX|M6812_OP_IDX_1|M6812_OP_IDX_2)
470
      /* Analyze the 68HC12 indexed byte.  */
471
      if (format & M6812_INDEXED_FLAGS)
472
        {
473
          int indirect;
474
          bfd_vma endaddr;
475
 
476
          endaddr = memaddr + pos + 1;
477
          if (format & M6811_OP_IND16)
478
            endaddr += 2;
479
          pc_src_offset = -1;
480
          pc_dst_offset = 1;
481
          status = print_indexed_operand (memaddr + pos, info, &indirect,
482
                                          (format & M6812_DST_MOVE),
483
                                          pc_src_offset, endaddr);
484
          if (status < 0)
485
            {
486
              return status;
487
            }
488
          pos += status;
489
 
490
          /* The indirect addressing mode of the call instruction does
491
             not need the page code.  */
492
          if ((format & M6812_OP_PAGE) && indirect)
493
            format &= ~M6812_OP_PAGE;
494
        }
495
 
496
      /* 68HC12 dbcc/ibcc/tbcc operands.  */
497
      if ((format & M6812_OP_REG) && (format & M6811_OP_JUMP_REL))
498
        {
499
          status = read_memory (memaddr + pos, &buffer[0], 2, info);
500
          if (status != 0)
501
            {
502
              return status;
503
            }
504
          (*info->fprintf_func) (info->stream, "%s,",
505
                                 reg_src_table[buffer[0] & 0x07]);
506
          sval = buffer[1] & 0x0ff;
507
          if (buffer[0] & 0x10)
508
            sval |= 0xff00;
509
 
510
          pos += 2;
511
          (*info->print_address_func) (memaddr + pos + sval, info);
512
          format &= ~(M6812_OP_REG | M6811_OP_JUMP_REL);
513
        }
514
      else if (format & (M6812_OP_REG | M6812_OP_REG_2))
515
        {
516
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
517
          if (status != 0)
518
            {
519
              return status;
520
            }
521
 
522
          pos++;
523
          (*info->fprintf_func) (info->stream, "%s,%s",
524
                                 reg_src_table[(buffer[0] >> 4) & 7],
525
                                 reg_dst_table[(buffer[0] & 7)]);
526
        }
527
 
528
      if (format & (M6811_OP_IMM16 | M6811_OP_IND16))
529
        {
530
          int val;
531
          bfd_vma addr;
532
          unsigned page = 0;
533
 
534
          status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
535
          if (status != 0)
536
            {
537
              return status;
538
            }
539
          if (format & M6812_OP_IDX_P2)
540
            offset = -2;
541
          else
542
            offset = 0;
543
          pos += 2;
544
 
545
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
546
          val &= 0x0FFFF;
547
          addr = val;
548
          pc_dst_offset = 2;
549
          if (format & M6812_OP_PAGE)
550
            {
551
              status = read_memory (memaddr + pos + offset, buffer, 1, info);
552
              if (status != 0)
553
                return status;
554
 
555
              page = (unsigned) buffer[0];
556
              if (addr >= M68HC12_BANK_BASE && addr < 0x0c000)
557
                addr = ((val - M68HC12_BANK_BASE)
558
                        | (page << M68HC12_BANK_SHIFT))
559
                   + M68HC12_BANK_VIRT;
560
            }
561
          else if ((arch & cpu6812)
562
                   && addr >= M68HC12_BANK_BASE && addr < 0x0c000)
563
             {
564
                int cur_page;
565
                bfd_vma vaddr;
566
 
567
                if (memaddr >= M68HC12_BANK_VIRT)
568
                   cur_page = ((memaddr - M68HC12_BANK_VIRT)
569
                               >> M68HC12_BANK_SHIFT);
570
                else
571
                   cur_page = 0;
572
 
573
                vaddr = ((addr - M68HC12_BANK_BASE)
574
                         + (cur_page << M68HC12_BANK_SHIFT))
575
                   + M68HC12_BANK_VIRT;
576
                if (!info->symbol_at_address_func (addr, info)
577
                    && info->symbol_at_address_func (vaddr, info))
578
                   addr = vaddr;
579
             }
580
          if (format & M6811_OP_IMM16)
581
            {
582
              format &= ~M6811_OP_IMM16;
583
              (*info->fprintf_func) (info->stream, "#");
584
            }
585
          else
586
            format &= ~M6811_OP_IND16;
587
 
588
          (*info->print_address_func) (addr, info);
589
          if (format & M6812_OP_PAGE)
590
            {
591
              (* info->fprintf_func) (info->stream, " {");
592
              (* info->print_address_func) (val, info);
593
              (* info->fprintf_func) (info->stream, ", %d}", page);
594
              format &= ~M6812_OP_PAGE;
595
              pos += 1;
596
            }
597
        }
598
 
599
      if (format & M6812_OP_IDX_P2)
600
        {
601
          (*info->fprintf_func) (info->stream, ", ");
602
          status = print_indexed_operand (memaddr + pos + offset, info,
603
                                          0, 1, pc_dst_offset,
604
                                          memaddr + pos + offset + 1);
605
          if (status < 0)
606
            return status;
607
          pos += status;
608
        }
609
 
610
      if (format & M6812_OP_IND16_P2)
611
        {
612
          int val;
613
 
614
          (*info->fprintf_func) (info->stream, ", ");
615
 
616
          status = read_memory (memaddr + pos + offset, &buffer[0], 2, info);
617
          if (status != 0)
618
            {
619
              return status;
620
            }
621
          pos += 2;
622
 
623
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
624
          val &= 0x0FFFF;
625
          (*info->print_address_func) (val, info);
626
        }
627
 
628
      /* M6811_OP_BITMASK and M6811_OP_JUMP_REL must be treated separately
629
         and in that order.  The brset/brclr insn have a bitmask and then
630
         a relative branch offset.  */
631
      if (format & M6811_OP_BITMASK)
632
        {
633
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
634
          if (status != 0)
635
            {
636
              return status;
637
            }
638
          pos++;
639
          (*info->fprintf_func) (info->stream, " #$%02x%s",
640
                                 buffer[0] & 0x0FF,
641
                                 (format & M6811_OP_JUMP_REL ? " " : ""));
642
          format &= ~M6811_OP_BITMASK;
643
        }
644
      if (format & M6811_OP_JUMP_REL)
645
        {
646
          int val;
647
 
648
          status = read_memory (memaddr + pos, &buffer[0], 1, info);
649
          if (status != 0)
650
            {
651
              return status;
652
            }
653
 
654
          pos++;
655
          val = (buffer[0] & 0x80) ? buffer[0] | 0xFFFFFF00 : buffer[0];
656
          (*info->print_address_func) (memaddr + pos + val, info);
657
          format &= ~M6811_OP_JUMP_REL;
658
        }
659
      else if (format & M6812_OP_JUMP_REL16)
660
        {
661
          int val;
662
 
663
          status = read_memory (memaddr + pos, &buffer[0], 2, info);
664
          if (status != 0)
665
            {
666
              return status;
667
            }
668
 
669
          pos += 2;
670
          val = ((buffer[0] << 8) | (buffer[1] & 0x0FF));
671
          if (val & 0x8000)
672
            val |= 0xffff0000;
673
 
674
          (*info->print_address_func) (memaddr + pos + val, info);
675
          format &= ~M6812_OP_JUMP_REL16;
676
        }
677
 
678
      if (format & M6812_OP_PAGE)
679
        {
680
          int val;
681
 
682
          status = read_memory (memaddr + pos + offset, &buffer[0], 1, info);
683
          if (status != 0)
684
            {
685
              return status;
686
            }
687
          pos += 1;
688
 
689
          val = buffer[0] & 0x0ff;
690
          (*info->fprintf_func) (info->stream, ", %d", val);
691
        }
692
 
693
#ifdef DEBUG
694
      /* Consistency check.  'format' must be 0, so that we have handled
695
         all formats; and the computed size of the insn must match the
696
         opcode table content.  */
697
      if (format & ~(M6811_OP_PAGE4 | M6811_OP_PAGE3 | M6811_OP_PAGE2))
698
        {
699
          (*info->fprintf_func) (info->stream, "; Error, format: %lx", format);
700
        }
701
      if (pos != opcode->size)
702
        {
703
          (*info->fprintf_func) (info->stream, "; Error, size: %ld expect %d",
704
                                 pos, opcode->size);
705
        }
706
#endif
707
      return pos;
708
    }
709
 
710
  /* Opcode not recognized.  */
711
  if (format == M6811_OP_PAGE2 && arch & cpu6812
712
      && ((code >= 0x30 && code <= 0x39) || (code >= 0x40)))
713
    (*info->fprintf_func) (info->stream, "trap\t#%d", code & 0x0ff);
714
 
715
  else if (format == M6811_OP_PAGE2)
716
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
717
                           M6811_OPCODE_PAGE2, code);
718
  else if (format == M6811_OP_PAGE3)
719
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
720
                           M6811_OPCODE_PAGE3, code);
721
  else if (format == M6811_OP_PAGE4)
722
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x",
723
                           M6811_OPCODE_PAGE4, code);
724
  else
725
    (*info->fprintf_func) (info->stream, ".byte\t0x%02x", code);
726
 
727
  return pos;
728
}
729
 
730
/* Disassemble one instruction at address 'memaddr'.  Returns the number
731
   of bytes used by that instruction.  */
732
int
733
print_insn_m68hc11 (bfd_vma memaddr, struct disassemble_info* info)
734
{
735
  return print_insn (memaddr, info, cpu6811);
736
}
737
 
738
int
739
print_insn_m68hc12 (bfd_vma memaddr, struct disassemble_info* info)
740
{
741
  return print_insn (memaddr, info, cpu6812);
742
}

powered by: WebSVN 2.1.0

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