2002-08-16 Andrew Cagney <ac131313@redhat.com>
[deliverable/binutils-gdb.git] / gdb / z8k-tdep.c
CommitLineData
c906108c 1/* Target-machine dependent code for Zilog Z8000, for GDB.
cda5a58a
AC
2
3 Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
4 2002 Free Software Foundation, Inc.
c906108c 5
c5aa993b 6 This file is part of GDB.
c906108c 7
c5aa993b
JM
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.
c906108c 12
c5aa993b
JM
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.
c906108c 17
c5aa993b
JM
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. */
c906108c
SS
22
23/*
c5aa993b
JM
24 Contributed by Steve Chamberlain
25 sac@cygnus.com
c906108c
SS
26 */
27
28#include "defs.h"
29#include "frame.h"
c906108c
SS
30#include "symtab.h"
31#include "gdbcmd.h"
32#include "gdbtypes.h"
33#include "dis-asm.h"
34#include "gdbcore.h"
4e052eda 35#include "regcache.h"
c906108c 36
d4f3574e
SS
37#include "value.h" /* For read_register() */
38
39
40static int read_memory_pointer (CORE_ADDR x);
c906108c
SS
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
47CORE_ADDR
fba45db2 48z8k_frame_saved_pc (struct frame_info *frame)
c906108c
SS
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
65static CORE_ADDR
fba45db2 66skip_adjust (CORE_ADDR pc, int *size)
c906108c
SS
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
a14ed312 87static CORE_ADDR examine_frame (CORE_ADDR, CORE_ADDR * regs, CORE_ADDR);
c906108c 88static CORE_ADDR
fba45db2 89examine_frame (CORE_ADDR pc, CORE_ADDR *regs, CORE_ADDR sp)
c906108c
SS
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
c5aa993b
JM
124 which needs stack space for locals, but has no fp. We fake up
125 the values as if we had an fp */
c906108c
SS
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 */
c5aa993b 134 /* regs[fp_regnum()] = fp; */
c906108c
SS
135 regs[SP_REGNUM] = sp;
136 return pc;
137}
138
139CORE_ADDR
fba45db2 140z8k_skip_prologue (CORE_ADDR start_pc)
c906108c
SS
141{
142 CORE_ADDR dummy[NUM_REGS];
143
144 return examine_frame (start_pc, dummy, 0);
145}
146
147CORE_ADDR
fba45db2 148z8k_addr_bits_remove (CORE_ADDR addr)
c906108c
SS
149{
150 return (addr & PTR_MASK);
151}
152
d4f3574e
SS
153static int
154read_memory_pointer (CORE_ADDR x)
c906108c
SS
155{
156 return read_memory_integer (ADDR_BITS_REMOVE (x), BIG ? 4 : 2);
157}
158
159CORE_ADDR
fba45db2 160z8k_frame_chain (struct frame_info *thisframe)
c906108c 161{
c906108c
SS
162 if (!inside_entry_file (thisframe->pc))
163 {
164 return read_memory_pointer (thisframe->frame);
165 }
166 return 0;
167}
168
169void
fba45db2 170init_frame_pc (void)
c906108c 171{
e1e9e218 172 internal_error (__FILE__, __LINE__, "failed internal consistency check");
c906108c
SS
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
181void
fba45db2 182z8k_frame_init_saved_regs (struct frame_info *frame_info)
c906108c
SS
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
195void
fba45db2 196z8k_push_dummy_frame (void)
c906108c 197{
e1e9e218 198 internal_error (__FILE__, __LINE__, "failed internal consistency check");
c906108c
SS
199}
200
201int
fba45db2 202gdb_print_insn_z8k (bfd_vma memaddr, disassemble_info *info)
c906108c
SS
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
c5aa993b 213 of the instruction. */
c906108c
SS
214
215CORE_ADDR
fba45db2 216NEXT_PROLOGUE_INSN (CORE_ADDR addr, CORE_ADDR lim, short *pword1)
c906108c
SS
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
239void
fba45db2 240frame_find_saved_regs (struct frame_info *fip, struct frame_saved_regs *fsrp)
c906108c
SS
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
281int
d4f3574e 282z8k_saved_pc_after_call (struct frame_info *frame)
c906108c 283{
c5aa993b 284 return ADDR_BITS_REMOVE
c906108c
SS
285 (read_memory_integer (read_register (SP_REGNUM), PTR_SIZE));
286}
287
288
289void
fba45db2 290extract_return_value (struct type *type, char *regbuf, char *valbuf)
c906108c
SS
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
305void
fba45db2 306write_return_value (struct type *type, char *valbuf)
c906108c
SS
307{
308 int reg;
309 int len;
310
311 for (len = 0; len < TYPE_LENGTH (type); len += 2)
c5aa993b 312 write_register_bytes (REGISTER_BYTE (len / 2 + 2), valbuf + len, 2);
c906108c
SS
313}
314
315void
fba45db2 316store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
c906108c
SS
317{
318 write_register (2, addr);
319}
320
321
322void
fba45db2 323z8k_print_register_hook (int regno)
c906108c
SS
324{
325 if ((regno & 1) == 0 && regno < 16)
326 {
df94e18a 327 unsigned char l[4];
c906108c 328
df94e18a
AC
329 frame_register_read (selected_frame, regno, l + 0);
330 frame_register_read (selected_frame, regno + 1, l + 2);
c906108c 331 printf_unfiltered ("\t");
df94e18a 332 printf_unfiltered ("0x%02x%02x%02x%02x", l[0], l[1], l[2], l[3]);
c906108c
SS
333 }
334
335 if ((regno & 3) == 0 && regno < 16)
336 {
df94e18a 337 unsigned char l[8];
c906108c 338
df94e18a
AC
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);
c906108c
SS
343
344 printf_unfiltered ("\t");
df94e18a
AC
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]);
c906108c
SS
347 }
348 if (regno == 15)
349 {
350 unsigned short rval;
351 int i;
352
cda5a58a 353 frame_register_read (selected_frame, regno, (char *) (&rval));
c906108c
SS
354
355 printf_unfiltered ("\n");
356 for (i = 0; i < 10; i += 2)
357 {
d4f3574e
SS
358 printf_unfiltered ("(sp+%d=%04x)", i,
359 (unsigned int)read_memory_short (rval + i));
c906108c
SS
360 }
361 }
362
363}
364
365void
fba45db2 366z8k_pop_frame (void)
c906108c
SS
367{
368}
369
370struct cmd_list_element *setmemorylist;
371
372void
fba45db2 373z8k_set_pointer_size (int newsize)
c906108c
SS
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 }
d4f3574e
SS
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. */
c906108c
SS
394 _initialize_gdbtypes ();
395 }
396}
397
398static void
fba45db2 399segmented_command (char *args, int from_tty)
c906108c
SS
400{
401 z8k_set_pointer_size (32);
402}
403
404static void
fba45db2 405unsegmented_command (char *args, int from_tty)
c906108c
SS
406{
407 z8k_set_pointer_size (16);
408}
409
410static void
fba45db2 411set_memory (char *args, int from_tty)
c906108c
SS
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
417void
fba45db2 418_initialize_z8ktdep (void)
c906108c
SS
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}
This page took 0.2883 seconds and 4 git commands to generate.