* findvar.c, defs.h
[external/binutils.git] / gdb / h8300-tdep.c
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., 675 Mass Ave, Cambridge, MA 02139, 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 #undef NUM_REGS
31 #define NUM_REGS 11
32
33 #define UNSIGNED_SHORT(X) ((X) & 0xffff)
34
35 /* an easy to debug H8 stack frame looks like:
36 0x6df6          push    r6
37 0x0d76          mov.w   r7,r6
38 0x6dfn          push    reg
39 0x7905 nnnn     mov.w  #n,r5    or   0x1b87  subs #2,sp
40 0x1957          sub.w  r5,sp
41
42  */
43
44 #define IS_PUSH(x) ((x & 0xff00)==0x6d00)
45 #define IS_PUSH_FP(x) (x == 0x6df6)
46 #define IS_MOVE_FP(x) (x == 0x0d76)
47 #define IS_MOV_SP_FP(x) (x == 0x0d76)
48 #define IS_SUB2_SP(x) (x==0x1b87)
49 #define IS_MOVK_R5(x) (x==0x7905)
50 #define IS_SUB_R5SP(x) (x==0x1957)
51 CORE_ADDR examine_prologue ();
52
53 void frame_find_saved_regs ();
54 CORE_ADDR 
55 h8300_skip_prologue (start_pc)
56      CORE_ADDR start_pc;
57 {
58   short int w;
59
60   w = read_memory_unsigned_integer (start_pc, 2);
61   /* Skip past all push insns */
62   while (IS_PUSH_FP (w))
63     {
64       start_pc += 2;
65       w = read_memory_unsigned_integer (start_pc, 2);
66     }
67
68   /* Skip past a move to FP */
69   if (IS_MOVE_FP (w))
70     {
71       start_pc += 2;
72       w = read_memory_unsigned_integer (start_pc, 2);
73     }
74
75   /* Skip the stack adjust */
76
77   if (IS_MOVK_R5 (w))
78     {
79       start_pc += 2;
80       w = read_memory_unsigned_integer (start_pc, 2);
81     }
82   if (IS_SUB_R5SP (w))
83     {
84       start_pc += 2;
85       w = read_memory_unsigned_integer (start_pc, 2);
86     }
87   while (IS_SUB2_SP (w))
88     {
89       start_pc += 2;
90       w = read_memory_unsigned_integer (start_pc, 2);
91     }
92
93   return start_pc;
94 }
95
96 int
97 print_insn (memaddr, stream)
98      CORE_ADDR memaddr;
99      FILE *stream;
100 {
101   disassemble_info info;
102   GDB_INIT_DISASSEMBLE_INFO(info, stream);
103   if (HMODE)
104     return print_insn_h8300h (memaddr, &info);
105   else
106     return print_insn_h8300 (memaddr, &info);
107 }
108
109 /* Given a GDB frame, determine the address of the calling function's frame.
110    This will be used to create a new GDB frame struct, and then
111    INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame.
112
113    For us, the frame address is its stack pointer value, so we look up
114    the function prologue to determine the caller's sp value, and return it.  */
115
116 FRAME_ADDR
117 FRAME_CHAIN (thisframe)
118      FRAME thisframe;
119 {
120   frame_find_saved_regs (thisframe, (struct frame_saved_regs *) 0);
121   return thisframe->fsr->regs[SP_REGNUM];
122 }
123
124 /* Put here the code to store, into a struct frame_saved_regs,
125    the addresses of the saved registers of frame described by FRAME_INFO.
126    This includes special registers such as pc and fp saved in special
127    ways in the stack frame.  sp is even more special:
128    the address we return for it IS the sp for the next frame.
129
130    We cache the result of doing this in the frame_cache_obstack, since
131    it is fairly expensive.  */
132
133 void
134 frame_find_saved_regs (fi, fsr)
135      struct frame_info *fi;
136      struct frame_saved_regs *fsr;
137 {
138   register CORE_ADDR next_addr;
139   register CORE_ADDR *saved_regs;
140   register int regnum;
141   register struct frame_saved_regs *cache_fsr;
142   extern struct obstack frame_cache_obstack;
143   CORE_ADDR ip;
144   struct symtab_and_line sal;
145   CORE_ADDR limit;
146
147   if (!fi->fsr)
148     {
149       cache_fsr = (struct frame_saved_regs *)
150         obstack_alloc (&frame_cache_obstack,
151                        sizeof (struct frame_saved_regs));
152       bzero (cache_fsr, sizeof (struct frame_saved_regs));
153
154       fi->fsr = cache_fsr;
155
156       /* Find the start and end of the function prologue.  If the PC
157          is in the function prologue, we only consider the part that
158          has executed already.  */
159
160       ip = get_pc_function_start (fi->pc);
161       sal = find_pc_line (ip, 0);
162       limit = (sal.end && sal.end < fi->pc) ? sal.end : fi->pc;
163
164       /* This will fill in fields in *fi as well as in cache_fsr.  */
165       examine_prologue (ip, limit, fi->frame, cache_fsr, fi);
166     }
167
168   if (fsr)
169     *fsr = *fi->fsr;
170 }
171
172 /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
173    is not the address of a valid instruction, the address of the next
174    instruction beyond ADDR otherwise.  *PWORD1 receives the first word
175    of the instruction.*/
176
177 CORE_ADDR
178 NEXT_PROLOGUE_INSN (addr, lim, pword1)
179      CORE_ADDR addr;
180      CORE_ADDR lim;
181      short *pword1;
182 {
183   char buf[2];
184   if (addr < lim + 8)
185     {
186       read_memory (addr, buf, 2);
187       *pword1 = extract_signed_integer (buf, 2);
188
189       return addr + 2;
190     }
191   return 0;
192 }
193
194 /* Examine the prologue of a function.  `ip' points to the first instruction.
195    `limit' is the limit of the prologue (e.g. the addr of the first
196    linenumber, or perhaps the program counter if we're stepping through).
197    `frame_sp' is the stack pointer value in use in this frame.
198    `fsr' is a pointer to a frame_saved_regs structure into which we put
199    info about the registers saved by this frame.
200    `fi' is a struct frame_info pointer; we fill in various fields in it
201    to reflect the offsets of the arg pointer and the locals pointer.  */
202
203 static CORE_ADDR
204 examine_prologue (ip, limit, after_prolog_fp, fsr, fi)
205      register CORE_ADDR ip;
206      register CORE_ADDR limit;
207      FRAME_ADDR after_prolog_fp;
208      struct frame_saved_regs *fsr;
209      struct frame_info *fi;
210 {
211   register CORE_ADDR next_ip;
212   int r;
213   int i;
214   int have_fp = 0;
215   register int src;
216   register struct pic_prologue_code *pcode;
217   INSN_WORD insn_word;
218   int size, offset;
219   /* Number of things pushed onto stack, starts at 2/4, 'cause the
220      PC is already there */
221   unsigned int reg_save_depth = HMODE ? 4 : 2;
222
223   unsigned int auto_depth = 0;  /* Number of bytes of autos */
224
225   char in_frame[11];            /* One for each reg */
226
227   memset (in_frame, 1, 11);
228   for (r = 0; r < 8; r++)
229     {
230       fsr->regs[r] = 0;
231     }
232   if (after_prolog_fp == 0)
233     {
234       after_prolog_fp = read_register (SP_REGNUM);
235     }
236   if (ip == 0 || ip & (HMODE ? ~0xffff : ~0xffff))
237     return 0;
238
239   next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
240
241   /* Skip over any fp push instructions */
242   fsr->regs[6] = after_prolog_fp;
243   while (next_ip && IS_PUSH_FP (insn_word))
244     {
245       ip = next_ip;
246
247       in_frame[insn_word & 0x7] = reg_save_depth;
248       next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
249       reg_save_depth += 2;
250     }
251
252   /* Is this a move into the fp */
253   if (next_ip && IS_MOV_SP_FP (insn_word))
254     {
255       ip = next_ip;
256       next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
257       have_fp = 1;
258     }
259
260   /* Skip over any stack adjustment, happens either with a number of
261      sub#2,sp or a mov #x,r5 sub r5,sp */
262
263   if (next_ip && IS_SUB2_SP (insn_word))
264     {
265       while (next_ip && IS_SUB2_SP (insn_word))
266         {
267           auto_depth += 2;
268           ip = next_ip;
269           next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
270         }
271     }
272   else
273     {
274       if (next_ip && IS_MOVK_R5 (insn_word))
275         {
276           ip = next_ip;
277           next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
278           auto_depth += insn_word;
279
280           next_ip = NEXT_PROLOGUE_INSN (next_ip, limit, &insn_word);
281           auto_depth += insn_word;
282         }
283     }
284   /* Work out which regs are stored where */
285   while (next_ip && IS_PUSH (insn_word))
286     {
287       ip = next_ip;
288       next_ip = NEXT_PROLOGUE_INSN (ip, limit, &insn_word);
289       fsr->regs[r] = after_prolog_fp + auto_depth;
290       auto_depth += 2;
291     }
292
293   /* The args are always reffed based from the stack pointer */
294   fi->args_pointer = after_prolog_fp;
295   /* Locals are always reffed based from the fp */
296   fi->locals_pointer = after_prolog_fp;
297   /* The PC is at a known place */
298   fi->from_pc = read_memory_unsigned_integer (after_prolog_fp + 2, BINWORD);
299
300   /* Rememeber any others too */
301   in_frame[PC_REGNUM] = 0;
302
303   if (have_fp)
304     /* We keep the old FP in the SP spot */
305     fsr->regs[SP_REGNUM] = read_memory_unsigned_integer (fsr->regs[6], BINWORD);
306   else
307     fsr->regs[SP_REGNUM] = after_prolog_fp + auto_depth;
308
309   return (ip);
310 }
311
312 void
313 init_extra_frame_info (fromleaf, fi)
314      int fromleaf;
315      struct frame_info *fi;
316 {
317   fi->fsr = 0;                  /* Not yet allocated */
318   fi->args_pointer = 0;         /* Unknown */
319   fi->locals_pointer = 0;       /* Unknown */
320   fi->from_pc = 0;
321 }
322
323 /* Return the saved PC from this frame.
324
325    If the frame has a memory copy of SRP_REGNUM, use that.  If not,
326    just use the register SRP_REGNUM itself.  */
327
328 CORE_ADDR
329 frame_saved_pc (frame)
330      FRAME frame;
331 {
332   return frame->from_pc;
333 }
334
335 CORE_ADDR
336 frame_locals_address (fi)
337      struct frame_info *fi;
338 {
339   if (!fi->locals_pointer)
340     {
341       struct frame_saved_regs ignore;
342
343       get_frame_saved_regs (fi, &ignore);
344
345     }
346   return fi->locals_pointer;
347 }
348
349 /* Return the address of the argument block for the frame
350    described by FI.  Returns 0 if the address is unknown.  */
351
352 CORE_ADDR
353 frame_args_address (fi)
354      struct frame_info *fi;
355 {
356   if (!fi->args_pointer)
357     {
358       struct frame_saved_regs ignore;
359
360       get_frame_saved_regs (fi, &ignore);
361
362     }
363
364   return fi->args_pointer;
365 }
366
367 void 
368 h8300_pop_frame ()
369 {
370   unsigned regnum;
371   struct frame_saved_regs fsr;
372   struct frame_info *fi;
373
374   FRAME frame = get_current_frame ();
375
376   fi = get_frame_info (frame);
377   get_frame_saved_regs (fi, &fsr);
378
379   for (regnum = 0; regnum < 8; regnum++)
380     {
381       if (fsr.regs[regnum])
382         {
383           write_register (regnum, read_memory_integer(fsr.regs[regnum]), BINWORD);
384         }
385
386       flush_cached_frames ();
387       set_current_frame (create_new_frame (read_register (FP_REGNUM),
388                                            read_pc ()));
389     }
390 }
391
392 void
393 print_register_hook (regno)
394 {
395   if (regno == 8)
396     {
397       /* CCR register */
398
399       int C, Z, N, V;
400       unsigned char b[2];
401       unsigned char l;
402
403       read_relative_register_raw_bytes (regno, b);
404       l = b[1];
405       printf ("\t");
406       printf ("I-%d - ", (l & 0x80) != 0);
407       printf ("H-%d - ", (l & 0x20) != 0);
408       N = (l & 0x8) != 0;
409       Z = (l & 0x4) != 0;
410       V = (l & 0x2) != 0;
411       C = (l & 0x1) != 0;
412       printf ("N-%d ", N);
413       printf ("Z-%d ", Z);
414       printf ("V-%d ", V);
415       printf ("C-%d ", C);
416       if ((C | Z) == 0)
417         printf ("u> ");
418       if ((C | Z) == 1)
419         printf ("u<= ");
420       if ((C == 0))
421         printf ("u>= ");
422       if (C == 1)
423         printf ("u< ");
424       if (Z == 0)
425         printf ("!= ");
426       if (Z == 1)
427         printf ("== ");
428       if ((N ^ V) == 0)
429         printf (">= ");
430       if ((N ^ V) == 1)
431         printf ("< ");
432       if ((Z | (N ^ V)) == 0)
433         printf ("> ");
434       if ((Z | (N ^ V)) == 1)
435         printf ("<= ");
436     }
437 }