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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [gdb/] [m68hc11-tdep.c] - Blame information for rev 309

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

Line No. Rev Author Line
1 24 jeremybenn
/* Target-dependent code for Motorola 68HC11 & 68HC12
2
 
3
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008
4
   Free Software Foundation, Inc.
5
 
6
   Contributed by Stephane Carrez, stcarrez@nerim.fr
7
 
8
   This file is part of GDB.
9
 
10
   This program is free software; you can redistribute it and/or modify
11
   it under the terms of the GNU General Public License as published by
12
   the Free Software Foundation; either version 3 of the License, or
13
   (at your option) any later version.
14
 
15
   This program is distributed in the hope that it will be useful,
16
   but WITHOUT ANY WARRANTY; without even the implied warranty of
17
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
   GNU General Public License for more details.
19
 
20
   You should have received a copy of the GNU General Public License
21
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
22
 
23
 
24
#include "defs.h"
25
#include "frame.h"
26
#include "frame-unwind.h"
27
#include "frame-base.h"
28
#include "dwarf2-frame.h"
29
#include "trad-frame.h"
30
#include "symtab.h"
31
#include "gdbtypes.h"
32
#include "gdbcmd.h"
33
#include "gdbcore.h"
34
#include "gdb_string.h"
35
#include "value.h"
36
#include "inferior.h"
37
#include "dis-asm.h"  
38
#include "symfile.h"
39
#include "objfiles.h"
40
#include "arch-utils.h"
41
#include "regcache.h"
42
#include "reggroups.h"
43
 
44
#include "target.h"
45
#include "opcode/m68hc11.h"
46
#include "elf/m68hc11.h"
47
#include "elf-bfd.h"
48
 
49
/* Macros for setting and testing a bit in a minimal symbol.
50
   For 68HC11/68HC12 we have two flags that tell which return
51
   type the function is using.  This is used for prologue and frame
52
   analysis to compute correct stack frame layout.
53
 
54
   The MSB of the minimal symbol's "info" field is used for this purpose.
55
 
56
   MSYMBOL_SET_RTC      Actually sets the "RTC" bit.
57
   MSYMBOL_SET_RTI      Actually sets the "RTI" bit.
58
   MSYMBOL_IS_RTC       Tests the "RTC" bit in a minimal symbol.
59
   MSYMBOL_IS_RTI       Tests the "RTC" bit in a minimal symbol.  */
60
 
61
#define MSYMBOL_SET_RTC(msym)                                           \
62
        MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym))    \
63
                                        | 0x80000000)
64
 
65
#define MSYMBOL_SET_RTI(msym)                                           \
66
        MSYMBOL_INFO (msym) = (char *) (((long) MSYMBOL_INFO (msym))    \
67
                                        | 0x40000000)
68
 
69
#define MSYMBOL_IS_RTC(msym)                            \
70
        (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0)
71
 
72
#define MSYMBOL_IS_RTI(msym)                            \
73
        (((long) MSYMBOL_INFO (msym) & 0x40000000) != 0)
74
 
75
enum insn_return_kind {
76
  RETURN_RTS,
77
  RETURN_RTC,
78
  RETURN_RTI
79
};
80
 
81
 
82
/* Register numbers of various important registers.  */
83
 
84
#define HARD_X_REGNUM   0
85
#define HARD_D_REGNUM   1
86
#define HARD_Y_REGNUM   2
87
#define HARD_SP_REGNUM  3
88
#define HARD_PC_REGNUM  4
89
 
90
#define HARD_A_REGNUM   5
91
#define HARD_B_REGNUM   6
92
#define HARD_CCR_REGNUM 7
93
 
94
/* 68HC12 page number register.
95
   Note: to keep a compatibility with gcc register naming, we must
96
   not have to rename FP and other soft registers.  The page register
97
   is a real hard register and must therefore be counted by gdbarch_num_regs.
98
   For this it has the same number as Z register (which is not used).  */
99
#define HARD_PAGE_REGNUM 8
100
#define M68HC11_LAST_HARD_REG (HARD_PAGE_REGNUM)
101
 
102
/* Z is replaced by X or Y by gcc during machine reorg.
103
   ??? There is no way to get it and even know whether
104
   it's in X or Y or in ZS.  */
105
#define SOFT_Z_REGNUM        8
106
 
107
/* Soft registers.  These registers are special.  There are treated
108
   like normal hard registers by gcc and gdb (ie, within dwarf2 info).
109
   They are physically located in memory.  */
110
#define SOFT_FP_REGNUM       9
111
#define SOFT_TMP_REGNUM     10
112
#define SOFT_ZS_REGNUM      11
113
#define SOFT_XY_REGNUM      12
114
#define SOFT_UNUSED_REGNUM  13
115
#define SOFT_D1_REGNUM      14
116
#define SOFT_D32_REGNUM     (SOFT_D1_REGNUM+31)
117
#define M68HC11_MAX_SOFT_REGS 32
118
 
119
#define M68HC11_NUM_REGS        (8)
120
#define M68HC11_NUM_PSEUDO_REGS (M68HC11_MAX_SOFT_REGS+5)
121
#define M68HC11_ALL_REGS        (M68HC11_NUM_REGS+M68HC11_NUM_PSEUDO_REGS)
122
 
123
#define M68HC11_REG_SIZE    (2)
124
 
125
#define M68HC12_NUM_REGS        (9)
126
#define M68HC12_NUM_PSEUDO_REGS ((M68HC11_MAX_SOFT_REGS+5)+1-1)
127
#define M68HC12_HARD_PC_REGNUM  (SOFT_D32_REGNUM+1)
128
 
129
struct insn_sequence;
130
struct gdbarch_tdep
131
  {
132
    /* Stack pointer correction value.  For 68hc11, the stack pointer points
133
       to the next push location.  An offset of 1 must be applied to obtain
134
       the address where the last value is saved.  For 68hc12, the stack
135
       pointer points to the last value pushed.  No offset is necessary.  */
136
    int stack_correction;
137
 
138
    /* Description of instructions in the prologue.  */
139
    struct insn_sequence *prologue;
140
 
141
    /* True if the page memory bank register is available
142
       and must be used.  */
143
    int use_page_register;
144
 
145
    /* ELF flags for ABI.  */
146
    int elf_flags;
147
  };
148
 
149
#define STACK_CORRECTION(gdbarch) (gdbarch_tdep (gdbarch)->stack_correction)
150
#define USE_PAGE_REGISTER(gdbarch) (gdbarch_tdep (gdbarch)->use_page_register)
151
 
152
struct m68hc11_unwind_cache
153
{
154
  /* The previous frame's inner most stack address.  Used as this
155
     frame ID's stack_addr.  */
156
  CORE_ADDR prev_sp;
157
  /* The frame's base, optionally used by the high-level debug info.  */
158
  CORE_ADDR base;
159
  CORE_ADDR pc;
160
  int size;
161
  int prologue_type;
162
  CORE_ADDR return_pc;
163
  CORE_ADDR sp_offset;
164
  int frameless;
165
  enum insn_return_kind return_kind;
166
 
167
  /* Table indicating the location of each and every register.  */
168
  struct trad_frame_saved_reg *saved_regs;
169
};
170
 
171
/* Table of registers for 68HC11.  This includes the hard registers
172
   and the soft registers used by GCC.  */
173
static char *
174
m68hc11_register_names[] =
175
{
176
  "x",    "d",    "y",    "sp",   "pc",   "a",    "b",
177
  "ccr",  "page", "frame","tmp",  "zs",   "xy",   0,
178
  "d1",   "d2",   "d3",   "d4",   "d5",   "d6",   "d7",
179
  "d8",   "d9",   "d10",  "d11",  "d12",  "d13",  "d14",
180
  "d15",  "d16",  "d17",  "d18",  "d19",  "d20",  "d21",
181
  "d22",  "d23",  "d24",  "d25",  "d26",  "d27",  "d28",
182
  "d29",  "d30",  "d31",  "d32"
183
};
184
 
185
struct m68hc11_soft_reg
186
{
187
  const char *name;
188
  CORE_ADDR   addr;
189
};
190
 
191
static struct m68hc11_soft_reg soft_regs[M68HC11_ALL_REGS];
192
 
193
#define M68HC11_FP_ADDR soft_regs[SOFT_FP_REGNUM].addr
194
 
195
static int soft_min_addr;
196
static int soft_max_addr;
197
static int soft_reg_initialized = 0;
198
 
199
/* Look in the symbol table for the address of a pseudo register
200
   in memory.  If we don't find it, pretend the register is not used
201
   and not available.  */
202
static void
203
m68hc11_get_register_info (struct m68hc11_soft_reg *reg, const char *name)
204
{
205
  struct minimal_symbol *msymbol;
206
 
207
  msymbol = lookup_minimal_symbol (name, NULL, NULL);
208
  if (msymbol)
209
    {
210
      reg->addr = SYMBOL_VALUE_ADDRESS (msymbol);
211
      reg->name = xstrdup (name);
212
 
213
      /* Keep track of the address range for soft registers.  */
214
      if (reg->addr < (CORE_ADDR) soft_min_addr)
215
        soft_min_addr = reg->addr;
216
      if (reg->addr > (CORE_ADDR) soft_max_addr)
217
        soft_max_addr = reg->addr;
218
    }
219
  else
220
    {
221
      reg->name = 0;
222
      reg->addr = 0;
223
    }
224
}
225
 
226
/* Initialize the table of soft register addresses according
227
   to the symbol table.  */
228
  static void
229
m68hc11_initialize_register_info (void)
230
{
231
  int i;
232
 
233
  if (soft_reg_initialized)
234
    return;
235
 
236
  soft_min_addr = INT_MAX;
237
  soft_max_addr = 0;
238
  for (i = 0; i < M68HC11_ALL_REGS; i++)
239
    {
240
      soft_regs[i].name = 0;
241
    }
242
 
243
  m68hc11_get_register_info (&soft_regs[SOFT_FP_REGNUM], "_.frame");
244
  m68hc11_get_register_info (&soft_regs[SOFT_TMP_REGNUM], "_.tmp");
245
  m68hc11_get_register_info (&soft_regs[SOFT_ZS_REGNUM], "_.z");
246
  soft_regs[SOFT_Z_REGNUM] = soft_regs[SOFT_ZS_REGNUM];
247
  m68hc11_get_register_info (&soft_regs[SOFT_XY_REGNUM], "_.xy");
248
 
249
  for (i = SOFT_D1_REGNUM; i < M68HC11_MAX_SOFT_REGS; i++)
250
    {
251
      char buf[10];
252
 
253
      sprintf (buf, "_.d%d", i - SOFT_D1_REGNUM + 1);
254
      m68hc11_get_register_info (&soft_regs[i], buf);
255
    }
256
 
257
  if (soft_regs[SOFT_FP_REGNUM].name == 0)
258
    warning (_("No frame soft register found in the symbol table.\n"
259
               "Stack backtrace will not work."));
260
  soft_reg_initialized = 1;
261
}
262
 
263
/* Given an address in memory, return the soft register number if
264
   that address corresponds to a soft register.  Returns -1 if not.  */
265
static int
266
m68hc11_which_soft_register (CORE_ADDR addr)
267
{
268
  int i;
269
 
270
  if (addr < soft_min_addr || addr > soft_max_addr)
271
    return -1;
272
 
273
  for (i = SOFT_FP_REGNUM; i < M68HC11_ALL_REGS; i++)
274
    {
275
      if (soft_regs[i].name && soft_regs[i].addr == addr)
276
        return i;
277
    }
278
  return -1;
279
}
280
 
281
/* Fetch a pseudo register.  The 68hc11 soft registers are treated like
282
   pseudo registers.  They are located in memory.  Translate the register
283
   fetch into a memory read.  */
284
static void
285
m68hc11_pseudo_register_read (struct gdbarch *gdbarch,
286
                              struct regcache *regcache,
287
                              int regno, gdb_byte *buf)
288
{
289
  /* The PC is a pseudo reg only for 68HC12 with the memory bank
290
     addressing mode.  */
291
  if (regno == M68HC12_HARD_PC_REGNUM)
292
    {
293
      ULONGEST pc;
294
      const int regsize = TYPE_LENGTH (builtin_type_uint32);
295
 
296
      regcache_cooked_read_unsigned (regcache, HARD_PC_REGNUM, &pc);
297
      if (pc >= 0x8000 && pc < 0xc000)
298
        {
299
          ULONGEST page;
300
 
301
          regcache_cooked_read_unsigned (regcache, HARD_PAGE_REGNUM, &page);
302
          pc -= 0x8000;
303
          pc += (page << 14);
304
          pc += 0x1000000;
305
        }
306
      store_unsigned_integer (buf, regsize, pc);
307
      return;
308
    }
309
 
310
  m68hc11_initialize_register_info ();
311
 
312
  /* Fetch a soft register: translate into a memory read.  */
313
  if (soft_regs[regno].name)
314
    {
315
      target_read_memory (soft_regs[regno].addr, buf, 2);
316
    }
317
  else
318
    {
319
      memset (buf, 0, 2);
320
    }
321
}
322
 
323
/* Store a pseudo register.  Translate the register store
324
   into a memory write.  */
325
static void
326
m68hc11_pseudo_register_write (struct gdbarch *gdbarch,
327
                               struct regcache *regcache,
328
                               int regno, const gdb_byte *buf)
329
{
330
  /* The PC is a pseudo reg only for 68HC12 with the memory bank
331
     addressing mode.  */
332
  if (regno == M68HC12_HARD_PC_REGNUM)
333
    {
334
      const int regsize = TYPE_LENGTH (builtin_type_uint32);
335
      char *tmp = alloca (regsize);
336
      CORE_ADDR pc;
337
 
338
      memcpy (tmp, buf, regsize);
339
      pc = extract_unsigned_integer (tmp, regsize);
340
      if (pc >= 0x1000000)
341
        {
342
          pc -= 0x1000000;
343
          regcache_cooked_write_unsigned (regcache, HARD_PAGE_REGNUM,
344
                                          (pc >> 14) & 0x0ff);
345
          pc &= 0x03fff;
346
          regcache_cooked_write_unsigned (regcache, HARD_PC_REGNUM,
347
                                          pc + 0x8000);
348
        }
349
      else
350
        regcache_cooked_write_unsigned (regcache, HARD_PC_REGNUM, pc);
351
      return;
352
    }
353
 
354
  m68hc11_initialize_register_info ();
355
 
356
  /* Store a soft register: translate into a memory write.  */
357
  if (soft_regs[regno].name)
358
    {
359
      const int regsize = 2;
360
      char *tmp = alloca (regsize);
361
      memcpy (tmp, buf, regsize);
362
      target_write_memory (soft_regs[regno].addr, tmp, regsize);
363
    }
364
}
365
 
366
static const char *
367
m68hc11_register_name (struct gdbarch *gdbarch, int reg_nr)
368
{
369
  if (reg_nr == M68HC12_HARD_PC_REGNUM && USE_PAGE_REGISTER (gdbarch))
370
    return "pc";
371
  if (reg_nr == HARD_PC_REGNUM && USE_PAGE_REGISTER (gdbarch))
372
    return "ppc";
373
 
374
  if (reg_nr < 0)
375
    return NULL;
376
  if (reg_nr >= M68HC11_ALL_REGS)
377
    return NULL;
378
 
379
  m68hc11_initialize_register_info ();
380
 
381
  /* If we don't know the address of a soft register, pretend it
382
     does not exist.  */
383
  if (reg_nr > M68HC11_LAST_HARD_REG && soft_regs[reg_nr].name == 0)
384
    return NULL;
385
  return m68hc11_register_names[reg_nr];
386
}
387
 
388
static const unsigned char *
389
m68hc11_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
390
                            int *lenptr)
391
{
392
  static unsigned char breakpoint[] = {0x0};
393
 
394
  *lenptr = sizeof (breakpoint);
395
  return breakpoint;
396
}
397
 
398
 
399
/* 68HC11 & 68HC12 prologue analysis.
400
 
401
 */
402
#define MAX_CODES 12
403
 
404
/* 68HC11 opcodes.  */
405
#undef M6811_OP_PAGE2
406
#define M6811_OP_PAGE2   (0x18)
407
#define M6811_OP_LDX     (0xde)
408
#define M6811_OP_LDX_EXT (0xfe)
409
#define M6811_OP_PSHX    (0x3c)
410
#define M6811_OP_STS     (0x9f)
411
#define M6811_OP_STS_EXT (0xbf)
412
#define M6811_OP_TSX     (0x30)
413
#define M6811_OP_XGDX    (0x8f)
414
#define M6811_OP_ADDD    (0xc3)
415
#define M6811_OP_TXS     (0x35)
416
#define M6811_OP_DES     (0x34)
417
 
418
/* 68HC12 opcodes.  */
419
#define M6812_OP_PAGE2   (0x18)
420
#define M6812_OP_MOVW    (0x01)
421
#define M6812_PB_PSHW    (0xae)
422
#define M6812_OP_STS     (0x5f)
423
#define M6812_OP_STS_EXT (0x7f)
424
#define M6812_OP_LEAS    (0x1b)
425
#define M6812_OP_PSHX    (0x34)
426
#define M6812_OP_PSHY    (0x35)
427
 
428
/* Operand extraction.  */
429
#define OP_DIRECT      (0x100) /* 8-byte direct addressing.  */
430
#define OP_IMM_LOW     (0x200) /* Low part of 16-bit constant/address.  */
431
#define OP_IMM_HIGH    (0x300) /* High part of 16-bit constant/address.  */
432
#define OP_PBYTE       (0x400) /* 68HC12 indexed operand.  */
433
 
434
/* Identification of the sequence.  */
435
enum m6811_seq_type
436
{
437
  P_LAST = 0,
438
  P_SAVE_REG,  /* Save a register on the stack.  */
439
  P_SET_FRAME, /* Setup the frame pointer.  */
440
  P_LOCAL_1,   /* Allocate 1 byte for locals.  */
441
  P_LOCAL_2,   /* Allocate 2 bytes for locals.  */
442
  P_LOCAL_N    /* Allocate N bytes for locals.  */
443
};
444
 
445
struct insn_sequence {
446
  enum m6811_seq_type type;
447
  unsigned length;
448
  unsigned short code[MAX_CODES];
449
};
450
 
451
/* Sequence of instructions in the 68HC11 function prologue.  */
452
static struct insn_sequence m6811_prologue[] = {
453
  /* Sequences to save a soft-register.  */
454
  { P_SAVE_REG, 3, { M6811_OP_LDX, OP_DIRECT,
455
                     M6811_OP_PSHX } },
456
  { P_SAVE_REG, 5, { M6811_OP_PAGE2, M6811_OP_LDX, OP_DIRECT,
457
                     M6811_OP_PAGE2, M6811_OP_PSHX } },
458
  { P_SAVE_REG, 4, { M6811_OP_LDX_EXT, OP_IMM_HIGH, OP_IMM_LOW,
459
                     M6811_OP_PSHX } },
460
  { P_SAVE_REG, 6, { M6811_OP_PAGE2, M6811_OP_LDX_EXT, OP_IMM_HIGH, OP_IMM_LOW,
461
                     M6811_OP_PAGE2, M6811_OP_PSHX } },
462
 
463
  /* Sequences to allocate local variables.  */
464
  { P_LOCAL_N,  7, { M6811_OP_TSX,
465
                     M6811_OP_XGDX,
466
                     M6811_OP_ADDD, OP_IMM_HIGH, OP_IMM_LOW,
467
                     M6811_OP_XGDX,
468
                     M6811_OP_TXS } },
469
  { P_LOCAL_N, 11, { M6811_OP_PAGE2, M6811_OP_TSX,
470
                     M6811_OP_PAGE2, M6811_OP_XGDX,
471
                     M6811_OP_ADDD, OP_IMM_HIGH, OP_IMM_LOW,
472
                     M6811_OP_PAGE2, M6811_OP_XGDX,
473
                     M6811_OP_PAGE2, M6811_OP_TXS } },
474
  { P_LOCAL_1,  1, { M6811_OP_DES } },
475
  { P_LOCAL_2,  1, { M6811_OP_PSHX } },
476
  { P_LOCAL_2,  2, { M6811_OP_PAGE2, M6811_OP_PSHX } },
477
 
478
  /* Initialize the frame pointer.  */
479
  { P_SET_FRAME, 2, { M6811_OP_STS, OP_DIRECT } },
480
  { P_SET_FRAME, 3, { M6811_OP_STS_EXT, OP_IMM_HIGH, OP_IMM_LOW } },
481
  { P_LAST, 0, { 0 } }
482
};
483
 
484
 
485
/* Sequence of instructions in the 68HC12 function prologue.  */
486
static struct insn_sequence m6812_prologue[] = {
487
  { P_SAVE_REG,  5, { M6812_OP_PAGE2, M6812_OP_MOVW, M6812_PB_PSHW,
488
                      OP_IMM_HIGH, OP_IMM_LOW } },
489
  { P_SET_FRAME, 2, { M6812_OP_STS, OP_DIRECT } },
490
  { P_SET_FRAME, 3, { M6812_OP_STS_EXT, OP_IMM_HIGH, OP_IMM_LOW } },
491
  { P_LOCAL_N,   2, { M6812_OP_LEAS, OP_PBYTE } },
492
  { P_LOCAL_2,   1, { M6812_OP_PSHX } },
493
  { P_LOCAL_2,   1, { M6812_OP_PSHY } },
494
  { P_LAST, 0 }
495
};
496
 
497
 
498
/* Analyze the sequence of instructions starting at the given address.
499
   Returns a pointer to the sequence when it is recognized and
500
   the optional value (constant/address) associated with it.  */
501
static struct insn_sequence *
502
m68hc11_analyze_instruction (struct insn_sequence *seq, CORE_ADDR pc,
503
                             CORE_ADDR *val)
504
{
505
  unsigned char buffer[MAX_CODES];
506
  unsigned bufsize;
507
  unsigned j;
508
  CORE_ADDR cur_val;
509
  short v = 0;
510
 
511
  bufsize = 0;
512
  for (; seq->type != P_LAST; seq++)
513
    {
514
      cur_val = 0;
515
      for (j = 0; j < seq->length; j++)
516
        {
517
          if (bufsize < j + 1)
518
            {
519
              buffer[bufsize] = read_memory_unsigned_integer (pc + bufsize,
520
                                                              1);
521
              bufsize++;
522
            }
523
          /* Continue while we match the opcode.  */
524
          if (seq->code[j] == buffer[j])
525
            continue;
526
 
527
          if ((seq->code[j] & 0xf00) == 0)
528
            break;
529
 
530
          /* Extract a sequence parameter (address or constant).  */
531
          switch (seq->code[j])
532
            {
533
            case OP_DIRECT:
534
              cur_val = (CORE_ADDR) buffer[j];
535
              break;
536
 
537
            case OP_IMM_HIGH:
538
              cur_val = cur_val & 0x0ff;
539
              cur_val |= (buffer[j] << 8);
540
              break;
541
 
542
            case OP_IMM_LOW:
543
              cur_val &= 0x0ff00;
544
              cur_val |= buffer[j];
545
              break;
546
 
547
            case OP_PBYTE:
548
              if ((buffer[j] & 0xE0) == 0x80)
549
                {
550
                  v = buffer[j] & 0x1f;
551
                  if (v & 0x10)
552
                    v |= 0xfff0;
553
                }
554
              else if ((buffer[j] & 0xfe) == 0xf0)
555
                {
556
                  v = read_memory_unsigned_integer (pc + j + 1, 1);
557
                  if (buffer[j] & 1)
558
                    v |= 0xff00;
559
                }
560
              else if (buffer[j] == 0xf2)
561
                {
562
                  v = read_memory_unsigned_integer (pc + j + 1, 2);
563
                }
564
              cur_val = v;
565
              break;
566
            }
567
        }
568
 
569
      /* We have a full match.  */
570
      if (j == seq->length)
571
        {
572
          *val = cur_val;
573
          return seq;
574
        }
575
    }
576
  return 0;
577
}
578
 
579
/* Return the instruction that the function at the PC is using.  */
580
static enum insn_return_kind
581
m68hc11_get_return_insn (CORE_ADDR pc)
582
{
583
  struct minimal_symbol *sym;
584
 
585
  /* A flag indicating that this is a STO_M68HC12_FAR or STO_M68HC12_INTERRUPT
586
     function is stored by elfread.c in the high bit of the info field.
587
     Use this to decide which instruction the function uses to return.  */
588
  sym = lookup_minimal_symbol_by_pc (pc);
589
  if (sym == 0)
590
    return RETURN_RTS;
591
 
592
  if (MSYMBOL_IS_RTC (sym))
593
    return RETURN_RTC;
594
  else if (MSYMBOL_IS_RTI (sym))
595
    return RETURN_RTI;
596
  else
597
    return RETURN_RTS;
598
}
599
 
600
/* Analyze the function prologue to find some information
601
   about the function:
602
    - the PC of the first line (for m68hc11_skip_prologue)
603
    - the offset of the previous frame saved address (from current frame)
604
    - the soft registers which are pushed.  */
605
static CORE_ADDR
606
m68hc11_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
607
                       CORE_ADDR current_pc, struct m68hc11_unwind_cache *info)
608
{
609
  LONGEST save_addr;
610
  CORE_ADDR func_end;
611
  int size;
612
  int found_frame_point;
613
  int saved_reg;
614
  int done = 0;
615
  struct insn_sequence *seq_table;
616
 
617
  info->size = 0;
618
  info->sp_offset = 0;
619
  if (pc >= current_pc)
620
    return current_pc;
621
 
622
  size = 0;
623
 
624
  m68hc11_initialize_register_info ();
625
  if (pc == 0)
626
    {
627
      info->size = 0;
628
      return pc;
629
    }
630
 
631
  seq_table = gdbarch_tdep (gdbarch)->prologue;
632
 
633
  /* The 68hc11 stack is as follows:
634
 
635
 
636
     |           |
637
     +-----------+
638
     |           |
639
     | args      |
640
     |           |
641
     +-----------+
642
     | PC-return |
643
     +-----------+
644
     | Old frame |
645
     +-----------+
646
     |           |
647
     | Locals    |
648
     |           |
649
     +-----------+ <--- current frame
650
     |           |
651
 
652
     With most processors (like 68K) the previous frame can be computed
653
     easily because it is always at a fixed offset (see link/unlink).
654
     That is, locals are accessed with negative offsets, arguments are
655
     accessed with positive ones.  Since 68hc11 only supports offsets
656
     in the range [0..255], the frame is defined at the bottom of
657
     locals (see picture).
658
 
659
     The purpose of the analysis made here is to find out the size
660
     of locals in this function.  An alternative to this is to use
661
     DWARF2 info.  This would be better but I don't know how to
662
     access dwarf2 debug from this function.
663
 
664
     Walk from the function entry point to the point where we save
665
     the frame.  While walking instructions, compute the size of bytes
666
     which are pushed.  This gives us the index to access the previous
667
     frame.
668
 
669
     We limit the search to 128 bytes so that the algorithm is bounded
670
     in case of random and wrong code.  We also stop and abort if
671
     we find an instruction which is not supposed to appear in the
672
     prologue (as generated by gcc 2.95, 2.96).
673
  */
674
  func_end = pc + 128;
675
  found_frame_point = 0;
676
  info->size = 0;
677
  save_addr = 0;
678
  while (!done && pc + 2 < func_end)
679
    {
680
      struct insn_sequence *seq;
681
      CORE_ADDR val;
682
 
683
      seq = m68hc11_analyze_instruction (seq_table, pc, &val);
684
      if (seq == 0)
685
        break;
686
 
687
      /* If we are within the instruction group, we can't advance the
688
         pc nor the stack offset.  Otherwise the caller's stack computed
689
         from the current stack can be wrong.  */
690
      if (pc + seq->length > current_pc)
691
        break;
692
 
693
      pc = pc + seq->length;
694
      if (seq->type == P_SAVE_REG)
695
        {
696
          if (found_frame_point)
697
            {
698
              saved_reg = m68hc11_which_soft_register (val);
699
              if (saved_reg < 0)
700
                break;
701
 
702
              save_addr -= 2;
703
              if (info->saved_regs)
704
                info->saved_regs[saved_reg].addr = save_addr;
705
            }
706
          else
707
            {
708
              size += 2;
709
            }
710
        }
711
      else if (seq->type == P_SET_FRAME)
712
        {
713
          found_frame_point = 1;
714
          info->size = size;
715
        }
716
      else if (seq->type == P_LOCAL_1)
717
        {
718
          size += 1;
719
        }
720
      else if (seq->type == P_LOCAL_2)
721
        {
722
          size += 2;
723
        }
724
      else if (seq->type == P_LOCAL_N)
725
        {
726
          /* Stack pointer is decremented for the allocation.  */
727
          if (val & 0x8000)
728
            size -= (int) (val) | 0xffff0000;
729
          else
730
            size -= val;
731
        }
732
    }
733
  if (found_frame_point == 0)
734
    info->sp_offset = size;
735
  else
736
    info->sp_offset = -1;
737
  return pc;
738
}
739
 
740
static CORE_ADDR
741
m68hc11_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
742
{
743
  CORE_ADDR func_addr, func_end;
744
  struct symtab_and_line sal;
745
  struct m68hc11_unwind_cache tmp_cache = { 0 };
746
 
747
  /* If we have line debugging information, then the end of the
748
     prologue should be the first assembly instruction of the
749
     first source line.  */
750
  if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
751
    {
752
      sal = find_pc_line (func_addr, 0);
753
      if (sal.end && sal.end < func_end)
754
        return sal.end;
755
    }
756
 
757
  pc = m68hc11_scan_prologue (gdbarch, pc, (CORE_ADDR) -1, &tmp_cache);
758
  return pc;
759
}
760
 
761
static CORE_ADDR
762
m68hc11_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
763
{
764
  ULONGEST pc;
765
 
766
  pc = frame_unwind_register_unsigned (next_frame, gdbarch_pc_regnum (gdbarch));
767
  return pc;
768
}
769
 
770
/* Put here the code to store, into fi->saved_regs, the addresses of
771
   the saved registers of frame described by FRAME_INFO.  This
772
   includes special registers such as pc and fp saved in special ways
773
   in the stack frame.  sp is even more special: the address we return
774
   for it IS the sp for the next frame. */
775
 
776
struct m68hc11_unwind_cache *
777
m68hc11_frame_unwind_cache (struct frame_info *next_frame,
778
                            void **this_prologue_cache)
779
{
780
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
781
  ULONGEST prev_sp;
782
  ULONGEST this_base;
783
  struct m68hc11_unwind_cache *info;
784
  CORE_ADDR current_pc;
785
  int i;
786
 
787
  if ((*this_prologue_cache))
788
    return (*this_prologue_cache);
789
 
790
  info = FRAME_OBSTACK_ZALLOC (struct m68hc11_unwind_cache);
791
  (*this_prologue_cache) = info;
792
  info->saved_regs = trad_frame_alloc_saved_regs (next_frame);
793
 
794
  info->pc = frame_func_unwind (next_frame, NORMAL_FRAME);
795
 
796
  info->size = 0;
797
  info->return_kind = m68hc11_get_return_insn (info->pc);
798
 
799
  /* The SP was moved to the FP.  This indicates that a new frame
800
     was created.  Get THIS frame's FP value by unwinding it from
801
     the next frame.  */
802
  this_base = frame_unwind_register_unsigned (next_frame, SOFT_FP_REGNUM);
803
  if (this_base == 0)
804
    {
805
      info->base = 0;
806
      return info;
807
    }
808
 
809
  current_pc = frame_pc_unwind (next_frame);
810
  if (info->pc != 0)
811
    m68hc11_scan_prologue (gdbarch, info->pc, current_pc, info);
812
 
813
  info->saved_regs[HARD_PC_REGNUM].addr = info->size;
814
 
815
  if (info->sp_offset != (CORE_ADDR) -1)
816
    {
817
      info->saved_regs[HARD_PC_REGNUM].addr = info->sp_offset;
818
      this_base = frame_unwind_register_unsigned (next_frame, HARD_SP_REGNUM);
819
      prev_sp = this_base + info->sp_offset + 2;
820
      this_base += STACK_CORRECTION (gdbarch);
821
    }
822
  else
823
    {
824
      /* The FP points at the last saved register.  Adjust the FP back
825
         to before the first saved register giving the SP.  */
826
      prev_sp = this_base + info->size + 2;
827
 
828
      this_base += STACK_CORRECTION (gdbarch);
829
      if (soft_regs[SOFT_FP_REGNUM].name)
830
        info->saved_regs[SOFT_FP_REGNUM].addr = info->size - 2;
831
   }
832
 
833
  if (info->return_kind == RETURN_RTC)
834
    {
835
      prev_sp += 1;
836
      info->saved_regs[HARD_PAGE_REGNUM].addr = info->size;
837
      info->saved_regs[HARD_PC_REGNUM].addr = info->size + 1;
838
    }
839
  else if (info->return_kind == RETURN_RTI)
840
    {
841
      prev_sp += 7;
842
      info->saved_regs[HARD_CCR_REGNUM].addr = info->size;
843
      info->saved_regs[HARD_D_REGNUM].addr = info->size + 1;
844
      info->saved_regs[HARD_X_REGNUM].addr = info->size + 3;
845
      info->saved_regs[HARD_Y_REGNUM].addr = info->size + 5;
846
      info->saved_regs[HARD_PC_REGNUM].addr = info->size + 7;
847
    }
848
 
849
  /* Add 1 here to adjust for the post-decrement nature of the push
850
     instruction.*/
851
  info->prev_sp = prev_sp;
852
 
853
  info->base = this_base;
854
 
855
  /* Adjust all the saved registers so that they contain addresses and not
856
     offsets.  */
857
  for (i = 0;
858
       i < gdbarch_num_regs (gdbarch)
859
           + gdbarch_num_pseudo_regs (gdbarch) - 1;
860
       i++)
861
    if (trad_frame_addr_p (info->saved_regs, i))
862
      {
863
        info->saved_regs[i].addr += this_base;
864
      }
865
 
866
  /* The previous frame's SP needed to be computed.  Save the computed
867
     value.  */
868
  trad_frame_set_value (info->saved_regs, HARD_SP_REGNUM, info->prev_sp);
869
 
870
  return info;
871
}
872
 
873
/* Given a GDB frame, determine the address of the calling function's
874
   frame.  This will be used to create a new GDB frame struct.  */
875
 
876
static void
877
m68hc11_frame_this_id (struct frame_info *next_frame,
878
                       void **this_prologue_cache,
879
                       struct frame_id *this_id)
880
{
881
  struct m68hc11_unwind_cache *info
882
    = m68hc11_frame_unwind_cache (next_frame, this_prologue_cache);
883
  CORE_ADDR base;
884
  CORE_ADDR func;
885
  struct frame_id id;
886
 
887
  /* The FUNC is easy.  */
888
  func = frame_func_unwind (next_frame, NORMAL_FRAME);
889
 
890
  /* Hopefully the prologue analysis either correctly determined the
891
     frame's base (which is the SP from the previous frame), or set
892
     that base to "NULL".  */
893
  base = info->prev_sp;
894
  if (base == 0)
895
    return;
896
 
897
  id = frame_id_build (base, func);
898
  (*this_id) = id;
899
}
900
 
901
static void
902
m68hc11_frame_prev_register (struct frame_info *next_frame,
903
                             void **this_prologue_cache,
904
                             int regnum, int *optimizedp,
905
                             enum lval_type *lvalp, CORE_ADDR *addrp,
906
                             int *realnump, gdb_byte *bufferp)
907
{
908
  struct m68hc11_unwind_cache *info
909
    = m68hc11_frame_unwind_cache (next_frame, this_prologue_cache);
910
 
911
  trad_frame_get_prev_register (next_frame, info->saved_regs, regnum,
912
                                optimizedp, lvalp, addrp, realnump, bufferp);
913
 
914
  if (regnum == HARD_PC_REGNUM)
915
    {
916
      /* Take into account the 68HC12 specific call (PC + page).  */
917
      if (info->return_kind == RETURN_RTC
918
          && *addrp >= 0x08000 && *addrp < 0x0c000
919
          && USE_PAGE_REGISTER (get_frame_arch (next_frame)))
920
        {
921
          int page_optimized;
922
 
923
          CORE_ADDR page;
924
 
925
          trad_frame_get_prev_register (next_frame, info->saved_regs,
926
                                        HARD_PAGE_REGNUM, &page_optimized,
927
                                        0, &page, 0, 0);
928
          *addrp -= 0x08000;
929
          *addrp += ((page & 0x0ff) << 14);
930
          *addrp += 0x1000000;
931
        }
932
    }
933
}
934
 
935
static const struct frame_unwind m68hc11_frame_unwind = {
936
  NORMAL_FRAME,
937
  m68hc11_frame_this_id,
938
  m68hc11_frame_prev_register
939
};
940
 
941
const struct frame_unwind *
942
m68hc11_frame_sniffer (struct frame_info *next_frame)
943
{
944
  return &m68hc11_frame_unwind;
945
}
946
 
947
static CORE_ADDR
948
m68hc11_frame_base_address (struct frame_info *next_frame, void **this_cache)
949
{
950
  struct m68hc11_unwind_cache *info
951
    = m68hc11_frame_unwind_cache (next_frame, this_cache);
952
 
953
  return info->base;
954
}
955
 
956
static CORE_ADDR
957
m68hc11_frame_args_address (struct frame_info *next_frame, void **this_cache)
958
{
959
  CORE_ADDR addr;
960
  struct m68hc11_unwind_cache *info
961
    = m68hc11_frame_unwind_cache (next_frame, this_cache);
962
 
963
  addr = info->base + info->size;
964
  if (info->return_kind == RETURN_RTC)
965
    addr += 1;
966
  else if (info->return_kind == RETURN_RTI)
967
    addr += 7;
968
 
969
  return addr;
970
}
971
 
972
static const struct frame_base m68hc11_frame_base = {
973
  &m68hc11_frame_unwind,
974
  m68hc11_frame_base_address,
975
  m68hc11_frame_base_address,
976
  m68hc11_frame_args_address
977
};
978
 
979
static CORE_ADDR
980
m68hc11_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
981
{
982
  ULONGEST sp;
983
  sp = frame_unwind_register_unsigned (next_frame, HARD_SP_REGNUM);
984
  return sp;
985
}
986
 
987
/* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
988
   dummy frame.  The frame ID's base needs to match the TOS value
989
   saved by save_dummy_frame_tos(), and the PC match the dummy frame's
990
   breakpoint.  */
991
 
992
static struct frame_id
993
m68hc11_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
994
{
995
  ULONGEST tos;
996
  CORE_ADDR pc = frame_pc_unwind (next_frame);
997
 
998
  tos = frame_unwind_register_unsigned (next_frame, SOFT_FP_REGNUM);
999
  tos += 2;
1000
  return frame_id_build (tos, pc);
1001
}
1002
 
1003
 
1004
/* Get and print the register from the given frame.  */
1005
static void
1006
m68hc11_print_register (struct gdbarch *gdbarch, struct ui_file *file,
1007
                        struct frame_info *frame, int regno)
1008
{
1009
  LONGEST rval;
1010
 
1011
  if (regno == HARD_PC_REGNUM || regno == HARD_SP_REGNUM
1012
      || regno == SOFT_FP_REGNUM || regno == M68HC12_HARD_PC_REGNUM)
1013
    rval = get_frame_register_unsigned (frame, regno);
1014
  else
1015
    rval = get_frame_register_signed (frame, regno);
1016
 
1017
  if (regno == HARD_A_REGNUM || regno == HARD_B_REGNUM
1018
      || regno == HARD_CCR_REGNUM || regno == HARD_PAGE_REGNUM)
1019
    {
1020
      fprintf_filtered (file, "0x%02x   ", (unsigned char) rval);
1021
      if (regno != HARD_CCR_REGNUM)
1022
        print_longest (file, 'd', 1, rval);
1023
    }
1024
  else
1025
    {
1026
      if (regno == HARD_PC_REGNUM && gdbarch_tdep (gdbarch)->use_page_register)
1027
        {
1028
          ULONGEST page;
1029
 
1030
          page = get_frame_register_unsigned (frame, HARD_PAGE_REGNUM);
1031
          fprintf_filtered (file, "0x%02x:%04x ", (unsigned) page,
1032
                            (unsigned) rval);
1033
        }
1034
      else
1035
        {
1036
          fprintf_filtered (file, "0x%04x ", (unsigned) rval);
1037
          if (regno != HARD_PC_REGNUM && regno != HARD_SP_REGNUM
1038
              && regno != SOFT_FP_REGNUM && regno != M68HC12_HARD_PC_REGNUM)
1039
            print_longest (file, 'd', 1, rval);
1040
        }
1041
    }
1042
 
1043
  if (regno == HARD_CCR_REGNUM)
1044
    {
1045
      /* CCR register */
1046
      int C, Z, N, V;
1047
      unsigned char l = rval & 0xff;
1048
 
1049
      fprintf_filtered (file, "%c%c%c%c%c%c%c%c   ",
1050
                        l & M6811_S_BIT ? 'S' : '-',
1051
                        l & M6811_X_BIT ? 'X' : '-',
1052
                        l & M6811_H_BIT ? 'H' : '-',
1053
                        l & M6811_I_BIT ? 'I' : '-',
1054
                        l & M6811_N_BIT ? 'N' : '-',
1055
                        l & M6811_Z_BIT ? 'Z' : '-',
1056
                        l & M6811_V_BIT ? 'V' : '-',
1057
                        l & M6811_C_BIT ? 'C' : '-');
1058
      N = (l & M6811_N_BIT) != 0;
1059
      Z = (l & M6811_Z_BIT) != 0;
1060
      V = (l & M6811_V_BIT) != 0;
1061
      C = (l & M6811_C_BIT) != 0;
1062
 
1063
      /* Print flags following the h8300  */
1064
      if ((C | Z) == 0)
1065
        fprintf_filtered (file, "u> ");
1066
      else if ((C | Z) == 1)
1067
        fprintf_filtered (file, "u<= ");
1068
      else if (C == 0)
1069
        fprintf_filtered (file, "u< ");
1070
 
1071
      if (Z == 0)
1072
        fprintf_filtered (file, "!= ");
1073
      else
1074
        fprintf_filtered (file, "== ");
1075
 
1076
      if ((N ^ V) == 0)
1077
        fprintf_filtered (file, ">= ");
1078
      else
1079
        fprintf_filtered (file, "< ");
1080
 
1081
      if ((Z | (N ^ V)) == 0)
1082
        fprintf_filtered (file, "> ");
1083
      else
1084
        fprintf_filtered (file, "<= ");
1085
    }
1086
}
1087
 
1088
/* Same as 'info reg' but prints the registers in a different way.  */
1089
static void
1090
m68hc11_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
1091
                              struct frame_info *frame, int regno, int cpregs)
1092
{
1093
  if (regno >= 0)
1094
    {
1095
      const char *name = gdbarch_register_name (gdbarch, regno);
1096
 
1097
      if (!name || !*name)
1098
        return;
1099
 
1100
      fprintf_filtered (file, "%-10s ", name);
1101
      m68hc11_print_register (gdbarch, file, frame, regno);
1102
      fprintf_filtered (file, "\n");
1103
    }
1104
  else
1105
    {
1106
      int i, nr;
1107
 
1108
      fprintf_filtered (file, "PC=");
1109
      m68hc11_print_register (gdbarch, file, frame, HARD_PC_REGNUM);
1110
 
1111
      fprintf_filtered (file, " SP=");
1112
      m68hc11_print_register (gdbarch, file, frame, HARD_SP_REGNUM);
1113
 
1114
      fprintf_filtered (file, " FP=");
1115
      m68hc11_print_register (gdbarch, file, frame, SOFT_FP_REGNUM);
1116
 
1117
      fprintf_filtered (file, "\nCCR=");
1118
      m68hc11_print_register (gdbarch, file, frame, HARD_CCR_REGNUM);
1119
 
1120
      fprintf_filtered (file, "\nD=");
1121
      m68hc11_print_register (gdbarch, file, frame, HARD_D_REGNUM);
1122
 
1123
      fprintf_filtered (file, " X=");
1124
      m68hc11_print_register (gdbarch, file, frame, HARD_X_REGNUM);
1125
 
1126
      fprintf_filtered (file, " Y=");
1127
      m68hc11_print_register (gdbarch, file, frame, HARD_Y_REGNUM);
1128
 
1129
      if (gdbarch_tdep (gdbarch)->use_page_register)
1130
        {
1131
          fprintf_filtered (file, "\nPage=");
1132
          m68hc11_print_register (gdbarch, file, frame, HARD_PAGE_REGNUM);
1133
        }
1134
      fprintf_filtered (file, "\n");
1135
 
1136
      nr = 0;
1137
      for (i = SOFT_D1_REGNUM; i < M68HC11_ALL_REGS; i++)
1138
        {
1139
          /* Skip registers which are not defined in the symbol table.  */
1140
          if (soft_regs[i].name == 0)
1141
            continue;
1142
 
1143
          fprintf_filtered (file, "D%d=", i - SOFT_D1_REGNUM + 1);
1144
          m68hc11_print_register (gdbarch, file, frame, i);
1145
          nr++;
1146
          if ((nr % 8) == 7)
1147
            fprintf_filtered (file, "\n");
1148
          else
1149
            fprintf_filtered (file, " ");
1150
        }
1151
      if (nr && (nr % 8) != 7)
1152
        fprintf_filtered (file, "\n");
1153
    }
1154
}
1155
 
1156
static CORE_ADDR
1157
m68hc11_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
1158
                         struct regcache *regcache, CORE_ADDR bp_addr,
1159
                         int nargs, struct value **args, CORE_ADDR sp,
1160
                         int struct_return, CORE_ADDR struct_addr)
1161
{
1162
  int argnum;
1163
  int first_stack_argnum;
1164
  struct type *type;
1165
  char *val;
1166
  int len;
1167
  char buf[2];
1168
 
1169
  first_stack_argnum = 0;
1170
  if (struct_return)
1171
    {
1172
      regcache_cooked_write_unsigned (regcache, HARD_D_REGNUM, struct_addr);
1173
    }
1174
  else if (nargs > 0)
1175
    {
1176
      type = value_type (args[0]);
1177
      len = TYPE_LENGTH (type);
1178
 
1179
      /* First argument is passed in D and X registers.  */
1180
      if (len <= 4)
1181
        {
1182
          ULONGEST v;
1183
 
1184
          v = extract_unsigned_integer (value_contents (args[0]), len);
1185
          first_stack_argnum = 1;
1186
 
1187
          regcache_cooked_write_unsigned (regcache, HARD_D_REGNUM, v);
1188
          if (len > 2)
1189
            {
1190
              v >>= 16;
1191
              regcache_cooked_write_unsigned (regcache, HARD_X_REGNUM, v);
1192
            }
1193
        }
1194
    }
1195
 
1196
  for (argnum = nargs - 1; argnum >= first_stack_argnum; argnum--)
1197
    {
1198
      type = value_type (args[argnum]);
1199
      len = TYPE_LENGTH (type);
1200
 
1201
      if (len & 1)
1202
        {
1203
          static char zero = 0;
1204
 
1205
          sp--;
1206
          write_memory (sp, &zero, 1);
1207
        }
1208
      val = (char*) value_contents (args[argnum]);
1209
      sp -= len;
1210
      write_memory (sp, val, len);
1211
    }
1212
 
1213
  /* Store return address.  */
1214
  sp -= 2;
1215
  store_unsigned_integer (buf, 2, bp_addr);
1216
  write_memory (sp, buf, 2);
1217
 
1218
  /* Finally, update the stack pointer...  */
1219
  sp -= STACK_CORRECTION (gdbarch);
1220
  regcache_cooked_write_unsigned (regcache, HARD_SP_REGNUM, sp);
1221
 
1222
  /* ...and fake a frame pointer.  */
1223
  regcache_cooked_write_unsigned (regcache, SOFT_FP_REGNUM, sp);
1224
 
1225
  /* DWARF2/GCC uses the stack address *before* the function call as a
1226
     frame's CFA.  */
1227
  return sp + 2;
1228
}
1229
 
1230
 
1231
/* Return the GDB type object for the "standard" data type
1232
   of data in register N.  */
1233
 
1234
static struct type *
1235
m68hc11_register_type (struct gdbarch *gdbarch, int reg_nr)
1236
{
1237
  switch (reg_nr)
1238
    {
1239
    case HARD_PAGE_REGNUM:
1240
    case HARD_A_REGNUM:
1241
    case HARD_B_REGNUM:
1242
    case HARD_CCR_REGNUM:
1243
      return builtin_type_uint8;
1244
 
1245
    case M68HC12_HARD_PC_REGNUM:
1246
      return builtin_type_uint32;
1247
 
1248
    default:
1249
      return builtin_type_uint16;
1250
    }
1251
}
1252
 
1253
static void
1254
m68hc11_store_return_value (struct type *type, struct regcache *regcache,
1255
                            const void *valbuf)
1256
{
1257
  int len;
1258
 
1259
  len = TYPE_LENGTH (type);
1260
 
1261
  /* First argument is passed in D and X registers.  */
1262
  if (len <= 2)
1263
    regcache_raw_write_part (regcache, HARD_D_REGNUM, 2 - len, len, valbuf);
1264
  else if (len <= 4)
1265
    {
1266
      regcache_raw_write_part (regcache, HARD_X_REGNUM, 4 - len,
1267
                               len - 2, valbuf);
1268
      regcache_raw_write (regcache, HARD_D_REGNUM, (char*) valbuf + (len - 2));
1269
    }
1270
  else
1271
    error (_("return of value > 4 is not supported."));
1272
}
1273
 
1274
 
1275
/* Given a return value in `regcache' with a type `type',
1276
   extract and copy its value into `valbuf'.  */
1277
 
1278
static void
1279
m68hc11_extract_return_value (struct type *type, struct regcache *regcache,
1280
                              void *valbuf)
1281
{
1282
  int len = TYPE_LENGTH (type);
1283
  char buf[M68HC11_REG_SIZE];
1284
 
1285
  regcache_raw_read (regcache, HARD_D_REGNUM, buf);
1286
  switch (len)
1287
    {
1288
    case 1:
1289
      memcpy (valbuf, buf + 1, 1);
1290
      break;
1291
 
1292
    case 2:
1293
      memcpy (valbuf, buf, 2);
1294
      break;
1295
 
1296
    case 3:
1297
      memcpy ((char*) valbuf + 1, buf, 2);
1298
      regcache_raw_read (regcache, HARD_X_REGNUM, buf);
1299
      memcpy (valbuf, buf + 1, 1);
1300
      break;
1301
 
1302
    case 4:
1303
      memcpy ((char*) valbuf + 2, buf, 2);
1304
      regcache_raw_read (regcache, HARD_X_REGNUM, buf);
1305
      memcpy (valbuf, buf, 2);
1306
      break;
1307
 
1308
    default:
1309
      error (_("bad size for return value"));
1310
    }
1311
}
1312
 
1313
enum return_value_convention
1314
m68hc11_return_value (struct gdbarch *gdbarch, struct type *valtype,
1315
                      struct regcache *regcache, gdb_byte *readbuf,
1316
                      const gdb_byte *writebuf)
1317
{
1318
  if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT
1319
      || TYPE_CODE (valtype) == TYPE_CODE_UNION
1320
      || TYPE_CODE (valtype) == TYPE_CODE_ARRAY
1321
      || TYPE_LENGTH (valtype) > 4)
1322
    return RETURN_VALUE_STRUCT_CONVENTION;
1323
  else
1324
    {
1325
      if (readbuf != NULL)
1326
        m68hc11_extract_return_value (valtype, regcache, readbuf);
1327
      if (writebuf != NULL)
1328
        m68hc11_store_return_value (valtype, regcache, writebuf);
1329
      return RETURN_VALUE_REGISTER_CONVENTION;
1330
    }
1331
}
1332
 
1333
/* Test whether the ELF symbol corresponds to a function using rtc or
1334
   rti to return.  */
1335
 
1336
static void
1337
m68hc11_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
1338
{
1339
  unsigned char flags;
1340
 
1341
  flags = ((elf_symbol_type *)sym)->internal_elf_sym.st_other;
1342
  if (flags & STO_M68HC12_FAR)
1343
    MSYMBOL_SET_RTC (msym);
1344
  if (flags & STO_M68HC12_INTERRUPT)
1345
    MSYMBOL_SET_RTI (msym);
1346
}
1347
 
1348
static int
1349
gdb_print_insn_m68hc11 (bfd_vma memaddr, disassemble_info *info)
1350
{
1351
  if (gdbarch_bfd_arch_info (current_gdbarch)->arch == bfd_arch_m68hc11)
1352
    return print_insn_m68hc11 (memaddr, info);
1353
  else
1354
    return print_insn_m68hc12 (memaddr, info);
1355
}
1356
 
1357
 
1358
 
1359
/* 68HC11/68HC12 register groups.
1360
   Identify real hard registers and soft registers used by gcc.  */
1361
 
1362
static struct reggroup *m68hc11_soft_reggroup;
1363
static struct reggroup *m68hc11_hard_reggroup;
1364
 
1365
static void
1366
m68hc11_init_reggroups (void)
1367
{
1368
  m68hc11_hard_reggroup = reggroup_new ("hard", USER_REGGROUP);
1369
  m68hc11_soft_reggroup = reggroup_new ("soft", USER_REGGROUP);
1370
}
1371
 
1372
static void
1373
m68hc11_add_reggroups (struct gdbarch *gdbarch)
1374
{
1375
  reggroup_add (gdbarch, m68hc11_hard_reggroup);
1376
  reggroup_add (gdbarch, m68hc11_soft_reggroup);
1377
  reggroup_add (gdbarch, general_reggroup);
1378
  reggroup_add (gdbarch, float_reggroup);
1379
  reggroup_add (gdbarch, all_reggroup);
1380
  reggroup_add (gdbarch, save_reggroup);
1381
  reggroup_add (gdbarch, restore_reggroup);
1382
  reggroup_add (gdbarch, vector_reggroup);
1383
  reggroup_add (gdbarch, system_reggroup);
1384
}
1385
 
1386
static int
1387
m68hc11_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
1388
                             struct reggroup *group)
1389
{
1390
  /* We must save the real hard register as well as gcc
1391
     soft registers including the frame pointer.  */
1392
  if (group == save_reggroup || group == restore_reggroup)
1393
    {
1394
      return (regnum <= gdbarch_num_regs (gdbarch)
1395
              || ((regnum == SOFT_FP_REGNUM
1396
                   || regnum == SOFT_TMP_REGNUM
1397
                   || regnum == SOFT_ZS_REGNUM
1398
                   || regnum == SOFT_XY_REGNUM)
1399
                  && m68hc11_register_name (gdbarch, regnum)));
1400
    }
1401
 
1402
  /* Group to identify gcc soft registers (d1..dN).  */
1403
  if (group == m68hc11_soft_reggroup)
1404
    {
1405
      return regnum >= SOFT_D1_REGNUM
1406
             && m68hc11_register_name (gdbarch, regnum);
1407
    }
1408
 
1409
  if (group == m68hc11_hard_reggroup)
1410
    {
1411
      return regnum == HARD_PC_REGNUM || regnum == HARD_SP_REGNUM
1412
        || regnum == HARD_X_REGNUM || regnum == HARD_D_REGNUM
1413
        || regnum == HARD_Y_REGNUM || regnum == HARD_CCR_REGNUM;
1414
    }
1415
  return default_register_reggroup_p (gdbarch, regnum, group);
1416
}
1417
 
1418
static struct gdbarch *
1419
m68hc11_gdbarch_init (struct gdbarch_info info,
1420
                      struct gdbarch_list *arches)
1421
{
1422
  struct gdbarch *gdbarch;
1423
  struct gdbarch_tdep *tdep;
1424
  int elf_flags;
1425
 
1426
  soft_reg_initialized = 0;
1427
 
1428
  /* Extract the elf_flags if available.  */
1429
  if (info.abfd != NULL
1430
      && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
1431
    elf_flags = elf_elfheader (info.abfd)->e_flags;
1432
  else
1433
    elf_flags = 0;
1434
 
1435
  /* try to find a pre-existing architecture */
1436
  for (arches = gdbarch_list_lookup_by_info (arches, &info);
1437
       arches != NULL;
1438
       arches = gdbarch_list_lookup_by_info (arches->next, &info))
1439
    {
1440
      if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags)
1441
        continue;
1442
 
1443
      return arches->gdbarch;
1444
    }
1445
 
1446
  /* Need a new architecture. Fill in a target specific vector.  */
1447
  tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
1448
  gdbarch = gdbarch_alloc (&info, tdep);
1449
  tdep->elf_flags = elf_flags;
1450
 
1451
  switch (info.bfd_arch_info->arch)
1452
    {
1453
    case bfd_arch_m68hc11:
1454
      tdep->stack_correction = 1;
1455
      tdep->use_page_register = 0;
1456
      tdep->prologue = m6811_prologue;
1457
      set_gdbarch_addr_bit (gdbarch, 16);
1458
      set_gdbarch_num_pseudo_regs (gdbarch, M68HC11_NUM_PSEUDO_REGS);
1459
      set_gdbarch_pc_regnum (gdbarch, HARD_PC_REGNUM);
1460
      set_gdbarch_num_regs (gdbarch, M68HC11_NUM_REGS);
1461
      break;
1462
 
1463
    case bfd_arch_m68hc12:
1464
      tdep->stack_correction = 0;
1465
      tdep->use_page_register = elf_flags & E_M68HC12_BANKS;
1466
      tdep->prologue = m6812_prologue;
1467
      set_gdbarch_addr_bit (gdbarch, elf_flags & E_M68HC12_BANKS ? 32 : 16);
1468
      set_gdbarch_num_pseudo_regs (gdbarch,
1469
                                   elf_flags & E_M68HC12_BANKS
1470
                                   ? M68HC12_NUM_PSEUDO_REGS
1471
                                   : M68HC11_NUM_PSEUDO_REGS);
1472
      set_gdbarch_pc_regnum (gdbarch, elf_flags & E_M68HC12_BANKS
1473
                             ? M68HC12_HARD_PC_REGNUM : HARD_PC_REGNUM);
1474
      set_gdbarch_num_regs (gdbarch, elf_flags & E_M68HC12_BANKS
1475
                            ? M68HC12_NUM_REGS : M68HC11_NUM_REGS);
1476
      break;
1477
 
1478
    default:
1479
      break;
1480
    }
1481
 
1482
  /* Initially set everything according to the ABI.
1483
     Use 16-bit integers since it will be the case for most
1484
     programs.  The size of these types should normally be set
1485
     according to the dwarf2 debug information.  */
1486
  set_gdbarch_short_bit (gdbarch, 16);
1487
  set_gdbarch_int_bit (gdbarch, elf_flags & E_M68HC11_I32 ? 32 : 16);
1488
  set_gdbarch_float_bit (gdbarch, 32);
1489
  set_gdbarch_double_bit (gdbarch, elf_flags & E_M68HC11_F64 ? 64 : 32);
1490
  set_gdbarch_long_double_bit (gdbarch, 64);
1491
  set_gdbarch_long_bit (gdbarch, 32);
1492
  set_gdbarch_ptr_bit (gdbarch, 16);
1493
  set_gdbarch_long_long_bit (gdbarch, 64);
1494
 
1495
  /* Characters are unsigned.  */
1496
  set_gdbarch_char_signed (gdbarch, 0);
1497
 
1498
  set_gdbarch_unwind_pc (gdbarch, m68hc11_unwind_pc);
1499
  set_gdbarch_unwind_sp (gdbarch, m68hc11_unwind_sp);
1500
 
1501
  /* Set register info.  */
1502
  set_gdbarch_fp0_regnum (gdbarch, -1);
1503
 
1504
  set_gdbarch_sp_regnum (gdbarch, HARD_SP_REGNUM);
1505
  set_gdbarch_register_name (gdbarch, m68hc11_register_name);
1506
  set_gdbarch_register_type (gdbarch, m68hc11_register_type);
1507
  set_gdbarch_pseudo_register_read (gdbarch, m68hc11_pseudo_register_read);
1508
  set_gdbarch_pseudo_register_write (gdbarch, m68hc11_pseudo_register_write);
1509
 
1510
  set_gdbarch_push_dummy_call (gdbarch, m68hc11_push_dummy_call);
1511
 
1512
  set_gdbarch_return_value (gdbarch, m68hc11_return_value);
1513
  set_gdbarch_skip_prologue (gdbarch, m68hc11_skip_prologue);
1514
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1515
  set_gdbarch_breakpoint_from_pc (gdbarch, m68hc11_breakpoint_from_pc);
1516
  set_gdbarch_print_insn (gdbarch, gdb_print_insn_m68hc11);
1517
 
1518
  m68hc11_add_reggroups (gdbarch);
1519
  set_gdbarch_register_reggroup_p (gdbarch, m68hc11_register_reggroup_p);
1520
  set_gdbarch_print_registers_info (gdbarch, m68hc11_print_registers_info);
1521
 
1522
  /* Hook in the DWARF CFI frame unwinder.  */
1523
  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
1524
 
1525
  frame_unwind_append_sniffer (gdbarch, m68hc11_frame_sniffer);
1526
  frame_base_set_default (gdbarch, &m68hc11_frame_base);
1527
 
1528
  /* Methods for saving / extracting a dummy frame's ID.  The ID's
1529
     stack address must match the SP value returned by
1530
     PUSH_DUMMY_CALL, and saved by generic_save_dummy_frame_tos.  */
1531
  set_gdbarch_unwind_dummy_id (gdbarch, m68hc11_unwind_dummy_id);
1532
 
1533
  /* Return the unwound PC value.  */
1534
  set_gdbarch_unwind_pc (gdbarch, m68hc11_unwind_pc);
1535
 
1536
  /* Minsymbol frobbing.  */
1537
  set_gdbarch_elf_make_msymbol_special (gdbarch,
1538
                                        m68hc11_elf_make_msymbol_special);
1539
 
1540
  set_gdbarch_believe_pcc_promotion (gdbarch, 1);
1541
 
1542
  return gdbarch;
1543
}
1544
 
1545
extern initialize_file_ftype _initialize_m68hc11_tdep; /* -Wmissing-prototypes */
1546
 
1547
void
1548
_initialize_m68hc11_tdep (void)
1549
{
1550
  register_gdbarch_init (bfd_arch_m68hc11, m68hc11_gdbarch_init);
1551
  register_gdbarch_init (bfd_arch_m68hc12, m68hc11_gdbarch_init);
1552
  m68hc11_init_reggroups ();
1553
}
1554
 

powered by: WebSVN 2.1.0

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