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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [h8500-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Target-dependent code for Hitachi H8/500, for GDB.
2
   Copyright 1993, 1994, 1995, 1998, 2000, 2001
3
   Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 2 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
/*
23
   Contributed by Steve Chamberlain
24
   sac@cygnus.com
25
 */
26
 
27
#include "defs.h"
28
#include "frame.h"
29
#include "obstack.h"
30
#include "symtab.h"
31
#include "gdbtypes.h"
32
#include "gdbcmd.h"
33
#include "value.h"
34
#include "dis-asm.h"
35
#include "gdbcore.h"
36
#include "regcache.h"
37
 
38
#define UNSIGNED_SHORT(X) ((X) & 0xffff)
39
 
40
static int code_size = 2;
41
 
42
static int data_size = 2;
43
 
44
/* Shape of an H8/500 frame :
45
 
46
   arg-n
47
   ..
48
   arg-2
49
   arg-1
50
   return address <2 or 4 bytes>
51
   old fp         <2 bytes>
52
   auto-n
53
   ..
54
   auto-1
55
   saved registers
56
 
57
 */
58
 
59
/* an easy to debug H8 stack frame looks like:
60
   0x6df6               push    r6
61
   0x0d76       mov.w   r7,r6
62
   0x6dfn          push    reg
63
   0x7905 nnnn          mov.w  #n,r5    or   0x1b87  subs #2,sp
64
   0x1957               sub.w  r5,sp
65
 
66
 */
67
 
68
#define IS_PUSH(x) (((x) & 0xff00)==0x6d00)
69
#define IS_LINK_8(x) ((x) == 0x17)
70
#define IS_LINK_16(x) ((x) == 0x1f)
71
#define IS_MOVE_FP(x) ((x) == 0x0d76)
72
#define IS_MOV_SP_FP(x) ((x) == 0x0d76)
73
#define IS_SUB2_SP(x) ((x) == 0x1b87)
74
#define IS_MOVK_R5(x) ((x) == 0x7905)
75
#define IS_SUB_R5SP(x) ((x) == 0x1957)
76
 
77
#define LINK_8 0x17
78
#define LINK_16 0x1f
79
 
80
int minimum_mode = 1;
81
 
82
CORE_ADDR
83
h8500_skip_prologue (CORE_ADDR start_pc)
84
{
85
  short int w;
86
 
87
  w = read_memory_integer (start_pc, 1);
88
  if (w == LINK_8)
89
    {
90
      start_pc += 2;
91
      w = read_memory_integer (start_pc, 1);
92
    }
93
 
94
  if (w == LINK_16)
95
    {
96
      start_pc += 3;
97
      w = read_memory_integer (start_pc, 2);
98
    }
99
 
100
  return start_pc;
101
}
102
 
103
CORE_ADDR
104
h8500_addr_bits_remove (CORE_ADDR addr)
105
{
106
  return ((addr) & 0xffffff);
107
}
108
 
109
/* Given a GDB frame, determine the address of the calling function's frame.
110
   This will be used to create a new GDB frame struct, and then
111
   INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
112
 
113
   For us, the frame address is its stack pointer value, so we look up
114
   the function prologue to determine the caller's sp value, and return it.  */
115
 
116
CORE_ADDR
117
h8500_frame_chain (struct frame_info *thisframe)
118
{
119
  if (!inside_entry_file (thisframe->pc))
120
    return (read_memory_integer (FRAME_FP (thisframe), PTR_SIZE));
121
  else
122
    return 0;
123
}
124
 
125
/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
126
   is not the address of a valid instruction, the address of the next
127
   instruction beyond ADDR otherwise.  *PWORD1 receives the first word
128
   of the instruction. */
129
 
130
CORE_ADDR
131
NEXT_PROLOGUE_INSN (CORE_ADDR addr, CORE_ADDR lim, char *pword1)
132
{
133
  if (addr < lim + 8)
134
    {
135
      read_memory (addr, pword1, 1);
136
      read_memory (addr, pword1 + 1, 1);
137
      return 1;
138
    }
139
  return 0;
140
}
141
 
142
/* Examine the prologue of a function.  `ip' points to the first
143
   instruction.  `limit' is the limit of the prologue (e.g. the addr
144
   of the first linenumber, or perhaps the program counter if we're
145
   stepping through).  `frame_sp' is the stack pointer value in use in
146
   this frame.  `fsr' is a pointer to a frame_saved_regs structure
147
   into which we put info about the registers saved by this frame.
148
   `fi' is a struct frame_info pointer; we fill in various fields in
149
   it to reflect the offsets of the arg pointer and the locals
150
   pointer.  */
151
 
152
/* Return the saved PC from this frame. */
153
 
154
CORE_ADDR
155
frame_saved_pc (struct frame_info *frame)
156
{
157
  return read_memory_integer (FRAME_FP (frame) + 2, PTR_SIZE);
158
}
159
 
160
void
161
h8500_pop_frame (void)
162
{
163
  unsigned regnum;
164
  struct frame_saved_regs fsr;
165
  struct frame_info *frame = get_current_frame ();
166
 
167
  get_frame_saved_regs (frame, &fsr);
168
 
169
  for (regnum = 0; regnum < 8; regnum++)
170
    {
171
      if (fsr.regs[regnum])
172
        write_register (regnum, read_memory_short (fsr.regs[regnum]));
173
 
174
      flush_cached_frames ();
175
    }
176
}
177
 
178
void
179
print_register_hook (int regno)
180
{
181
  if (regno == CCR_REGNUM)
182
    {
183
      /* CCR register */
184
 
185
      int C, Z, N, V;
186
      unsigned char b[2];
187
      unsigned char l;
188
 
189
      read_relative_register_raw_bytes (regno, b);
190
      l = b[1];
191
      printf_unfiltered ("\t");
192
      printf_unfiltered ("I-%d - ", (l & 0x80) != 0);
193
      N = (l & 0x8) != 0;
194
      Z = (l & 0x4) != 0;
195
      V = (l & 0x2) != 0;
196
      C = (l & 0x1) != 0;
197
      printf_unfiltered ("N-%d ", N);
198
      printf_unfiltered ("Z-%d ", Z);
199
      printf_unfiltered ("V-%d ", V);
200
      printf_unfiltered ("C-%d ", C);
201
      if ((C | Z) == 0)
202
        printf_unfiltered ("u> ");
203
      if ((C | Z) == 1)
204
        printf_unfiltered ("u<= ");
205
      if ((C == 0))
206
        printf_unfiltered ("u>= ");
207
      if (C == 1)
208
        printf_unfiltered ("u< ");
209
      if (Z == 0)
210
        printf_unfiltered ("!= ");
211
      if (Z == 1)
212
        printf_unfiltered ("== ");
213
      if ((N ^ V) == 0)
214
        printf_unfiltered (">= ");
215
      if ((N ^ V) == 1)
216
        printf_unfiltered ("< ");
217
      if ((Z | (N ^ V)) == 0)
218
        printf_unfiltered ("> ");
219
      if ((Z | (N ^ V)) == 1)
220
        printf_unfiltered ("<= ");
221
    }
222
}
223
 
224
int
225
h8500_register_size (int regno)
226
{
227
  switch (regno)
228
    {
229
    case SEG_C_REGNUM:
230
    case SEG_D_REGNUM:
231
    case SEG_E_REGNUM:
232
    case SEG_T_REGNUM:
233
      return 1;
234
    case R0_REGNUM:
235
    case R1_REGNUM:
236
    case R2_REGNUM:
237
    case R3_REGNUM:
238
    case R4_REGNUM:
239
    case R5_REGNUM:
240
    case R6_REGNUM:
241
    case R7_REGNUM:
242
    case CCR_REGNUM:
243
      return 2;
244
 
245
    case PR0_REGNUM:
246
    case PR1_REGNUM:
247
    case PR2_REGNUM:
248
    case PR3_REGNUM:
249
    case PR4_REGNUM:
250
    case PR5_REGNUM:
251
    case PR6_REGNUM:
252
    case PR7_REGNUM:
253
    case PC_REGNUM:
254
      return 4;
255
    default:
256
      internal_error (__FILE__, __LINE__, "failed internal consistency check");
257
    }
258
}
259
 
260
struct type *
261
h8500_register_virtual_type (int regno)
262
{
263
  switch (regno)
264
    {
265
    case SEG_C_REGNUM:
266
    case SEG_E_REGNUM:
267
    case SEG_D_REGNUM:
268
    case SEG_T_REGNUM:
269
      return builtin_type_unsigned_char;
270
    case R0_REGNUM:
271
    case R1_REGNUM:
272
    case R2_REGNUM:
273
    case R3_REGNUM:
274
    case R4_REGNUM:
275
    case R5_REGNUM:
276
    case R6_REGNUM:
277
    case R7_REGNUM:
278
    case CCR_REGNUM:
279
      return builtin_type_unsigned_short;
280
    case PR0_REGNUM:
281
    case PR1_REGNUM:
282
    case PR2_REGNUM:
283
    case PR3_REGNUM:
284
    case PR4_REGNUM:
285
    case PR5_REGNUM:
286
    case PR6_REGNUM:
287
    case PR7_REGNUM:
288
    case PC_REGNUM:
289
      return builtin_type_unsigned_long;
290
    default:
291
      internal_error (__FILE__, __LINE__, "failed internal consistency check");
292
    }
293
}
294
 
295
/* Put here the code to store, into a struct frame_saved_regs,
296
   the addresses of the saved registers of frame described by FRAME_INFO.
297
   This includes special registers such as pc and fp saved in special
298
   ways in the stack frame.  sp is even more special:
299
   the address we return for it IS the sp for the next frame.  */
300
 
301
void
302
frame_find_saved_regs (struct frame_info *frame_info,
303
                       struct frame_saved_regs *frame_saved_regs)
304
{
305
  register int regnum;
306
  register int regmask;
307
  register CORE_ADDR next_addr;
308
  register CORE_ADDR pc;
309
  unsigned char thebyte;
310
 
311
  memset (frame_saved_regs, '\0', sizeof *frame_saved_regs);
312
 
313
  if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4
314
      && (frame_info)->pc <= (frame_info)->frame)
315
    {
316
      next_addr = (frame_info)->frame;
317
      pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4;
318
    }
319
  else
320
    {
321
      pc = get_pc_function_start ((frame_info)->pc);
322
      /* Verify we have a link a6 instruction next;
323
         if not we lose.  If we win, find the address above the saved
324
         regs using the amount of storage from the link instruction.
325
       */
326
 
327
      thebyte = read_memory_integer (pc, 1);
328
      if (0x1f == thebyte)
329
        next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 2), pc += 2;
330
      else if (0x17 == thebyte)
331
        next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 1), pc += 1;
332
      else
333
        goto lose;
334
#if 0
335
      /* FIXME steve */
336
      /* If have an add:g.waddal #-n, sp next, adjust next_addr.  */
337
      if ((0x0c0177777 & read_memory_integer (pc, 2)) == 0157774)
338
        next_addr += read_memory_integer (pc += 2, 4), pc += 4;
339
#endif
340
    }
341
 
342
  thebyte = read_memory_integer (pc, 1);
343
  if (thebyte == 0x12)
344
    {
345
      /* Got stm */
346
      pc++;
347
      regmask = read_memory_integer (pc, 1);
348
      pc++;
349
      for (regnum = 0; regnum < 8; regnum++, regmask >>= 1)
350
        {
351
          if (regmask & 1)
352
            {
353
              (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
354
            }
355
        }
356
      thebyte = read_memory_integer (pc, 1);
357
    }
358
  /* Maybe got a load of pushes */
359
  while (thebyte == 0xbf)
360
    {
361
      pc++;
362
      regnum = read_memory_integer (pc, 1) & 0x7;
363
      pc++;
364
      (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2;
365
      thebyte = read_memory_integer (pc, 1);
366
    }
367
 
368
lose:;
369
 
370
  /* Remember the address of the frame pointer */
371
  (frame_saved_regs)->regs[FP_REGNUM] = (frame_info)->frame;
372
 
373
  /* This is where the old sp is hidden */
374
  (frame_saved_regs)->regs[SP_REGNUM] = (frame_info)->frame;
375
 
376
  /* And the PC - remember the pushed FP is always two bytes long */
377
  (frame_saved_regs)->regs[PC_REGNUM] = (frame_info)->frame + 2;
378
}
379
 
380
CORE_ADDR
381
saved_pc_after_call (void)
382
{
383
  int x;
384
  int a = read_register (SP_REGNUM);
385
 
386
  x = read_memory_integer (a, code_size);
387
  if (code_size == 2)
388
    {
389
      /* Stick current code segement onto top */
390
      x &= 0xffff;
391
      x |= read_register (SEG_C_REGNUM) << 16;
392
    }
393
  x &= 0xffffff;
394
  return x;
395
}
396
 
397
void
398
h8500_set_pointer_size (int newsize)
399
{
400
  static int oldsize = 0;
401
 
402
  if (oldsize != newsize)
403
    {
404
      printf_unfiltered ("pointer size set to %d bits\n", newsize);
405
      oldsize = newsize;
406
      if (newsize == 32)
407
        {
408
          minimum_mode = 0;
409
        }
410
      else
411
        {
412
          minimum_mode = 1;
413
        }
414
      _initialize_gdbtypes ();
415
    }
416
}
417
 
418
static void
419
big_command (char *arg, int from_tty)
420
{
421
  h8500_set_pointer_size (32);
422
  code_size = 4;
423
  data_size = 4;
424
}
425
 
426
static void
427
medium_command (char *arg, int from_tty)
428
{
429
  h8500_set_pointer_size (32);
430
  code_size = 4;
431
  data_size = 2;
432
}
433
 
434
static void
435
compact_command (char *arg, int from_tty)
436
{
437
  h8500_set_pointer_size (32);
438
  code_size = 2;
439
  data_size = 4;
440
}
441
 
442
static void
443
small_command (char *arg, int from_tty)
444
{
445
  h8500_set_pointer_size (16);
446
  code_size = 2;
447
  data_size = 2;
448
}
449
 
450
static struct cmd_list_element *setmemorylist;
451
 
452
static void
453
set_memory (char *args, int from_tty)
454
{
455
  printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
456
  help_list (setmemorylist, "set memory ", -1, gdb_stdout);
457
}
458
 
459
/* See if variable name is ppc or pr[0-7] */
460
 
461
int
462
h8500_is_trapped_internalvar (char *name)
463
{
464
  if (name[0] != 'p')
465
    return 0;
466
 
467
  if (strcmp (name + 1, "pc") == 0)
468
    return 1;
469
 
470
  if (name[1] == 'r'
471
      && name[2] >= '0'
472
      && name[2] <= '7'
473
      && name[3] == '\000')
474
    return 1;
475
  else
476
    return 0;
477
}
478
 
479
value_ptr
480
h8500_value_of_trapped_internalvar (struct internalvar *var)
481
{
482
  LONGEST regval;
483
  unsigned char regbuf[4];
484
  int page_regnum, regnum;
485
 
486
  regnum = var->name[2] == 'c' ? PC_REGNUM : var->name[2] - '0';
487
 
488
  switch (var->name[2])
489
    {
490
    case 'c':
491
      page_regnum = SEG_C_REGNUM;
492
      break;
493
    case '0':
494
    case '1':
495
    case '2':
496
    case '3':
497
      page_regnum = SEG_D_REGNUM;
498
      break;
499
    case '4':
500
    case '5':
501
      page_regnum = SEG_E_REGNUM;
502
      break;
503
    case '6':
504
    case '7':
505
      page_regnum = SEG_T_REGNUM;
506
      break;
507
    }
508
 
509
  get_saved_register (regbuf, NULL, NULL, selected_frame, page_regnum, NULL);
510
  regval = regbuf[0] << 16;
511
 
512
  get_saved_register (regbuf, NULL, NULL, selected_frame, regnum, NULL);
513
  regval |= regbuf[0] << 8 | regbuf[1];          /* XXX host/target byte order */
514
 
515
  xfree (var->value);           /* Free up old value */
516
 
517
  var->value = value_from_longest (builtin_type_unsigned_long, regval);
518
  release_value (var->value);   /* Unchain new value */
519
 
520
  VALUE_LVAL (var->value) = lval_internalvar;
521
  VALUE_INTERNALVAR (var->value) = var;
522
  return var->value;
523
}
524
 
525
void
526
h8500_set_trapped_internalvar (struct internalvar *var, value_ptr newval,
527
                               int bitpos, int bitsize, int offset)
528
{
529
  char *page_regnum, *regnum;
530
  char expression[100];
531
  unsigned new_regval;
532
  struct type *type;
533
  enum type_code newval_type_code;
534
 
535
  type = check_typedef (VALUE_TYPE (newval));
536
  newval_type_code = TYPE_CODE (type);
537
 
538
  if ((newval_type_code != TYPE_CODE_INT
539
       && newval_type_code != TYPE_CODE_PTR)
540
      || TYPE_LENGTH (type) != sizeof (new_regval))
541
    error ("Illegal type (%s) for assignment to $%s\n",
542
           TYPE_NAME (VALUE_TYPE (newval)), var->name);
543
 
544
  new_regval = *(long *) VALUE_CONTENTS_RAW (newval);
545
 
546
  regnum = var->name + 1;
547
 
548
  switch (var->name[2])
549
    {
550
    case 'c':
551
      page_regnum = "cp";
552
      break;
553
    case '0':
554
    case '1':
555
    case '2':
556
    case '3':
557
      page_regnum = "dp";
558
      break;
559
    case '4':
560
    case '5':
561
      page_regnum = "ep";
562
      break;
563
    case '6':
564
    case '7':
565
      page_regnum = "tp";
566
      break;
567
    }
568
 
569
  sprintf (expression, "$%s=%d", page_regnum, new_regval >> 16);
570
  parse_and_eval (expression);
571
 
572
  sprintf (expression, "$%s=%d", regnum, new_regval & 0xffff);
573
  parse_and_eval (expression);
574
}
575
 
576
CORE_ADDR
577
h8500_read_sp (void)
578
{
579
  return read_register (PR7_REGNUM);
580
}
581
 
582
void
583
h8500_write_sp (CORE_ADDR v)
584
{
585
  write_register (PR7_REGNUM, v);
586
}
587
 
588
CORE_ADDR
589
h8500_read_pc (ptid_t ptid)
590
{
591
  return read_register (PC_REGNUM);
592
}
593
 
594
void
595
h8500_write_pc (CORE_ADDR v, ptid_t ptid)
596
{
597
  write_register (PC_REGNUM, v);
598
}
599
 
600
CORE_ADDR
601
h8500_read_fp (void)
602
{
603
  return read_register (PR6_REGNUM);
604
}
605
 
606
void
607
h8500_write_fp (CORE_ADDR v)
608
{
609
  write_register (PR6_REGNUM, v);
610
}
611
 
612
void
613
_initialize_h8500_tdep (void)
614
{
615
  tm_print_insn = print_insn_h8500;
616
 
617
  add_prefix_cmd ("memory", no_class, set_memory,
618
                  "set the memory model", &setmemorylist, "set memory ", 0,
619
                  &setlist);
620
 
621
  add_cmd ("small", class_support, small_command,
622
      "Set small memory model. (16 bit code, 16 bit data)", &setmemorylist);
623
 
624
  add_cmd ("big", class_support, big_command,
625
        "Set big memory model. (32 bit code, 32 bit data)", &setmemorylist);
626
 
627
  add_cmd ("medium", class_support, medium_command,
628
     "Set medium memory model. (32 bit code, 16 bit data)", &setmemorylist);
629
 
630
  add_cmd ("compact", class_support, compact_command,
631
    "Set compact memory model. (16 bit code, 32 bit data)", &setmemorylist);
632
 
633
}

powered by: WebSVN 2.1.0

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