xref: /openbsd-src/gnu/usr.bin/binutils/gdb/h8300-tdep.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /* Target-machine dependent code for Hitachi H8/300, for GDB.
2    Copyright (C) 1988, 1990, 1991 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, Boston, MA 02111-1307, USA.  */
19 
20 /*
21  Contributed by Steve Chamberlain
22                 sac@cygnus.com
23  */
24 
25 #include "defs.h"
26 #include "frame.h"
27 #include "obstack.h"
28 #include "symtab.h"
29 #include "dis-asm.h"
30 #include "gdbcmd.h"
31 #include "gdbtypes.h"
32 #include "gdbcore.h"
33 #include "gdb_string.h"
34 #include "value.h"
35 
36 
37 #undef NUM_REGS
38 #define NUM_REGS 11
39 
40 #define UNSIGNED_SHORT(X) ((X) & 0xffff)
41 
42 #define IS_PUSH(x) ((x & 0xfff0)==0x6df0)
43 #define IS_PUSH_FP(x) (x == 0x6df6)
44 #define IS_MOVE_FP(x) (x == 0x0d76 || x == 0x0ff6)
45 #define IS_MOV_SP_FP(x) (x == 0x0d76 || x == 0x0ff6)
46 #define IS_SUB2_SP(x) (x==0x1b87)
47 #define IS_SUB4_SP(x) (x==0x1b97)
48 #define IS_SUBL_SP(x) (x==0x7a37)
49 #define IS_MOVK_R5(x) (x==0x7905)
50 #define IS_SUB_R5SP(x) (x==0x1957)
51 
52 /* Local function declarations.  */
53 
54 static CORE_ADDR examine_prologue ();
55 static void set_machine_hook PARAMS ((char *filename));
56 
57 void frame_find_saved_regs ();
58 CORE_ADDR
59 h8300_skip_prologue (start_pc)
60      CORE_ADDR start_pc;
61 {
62   short int w;
63   int adjust = 0;
64 
65   /* Skip past all push and stm insns.  */
66   while (1)
67     {
68       w = read_memory_unsigned_integer (start_pc, 2);
69       /* First look for push insns.  */
70       if (w == 0x0100 || w == 0x0110 || w == 0x0120 || w == 0x0130)
71 	{
72 	  w = read_memory_unsigned_integer (start_pc + 2, 2);
73 	  adjust = 2;
74 	}
75 
76       if (IS_PUSH (w))
77 	{
78 	  start_pc += 2 + adjust;
79 	  w = read_memory_unsigned_integer (start_pc, 2);
80 	  continue;
81 	}
82       adjust = 0;
83       break;
84     }
85 
86   /* Skip past a move to FP, either word or long sized */
87   w = read_memory_unsigned_integer (start_pc, 2);
88   if (w == 0x0100)
89     {
90       w = read_memory_unsigned_integer (start_pc + 2, 2);
91       adjust += 2;
92     }
93 
94   if (IS_MOVE_FP (w))
95     {
96       start_pc += 2 + adjust;
97       w = read_memory_unsigned_integer (start_pc, 2);
98     }
99 
100   /* Check for loading either a word constant into r5;
101      long versions are handled by the SUBL_SP below.  */
102   if (IS_MOVK_R5 (w))
103     {
104       start_pc += 2;
105       w = read_memory_unsigned_integer (start_pc, 2);
106     }
107 
108   /* Now check for subtracting r5 from sp, word sized only.  */
109   if (IS_SUB_R5SP (w))
110     {
111       start_pc += 2 + adjust;
112       w = read_memory_unsigned_integer (start_pc, 2);
113     }
114 
115   /* Check for subs #2 and subs #4. */
116   while (IS_SUB2_SP (w) || IS_SUB4_SP (w))
117     {
118       start_pc += 2 + adjust;
119       w = read_memory_unsigned_integer (start_pc, 2);
120     }
121 
122   /* Check for a 32bit subtract.  */
123   if (IS_SUBL_SP (w))
124     start_pc += 6 + adjust;
125 
126   return start_pc;
127 }
128 
129 int
130 gdb_print_insn_h8300 (memaddr, info)
131      bfd_vma memaddr;
132      disassemble_info *info;
133 {
134   if (h8300smode)
135     return print_insn_h8300s (memaddr, info);
136   else if (h8300hmode)
137     return print_insn_h8300h (memaddr, info);
138   else
139     return print_insn_h8300 (memaddr, info);
140 }
141 
142 /* Given a GDB frame, determine the address of the calling function's frame.
143    This will be used to create a new GDB frame struct, and then
144    INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
145 
146    For us, the frame address is its stack pointer value, so we look up
147    the function prologue to determine the caller's sp value, and return it.  */
148 
149 CORE_ADDR
150 h8300_frame_chain (thisframe)
151      struct frame_info *thisframe;
152 {
153   frame_find_saved_regs (thisframe, (struct frame_saved_regs *) 0);
154   return thisframe->fsr->regs[SP_REGNUM];
155 }
156 
157 /* Put here the code to store, into a struct frame_saved_regs,
158    the addresses of the saved registers of frame described by FRAME_INFO.
159    This includes special registers such as pc and fp saved in special
160    ways in the stack frame.  sp is even more special:
161    the address we return for it IS the sp for the next frame.
162 
163    We cache the result of doing this in the frame_cache_obstack, since
164    it is fairly expensive.  */
165 
166 void
167 frame_find_saved_regs (fi, fsr)
168      struct frame_info *fi;
169      struct frame_saved_regs *fsr;
170 {
171   register struct frame_saved_regs *cache_fsr;
172   extern struct obstack frame_cache_obstack;
173   CORE_ADDR ip;
174   struct symtab_and_line sal;
175   CORE_ADDR limit;
176 
177   if (!fi->fsr)
178     {
179       cache_fsr = (struct frame_saved_regs *)
180 	obstack_alloc (&frame_cache_obstack,
181 		       sizeof (struct frame_saved_regs));
182       memset (cache_fsr, '\0', sizeof (struct frame_saved_regs));
183 
184       fi->fsr = cache_fsr;
185 
186       /* Find the start and end of the function prologue.  If the PC
187 	 is in the function prologue, we only consider the part that
188 	 has executed already.  */
189 
190       ip = get_pc_function_start (fi->pc);
191       sal = find_pc_line (ip, 0);
192       limit = (sal.end && sal.end < fi->pc) ? sal.end : fi->pc;
193 
194       /* This will fill in fields in *fi as well as in cache_fsr.  */
195       examine_prologue (ip, limit, fi->frame, cache_fsr, fi);
196     }
197 
198   if (fsr)
199     *fsr = *fi->fsr;
200 }
201 
202 /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
203    is not the address of a valid instruction, the address of the next
204    instruction beyond ADDR otherwise.  *PWORD1 receives the first word
205    of the instruction.*/
206 
207 CORE_ADDR
208 NEXT_PROLOGUE_INSN (addr, lim, pword1)
209      CORE_ADDR addr;
210      CORE_ADDR lim;
211      INSN_WORD *pword1;
212 {
213   char buf[2];
214   if (addr < lim + 8)
215     {
216       read_memory (addr, buf, 2);
217       *pword1 = extract_signed_integer (buf, 2);
218 
219       return addr + 2;
220     }
221   return 0;
222 }
223 
224 /* Examine the prologue of a function.  `ip' points to the first instruction.
225    `limit' is the limit of the prologue (e.g. the addr of the first
226    linenumber, or perhaps the program counter if we're stepping through).
227    `frame_sp' is the stack pointer value in use in this frame.
228    `fsr' is a pointer to a frame_saved_regs structure into which we put
229    info about the registers saved by this frame.
230    `fi' is a struct frame_info pointer; we fill in various fields in it
231    to reflect the offsets of the arg pointer and the locals pointer.  */
232 
233 static CORE_ADDR
234 examine_prologue (ip, limit, after_prolog_fp, fsr, fi)
235      register CORE_ADDR ip;
236      register CORE_ADDR limit;
237      CORE_ADDR after_prolog_fp;
238      struct frame_saved_regs *fsr;
239      struct frame_info *fi;
240 {
241   register CORE_ADDR next_ip;
242   int r;
243   int have_fp = 0;
244   INSN_WORD insn_word;
245   /* Number of things pushed onto stack, starts at 2/4, 'cause the
246      PC is already there */
247   unsigned int reg_save_depth = h8300hmode ? 4 : 2;
248 
249   unsigned int auto_depth = 0;	/* Number of bytes of autos */
250 
251   char in_frame[11];		/* One for each reg */
252 
253   int adjust = 0;
254 
255   memset (in_frame, 1, 11);
256   for (r = 0; r < 8; r++)
257     {
258       fsr->regs[r] = 0;
259     }
260   if (after_prolog_fp == 0)
261     {
262       after_prolog_fp = read_register (SP_REGNUM);
263     }
264 
265   /* If the PC isn't valid, quit now.  */
266   if (ip == 0 || ip & (h8300hmode ? ~0xffffff : ~0xffff))
267     return 0;
268 
269   next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
270 
271   if (insn_word == 0x0100)
272     {
273       insn_word = read_memory_unsigned_integer (ip + 2, 2);
274       adjust = 2;
275     }
276 
277   /* Skip over any fp push instructions */
278   fsr->regs[6] = after_prolog_fp;
279   while (next_ip && IS_PUSH_FP (insn_word))
280     {
281       ip = next_ip + adjust;
282 
283       in_frame[insn_word & 0x7] = reg_save_depth;
284       next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
285       reg_save_depth += 2 + adjust;
286     }
287 
288   /* Is this a move into the fp */
289   if (next_ip && IS_MOV_SP_FP (insn_word))
290     {
291       ip = next_ip;
292       next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
293       have_fp = 1;
294     }
295 
296   /* Skip over any stack adjustment, happens either with a number of
297      sub#2,sp or a mov #x,r5 sub r5,sp */
298 
299   if (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
300     {
301       while (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
302 	{
303 	  auto_depth += IS_SUB2_SP (insn_word) ? 2 : 4;
304 	  ip = next_ip;
305 	  next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
306 	}
307     }
308   else
309     {
310       if (next_ip && IS_MOVK_R5 (insn_word))
311 	{
312 	  ip = next_ip;
313 	  next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
314 	  auto_depth += insn_word;
315 
316 	  next_ip = NEXT_PROLOGUE_INSN (next_ip, limit, &insn_word);
317 	  auto_depth += insn_word;
318 	}
319       if (next_ip && IS_SUBL_SP (insn_word))
320 	{
321 	  ip = next_ip;
322 	  auto_depth += read_memory_unsigned_integer (ip, 4);
323 	  ip += 4;
324 
325 	  next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
326 	}
327     }
328 
329   /* Now examine the push insns to determine where everything lives
330      on the stack.  */
331   while (1)
332     {
333       adjust = 0;
334       if (!next_ip)
335 	break;
336 
337       if (insn_word == 0x0100)
338 	{
339 	  ip = next_ip;
340 	  next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
341 	  adjust = 2;
342 	}
343 
344       if (IS_PUSH (insn_word))
345 	{
346 	  ip = next_ip;
347 	  next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
348 	  fsr->regs[r] = after_prolog_fp + auto_depth;
349 	  auto_depth += 2 + adjust;
350 	  continue;
351 	}
352 
353       /* Now check for push multiple insns.  */
354       if (insn_word == 0x0110 || insn_word == 0x0120 || insn_word == 0x0130)
355 	{
356 	  int count = ((insn_word >> 4) & 0xf) + 1;
357 	  int start, i;
358 
359 	  ip = next_ip;
360 	  next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
361 	  start = insn_word & 0x7;
362 
363 	  for (i = start; i <= start + count; i++)
364 	    {
365 	      fsr->regs[i] = after_prolog_fp + auto_depth;
366 	      auto_depth += 4;
367 	    }
368 	}
369       break;
370     }
371 
372   /* The args are always reffed based from the stack pointer */
373   fi->args_pointer = after_prolog_fp;
374   /* Locals are always reffed based from the fp */
375   fi->locals_pointer = after_prolog_fp;
376   /* The PC is at a known place */
377   fi->from_pc = read_memory_unsigned_integer (after_prolog_fp + BINWORD, BINWORD);
378 
379   /* Rememeber any others too */
380   in_frame[PC_REGNUM] = 0;
381 
382   if (have_fp)
383     /* We keep the old FP in the SP spot */
384     fsr->regs[SP_REGNUM] = read_memory_unsigned_integer (fsr->regs[6], BINWORD);
385   else
386     fsr->regs[SP_REGNUM] = after_prolog_fp + auto_depth;
387 
388   return (ip);
389 }
390 
391 void
392 init_extra_frame_info (fromleaf, fi)
393      int fromleaf;
394      struct frame_info *fi;
395 {
396   fi->fsr = 0;			/* Not yet allocated */
397   fi->args_pointer = 0;		/* Unknown */
398   fi->locals_pointer = 0;	/* Unknown */
399   fi->from_pc = 0;
400 }
401 
402 /* Return the saved PC from this frame.
403 
404    If the frame has a memory copy of SRP_REGNUM, use that.  If not,
405    just use the register SRP_REGNUM itself.  */
406 
407 CORE_ADDR
408 frame_saved_pc (frame)
409      struct frame_info *frame;
410 {
411   return frame->from_pc;
412 }
413 
414 CORE_ADDR
415 frame_locals_address (fi)
416      struct frame_info *fi;
417 {
418   if (!fi->locals_pointer)
419     {
420       struct frame_saved_regs ignore;
421 
422       get_frame_saved_regs (fi, &ignore);
423 
424     }
425   return fi->locals_pointer;
426 }
427 
428 /* Return the address of the argument block for the frame
429    described by FI.  Returns 0 if the address is unknown.  */
430 
431 CORE_ADDR
432 frame_args_address (fi)
433      struct frame_info *fi;
434 {
435   if (!fi->args_pointer)
436     {
437       struct frame_saved_regs ignore;
438 
439       get_frame_saved_regs (fi, &ignore);
440 
441     }
442 
443   return fi->args_pointer;
444 }
445 
446 void
447 h8300_pop_frame ()
448 {
449   unsigned regnum;
450   struct frame_saved_regs fsr;
451   struct frame_info *frame = get_current_frame ();
452 
453   get_frame_saved_regs (frame, &fsr);
454 
455   for (regnum = 0; regnum < 8; regnum++)
456     {
457       /* Don't forget SP_REGNUM is a frame_saved_regs struct is the
458 	 actual value we want, not the address of the value we want.  */
459       if (fsr.regs[regnum] && regnum != SP_REGNUM)
460 	write_register (regnum, read_memory_integer(fsr.regs[regnum], BINWORD));
461       else if (fsr.regs[regnum] && regnum == SP_REGNUM)
462 	write_register (regnum, fsr.regs[regnum]);
463     }
464 
465   /* Don't forget the update the PC too!  */
466   write_pc (frame->from_pc);
467   flush_cached_frames ();
468 }
469 
470 
471 struct cmd_list_element *setmemorylist;
472 
473 static void
474 h8300_command(args, from_tty)
475 {
476   extern int h8300hmode;
477   h8300hmode = 0;
478   h8300smode = 0;
479 }
480 
481 static void
482 h8300h_command(args, from_tty)
483 {
484   extern int h8300hmode;
485   h8300hmode = 1;
486   h8300smode = 0;
487 }
488 static void
489 h8300s_command(args, from_tty)
490 {
491   extern int h8300smode;
492   extern int h8300hmode;
493   h8300smode = 1;
494   h8300hmode = 1;
495 }
496 
497 
498 static void
499 set_machine (args, from_tty)
500      char *args;
501      int from_tty;
502 {
503   printf_unfiltered ("\"set machine\" must be followed by h8300, h8300h");
504   printf_unfiltered ("or h8300s");
505   help_list (setmemorylist, "set memory ", -1, gdb_stdout);
506 }
507 
508 /* set_machine_hook is called as the exec file is being opened, but
509    before the symbol file is opened.  This allows us to set the
510    h8300hmode flag based on the machine type specified in the exec
511    file.  This in turn will cause subsequently defined pointer types
512    to be 16 or 32 bits as appropriate for the machine.  */
513 
514 static void
515 set_machine_hook (filename)
516      char *filename;
517 {
518   if (bfd_get_mach (exec_bfd) == bfd_mach_h8300s)
519     {
520       h8300smode = 1;
521       h8300hmode = 1;
522     }
523   else
524     if (bfd_get_mach (exec_bfd) == bfd_mach_h8300h)
525     {
526       h8300smode = 0;
527       h8300hmode = 1;
528     }
529   else
530     {
531       h8300smode = 0;
532       h8300hmode = 0;
533     }
534 }
535 
536 void
537 _initialize_h8300m ()
538 {
539   add_prefix_cmd ("machine", no_class, set_machine,
540 		  "set the machine type", &setmemorylist, "set machine ", 0,
541 		  &setlist);
542 
543   add_cmd ("h8300", class_support, h8300_command,
544 	   "Set machine to be H8/300.", &setmemorylist);
545 
546   add_cmd ("h8300h", class_support, h8300h_command,
547 	   "Set machine to be H8/300H.", &setmemorylist);
548 
549   add_cmd ("h8300s", class_support, h8300s_command,
550 	   "Set machine to be H8/300S.", &setmemorylist);
551 
552   /* Add a hook to set the machine type when we're loading a file. */
553 
554   specify_exec_file_hook(set_machine_hook);
555 }
556 
557 
558 
559 void
560 print_register_hook (regno)
561 {
562   if (regno == 8)
563     {
564       /* CCR register */
565       int C, Z, N, V;
566       unsigned char b[4];
567       unsigned char l;
568       read_relative_register_raw_bytes (regno, b);
569       l = b[REGISTER_VIRTUAL_SIZE(8) -1];
570       printf_unfiltered ("\t");
571       printf_unfiltered ("I-%d - ", (l & 0x80) != 0);
572       printf_unfiltered ("H-%d - ", (l & 0x20) != 0);
573       N = (l & 0x8) != 0;
574       Z = (l & 0x4) != 0;
575       V = (l & 0x2) != 0;
576       C = (l & 0x1) != 0;
577       printf_unfiltered ("N-%d ", N);
578       printf_unfiltered ("Z-%d ", Z);
579       printf_unfiltered ("V-%d ", V);
580       printf_unfiltered ("C-%d ", C);
581       if ((C | Z) == 0)
582 	printf_unfiltered ("u> ");
583       if ((C | Z) == 1)
584 	printf_unfiltered ("u<= ");
585       if ((C == 0))
586 	printf_unfiltered ("u>= ");
587       if (C == 1)
588 	printf_unfiltered ("u< ");
589       if (Z == 0)
590 	printf_unfiltered ("!= ");
591       if (Z == 1)
592 	printf_unfiltered ("== ");
593       if ((N ^ V) == 0)
594 	printf_unfiltered (">= ");
595       if ((N ^ V) == 1)
596 	printf_unfiltered ("< ");
597       if ((Z | (N ^ V)) == 0)
598 	printf_unfiltered ("> ");
599       if ((Z | (N ^ V)) == 1)
600 	printf_unfiltered ("<= ");
601     }
602 }
603 
604 void
605 _initialize_h8300_tdep ()
606 {
607   tm_print_insn = gdb_print_insn_h8300;
608 }
609