]> Git Repo - binutils.git/blob - gdb/z8k-tdep.c
This commit was generated by cvs2svn to track changes on a CVS vendor
[binutils.git] / gdb / z8k-tdep.c
1 /* Target-machine dependent code for Zilog Z8000, for GDB.
2    Copyright (C) 1992, 1993, 1994 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    [email protected]
24  */
25
26 #include "defs.h"
27 #include "frame.h"
28 #include "obstack.h"
29 #include "symtab.h"
30 #include "gdbcmd.h"
31 #include "gdbtypes.h"
32 #include "dis-asm.h"
33 #include "gdbcore.h"
34
35
36 /* Return the saved PC from this frame.
37
38    If the frame has a memory copy of SRP_REGNUM, use that.  If not,
39    just use the register SRP_REGNUM itself.  */
40
41 CORE_ADDR
42 frame_saved_pc (frame)
43      struct frame_info *frame;
44 {
45   return read_memory_pointer (frame->frame + (BIG ? 4 : 2));
46 }
47
48 #define IS_PUSHL(x) (BIG ? ((x & 0xfff0) == 0x91e0):((x & 0xfff0) == 0x91F0))
49 #define IS_PUSHW(x) (BIG ? ((x & 0xfff0) == 0x93e0):((x & 0xfff0)==0x93f0))
50 #define IS_MOVE_FP(x) (BIG ? x == 0xa1ea : x == 0xa1fa)
51 #define IS_MOV_SP_FP(x) (BIG ? x == 0x94ea : x == 0x0d76)
52 #define IS_SUB2_SP(x) (x==0x1b87)
53 #define IS_MOVK_R5(x) (x==0x7905)
54 #define IS_SUB_SP(x) ((x & 0xffff) == 0x020f)
55 #define IS_PUSH_FP(x) (BIG ? (x == 0x93ea) : (x == 0x93fa))
56
57 /* work out how much local space is on the stack and
58    return the pc pointing to the first push */
59
60 static CORE_ADDR
61 skip_adjust (pc, size)
62      CORE_ADDR pc;
63      int *size;
64 {
65   *size = 0;
66
67   if (IS_PUSH_FP (read_memory_short (pc))
68       && IS_MOV_SP_FP (read_memory_short (pc + 2)))
69     {
70       /* This is a function with an explict frame pointer */
71       pc += 4;
72       *size += 2;               /* remember the frame pointer */
73     }
74
75   /* remember any stack adjustment */
76   if (IS_SUB_SP (read_memory_short (pc)))
77     {
78       *size += read_memory_short (pc + 2);
79       pc += 4;
80     }
81   return pc;
82 }
83
84 static CORE_ADDR examine_frame PARAMS ((CORE_ADDR, CORE_ADDR * regs, CORE_ADDR));
85 static CORE_ADDR
86 examine_frame (pc, regs, sp)
87      CORE_ADDR pc;
88      CORE_ADDR *regs;
89      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 (start_pc)
141      CORE_ADDR start_pc;
142 {
143   CORE_ADDR dummy[NUM_REGS];
144
145   return examine_frame (start_pc, dummy, 0);
146 }
147
148 CORE_ADDR
149 z8k_addr_bits_remove (addr)
150      CORE_ADDR addr;
151 {
152   return (addr & PTR_MASK);
153 }
154
155 int
156 read_memory_pointer (x)
157      CORE_ADDR x;
158 {
159   return read_memory_integer (ADDR_BITS_REMOVE (x), BIG ? 4 : 2);
160 }
161
162 CORE_ADDR
163 frame_chain (thisframe)
164      struct frame_info *thisframe;
165 {
166   if (thisframe->prev == 0)
167     {
168       /* This is the top of the stack, let's get the sp for real */
169     }
170   if (!inside_entry_file (thisframe->pc))
171     {
172       return read_memory_pointer (thisframe->frame);
173     }
174   return 0;
175 }
176
177 void
178 init_frame_pc ()
179 {
180   abort ();
181 }
182
183 /* Put here the code to store, into a struct frame_saved_regs,
184    the addresses of the saved registers of frame described by FRAME_INFO.
185    This includes special registers such as pc and fp saved in special
186    ways in the stack frame.  sp is even more special:
187    the address we return for it IS the sp for the next frame.  */
188
189 void
190 z8k_frame_init_saved_regs (frame_info)
191      struct frame_info *frame_info;
192 {
193   CORE_ADDR pc;
194   int w;
195
196   frame_saved_regs_zalloc (frame_info);
197   pc = get_pc_function_start (frame_info->pc);
198
199   /* wander down the instruction stream */
200   examine_frame (pc, frame_info->saved_regs, frame_info->frame);
201
202 }
203
204 void
205 z8k_push_dummy_frame ()
206 {
207   abort ();
208 }
209
210 int
211 gdb_print_insn_z8k (memaddr, info)
212      bfd_vma memaddr;
213      disassemble_info *info;
214 {
215   if (BIG)
216     return print_insn_z8001 (memaddr, info);
217   else
218     return print_insn_z8002 (memaddr, info);
219 }
220
221 /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
222    is not the address of a valid instruction, the address of the next
223    instruction beyond ADDR otherwise.  *PWORD1 receives the first word
224    of the instruction. */
225
226 CORE_ADDR
227 NEXT_PROLOGUE_INSN (addr, lim, pword1)
228      CORE_ADDR addr;
229      CORE_ADDR lim;
230      short *pword1;
231 {
232   char buf[2];
233   if (addr < lim + 8)
234     {
235       read_memory (addr, buf, 2);
236       *pword1 = extract_signed_integer (buf, 2);
237
238       return addr + 2;
239     }
240   return 0;
241 }
242
243 #if 0
244 /* Put here the code to store, into a struct frame_saved_regs,
245    the addresses of the saved registers of frame described by FRAME_INFO.
246    This includes special registers such as pc and fp saved in special
247    ways in the stack frame.  sp is even more special:
248    the address we return for it IS the sp for the next frame.
249
250    We cache the result of doing this in the frame_cache_obstack, since
251    it is fairly expensive.  */
252
253 void
254 frame_find_saved_regs (fip, fsrp)
255      struct frame_info *fip;
256      struct frame_saved_regs *fsrp;
257 {
258   int locals;
259   CORE_ADDR pc;
260   CORE_ADDR adr;
261   int i;
262
263   memset (fsrp, 0, sizeof *fsrp);
264
265   pc = skip_adjust (get_pc_function_start (fip->pc), &locals);
266
267   {
268     adr = FRAME_FP (fip) - locals;
269     for (i = 0; i < 8; i++)
270       {
271         int word = read_memory_short (pc);
272
273         pc += 2;
274         if (IS_PUSHL (word))
275           {
276             fsrp->regs[word & 0xf] = adr;
277             fsrp->regs[(word & 0xf) + 1] = adr - 2;
278             adr -= 4;
279           }
280         else if (IS_PUSHW (word))
281           {
282             fsrp->regs[word & 0xf] = adr;
283             adr -= 2;
284           }
285         else
286           break;
287       }
288
289   }
290
291   fsrp->regs[PC_REGNUM] = fip->frame + 4;
292   fsrp->regs[FP_REGNUM] = fip->frame;
293
294 }
295 #endif
296
297 int
298 saved_pc_after_call ()
299 {
300   return ADDR_BITS_REMOVE
301     (read_memory_integer (read_register (SP_REGNUM), PTR_SIZE));
302 }
303
304
305 void
306 extract_return_value (type, regbuf, valbuf)
307      struct type *type;
308      char *regbuf;
309      char *valbuf;
310 {
311   int b;
312   int len = TYPE_LENGTH (type);
313
314   for (b = 0; b < len; b += 2)
315     {
316       int todo = len - b;
317
318       if (todo > 2)
319         todo = 2;
320       memcpy (valbuf + b, regbuf + b, todo);
321     }
322 }
323
324 void
325 write_return_value (type, valbuf)
326      struct type *type;
327      char *valbuf;
328 {
329   int reg;
330   int len;
331
332   for (len = 0; len < TYPE_LENGTH (type); len += 2)
333     write_register_bytes (REGISTER_BYTE (len / 2 + 2), valbuf + len, 2);
334 }
335
336 void
337 store_struct_return (addr, sp)
338      CORE_ADDR addr;
339      CORE_ADDR sp;
340 {
341   write_register (2, addr);
342 }
343
344
345 void
346 print_register_hook (regno)
347      int regno;
348 {
349   if ((regno & 1) == 0 && regno < 16)
350     {
351       unsigned short l[2];
352
353       read_relative_register_raw_bytes (regno, (char *) (l + 0));
354       read_relative_register_raw_bytes (regno + 1, (char *) (l + 1));
355       printf_unfiltered ("\t");
356       printf_unfiltered ("%04x%04x", l[0], l[1]);
357     }
358
359   if ((regno & 3) == 0 && regno < 16)
360     {
361       unsigned short l[4];
362
363       read_relative_register_raw_bytes (regno, (char *) (l + 0));
364       read_relative_register_raw_bytes (regno + 1, (char *) (l + 1));
365       read_relative_register_raw_bytes (regno + 2, (char *) (l + 2));
366       read_relative_register_raw_bytes (regno + 3, (char *) (l + 3));
367
368       printf_unfiltered ("\t");
369       printf_unfiltered ("%04x%04x%04x%04x", l[0], l[1], l[2], l[3]);
370     }
371   if (regno == 15)
372     {
373       unsigned short rval;
374       int i;
375
376       read_relative_register_raw_bytes (regno, (char *) (&rval));
377
378       printf_unfiltered ("\n");
379       for (i = 0; i < 10; i += 2)
380         {
381           printf_unfiltered ("(sp+%d=%04x)", i, read_memory_short (rval + i));
382         }
383     }
384
385 }
386
387 void
388 z8k_pop_frame ()
389 {
390 }
391
392 struct cmd_list_element *setmemorylist;
393
394 void
395 z8k_set_pointer_size (newsize)
396      int newsize;
397 {
398   static int oldsize = 0;
399
400   if (oldsize != newsize)
401     {
402       printf_unfiltered ("pointer size set to %d bits\n", newsize);
403       oldsize = newsize;
404       if (newsize == 32)
405         {
406           BIG = 1;
407         }
408       else
409         {
410           BIG = 0;
411         }
412       _initialize_gdbtypes ();
413     }
414 }
415
416 static void
417 segmented_command (args, from_tty)
418      char *args;
419      int from_tty;
420 {
421   z8k_set_pointer_size (32);
422 }
423
424 static void
425 unsegmented_command (args, from_tty)
426      char *args;
427      int from_tty;
428 {
429   z8k_set_pointer_size (16);
430 }
431
432 static void
433 set_memory (args, from_tty)
434      char *args;
435      int from_tty;
436 {
437   printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n");
438   help_list (setmemorylist, "set memory ", -1, gdb_stdout);
439 }
440
441 void
442 _initialize_z8ktdep ()
443 {
444   tm_print_insn = gdb_print_insn_z8k;
445
446   add_prefix_cmd ("memory", no_class, set_memory,
447                   "set the memory model", &setmemorylist, "set memory ", 0,
448                   &setlist);
449   add_cmd ("segmented", class_support, segmented_command,
450            "Set segmented memory model.", &setmemorylist);
451   add_cmd ("unsegmented", class_support, unsegmented_command,
452            "Set unsegmented memory model.", &setmemorylist);
453
454 }
This page took 0.050679 seconds and 4 git commands to generate.