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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [z8k-tdep.c] - Blame information for rev 578

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

Line No. Rev Author Line
1 578 markom
/* Target-machine dependent code for Zilog Z8000, for GDB.
2
   Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 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 "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 (thisframe->prev == 0)
163
    {
164
      /* This is the top of the stack, let's get the sp for real */
165
    }
166
  if (!inside_entry_file (thisframe->pc))
167
    {
168
      return read_memory_pointer (thisframe->frame);
169
    }
170
  return 0;
171
}
172
 
173
void
174
init_frame_pc (void)
175
{
176
  internal_error (__FILE__, __LINE__, "failed internal consistency check");
177
}
178
 
179
/* Put here the code to store, into a struct frame_saved_regs,
180
   the addresses of the saved registers of frame described by FRAME_INFO.
181
   This includes special registers such as pc and fp saved in special
182
   ways in the stack frame.  sp is even more special:
183
   the address we return for it IS the sp for the next frame.  */
184
 
185
void
186
z8k_frame_init_saved_regs (struct frame_info *frame_info)
187
{
188
  CORE_ADDR pc;
189
  int w;
190
 
191
  frame_saved_regs_zalloc (frame_info);
192
  pc = get_pc_function_start (frame_info->pc);
193
 
194
  /* wander down the instruction stream */
195
  examine_frame (pc, frame_info->saved_regs, frame_info->frame);
196
 
197
}
198
 
199
void
200
z8k_push_dummy_frame (void)
201
{
202
  internal_error (__FILE__, __LINE__, "failed internal consistency check");
203
}
204
 
205
int
206
gdb_print_insn_z8k (bfd_vma memaddr, disassemble_info *info)
207
{
208
  if (BIG)
209
    return print_insn_z8001 (memaddr, info);
210
  else
211
    return print_insn_z8002 (memaddr, info);
212
}
213
 
214
/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
215
   is not the address of a valid instruction, the address of the next
216
   instruction beyond ADDR otherwise.  *PWORD1 receives the first word
217
   of the instruction. */
218
 
219
CORE_ADDR
220
NEXT_PROLOGUE_INSN (CORE_ADDR addr, CORE_ADDR lim, short *pword1)
221
{
222
  char buf[2];
223
  if (addr < lim + 8)
224
    {
225
      read_memory (addr, buf, 2);
226
      *pword1 = extract_signed_integer (buf, 2);
227
 
228
      return addr + 2;
229
    }
230
  return 0;
231
}
232
 
233
#if 0
234
/* Put here the code to store, into a struct frame_saved_regs,
235
   the addresses of the saved registers of frame described by FRAME_INFO.
236
   This includes special registers such as pc and fp saved in special
237
   ways in the stack frame.  sp is even more special:
238
   the address we return for it IS the sp for the next frame.
239
 
240
   We cache the result of doing this in the frame_cache_obstack, since
241
   it is fairly expensive.  */
242
 
243
void
244
frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp)
245
{
246
  int locals;
247
  CORE_ADDR pc;
248
  CORE_ADDR adr;
249
  int i;
250
 
251
  memset (fsrp, 0, sizeof *fsrp);
252
 
253
  pc = skip_adjust (get_pc_function_start (fip->pc), &locals);
254
 
255
  {
256
    adr = FRAME_FP (fip) - locals;
257
    for (i = 0; i < 8; i++)
258
      {
259
        int word = read_memory_short (pc);
260
 
261
        pc += 2;
262
        if (IS_PUSHL (word))
263
          {
264
            fsrp->regs[word & 0xf] = adr;
265
            fsrp->regs[(word & 0xf) + 1] = adr - 2;
266
            adr -= 4;
267
          }
268
        else if (IS_PUSHW (word))
269
          {
270
            fsrp->regs[word & 0xf] = adr;
271
            adr -= 2;
272
          }
273
        else
274
          break;
275
      }
276
 
277
  }
278
 
279
  fsrp->regs[PC_REGNUM] = fip->frame + 4;
280
  fsrp->regs[FP_REGNUM] = fip->frame;
281
 
282
}
283
#endif
284
 
285
int
286
z8k_saved_pc_after_call (struct frame_info *frame)
287
{
288
  return ADDR_BITS_REMOVE
289
    (read_memory_integer (read_register (SP_REGNUM), PTR_SIZE));
290
}
291
 
292
 
293
void
294
extract_return_value (struct type *type, char *regbuf, char *valbuf)
295
{
296
  int b;
297
  int len = TYPE_LENGTH (type);
298
 
299
  for (b = 0; b < len; b += 2)
300
    {
301
      int todo = len - b;
302
 
303
      if (todo > 2)
304
        todo = 2;
305
      memcpy (valbuf + b, regbuf + b, todo);
306
    }
307
}
308
 
309
void
310
write_return_value (struct type *type, char *valbuf)
311
{
312
  int reg;
313
  int len;
314
 
315
  for (len = 0; len < TYPE_LENGTH (type); len += 2)
316
    write_register_bytes (REGISTER_BYTE (len / 2 + 2), valbuf + len, 2);
317
}
318
 
319
void
320
store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
321
{
322
  write_register (2, addr);
323
}
324
 
325
 
326
void
327
z8k_print_register_hook (int regno)
328
{
329
  if ((regno & 1) == 0 && regno < 16)
330
    {
331
      unsigned short l[2];
332
 
333
      read_relative_register_raw_bytes (regno, (char *) (l + 0));
334
      read_relative_register_raw_bytes (regno + 1, (char *) (l + 1));
335
      printf_unfiltered ("\t");
336
      printf_unfiltered ("%04x%04x", l[0], l[1]);
337
    }
338
 
339
  if ((regno & 3) == 0 && regno < 16)
340
    {
341
      unsigned short l[4];
342
 
343
      read_relative_register_raw_bytes (regno, (char *) (l + 0));
344
      read_relative_register_raw_bytes (regno + 1, (char *) (l + 1));
345
      read_relative_register_raw_bytes (regno + 2, (char *) (l + 2));
346
      read_relative_register_raw_bytes (regno + 3, (char *) (l + 3));
347
 
348
      printf_unfiltered ("\t");
349
      printf_unfiltered ("%04x%04x%04x%04x", l[0], l[1], l[2], l[3]);
350
    }
351
  if (regno == 15)
352
    {
353
      unsigned short rval;
354
      int i;
355
 
356
      read_relative_register_raw_bytes (regno, (char *) (&rval));
357
 
358
      printf_unfiltered ("\n");
359
      for (i = 0; i < 10; i += 2)
360
        {
361
          printf_unfiltered ("(sp+%d=%04x)", i,
362
                             (unsigned int)read_memory_short (rval + i));
363
        }
364
    }
365
 
366
}
367
 
368
void
369
z8k_pop_frame (void)
370
{
371
}
372
 
373
struct cmd_list_element *setmemorylist;
374
 
375
void
376
z8k_set_pointer_size (int newsize)
377
{
378
  static int oldsize = 0;
379
 
380
  if (oldsize != newsize)
381
    {
382
      printf_unfiltered ("pointer size set to %d bits\n", newsize);
383
      oldsize = newsize;
384
      if (newsize == 32)
385
        {
386
          BIG = 1;
387
        }
388
      else
389
        {
390
          BIG = 0;
391
        }
392
      /* FIXME: This code should be using the GDBARCH framework to
393
         handle changed type sizes.  If this problem is ever fixed
394
         (the direct reference to _initialize_gdbtypes() below
395
         eliminated) then Makefile.in should be updated so that
396
         z8k-tdep.c is again compiled with -Werror. */
397
      _initialize_gdbtypes ();
398
    }
399
}
400
 
401
static void
402
segmented_command (char *args, int from_tty)
403
{
404
  z8k_set_pointer_size (32);
405
}
406
 
407
static void
408
unsegmented_command (char *args, int from_tty)
409
{
410
  z8k_set_pointer_size (16);
411
}
412
 
413
static void
414
set_memory (char *args, int from_tty)
415
{
416
  printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
417
  help_list (setmemorylist, "set memory ", -1, gdb_stdout);
418
}
419
 
420
void
421
_initialize_z8ktdep (void)
422
{
423
  tm_print_insn = gdb_print_insn_z8k;
424
 
425
  add_prefix_cmd ("memory", no_class, set_memory,
426
                  "set the memory model", &setmemorylist, "set memory ", 0,
427
                  &setlist);
428
  add_cmd ("segmented", class_support, segmented_command,
429
           "Set segmented memory model.", &setmemorylist);
430
  add_cmd ("unsegmented", class_support, unsegmented_command,
431
           "Set unsegmented memory model.", &setmemorylist);
432
 
433
}

powered by: WebSVN 2.1.0

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