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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [z8k-tdep.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Target-machine dependent code for Zilog Z8000, for GDB.
2
 
3
   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
4
   2002 Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program 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 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public 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., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
/*
24
   Contributed by Steve Chamberlain
25
   sac@cygnus.com
26
 */
27
 
28
#include "defs.h"
29
#include "frame.h"
30
#include "symtab.h"
31
#include "gdbcmd.h"
32
#include "gdbtypes.h"
33
#include "dis-asm.h"
34
#include "gdbcore.h"
35
#include "regcache.h"
36
 
37
#include "value.h" /* For read_register() */
38
 
39
 
40
static int read_memory_pointer (CORE_ADDR x);
41
 
42
/* Return the saved PC from this frame.
43
 
44
   If the frame has a memory copy of SRP_REGNUM, use that.  If not,
45
   just use the register SRP_REGNUM itself.  */
46
 
47
CORE_ADDR
48
z8k_frame_saved_pc (struct frame_info *frame)
49
{
50
  return read_memory_pointer (frame->frame + (BIG ? 4 : 2));
51
}
52
 
53
#define IS_PUSHL(x) (BIG ? ((x & 0xfff0) == 0x91e0):((x & 0xfff0) == 0x91F0))
54
#define IS_PUSHW(x) (BIG ? ((x & 0xfff0) == 0x93e0):((x & 0xfff0)==0x93f0))
55
#define IS_MOVE_FP(x) (BIG ? x == 0xa1ea : x == 0xa1fa)
56
#define IS_MOV_SP_FP(x) (BIG ? x == 0x94ea : x == 0x0d76)
57
#define IS_SUB2_SP(x) (x==0x1b87)
58
#define IS_MOVK_R5(x) (x==0x7905)
59
#define IS_SUB_SP(x) ((x & 0xffff) == 0x020f)
60
#define IS_PUSH_FP(x) (BIG ? (x == 0x93ea) : (x == 0x93fa))
61
 
62
/* work out how much local space is on the stack and
63
   return the pc pointing to the first push */
64
 
65
static CORE_ADDR
66
skip_adjust (CORE_ADDR pc, int *size)
67
{
68
  *size = 0;
69
 
70
  if (IS_PUSH_FP (read_memory_short (pc))
71
      && IS_MOV_SP_FP (read_memory_short (pc + 2)))
72
    {
73
      /* This is a function with an explict frame pointer */
74
      pc += 4;
75
      *size += 2;               /* remember the frame pointer */
76
    }
77
 
78
  /* remember any stack adjustment */
79
  if (IS_SUB_SP (read_memory_short (pc)))
80
    {
81
      *size += read_memory_short (pc + 2);
82
      pc += 4;
83
    }
84
  return pc;
85
}
86
 
87
static CORE_ADDR examine_frame (CORE_ADDR, CORE_ADDR * regs, CORE_ADDR);
88
static CORE_ADDR
89
examine_frame (CORE_ADDR pc, CORE_ADDR *regs, CORE_ADDR sp)
90
{
91
  int w = read_memory_short (pc);
92
  int offset = 0;
93
  int regno;
94
 
95
  for (regno = 0; regno < NUM_REGS; regno++)
96
    regs[regno] = 0;
97
 
98
  while (IS_PUSHW (w) || IS_PUSHL (w))
99
    {
100
      /* work out which register is being pushed to where */
101
      if (IS_PUSHL (w))
102
        {
103
          regs[w & 0xf] = offset;
104
          regs[(w & 0xf) + 1] = offset + 2;
105
          offset += 4;
106
        }
107
      else
108
        {
109
          regs[w & 0xf] = offset;
110
          offset += 2;
111
        }
112
      pc += 2;
113
      w = read_memory_short (pc);
114
    }
115
 
116
  if (IS_MOVE_FP (w))
117
    {
118
      /* We know the fp */
119
 
120
    }
121
  else if (IS_SUB_SP (w))
122
    {
123
      /* Subtracting a value from the sp, so were in a function
124
         which needs stack space for locals, but has no fp.  We fake up
125
         the values as if we had an fp */
126
      regs[FP_REGNUM] = sp;
127
    }
128
  else
129
    {
130
      /* This one didn't have an fp, we'll fake it up */
131
      regs[SP_REGNUM] = sp;
132
    }
133
  /* stack pointer contains address of next frame */
134
  /*  regs[fp_regnum()] = fp; */
135
  regs[SP_REGNUM] = sp;
136
  return pc;
137
}
138
 
139
CORE_ADDR
140
z8k_skip_prologue (CORE_ADDR start_pc)
141
{
142
  CORE_ADDR dummy[NUM_REGS];
143
 
144
  return examine_frame (start_pc, dummy, 0);
145
}
146
 
147
CORE_ADDR
148
z8k_addr_bits_remove (CORE_ADDR addr)
149
{
150
  return (addr & PTR_MASK);
151
}
152
 
153
static int
154
read_memory_pointer (CORE_ADDR x)
155
{
156
  return read_memory_integer (ADDR_BITS_REMOVE (x), BIG ? 4 : 2);
157
}
158
 
159
CORE_ADDR
160
z8k_frame_chain (struct frame_info *thisframe)
161
{
162
  if (!inside_entry_file (thisframe->pc))
163
    {
164
      return read_memory_pointer (thisframe->frame);
165
    }
166
  return 0;
167
}
168
 
169
void
170
init_frame_pc (void)
171
{
172
  internal_error (__FILE__, __LINE__, "failed internal consistency check");
173
}
174
 
175
/* Put here the code to store, into a struct frame_saved_regs,
176
   the addresses of the saved registers of frame described by FRAME_INFO.
177
   This includes special registers such as pc and fp saved in special
178
   ways in the stack frame.  sp is even more special:
179
   the address we return for it IS the sp for the next frame.  */
180
 
181
void
182
z8k_frame_init_saved_regs (struct frame_info *frame_info)
183
{
184
  CORE_ADDR pc;
185
  int w;
186
 
187
  frame_saved_regs_zalloc (frame_info);
188
  pc = get_pc_function_start (frame_info->pc);
189
 
190
  /* wander down the instruction stream */
191
  examine_frame (pc, frame_info->saved_regs, frame_info->frame);
192
 
193
}
194
 
195
void
196
z8k_push_dummy_frame (void)
197
{
198
  internal_error (__FILE__, __LINE__, "failed internal consistency check");
199
}
200
 
201
int
202
gdb_print_insn_z8k (bfd_vma memaddr, disassemble_info *info)
203
{
204
  if (BIG)
205
    return print_insn_z8001 (memaddr, info);
206
  else
207
    return print_insn_z8002 (memaddr, info);
208
}
209
 
210
/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
211
   is not the address of a valid instruction, the address of the next
212
   instruction beyond ADDR otherwise.  *PWORD1 receives the first word
213
   of the instruction. */
214
 
215
CORE_ADDR
216
NEXT_PROLOGUE_INSN (CORE_ADDR addr, CORE_ADDR lim, short *pword1)
217
{
218
  char buf[2];
219
  if (addr < lim + 8)
220
    {
221
      read_memory (addr, buf, 2);
222
      *pword1 = extract_signed_integer (buf, 2);
223
 
224
      return addr + 2;
225
    }
226
  return 0;
227
}
228
 
229
#if 0
230
/* Put here the code to store, into a struct frame_saved_regs,
231
   the addresses of the saved registers of frame described by FRAME_INFO.
232
   This includes special registers such as pc and fp saved in special
233
   ways in the stack frame.  sp is even more special:
234
   the address we return for it IS the sp for the next frame.
235
 
236
   We cache the result of doing this in the frame_cache_obstack, since
237
   it is fairly expensive.  */
238
 
239
void
240
frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp)
241
{
242
  int locals;
243
  CORE_ADDR pc;
244
  CORE_ADDR adr;
245
  int i;
246
 
247
  memset (fsrp, 0, sizeof *fsrp);
248
 
249
  pc = skip_adjust (get_pc_function_start (fip->pc), &locals);
250
 
251
  {
252
    adr = FRAME_FP (fip) - locals;
253
    for (i = 0; i < 8; i++)
254
      {
255
        int word = read_memory_short (pc);
256
 
257
        pc += 2;
258
        if (IS_PUSHL (word))
259
          {
260
            fsrp->regs[word & 0xf] = adr;
261
            fsrp->regs[(word & 0xf) + 1] = adr - 2;
262
            adr -= 4;
263
          }
264
        else if (IS_PUSHW (word))
265
          {
266
            fsrp->regs[word & 0xf] = adr;
267
            adr -= 2;
268
          }
269
        else
270
          break;
271
      }
272
 
273
  }
274
 
275
  fsrp->regs[PC_REGNUM] = fip->frame + 4;
276
  fsrp->regs[FP_REGNUM] = fip->frame;
277
 
278
}
279
#endif
280
 
281
int
282
z8k_saved_pc_after_call (struct frame_info *frame)
283
{
284
  return ADDR_BITS_REMOVE
285
    (read_memory_integer (read_register (SP_REGNUM), PTR_SIZE));
286
}
287
 
288
 
289
void
290
extract_return_value (struct type *type, char *regbuf, char *valbuf)
291
{
292
  int b;
293
  int len = TYPE_LENGTH (type);
294
 
295
  for (b = 0; b < len; b += 2)
296
    {
297
      int todo = len - b;
298
 
299
      if (todo > 2)
300
        todo = 2;
301
      memcpy (valbuf + b, regbuf + b, todo);
302
    }
303
}
304
 
305
void
306
write_return_value (struct type *type, char *valbuf)
307
{
308
  int reg;
309
  int len;
310
 
311
  for (len = 0; len < TYPE_LENGTH (type); len += 2)
312
    write_register_bytes (REGISTER_BYTE (len / 2 + 2), valbuf + len, 2);
313
}
314
 
315
void
316
store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
317
{
318
  write_register (2, addr);
319
}
320
 
321
 
322
void
323
z8k_print_register_hook (int regno)
324
{
325
  if ((regno & 1) == 0 && regno < 16)
326
    {
327
      unsigned char l[4];
328
 
329
      frame_register_read (selected_frame, regno, l + 0);
330
      frame_register_read (selected_frame, regno + 1, l + 2);
331
      printf_unfiltered ("\t");
332
      printf_unfiltered ("0x%02x%02x%02x%02x", l[0], l[1], l[2], l[3]);
333
    }
334
 
335
  if ((regno & 3) == 0 && regno < 16)
336
    {
337
      unsigned char l[8];
338
 
339
      frame_register_read (selected_frame, regno, l + 0);
340
      frame_register_read (selected_frame, regno + 1, l + 2);
341
      frame_register_read (selected_frame, regno + 2, l + 4);
342
      frame_register_read (selected_frame, regno + 3, l + 6);
343
 
344
      printf_unfiltered ("\t");
345
      printf_unfiltered ("0x%02x%02x%02x%02x%02x%02x%02x%02x",
346
                         l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7]);
347
    }
348
  if (regno == 15)
349
    {
350
      unsigned short rval;
351
      int i;
352
 
353
      frame_register_read (selected_frame, regno, (char *) (&rval));
354
 
355
      printf_unfiltered ("\n");
356
      for (i = 0; i < 10; i += 2)
357
        {
358
          printf_unfiltered ("(sp+%d=%04x)", i,
359
                             (unsigned int)read_memory_short (rval + i));
360
        }
361
    }
362
 
363
}
364
 
365
void
366
z8k_pop_frame (void)
367
{
368
}
369
 
370
struct cmd_list_element *setmemorylist;
371
 
372
void
373
z8k_set_pointer_size (int newsize)
374
{
375
  static int oldsize = 0;
376
 
377
  if (oldsize != newsize)
378
    {
379
      printf_unfiltered ("pointer size set to %d bits\n", newsize);
380
      oldsize = newsize;
381
      if (newsize == 32)
382
        {
383
          BIG = 1;
384
        }
385
      else
386
        {
387
          BIG = 0;
388
        }
389
      /* FIXME: This code should be using the GDBARCH framework to
390
         handle changed type sizes.  If this problem is ever fixed
391
         (the direct reference to _initialize_gdbtypes() below
392
         eliminated) then Makefile.in should be updated so that
393
         z8k-tdep.c is again compiled with -Werror. */
394
      _initialize_gdbtypes ();
395
    }
396
}
397
 
398
static void
399
segmented_command (char *args, int from_tty)
400
{
401
  z8k_set_pointer_size (32);
402
}
403
 
404
static void
405
unsegmented_command (char *args, int from_tty)
406
{
407
  z8k_set_pointer_size (16);
408
}
409
 
410
static void
411
set_memory (char *args, int from_tty)
412
{
413
  printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
414
  help_list (setmemorylist, "set memory ", -1, gdb_stdout);
415
}
416
 
417
void
418
_initialize_z8ktdep (void)
419
{
420
  tm_print_insn = gdb_print_insn_z8k;
421
 
422
  add_prefix_cmd ("memory", no_class, set_memory,
423
                  "set the memory model", &setmemorylist, "set memory ", 0,
424
                  &setlist);
425
  add_cmd ("segmented", class_support, segmented_command,
426
           "Set segmented memory model.", &setmemorylist);
427
  add_cmd ("unsegmented", class_support, unsegmented_command,
428
           "Set unsegmented memory model.", &setmemorylist);
429
 
430
}

powered by: WebSVN 2.1.0

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