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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [h8500-tdep.c] - Blame information for rev 1774

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

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

powered by: WebSVN 2.1.0

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