xref: /openbsd-src/gnu/usr.bin/binutils/gdb/h8300-tdep.c (revision 63addd46c1e40ca0f49488ddcdc4ab598023b0c1)
1b725ae77Skettenis /* Target-machine dependent code for Renesas H8/300, for GDB.
2b725ae77Skettenis 
3b725ae77Skettenis    Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
4b725ae77Skettenis    1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
5e93f7393Sniklas 
6e93f7393Sniklas    This file is part of GDB.
7e93f7393Sniklas 
8e93f7393Sniklas    This program is free software; you can redistribute it and/or modify
9e93f7393Sniklas    it under the terms of the GNU General Public License as published by
10e93f7393Sniklas    the Free Software Foundation; either version 2 of the License, or
11e93f7393Sniklas    (at your option) any later version.
12e93f7393Sniklas 
13e93f7393Sniklas    This program is distributed in the hope that it will be useful,
14e93f7393Sniklas    but WITHOUT ANY WARRANTY; without even the implied warranty of
15e93f7393Sniklas    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e93f7393Sniklas    GNU General Public License for more details.
17e93f7393Sniklas 
18e93f7393Sniklas    You should have received a copy of the GNU General Public License
19e93f7393Sniklas    along with this program; if not, write to the Free Software
20b725ae77Skettenis    Foundation, Inc., 59 Temple Place - Suite 330,
21b725ae77Skettenis    Boston, MA 02111-1307, USA.  */
22e93f7393Sniklas 
23e93f7393Sniklas /*
24e93f7393Sniklas    Contributed by Steve Chamberlain
25e93f7393Sniklas    sac@cygnus.com
26e93f7393Sniklas  */
27e93f7393Sniklas 
28e93f7393Sniklas #include "defs.h"
29e93f7393Sniklas #include "value.h"
30b725ae77Skettenis #include "inferior.h"
31b725ae77Skettenis #include "symfile.h"
32b725ae77Skettenis #include "arch-utils.h"
33b725ae77Skettenis #include "regcache.h"
34b725ae77Skettenis #include "gdbcore.h"
35b725ae77Skettenis #include "objfiles.h"
36b725ae77Skettenis #include "gdbcmd.h"
37b725ae77Skettenis #include "gdb_assert.h"
38b725ae77Skettenis #include "dis-asm.h"
39e93f7393Sniklas 
40b725ae77Skettenis /* Extra info which is saved in each frame_info. */
41b725ae77Skettenis struct frame_extra_info
42b725ae77Skettenis {
43b725ae77Skettenis   CORE_ADDR from_pc;
44b725ae77Skettenis };
45e93f7393Sniklas 
46b725ae77Skettenis enum
47b725ae77Skettenis {
48b725ae77Skettenis   h8300_reg_size = 2,
49b725ae77Skettenis   h8300h_reg_size = 4,
50b725ae77Skettenis   h8300_max_reg_size = 4,
51b725ae77Skettenis };
52b725ae77Skettenis 
53b725ae77Skettenis static int is_h8300hmode (struct gdbarch *gdbarch);
54b725ae77Skettenis static int is_h8300smode (struct gdbarch *gdbarch);
55b725ae77Skettenis static int is_h8300sxmode (struct gdbarch *gdbarch);
56b725ae77Skettenis static int is_h8300_normal_mode (struct gdbarch *gdbarch);
57b725ae77Skettenis 
58b725ae77Skettenis #define BINWORD (is_h8300hmode (current_gdbarch) && \
59b725ae77Skettenis 		  !is_h8300_normal_mode (current_gdbarch) ? h8300h_reg_size : h8300_reg_size)
60b725ae77Skettenis 
61b725ae77Skettenis enum gdb_regnum
62b725ae77Skettenis {
63b725ae77Skettenis   E_R0_REGNUM, E_ER0_REGNUM = E_R0_REGNUM, E_ARG0_REGNUM = E_R0_REGNUM,
64b725ae77Skettenis 					   E_RET0_REGNUM = E_R0_REGNUM,
65b725ae77Skettenis   E_R1_REGNUM, E_ER1_REGNUM = E_R1_REGNUM, E_RET1_REGNUM = E_R1_REGNUM,
66b725ae77Skettenis   E_R2_REGNUM, E_ER2_REGNUM = E_R2_REGNUM, E_ARGLAST_REGNUM = E_R2_REGNUM,
67b725ae77Skettenis   E_R3_REGNUM, E_ER3_REGNUM = E_R3_REGNUM,
68b725ae77Skettenis   E_R4_REGNUM, E_ER4_REGNUM = E_R4_REGNUM,
69b725ae77Skettenis   E_R5_REGNUM, E_ER5_REGNUM = E_R5_REGNUM,
70b725ae77Skettenis   E_R6_REGNUM, E_ER6_REGNUM = E_R6_REGNUM, E_FP_REGNUM = E_R6_REGNUM,
71b725ae77Skettenis   E_SP_REGNUM,
72b725ae77Skettenis   E_CCR_REGNUM,
73b725ae77Skettenis   E_PC_REGNUM,
74b725ae77Skettenis   E_CYCLES_REGNUM,
75b725ae77Skettenis   E_TICK_REGNUM, E_EXR_REGNUM = E_TICK_REGNUM,
76b725ae77Skettenis   E_INST_REGNUM, E_TICKS_REGNUM = E_INST_REGNUM,
77b725ae77Skettenis   E_INSTS_REGNUM,
78b725ae77Skettenis   E_MACH_REGNUM,
79b725ae77Skettenis   E_MACL_REGNUM,
80b725ae77Skettenis   E_SBR_REGNUM,
81b725ae77Skettenis   E_VBR_REGNUM
82b725ae77Skettenis };
83b725ae77Skettenis 
84b725ae77Skettenis #define E_PSEUDO_CCR_REGNUM (NUM_REGS)
85b725ae77Skettenis #define E_PSEUDO_EXR_REGNUM (NUM_REGS+1)
86e93f7393Sniklas 
87e93f7393Sniklas #define UNSIGNED_SHORT(X) ((X) & 0xffff)
88e93f7393Sniklas 
89e93f7393Sniklas #define IS_PUSH(x) ((x & 0xfff0)==0x6df0)
90e93f7393Sniklas #define IS_PUSH_FP(x) (x == 0x6df6)
91e93f7393Sniklas #define IS_MOVE_FP(x) (x == 0x0d76 || x == 0x0ff6)
92e93f7393Sniklas #define IS_MOV_SP_FP(x) (x == 0x0d76 || x == 0x0ff6)
93e93f7393Sniklas #define IS_SUB2_SP(x) (x==0x1b87)
94e93f7393Sniklas #define IS_SUB4_SP(x) (x==0x1b97)
95e93f7393Sniklas #define IS_SUBL_SP(x) (x==0x7a37)
96e93f7393Sniklas #define IS_MOVK_R5(x) (x==0x7905)
97e93f7393Sniklas #define IS_SUB_R5SP(x) (x==0x1957)
98e93f7393Sniklas 
99b725ae77Skettenis /* If the instruction at PC is an argument register spill, return its
100b725ae77Skettenis    length.  Otherwise, return zero.
101e93f7393Sniklas 
102b725ae77Skettenis    An argument register spill is an instruction that moves an argument
103b725ae77Skettenis    from the register in which it was passed to the stack slot in which
104b725ae77Skettenis    it really lives.  It is a byte, word, or longword move from an
105b725ae77Skettenis    argument register to a negative offset from the frame pointer.
106e93f7393Sniklas 
107b725ae77Skettenis    CV, 2003-06-16: Or, in optimized code or when the `register' qualifier
108b725ae77Skettenis    is used, it could be a byte, word or long move to registers r3-r5.  */
109b725ae77Skettenis 
110b725ae77Skettenis static int
h8300_is_argument_spill(CORE_ADDR pc)111b725ae77Skettenis h8300_is_argument_spill (CORE_ADDR pc)
112b725ae77Skettenis {
113b725ae77Skettenis   int w = read_memory_unsigned_integer (pc, 2);
114b725ae77Skettenis 
115b725ae77Skettenis   if (((w & 0xff88) == 0x0c88                 /* mov.b Rsl, Rdl */
116b725ae77Skettenis        || (w & 0xff88) == 0x0d00              /* mov.w Rs, Rd */
117b725ae77Skettenis        || (w & 0xff88) == 0x0f80)             /* mov.l Rs, Rd */
118b725ae77Skettenis       && (w & 0x70) <= 0x20                   /* Rs is R0, R1 or R2 */
119b725ae77Skettenis       && (w & 0x7) >= 0x3 && (w & 0x7) <= 0x5)/* Rd is R3, R4 or R5 */
120b725ae77Skettenis     return 2;
121b725ae77Skettenis 
122b725ae77Skettenis   if ((w & 0xfff0) == 0x6ee0                  /* mov.b Rs,@(d:16,er6) */
123b725ae77Skettenis       && 8 <= (w & 0xf) && (w & 0xf) <= 10)   /* Rs is R0L, R1L, or R2L  */
124b725ae77Skettenis     {
125b725ae77Skettenis       int w2 = read_memory_integer (pc + 2, 2);
126b725ae77Skettenis 
127b725ae77Skettenis       /* ... and d:16 is negative.  */
128b725ae77Skettenis       if (w2 < 0)
129b725ae77Skettenis         return 4;
130b725ae77Skettenis     }
131b725ae77Skettenis   else if (w == 0x7860)
132b725ae77Skettenis     {
133b725ae77Skettenis       int w2 = read_memory_integer (pc + 2, 2);
134b725ae77Skettenis 
135b725ae77Skettenis       if ((w2 & 0xfff0) == 0x6aa0)              /* mov.b Rs, @(d:24,er6) */
136b725ae77Skettenis         {
137b725ae77Skettenis           LONGEST disp = read_memory_integer (pc + 4, 4);
138b725ae77Skettenis 
139b725ae77Skettenis           /* ... and d:24 is negative.  */
140b725ae77Skettenis           if (disp < 0 && disp > 0xffffff)
141b725ae77Skettenis             return 8;
142b725ae77Skettenis         }
143b725ae77Skettenis     }
144b725ae77Skettenis   else if ((w & 0xfff0) == 0x6fe0             /* mov.w Rs,@(d:16,er6) */
145b725ae77Skettenis            && (w & 0xf) <= 2)                 /* Rs is R0, R1, or R2 */
146b725ae77Skettenis     {
147b725ae77Skettenis       int w2 = read_memory_integer (pc + 2, 2);
148b725ae77Skettenis 
149b725ae77Skettenis       /* ... and d:16 is negative.  */
150b725ae77Skettenis       if (w2 < 0)
151b725ae77Skettenis         return 4;
152b725ae77Skettenis     }
153b725ae77Skettenis   else if (w == 0x78e0)
154b725ae77Skettenis     {
155b725ae77Skettenis       int w2 = read_memory_integer (pc + 2, 2);
156b725ae77Skettenis 
157b725ae77Skettenis       if ((w2 & 0xfff0) == 0x6ba0)              /* mov.b Rs, @(d:24,er6) */
158b725ae77Skettenis         {
159b725ae77Skettenis           LONGEST disp = read_memory_integer (pc + 4, 4);
160b725ae77Skettenis 
161b725ae77Skettenis           /* ... and d:24 is negative.  */
162b725ae77Skettenis           if (disp < 0 && disp > 0xffffff)
163b725ae77Skettenis             return 8;
164b725ae77Skettenis         }
165b725ae77Skettenis     }
166b725ae77Skettenis   else if (w == 0x0100)
167b725ae77Skettenis     {
168b725ae77Skettenis       int w2 = read_memory_integer (pc + 2, 2);
169b725ae77Skettenis 
170b725ae77Skettenis       if ((w2 & 0xfff0) == 0x6fe0             /* mov.l Rs,@(d:16,er6) */
171b725ae77Skettenis           && (w2 & 0xf) <= 2)                /* Rs is ER0, ER1, or ER2 */
172b725ae77Skettenis         {
173b725ae77Skettenis           int w3 = read_memory_integer (pc + 4, 2);
174b725ae77Skettenis 
175b725ae77Skettenis           /* ... and d:16 is negative.  */
176b725ae77Skettenis           if (w3 < 0)
177b725ae77Skettenis             return 6;
178b725ae77Skettenis         }
179b725ae77Skettenis       else if (w2 == 0x78e0)
180b725ae77Skettenis         {
181b725ae77Skettenis           int w3 = read_memory_integer (pc + 4, 2);
182b725ae77Skettenis 
183b725ae77Skettenis           if ((w3 & 0xfff0) == 0x6ba0)          /* mov.l Rs, @(d:24,er6) */
184b725ae77Skettenis             {
185b725ae77Skettenis               LONGEST disp = read_memory_integer (pc + 6, 4);
186b725ae77Skettenis 
187b725ae77Skettenis               /* ... and d:24 is negative.  */
188b725ae77Skettenis               if (disp < 0 && disp > 0xffffff)
189b725ae77Skettenis                 return 10;
190b725ae77Skettenis             }
191b725ae77Skettenis         }
192b725ae77Skettenis     }
193b725ae77Skettenis 
194b725ae77Skettenis   return 0;
195b725ae77Skettenis }
196b725ae77Skettenis 
197b725ae77Skettenis static CORE_ADDR
h8300_skip_prologue(CORE_ADDR start_pc)198b725ae77Skettenis h8300_skip_prologue (CORE_ADDR start_pc)
199e93f7393Sniklas {
200e93f7393Sniklas   short int w;
201e93f7393Sniklas   int adjust = 0;
202e93f7393Sniklas 
203e93f7393Sniklas   /* Skip past all push and stm insns.  */
204e93f7393Sniklas   while (1)
205e93f7393Sniklas     {
206e93f7393Sniklas       w = read_memory_unsigned_integer (start_pc, 2);
207e93f7393Sniklas       /* First look for push insns.  */
208e93f7393Sniklas       if (w == 0x0100 || w == 0x0110 || w == 0x0120 || w == 0x0130)
209e93f7393Sniklas 	{
210e93f7393Sniklas 	  w = read_memory_unsigned_integer (start_pc + 2, 2);
211e93f7393Sniklas 	  adjust = 2;
212e93f7393Sniklas 	}
213e93f7393Sniklas 
214e93f7393Sniklas       if (IS_PUSH (w))
215e93f7393Sniklas 	{
216e93f7393Sniklas 	  start_pc += 2 + adjust;
217e93f7393Sniklas 	  w = read_memory_unsigned_integer (start_pc, 2);
218e93f7393Sniklas 	  continue;
219e93f7393Sniklas 	}
220e93f7393Sniklas       adjust = 0;
221e93f7393Sniklas       break;
222e93f7393Sniklas     }
223e93f7393Sniklas 
224e93f7393Sniklas   /* Skip past a move to FP, either word or long sized */
225e93f7393Sniklas   w = read_memory_unsigned_integer (start_pc, 2);
226e93f7393Sniklas   if (w == 0x0100)
227e93f7393Sniklas     {
228e93f7393Sniklas       w = read_memory_unsigned_integer (start_pc + 2, 2);
229e93f7393Sniklas       adjust += 2;
230e93f7393Sniklas     }
231e93f7393Sniklas 
232e93f7393Sniklas   if (IS_MOVE_FP (w))
233e93f7393Sniklas     {
234e93f7393Sniklas       start_pc += 2 + adjust;
235e93f7393Sniklas       w = read_memory_unsigned_integer (start_pc, 2);
236e93f7393Sniklas     }
237e93f7393Sniklas 
238e93f7393Sniklas   /* Check for loading either a word constant into r5;
239e93f7393Sniklas      long versions are handled by the SUBL_SP below.  */
240e93f7393Sniklas   if (IS_MOVK_R5 (w))
241e93f7393Sniklas     {
242e93f7393Sniklas       start_pc += 2;
243e93f7393Sniklas       w = read_memory_unsigned_integer (start_pc, 2);
244e93f7393Sniklas     }
245e93f7393Sniklas 
246e93f7393Sniklas   /* Now check for subtracting r5 from sp, word sized only.  */
247e93f7393Sniklas   if (IS_SUB_R5SP (w))
248e93f7393Sniklas     {
249e93f7393Sniklas       start_pc += 2 + adjust;
250e93f7393Sniklas       w = read_memory_unsigned_integer (start_pc, 2);
251e93f7393Sniklas     }
252e93f7393Sniklas 
253e93f7393Sniklas   /* Check for subs #2 and subs #4. */
254e93f7393Sniklas   while (IS_SUB2_SP (w) || IS_SUB4_SP (w))
255e93f7393Sniklas     {
256e93f7393Sniklas       start_pc += 2 + adjust;
257e93f7393Sniklas       w = read_memory_unsigned_integer (start_pc, 2);
258e93f7393Sniklas     }
259e93f7393Sniklas 
260e93f7393Sniklas   /* Check for a 32bit subtract.  */
261e93f7393Sniklas   if (IS_SUBL_SP (w))
262e93f7393Sniklas     start_pc += 6 + adjust;
263e93f7393Sniklas 
264b725ae77Skettenis   /* Skip past another possible stm insn for registers R3 to R5 (possibly used
265b725ae77Skettenis      for register qualified arguments.  */
266b725ae77Skettenis   w = read_memory_unsigned_integer (start_pc, 2);
267b725ae77Skettenis   /* First look for push insns.  */
268b725ae77Skettenis   if (w == 0x0110 || w == 0x0120 || w == 0x0130)
269b725ae77Skettenis     {
270b725ae77Skettenis       w = read_memory_unsigned_integer (start_pc + 2, 2);
271b725ae77Skettenis       if (IS_PUSH (w) && (w & 0xf) >= 0x3 && (w & 0xf) <= 0x5)
272b725ae77Skettenis 	start_pc += 4;
273b725ae77Skettenis     }
274b725ae77Skettenis 
275b725ae77Skettenis   /* Check for spilling an argument register to the stack frame.
276b725ae77Skettenis      This could also be an initializing store from non-prologue code,
277b725ae77Skettenis      but I don't think there's any harm in skipping that.  */
278b725ae77Skettenis   for (;;)
279b725ae77Skettenis     {
280b725ae77Skettenis       int spill_size = h8300_is_argument_spill (start_pc);
281b725ae77Skettenis       if (spill_size == 0)
282b725ae77Skettenis         break;
283b725ae77Skettenis       start_pc += spill_size;
284b725ae77Skettenis     }
285b725ae77Skettenis 
286e93f7393Sniklas   return start_pc;
287e93f7393Sniklas }
288e93f7393Sniklas 
289e93f7393Sniklas /* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
290e93f7393Sniklas    is not the address of a valid instruction, the address of the next
291e93f7393Sniklas    instruction beyond ADDR otherwise.  *PWORD1 receives the first word
292e93f7393Sniklas    of the instruction. */
293e93f7393Sniklas 
294b725ae77Skettenis static CORE_ADDR
h8300_next_prologue_insn(CORE_ADDR addr,CORE_ADDR lim,unsigned short * pword1)295b725ae77Skettenis h8300_next_prologue_insn (CORE_ADDR addr,
296b725ae77Skettenis 			  CORE_ADDR lim,
297b725ae77Skettenis 			  unsigned short* pword1)
298e93f7393Sniklas {
299e93f7393Sniklas   char buf[2];
300e93f7393Sniklas   if (addr < lim + 8)
301e93f7393Sniklas     {
302e93f7393Sniklas       read_memory (addr, buf, 2);
303e93f7393Sniklas       *pword1 = extract_signed_integer (buf, 2);
304e93f7393Sniklas 
305e93f7393Sniklas       return addr + 2;
306e93f7393Sniklas     }
307e93f7393Sniklas   return 0;
308e93f7393Sniklas }
309e93f7393Sniklas 
310e93f7393Sniklas /* Examine the prologue of a function.  `ip' points to the first instruction.
311e93f7393Sniklas    `limit' is the limit of the prologue (e.g. the addr of the first
312e93f7393Sniklas    linenumber, or perhaps the program counter if we're stepping through).
313e93f7393Sniklas    `frame_sp' is the stack pointer value in use in this frame.
314e93f7393Sniklas    `fsr' is a pointer to a frame_saved_regs structure into which we put
315e93f7393Sniklas    info about the registers saved by this frame.
316e93f7393Sniklas    `fi' is a struct frame_info pointer; we fill in various fields in it
317e93f7393Sniklas    to reflect the offsets of the arg pointer and the locals pointer.  */
318e93f7393Sniklas 
319b725ae77Skettenis /* Any function with a frame looks like this
320b725ae77Skettenis    SECOND ARG
321b725ae77Skettenis    FIRST ARG
322b725ae77Skettenis    RET PC
323b725ae77Skettenis    SAVED R2
324b725ae77Skettenis    SAVED R3
325b725ae77Skettenis    SAVED FP   <-FP POINTS HERE
326b725ae77Skettenis    LOCALS0
327b725ae77Skettenis    LOCALS1    <-SP POINTS HERE
328b725ae77Skettenis  */
329b725ae77Skettenis 
330e93f7393Sniklas static CORE_ADDR
h8300_examine_prologue(CORE_ADDR ip,CORE_ADDR limit,CORE_ADDR after_prolog_fp,CORE_ADDR * fsr,struct frame_info * fi)331b725ae77Skettenis h8300_examine_prologue (CORE_ADDR ip, CORE_ADDR limit,
332b725ae77Skettenis 			CORE_ADDR after_prolog_fp, CORE_ADDR *fsr,
333b725ae77Skettenis 			struct frame_info *fi)
334e93f7393Sniklas {
335b725ae77Skettenis   CORE_ADDR next_ip;
336e93f7393Sniklas   int r;
337e93f7393Sniklas   int have_fp = 0;
338b725ae77Skettenis   unsigned short insn_word;
339e93f7393Sniklas   /* Number of things pushed onto stack, starts at 2/4, 'cause the
340e93f7393Sniklas      PC is already there */
341b725ae77Skettenis   unsigned int reg_save_depth = BINWORD;
342e93f7393Sniklas 
343e93f7393Sniklas   unsigned int auto_depth = 0;	/* Number of bytes of autos */
344e93f7393Sniklas 
345e93f7393Sniklas   char in_frame[11];		/* One for each reg */
346e93f7393Sniklas 
347e93f7393Sniklas   int adjust = 0;
348e93f7393Sniklas 
349e93f7393Sniklas   memset (in_frame, 1, 11);
350e93f7393Sniklas   for (r = 0; r < 8; r++)
351e93f7393Sniklas     {
352b725ae77Skettenis       fsr[r] = 0;
353e93f7393Sniklas     }
354e93f7393Sniklas   if (after_prolog_fp == 0)
355e93f7393Sniklas     {
356b725ae77Skettenis       after_prolog_fp = read_register (E_SP_REGNUM);
357e93f7393Sniklas     }
358e93f7393Sniklas 
359e93f7393Sniklas   /* If the PC isn't valid, quit now.  */
360b725ae77Skettenis   if (ip == 0 || ip & (is_h8300hmode (current_gdbarch) &&
361b725ae77Skettenis 			 !is_h8300_normal_mode (current_gdbarch) ? ~0xffffff : ~0xffff))
362e93f7393Sniklas     return 0;
363e93f7393Sniklas 
364b725ae77Skettenis   next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
365e93f7393Sniklas 
366b725ae77Skettenis   if (insn_word == 0x0100)	/* mov.l */
367e93f7393Sniklas     {
368e93f7393Sniklas       insn_word = read_memory_unsigned_integer (ip + 2, 2);
369e93f7393Sniklas       adjust = 2;
370e93f7393Sniklas     }
371e93f7393Sniklas 
372e93f7393Sniklas   /* Skip over any fp push instructions */
373b725ae77Skettenis   fsr[E_FP_REGNUM] = after_prolog_fp;
374e93f7393Sniklas   while (next_ip && IS_PUSH_FP (insn_word))
375e93f7393Sniklas     {
376e93f7393Sniklas       ip = next_ip + adjust;
377e93f7393Sniklas 
378e93f7393Sniklas       in_frame[insn_word & 0x7] = reg_save_depth;
379b725ae77Skettenis       next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
380e93f7393Sniklas       reg_save_depth += 2 + adjust;
381e93f7393Sniklas     }
382e93f7393Sniklas 
383e93f7393Sniklas   /* Is this a move into the fp */
384e93f7393Sniklas   if (next_ip && IS_MOV_SP_FP (insn_word))
385e93f7393Sniklas     {
386e93f7393Sniklas       ip = next_ip;
387b725ae77Skettenis       next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
388e93f7393Sniklas       have_fp = 1;
389e93f7393Sniklas     }
390e93f7393Sniklas 
391e93f7393Sniklas   /* Skip over any stack adjustment, happens either with a number of
392e93f7393Sniklas      sub#2,sp or a mov #x,r5 sub r5,sp */
393e93f7393Sniklas 
394e93f7393Sniklas   if (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
395e93f7393Sniklas     {
396e93f7393Sniklas       while (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
397e93f7393Sniklas 	{
398e93f7393Sniklas 	  auto_depth += IS_SUB2_SP (insn_word) ? 2 : 4;
399e93f7393Sniklas 	  ip = next_ip;
400b725ae77Skettenis 	  next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
401e93f7393Sniklas 	}
402e93f7393Sniklas     }
403e93f7393Sniklas   else
404e93f7393Sniklas     {
405e93f7393Sniklas       if (next_ip && IS_MOVK_R5 (insn_word))
406e93f7393Sniklas 	{
407e93f7393Sniklas 	  ip = next_ip;
408b725ae77Skettenis 	  next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
409e93f7393Sniklas 	  auto_depth += insn_word;
410e93f7393Sniklas 
411b725ae77Skettenis 	  next_ip = h8300_next_prologue_insn (next_ip, limit, &insn_word);
412e93f7393Sniklas 	  auto_depth += insn_word;
413e93f7393Sniklas 	}
414e93f7393Sniklas       if (next_ip && IS_SUBL_SP (insn_word))
415e93f7393Sniklas 	{
416e93f7393Sniklas 	  ip = next_ip;
417e93f7393Sniklas 	  auto_depth += read_memory_unsigned_integer (ip, 4);
418e93f7393Sniklas 	  ip += 4;
419e93f7393Sniklas 
420b725ae77Skettenis 	  next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
421e93f7393Sniklas 	}
422e93f7393Sniklas     }
423e93f7393Sniklas 
424e93f7393Sniklas   /* Now examine the push insns to determine where everything lives
425e93f7393Sniklas      on the stack.  */
426e93f7393Sniklas   while (1)
427e93f7393Sniklas     {
428e93f7393Sniklas       adjust = 0;
429e93f7393Sniklas       if (!next_ip)
430e93f7393Sniklas 	break;
431e93f7393Sniklas 
432e93f7393Sniklas       if (insn_word == 0x0100)
433e93f7393Sniklas 	{
434e93f7393Sniklas 	  ip = next_ip;
435b725ae77Skettenis 	  next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
436e93f7393Sniklas 	  adjust = 2;
437e93f7393Sniklas 	}
438e93f7393Sniklas 
439e93f7393Sniklas       if (IS_PUSH (insn_word))
440e93f7393Sniklas 	{
441e93f7393Sniklas 	  auto_depth += 2 + adjust;
442b725ae77Skettenis 	  fsr[insn_word & 0x7] = after_prolog_fp - auto_depth;
443b725ae77Skettenis 	  ip = next_ip;
444b725ae77Skettenis 	  next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
445e93f7393Sniklas 	  continue;
446e93f7393Sniklas 	}
447e93f7393Sniklas 
448e93f7393Sniklas       /* Now check for push multiple insns.  */
449e93f7393Sniklas       if (insn_word == 0x0110 || insn_word == 0x0120 || insn_word == 0x0130)
450e93f7393Sniklas 	{
451e93f7393Sniklas 	  int count = ((insn_word >> 4) & 0xf) + 1;
452e93f7393Sniklas 	  int start, i;
453e93f7393Sniklas 
454e93f7393Sniklas 	  ip = next_ip;
455b725ae77Skettenis 	  next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
456e93f7393Sniklas 	  start = insn_word & 0x7;
457e93f7393Sniklas 
458b725ae77Skettenis 	  for (i = start; i < start + count; i++)
459e93f7393Sniklas 	    {
460e93f7393Sniklas 	      auto_depth += 4;
461b725ae77Skettenis 	      fsr[i] = after_prolog_fp - auto_depth;
462e93f7393Sniklas 	    }
463e93f7393Sniklas 	}
464e93f7393Sniklas       break;
465e93f7393Sniklas     }
466e93f7393Sniklas 
467e93f7393Sniklas   /* The PC is at a known place */
468b725ae77Skettenis   get_frame_extra_info (fi)->from_pc =
469b725ae77Skettenis     read_memory_unsigned_integer (after_prolog_fp + BINWORD, BINWORD);
470e93f7393Sniklas 
471e93f7393Sniklas   /* Rememeber any others too */
472b725ae77Skettenis   in_frame[E_PC_REGNUM] = 0;
473e93f7393Sniklas 
474e93f7393Sniklas   if (have_fp)
475e93f7393Sniklas     /* We keep the old FP in the SP spot */
476b725ae77Skettenis     fsr[E_SP_REGNUM] = read_memory_unsigned_integer (fsr[E_FP_REGNUM],
477b725ae77Skettenis 						     BINWORD);
478e93f7393Sniklas   else
479b725ae77Skettenis     fsr[E_SP_REGNUM] = after_prolog_fp + auto_depth;
480e93f7393Sniklas 
481e93f7393Sniklas   return (ip);
482e93f7393Sniklas }
483e93f7393Sniklas 
484b725ae77Skettenis static void
h8300_frame_init_saved_regs(struct frame_info * fi)485b725ae77Skettenis h8300_frame_init_saved_regs (struct frame_info *fi)
486e93f7393Sniklas {
487b725ae77Skettenis   CORE_ADDR func_addr, func_end;
488b725ae77Skettenis 
489b725ae77Skettenis   if (!deprecated_get_frame_saved_regs (fi))
490b725ae77Skettenis     {
491b725ae77Skettenis       frame_saved_regs_zalloc (fi);
492b725ae77Skettenis 
493b725ae77Skettenis       /* Find the beginning of this function, so we can analyze its
494b725ae77Skettenis 	 prologue. */
495b725ae77Skettenis       if (find_pc_partial_function (get_frame_pc (fi), NULL,
496b725ae77Skettenis 				    &func_addr, &func_end))
497b725ae77Skettenis         {
498b725ae77Skettenis 	  struct symtab_and_line sal = find_pc_line (func_addr, 0);
499b725ae77Skettenis 	  CORE_ADDR limit = (sal.end && sal.end < get_frame_pc (fi))
500b725ae77Skettenis 	    ? sal.end : get_frame_pc (fi);
501b725ae77Skettenis 	  /* This will fill in fields in fi. */
502b725ae77Skettenis 	  h8300_examine_prologue (func_addr, limit, get_frame_base (fi),
503b725ae77Skettenis 				  deprecated_get_frame_saved_regs (fi), fi);
504b725ae77Skettenis 	}
505b725ae77Skettenis       /* Else we're out of luck (can't debug completely stripped code).
506b725ae77Skettenis 	 FIXME. */
507b725ae77Skettenis     }
508b725ae77Skettenis }
509b725ae77Skettenis 
510b725ae77Skettenis /* Given a GDB frame, determine the address of the calling function's
511b725ae77Skettenis    frame.  This will be used to create a new GDB frame struct, and
512b725ae77Skettenis    then DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_INIT_FRAME_PC
513b725ae77Skettenis    will be called for the new frame.
514b725ae77Skettenis 
515b725ae77Skettenis    For us, the frame address is its stack pointer value, so we look up
516b725ae77Skettenis    the function prologue to determine the caller's sp value, and
517b725ae77Skettenis    return it.  */
518b725ae77Skettenis 
519b725ae77Skettenis static CORE_ADDR
h8300_frame_chain(struct frame_info * thisframe)520b725ae77Skettenis h8300_frame_chain (struct frame_info *thisframe)
521b725ae77Skettenis {
522*63addd46Skettenis   if (deprecated_pc_in_call_dummy (get_frame_pc (thisframe)))
523b725ae77Skettenis     {				/* initialize the from_pc now */
524b725ae77Skettenis       get_frame_extra_info (thisframe)->from_pc =
525b725ae77Skettenis 	deprecated_read_register_dummy (get_frame_pc (thisframe),
526b725ae77Skettenis 					get_frame_base (thisframe),
527b725ae77Skettenis 					E_PC_REGNUM);
528b725ae77Skettenis       return get_frame_base (thisframe);
529b725ae77Skettenis     }
530b725ae77Skettenis   return deprecated_get_frame_saved_regs (thisframe)[E_SP_REGNUM];
531e93f7393Sniklas }
532e93f7393Sniklas 
533e93f7393Sniklas /* Return the saved PC from this frame.
534e93f7393Sniklas 
535e93f7393Sniklas    If the frame has a memory copy of SRP_REGNUM, use that.  If not,
536e93f7393Sniklas    just use the register SRP_REGNUM itself.  */
537e93f7393Sniklas 
538b725ae77Skettenis static CORE_ADDR
h8300_frame_saved_pc(struct frame_info * frame)539b725ae77Skettenis h8300_frame_saved_pc (struct frame_info *frame)
540e93f7393Sniklas {
541*63addd46Skettenis   if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
542b725ae77Skettenis     return deprecated_read_register_dummy (get_frame_pc (frame),
543b725ae77Skettenis 					   get_frame_base (frame),
544b725ae77Skettenis 					   E_PC_REGNUM);
545b725ae77Skettenis   else
546b725ae77Skettenis     return get_frame_extra_info (frame)->from_pc;
547e93f7393Sniklas }
548e93f7393Sniklas 
549b725ae77Skettenis static void
h8300_init_extra_frame_info(int fromleaf,struct frame_info * fi)550b725ae77Skettenis h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
551e93f7393Sniklas {
552b725ae77Skettenis   if (!get_frame_extra_info (fi))
553e93f7393Sniklas     {
554b725ae77Skettenis       frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
555b725ae77Skettenis       get_frame_extra_info (fi)->from_pc = 0;
556e93f7393Sniklas 
557b725ae77Skettenis       if (!get_frame_pc (fi))
558b725ae77Skettenis         {
559b725ae77Skettenis 	  if (get_next_frame (fi))
560b725ae77Skettenis 	    deprecated_update_frame_pc_hack (fi, h8300_frame_saved_pc (get_next_frame (fi)));
561e93f7393Sniklas 	}
562b725ae77Skettenis       h8300_frame_init_saved_regs (fi);
563b725ae77Skettenis     }
564e93f7393Sniklas }
565e93f7393Sniklas 
566b725ae77Skettenis /* Function: push_dummy_call
567b725ae77Skettenis    Setup the function arguments for calling a function in the inferior.
568b725ae77Skettenis    In this discussion, a `word' is 16 bits on the H8/300s, and 32 bits
569b725ae77Skettenis    on the H8/300H.
570e93f7393Sniklas 
571b725ae77Skettenis    There are actually two ABI's here: -mquickcall (the default) and
572b725ae77Skettenis    -mno-quickcall.  With -mno-quickcall, all arguments are passed on
573b725ae77Skettenis    the stack after the return address, word-aligned.  With
574b725ae77Skettenis    -mquickcall, GCC tries to use r0 -- r2 to pass registers.  Since
575b725ae77Skettenis    GCC doesn't indicate in the object file which ABI was used to
576b725ae77Skettenis    compile it, GDB only supports the default --- -mquickcall.
577b725ae77Skettenis 
578b725ae77Skettenis    Here are the rules for -mquickcall, in detail:
579b725ae77Skettenis 
580b725ae77Skettenis    Each argument, whether scalar or aggregate, is padded to occupy a
581b725ae77Skettenis    whole number of words.  Arguments smaller than a word are padded at
582b725ae77Skettenis    the most significant end; those larger than a word are padded at
583b725ae77Skettenis    the least significant end.
584b725ae77Skettenis 
585b725ae77Skettenis    The initial arguments are passed in r0 -- r2.  Earlier arguments go in
586b725ae77Skettenis    lower-numbered registers.  Multi-word arguments are passed in
587b725ae77Skettenis    consecutive registers, with the most significant end in the
588b725ae77Skettenis    lower-numbered register.
589b725ae77Skettenis 
590b725ae77Skettenis    If an argument doesn't fit entirely in the remaining registers, it
591b725ae77Skettenis    is passed entirely on the stack.  Stack arguments begin just after
592b725ae77Skettenis    the return address.  Once an argument has overflowed onto the stack
593b725ae77Skettenis    this way, all subsequent arguments are passed on the stack.
594b725ae77Skettenis 
595b725ae77Skettenis    The above rule has odd consequences.  For example, on the h8/300s,
596b725ae77Skettenis    if a function takes two longs and an int as arguments:
597b725ae77Skettenis    - the first long will be passed in r0/r1,
598b725ae77Skettenis    - the second long will be passed entirely on the stack, since it
599b725ae77Skettenis      doesn't fit in r2,
600b725ae77Skettenis    - and the int will be passed on the stack, even though it could fit
601b725ae77Skettenis      in r2.
602b725ae77Skettenis 
603b725ae77Skettenis    A weird exception: if an argument is larger than a word, but not a
604b725ae77Skettenis    whole number of words in length (before padding), it is passed on
605b725ae77Skettenis    the stack following the rules for stack arguments above, even if
606b725ae77Skettenis    there are sufficient registers available to hold it.  Stranger
607b725ae77Skettenis    still, the argument registers are still `used up' --- even though
608b725ae77Skettenis    there's nothing in them.
609b725ae77Skettenis 
610b725ae77Skettenis    So, for example, on the h8/300s, if a function expects a three-byte
611b725ae77Skettenis    structure and an int, the structure will go on the stack, and the
612b725ae77Skettenis    int will go in r2, not r0.
613b725ae77Skettenis 
614b725ae77Skettenis    If the function returns an aggregate type (struct, union, or class)
615b725ae77Skettenis    by value, the caller must allocate space to hold the return value,
616b725ae77Skettenis    and pass the callee a pointer to this space as an invisible first
617b725ae77Skettenis    argument, in R0.
618b725ae77Skettenis 
619b725ae77Skettenis    For varargs functions, the last fixed argument and all the variable
620b725ae77Skettenis    arguments are always passed on the stack.  This means that calls to
621b725ae77Skettenis    varargs functions don't work properly unless there is a prototype
622b725ae77Skettenis    in scope.
623b725ae77Skettenis 
624b725ae77Skettenis    Basically, this ABI is not good, for the following reasons:
625b725ae77Skettenis    - You can't call vararg functions properly unless a prototype is in scope.
626b725ae77Skettenis    - Structure passing is inconsistent, to no purpose I can see.
627b725ae77Skettenis    - It often wastes argument registers, of which there are only three
628b725ae77Skettenis      to begin with.  */
629b725ae77Skettenis 
630b725ae77Skettenis static CORE_ADDR
h8300_push_dummy_call(struct gdbarch * gdbarch,struct value * function,struct regcache * regcache,CORE_ADDR bp_addr,int nargs,struct value ** args,CORE_ADDR sp,int struct_return,CORE_ADDR struct_addr)631*63addd46Skettenis h8300_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
632b725ae77Skettenis 		       struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
633b725ae77Skettenis 		       struct value **args, CORE_ADDR sp, int struct_return,
634b725ae77Skettenis 		       CORE_ADDR struct_addr)
635e93f7393Sniklas {
636b725ae77Skettenis   int stack_alloc = 0, stack_offset = 0;
637b725ae77Skettenis   int wordsize = BINWORD;
638b725ae77Skettenis   int reg = E_ARG0_REGNUM;
639b725ae77Skettenis   int argument;
640b725ae77Skettenis 
641b725ae77Skettenis   /* First, make sure the stack is properly aligned.  */
642b725ae77Skettenis   sp = align_down (sp, wordsize);
643b725ae77Skettenis 
644b725ae77Skettenis   /* Now make sure there's space on the stack for the arguments.  We
645b725ae77Skettenis      may over-allocate a little here, but that won't hurt anything.  */
646b725ae77Skettenis   for (argument = 0; argument < nargs; argument++)
647b725ae77Skettenis     stack_alloc += align_up (TYPE_LENGTH (VALUE_TYPE (args[argument])),
648b725ae77Skettenis                              wordsize);
649b725ae77Skettenis   sp -= stack_alloc;
650b725ae77Skettenis 
651b725ae77Skettenis   /* Now load as many arguments as possible into registers, and push
652b725ae77Skettenis      the rest onto the stack.
653b725ae77Skettenis      If we're returning a structure by value, then we must pass a
654b725ae77Skettenis      pointer to the buffer for the return value as an invisible first
655b725ae77Skettenis      argument.  */
656b725ae77Skettenis   if (struct_return)
657b725ae77Skettenis     regcache_cooked_write_unsigned (regcache, reg++, struct_addr);
658b725ae77Skettenis 
659b725ae77Skettenis   for (argument = 0; argument < nargs; argument++)
660e93f7393Sniklas     {
661b725ae77Skettenis       struct type *type = VALUE_TYPE (args[argument]);
662b725ae77Skettenis       int len = TYPE_LENGTH (type);
663b725ae77Skettenis       char *contents = (char *) VALUE_CONTENTS (args[argument]);
664e93f7393Sniklas 
665b725ae77Skettenis       /* Pad the argument appropriately.  */
666b725ae77Skettenis       int padded_len = align_up (len, wordsize);
667b725ae77Skettenis       char *padded = alloca (padded_len);
668e93f7393Sniklas 
669b725ae77Skettenis       memset (padded, 0, padded_len);
670b725ae77Skettenis       memcpy (len < wordsize ? padded + padded_len - len : padded,
671b725ae77Skettenis               contents, len);
672b725ae77Skettenis 
673b725ae77Skettenis       /* Could the argument fit in the remaining registers?  */
674b725ae77Skettenis       if (padded_len <= (E_ARGLAST_REGNUM - reg + 1) * wordsize)
675b725ae77Skettenis         {
676b725ae77Skettenis           /* Are we going to pass it on the stack anyway, for no good
677b725ae77Skettenis              reason?  */
678b725ae77Skettenis           if (len > wordsize && len % wordsize)
679b725ae77Skettenis             {
680b725ae77Skettenis               /* I feel so unclean.  */
681b725ae77Skettenis               write_memory (sp + stack_offset, padded, padded_len);
682b725ae77Skettenis               stack_offset += padded_len;
683b725ae77Skettenis 
684b725ae77Skettenis               /* That's right --- even though we passed the argument
685b725ae77Skettenis                  on the stack, we consume the registers anyway!  Love
686b725ae77Skettenis                  me, love my dog.  */
687b725ae77Skettenis               reg += padded_len / wordsize;
688b725ae77Skettenis             }
689b725ae77Skettenis           else
690b725ae77Skettenis             {
691b725ae77Skettenis               /* Heavens to Betsy --- it's really going in registers!
692b725ae77Skettenis                  It would be nice if we could use write_register_bytes
693b725ae77Skettenis                  here, but on the h8/300s, there are gaps between
694b725ae77Skettenis                  the registers in the register file.  */
695b725ae77Skettenis               int offset;
696b725ae77Skettenis 
697b725ae77Skettenis               for (offset = 0; offset < padded_len; offset += wordsize)
698b725ae77Skettenis                 {
699b725ae77Skettenis                   ULONGEST word = extract_unsigned_integer (padded + offset,
700b725ae77Skettenis 							    wordsize);
701b725ae77Skettenis 		  regcache_cooked_write_unsigned (regcache, reg++, word);
702b725ae77Skettenis                 }
703b725ae77Skettenis             }
704b725ae77Skettenis         }
705b725ae77Skettenis       else
706b725ae77Skettenis         {
707b725ae77Skettenis           /* It doesn't fit in registers!  Onto the stack it goes.  */
708b725ae77Skettenis           write_memory (sp + stack_offset, padded, padded_len);
709b725ae77Skettenis           stack_offset += padded_len;
710b725ae77Skettenis 
711b725ae77Skettenis           /* Once one argument has spilled onto the stack, all
712b725ae77Skettenis              subsequent arguments go on the stack.  */
713b725ae77Skettenis           reg = E_ARGLAST_REGNUM + 1;
714b725ae77Skettenis         }
715e93f7393Sniklas     }
716e93f7393Sniklas 
717b725ae77Skettenis   /* Store return address.  */
718b725ae77Skettenis   sp -= wordsize;
719b725ae77Skettenis   write_memory_unsigned_integer (sp, wordsize, bp_addr);
720b725ae77Skettenis 
721b725ae77Skettenis   /* Update stack pointer.  */
722b725ae77Skettenis   regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp);
723b725ae77Skettenis 
724b725ae77Skettenis   return sp;
725e93f7393Sniklas }
726e93f7393Sniklas 
727b725ae77Skettenis /* Function: h8300_pop_frame
728b725ae77Skettenis    Restore the machine to the state it had before the current frame
729b725ae77Skettenis    was created.  Usually used either by the "RETURN" command, or by
730b725ae77Skettenis    call_function_by_hand after the dummy_frame is finished. */
731b725ae77Skettenis 
732b725ae77Skettenis static void
h8300_pop_frame(void)733b725ae77Skettenis h8300_pop_frame (void)
734e93f7393Sniklas {
735b725ae77Skettenis   unsigned regno;
736e93f7393Sniklas   struct frame_info *frame = get_current_frame ();
737e93f7393Sniklas 
738*63addd46Skettenis   if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
739e93f7393Sniklas     {
740*63addd46Skettenis       deprecated_pop_dummy_frame ();
741b725ae77Skettenis     }
742b725ae77Skettenis   else
743b725ae77Skettenis     {
744b725ae77Skettenis       for (regno = 0; regno < 8; regno++)
745b725ae77Skettenis 	{
746b725ae77Skettenis 	  /* Don't forget E_SP_REGNUM is a frame_saved_regs struct is the
747e93f7393Sniklas 	     actual value we want, not the address of the value we want.  */
748b725ae77Skettenis 	  if (deprecated_get_frame_saved_regs (frame)[regno] && regno != E_SP_REGNUM)
749b725ae77Skettenis 	    write_register (regno,
750b725ae77Skettenis 			    read_memory_integer
751b725ae77Skettenis 			    (deprecated_get_frame_saved_regs (frame)[regno], BINWORD));
752b725ae77Skettenis 	  else if (deprecated_get_frame_saved_regs (frame)[regno] && regno == E_SP_REGNUM)
753b725ae77Skettenis 	    write_register (regno, get_frame_base (frame) + 2 * BINWORD);
754e93f7393Sniklas 	}
755e93f7393Sniklas 
756b725ae77Skettenis       /* Don't forget to update the PC too!  */
757b725ae77Skettenis       write_register (E_PC_REGNUM, get_frame_extra_info (frame)->from_pc);
758b725ae77Skettenis     }
759e93f7393Sniklas   flush_cached_frames ();
760e93f7393Sniklas }
761e93f7393Sniklas 
762b725ae77Skettenis /* Function: extract_return_value
763b725ae77Skettenis    Figure out where in REGBUF the called function has left its return value.
764b725ae77Skettenis    Copy that into VALBUF.  Be sure to account for CPU type.   */
765e93f7393Sniklas 
766e93f7393Sniklas static void
h8300_extract_return_value(struct type * type,struct regcache * regcache,void * valbuf)767b725ae77Skettenis h8300_extract_return_value (struct type *type, struct regcache *regcache,
768b725ae77Skettenis 			    void *valbuf)
769e93f7393Sniklas {
770b725ae77Skettenis   int len = TYPE_LENGTH (type);
771b725ae77Skettenis   ULONGEST c, addr;
772e93f7393Sniklas 
773b725ae77Skettenis   switch (len)
774e93f7393Sniklas     {
775b725ae77Skettenis       case 1:
776b725ae77Skettenis       case 2:
777b725ae77Skettenis 	regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
778b725ae77Skettenis 	store_unsigned_integer (valbuf, len, c);
779b725ae77Skettenis 	break;
780b725ae77Skettenis       case 4:	/* Needs two registers on plain H8/300 */
781b725ae77Skettenis 	regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
782b725ae77Skettenis 	store_unsigned_integer (valbuf, 2, c);
783b725ae77Skettenis 	regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c);
784b725ae77Skettenis 	store_unsigned_integer ((void*)((char *)valbuf + 2), 2, c);
785b725ae77Skettenis 	break;
786b725ae77Skettenis       case 8:	/* long long is now 8 bytes.  */
787b725ae77Skettenis 	if (TYPE_CODE (type) == TYPE_CODE_INT)
788e93f7393Sniklas 	  {
789b725ae77Skettenis 	    regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
790b725ae77Skettenis 	    c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
791b725ae77Skettenis 	    store_unsigned_integer (valbuf, len, c);
792e93f7393Sniklas 	  }
793e93f7393Sniklas 	else
794e93f7393Sniklas 	  {
795b725ae77Skettenis 	    error ("I don't know how this 8 byte value is returned.");
796b725ae77Skettenis 	  }
797b725ae77Skettenis 	break;
798e93f7393Sniklas     }
799e93f7393Sniklas }
800e93f7393Sniklas 
801b725ae77Skettenis static void
h8300h_extract_return_value(struct type * type,struct regcache * regcache,void * valbuf)802b725ae77Skettenis h8300h_extract_return_value (struct type *type, struct regcache *regcache,
803b725ae77Skettenis 			    void *valbuf)
804e93f7393Sniklas {
805b725ae77Skettenis   int len = TYPE_LENGTH (type);
806b725ae77Skettenis   ULONGEST c, addr;
807e93f7393Sniklas 
808b725ae77Skettenis   switch (len)
809b725ae77Skettenis     {
810b725ae77Skettenis       case 1:
811b725ae77Skettenis       case 2:
812b725ae77Skettenis       case 4:
813b725ae77Skettenis 	regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
814b725ae77Skettenis 	store_unsigned_integer (valbuf, len, c);
815b725ae77Skettenis 	break;
816b725ae77Skettenis       case 8:	/* long long is now 8 bytes.  */
817b725ae77Skettenis 	if (TYPE_CODE (type) == TYPE_CODE_INT)
818b725ae77Skettenis 	  {
819b725ae77Skettenis 	    regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
820b725ae77Skettenis 	    c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
821b725ae77Skettenis 	    store_unsigned_integer (valbuf, len, c);
822b725ae77Skettenis 	  }
823b725ae77Skettenis 	else
824b725ae77Skettenis 	  {
825b725ae77Skettenis 	    error ("I don't know how this 8 byte value is returned.");
826b725ae77Skettenis 	  }
827b725ae77Skettenis 	break;
828b725ae77Skettenis     }
829e93f7393Sniklas }
830e93f7393Sniklas 
831e93f7393Sniklas 
832b725ae77Skettenis /* Function: store_return_value
833b725ae77Skettenis    Place the appropriate value in the appropriate registers.
834b725ae77Skettenis    Primarily used by the RETURN command.  */
835e93f7393Sniklas 
836b725ae77Skettenis static void
h8300_store_return_value(struct type * type,struct regcache * regcache,const void * valbuf)837b725ae77Skettenis h8300_store_return_value (struct type *type, struct regcache *regcache,
838b725ae77Skettenis 			  const void *valbuf)
839e93f7393Sniklas {
840b725ae77Skettenis   int len = TYPE_LENGTH (type);
841b725ae77Skettenis   ULONGEST val;
842b725ae77Skettenis 
843b725ae77Skettenis   switch (len)
844b725ae77Skettenis     {
845b725ae77Skettenis       case 1:
846b725ae77Skettenis     case 2:	/* short... */
847b725ae77Skettenis 	val = extract_unsigned_integer (valbuf, len);
848b725ae77Skettenis 	regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
849b725ae77Skettenis 	break;
850b725ae77Skettenis       case 4:	/* long, float */
851b725ae77Skettenis 	val = extract_unsigned_integer (valbuf, len);
852b725ae77Skettenis 	regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM,
853b725ae77Skettenis 					(val >> 16) &0xffff);
854b725ae77Skettenis 	regcache_cooked_write_unsigned (regcache, E_RET1_REGNUM, val & 0xffff);
855b725ae77Skettenis 	break;
856b725ae77Skettenis       case 8:	/* long long, double and long double are all defined
857b725ae77Skettenis 		   as 4 byte types so far so this shouldn't happen.  */
858b725ae77Skettenis 	error ("I don't know how to return an 8 byte value.");
859b725ae77Skettenis 	break;
860b725ae77Skettenis     }
861b725ae77Skettenis }
862b725ae77Skettenis 
863b725ae77Skettenis static void
h8300h_store_return_value(struct type * type,struct regcache * regcache,const void * valbuf)864b725ae77Skettenis h8300h_store_return_value (struct type *type, struct regcache *regcache,
865b725ae77Skettenis 			   const void *valbuf)
866b725ae77Skettenis {
867b725ae77Skettenis   int len = TYPE_LENGTH (type);
868b725ae77Skettenis   ULONGEST val;
869b725ae77Skettenis 
870b725ae77Skettenis   switch (len)
871b725ae77Skettenis     {
872b725ae77Skettenis       case 1:
873b725ae77Skettenis       case 2:
874b725ae77Skettenis       case 4:	/* long, float */
875b725ae77Skettenis 	val = extract_unsigned_integer (valbuf, len);
876b725ae77Skettenis 	regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
877b725ae77Skettenis 	break;
878b725ae77Skettenis       case 8:	/* long long, double and long double are all defined
879b725ae77Skettenis 		   as 4 byte types so far so this shouldn't happen.  */
880b725ae77Skettenis 	error ("I don't know how to return an 8 byte value.");
881b725ae77Skettenis 	break;
882b725ae77Skettenis     }
883b725ae77Skettenis }
884b725ae77Skettenis 
885b725ae77Skettenis static struct cmd_list_element *setmachinelist;
886b725ae77Skettenis 
887b725ae77Skettenis static const char *
h8300_register_name(int regno)888b725ae77Skettenis h8300_register_name (int regno)
889b725ae77Skettenis {
890b725ae77Skettenis   /* The register names change depending on which h8300 processor
891b725ae77Skettenis      type is selected. */
892b725ae77Skettenis   static char *register_names[] = {
893b725ae77Skettenis     "r0", "r1", "r2", "r3", "r4", "r5", "r6",
894b725ae77Skettenis     "sp", "","pc","cycles", "tick", "inst",
895b725ae77Skettenis     "ccr", /* pseudo register */
896b725ae77Skettenis   };
897b725ae77Skettenis   if (regno < 0
898b725ae77Skettenis       || regno >= (sizeof (register_names) / sizeof (*register_names)))
899b725ae77Skettenis     internal_error (__FILE__, __LINE__,
900b725ae77Skettenis                     "h8300_register_name: illegal register number %d", regno);
901b725ae77Skettenis   else
902b725ae77Skettenis     return register_names[regno];
903b725ae77Skettenis }
904b725ae77Skettenis 
905b725ae77Skettenis static const char *
h8300s_register_name(int regno)906b725ae77Skettenis h8300s_register_name (int regno)
907b725ae77Skettenis {
908b725ae77Skettenis   static char *register_names[] = {
909b725ae77Skettenis     "er0", "er1", "er2", "er3", "er4", "er5", "er6",
910b725ae77Skettenis     "sp", "", "pc", "cycles", "", "tick", "inst",
911b725ae77Skettenis     "mach", "macl",
912b725ae77Skettenis     "ccr", "exr" /* pseudo registers */
913b725ae77Skettenis   };
914b725ae77Skettenis   if (regno < 0
915b725ae77Skettenis       || regno >= (sizeof (register_names) / sizeof (*register_names)))
916b725ae77Skettenis     internal_error (__FILE__, __LINE__,
917b725ae77Skettenis                     "h8300s_register_name: illegal register number %d", regno);
918b725ae77Skettenis   else
919b725ae77Skettenis     return register_names[regno];
920b725ae77Skettenis }
921b725ae77Skettenis 
922b725ae77Skettenis static const char *
h8300sx_register_name(int regno)923b725ae77Skettenis h8300sx_register_name (int regno)
924b725ae77Skettenis {
925b725ae77Skettenis   static char *register_names[] = {
926b725ae77Skettenis     "er0", "er1", "er2", "er3", "er4", "er5", "er6",
927b725ae77Skettenis     "sp", "", "pc", "cycles", "", "tick", "inst",
928b725ae77Skettenis     "mach", "macl", "sbr", "vbr",
929b725ae77Skettenis     "ccr", "exr" /* pseudo registers */
930b725ae77Skettenis   };
931b725ae77Skettenis   if (regno < 0
932b725ae77Skettenis       || regno >= (sizeof (register_names) / sizeof (*register_names)))
933b725ae77Skettenis     internal_error (__FILE__, __LINE__,
934b725ae77Skettenis 		    "h8300sx_register_name: illegal register number %d", regno);
935b725ae77Skettenis   else
936b725ae77Skettenis     return register_names[regno];
937b725ae77Skettenis }
938b725ae77Skettenis 
939b725ae77Skettenis static void
h8300_print_register(struct gdbarch * gdbarch,struct ui_file * file,struct frame_info * frame,int regno)940b725ae77Skettenis h8300_print_register (struct gdbarch *gdbarch, struct ui_file *file,
941b725ae77Skettenis 		      struct frame_info *frame, int regno)
942b725ae77Skettenis {
943b725ae77Skettenis   LONGEST rval;
944b725ae77Skettenis   const char *name = gdbarch_register_name (gdbarch, regno);
945b725ae77Skettenis 
946b725ae77Skettenis   if (!name || !*name)
947b725ae77Skettenis     return;
948b725ae77Skettenis 
949b725ae77Skettenis   rval = get_frame_register_signed (frame, regno);
950b725ae77Skettenis 
951b725ae77Skettenis   fprintf_filtered (file, "%-14s ", name);
952b725ae77Skettenis   if (regno == E_PSEUDO_CCR_REGNUM ||
953b725ae77Skettenis        (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch)))
954b725ae77Skettenis     {
955b725ae77Skettenis       fprintf_filtered (file, "0x%02x        ", (unsigned char)rval);
956b725ae77Skettenis       print_longest (file, 'u', 1, rval);
957b725ae77Skettenis     }
958b725ae77Skettenis   else
959b725ae77Skettenis     {
960b725ae77Skettenis       fprintf_filtered (file, "0x%s  ", phex ((ULONGEST)rval, BINWORD));
961b725ae77Skettenis       print_longest (file, 'd', 1, rval);
962b725ae77Skettenis     }
963b725ae77Skettenis   if (regno == E_PSEUDO_CCR_REGNUM)
964e93f7393Sniklas     {
965e93f7393Sniklas       /* CCR register */
966e93f7393Sniklas       int C, Z, N, V;
967b725ae77Skettenis       unsigned char l = rval & 0xff;
968b725ae77Skettenis       fprintf_filtered (file, "\t");
969b725ae77Skettenis       fprintf_filtered (file, "I-%d ", (l & 0x80) != 0);
970b725ae77Skettenis       fprintf_filtered (file, "UI-%d ", (l & 0x40) != 0);
971b725ae77Skettenis       fprintf_filtered (file, "H-%d ", (l & 0x20) != 0);
972b725ae77Skettenis       fprintf_filtered (file, "U-%d ", (l & 0x10) != 0);
973e93f7393Sniklas       N = (l & 0x8) != 0;
974e93f7393Sniklas       Z = (l & 0x4) != 0;
975e93f7393Sniklas       V = (l & 0x2) != 0;
976e93f7393Sniklas       C = (l & 0x1) != 0;
977b725ae77Skettenis       fprintf_filtered (file, "N-%d ", N);
978b725ae77Skettenis       fprintf_filtered (file, "Z-%d ", Z);
979b725ae77Skettenis       fprintf_filtered (file, "V-%d ", V);
980b725ae77Skettenis       fprintf_filtered (file, "C-%d ", C);
981e93f7393Sniklas       if ((C | Z) == 0)
982b725ae77Skettenis 	fprintf_filtered (file, "u> ");
983e93f7393Sniklas       if ((C | Z) == 1)
984b725ae77Skettenis 	fprintf_filtered (file, "u<= ");
985e93f7393Sniklas       if ((C == 0))
986b725ae77Skettenis 	fprintf_filtered (file, "u>= ");
987e93f7393Sniklas       if (C == 1)
988b725ae77Skettenis 	fprintf_filtered (file, "u< ");
989e93f7393Sniklas       if (Z == 0)
990b725ae77Skettenis 	fprintf_filtered (file, "!= ");
991e93f7393Sniklas       if (Z == 1)
992b725ae77Skettenis 	fprintf_filtered (file, "== ");
993e93f7393Sniklas       if ((N ^ V) == 0)
994b725ae77Skettenis 	fprintf_filtered (file, ">= ");
995e93f7393Sniklas       if ((N ^ V) == 1)
996b725ae77Skettenis 	fprintf_filtered (file, "< ");
997e93f7393Sniklas       if ((Z | (N ^ V)) == 0)
998b725ae77Skettenis 	fprintf_filtered (file, "> ");
999e93f7393Sniklas       if ((Z | (N ^ V)) == 1)
1000b725ae77Skettenis 	fprintf_filtered (file, "<= ");
1001b725ae77Skettenis     }
1002b725ae77Skettenis   else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
1003b725ae77Skettenis     {
1004b725ae77Skettenis       /* EXR register */
1005b725ae77Skettenis       unsigned char l = rval & 0xff;
1006b725ae77Skettenis       fprintf_filtered (file, "\t");
1007b725ae77Skettenis       fprintf_filtered (file, "T-%d - - - ", (l & 0x80) != 0);
1008b725ae77Skettenis       fprintf_filtered (file, "I2-%d ", (l & 4) != 0);
1009b725ae77Skettenis       fprintf_filtered (file, "I1-%d ", (l & 2) != 0);
1010b725ae77Skettenis       fprintf_filtered (file, "I0-%d", (l & 1) != 0);
1011b725ae77Skettenis     }
1012b725ae77Skettenis   fprintf_filtered (file, "\n");
1013b725ae77Skettenis }
1014b725ae77Skettenis 
1015b725ae77Skettenis static void
h8300_print_registers_info(struct gdbarch * gdbarch,struct ui_file * file,struct frame_info * frame,int regno,int cpregs)1016b725ae77Skettenis h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
1017b725ae77Skettenis 			    struct frame_info *frame, int regno, int cpregs)
1018b725ae77Skettenis {
1019b725ae77Skettenis   if (regno < 0)
1020b725ae77Skettenis     {
1021b725ae77Skettenis       for (regno = E_R0_REGNUM; regno <= E_SP_REGNUM; ++regno)
1022b725ae77Skettenis 	h8300_print_register (gdbarch, file, frame, regno);
1023b725ae77Skettenis       h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
1024b725ae77Skettenis       h8300_print_register (gdbarch, file, frame, E_PC_REGNUM);
1025b725ae77Skettenis       if (is_h8300smode (current_gdbarch))
1026b725ae77Skettenis         {
1027b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
1028b725ae77Skettenis 	  if (is_h8300sxmode (current_gdbarch))
1029b725ae77Skettenis 	    {
1030b725ae77Skettenis 	      h8300_print_register (gdbarch, file, frame, E_SBR_REGNUM);
1031b725ae77Skettenis 	      h8300_print_register (gdbarch, file, frame, E_VBR_REGNUM);
1032b725ae77Skettenis 	    }
1033b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_MACH_REGNUM);
1034b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_MACL_REGNUM);
1035b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_CYCLES_REGNUM);
1036b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_TICKS_REGNUM);
1037b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_INSTS_REGNUM);
1038b725ae77Skettenis 	}
1039b725ae77Skettenis       else
1040b725ae77Skettenis         {
1041b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_CYCLES_REGNUM);
1042b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_TICK_REGNUM);
1043b725ae77Skettenis 	  h8300_print_register (gdbarch, file, frame, E_INST_REGNUM);
1044b725ae77Skettenis 	}
1045b725ae77Skettenis     }
1046b725ae77Skettenis   else
1047b725ae77Skettenis     {
1048b725ae77Skettenis       if (regno == E_CCR_REGNUM)
1049b725ae77Skettenis         h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
1050b725ae77Skettenis       else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
1051b725ae77Skettenis 	h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
1052b725ae77Skettenis       else
1053b725ae77Skettenis 	h8300_print_register (gdbarch, file, frame, regno);
1054e93f7393Sniklas     }
1055e93f7393Sniklas }
1056e93f7393Sniklas 
1057b725ae77Skettenis static CORE_ADDR
h8300_saved_pc_after_call(struct frame_info * ignore)1058b725ae77Skettenis h8300_saved_pc_after_call (struct frame_info *ignore)
1059e93f7393Sniklas {
1060b725ae77Skettenis   return read_memory_unsigned_integer (read_register (E_SP_REGNUM), BINWORD);
1061e93f7393Sniklas }
1062b725ae77Skettenis 
1063b725ae77Skettenis static struct type *
h8300_register_type(struct gdbarch * gdbarch,int regno)1064b725ae77Skettenis h8300_register_type (struct gdbarch *gdbarch, int regno)
1065b725ae77Skettenis {
1066b725ae77Skettenis   if (regno < 0 || regno >= NUM_REGS + NUM_PSEUDO_REGS)
1067b725ae77Skettenis     internal_error (__FILE__, __LINE__,
1068b725ae77Skettenis 		    "h8300_register_type: illegal register number %d",
1069b725ae77Skettenis 		    regno);
1070b725ae77Skettenis   else
1071b725ae77Skettenis     {
1072b725ae77Skettenis       switch (regno)
1073b725ae77Skettenis         {
1074b725ae77Skettenis 	  case E_PC_REGNUM:
1075b725ae77Skettenis 	    return builtin_type_void_func_ptr;
1076b725ae77Skettenis 	  case E_SP_REGNUM:
1077b725ae77Skettenis 	  case E_FP_REGNUM:
1078b725ae77Skettenis 	    return builtin_type_void_data_ptr;
1079b725ae77Skettenis 	  default:
1080b725ae77Skettenis 	    if (regno == E_PSEUDO_CCR_REGNUM)
1081b725ae77Skettenis 	      return builtin_type_uint8;
1082b725ae77Skettenis 	    else if (regno == E_PSEUDO_EXR_REGNUM)
1083b725ae77Skettenis 	      return builtin_type_uint8;
1084b725ae77Skettenis 	    else if (is_h8300hmode (current_gdbarch))
1085b725ae77Skettenis 	      return builtin_type_int32;
1086b725ae77Skettenis 	    else
1087b725ae77Skettenis 	      return builtin_type_int16;
1088b725ae77Skettenis         }
1089b725ae77Skettenis     }
1090b725ae77Skettenis }
1091b725ae77Skettenis 
1092b725ae77Skettenis static void
h8300_pseudo_register_read(struct gdbarch * gdbarch,struct regcache * regcache,int regno,void * buf)1093b725ae77Skettenis h8300_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
1094b725ae77Skettenis 			    int regno, void *buf)
1095b725ae77Skettenis {
1096b725ae77Skettenis   if (regno == E_PSEUDO_CCR_REGNUM)
1097b725ae77Skettenis     regcache_raw_read (regcache, E_CCR_REGNUM, buf);
1098b725ae77Skettenis   else if (regno == E_PSEUDO_EXR_REGNUM)
1099b725ae77Skettenis     regcache_raw_read (regcache, E_EXR_REGNUM, buf);
1100b725ae77Skettenis   else
1101b725ae77Skettenis     regcache_raw_read (regcache, regno, buf);
1102b725ae77Skettenis }
1103b725ae77Skettenis 
1104b725ae77Skettenis static void
h8300_pseudo_register_write(struct gdbarch * gdbarch,struct regcache * regcache,int regno,const void * buf)1105b725ae77Skettenis h8300_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
1106b725ae77Skettenis 			     int regno, const void *buf)
1107b725ae77Skettenis {
1108b725ae77Skettenis   if (regno == E_PSEUDO_CCR_REGNUM)
1109b725ae77Skettenis     regcache_raw_write (regcache, E_CCR_REGNUM, buf);
1110b725ae77Skettenis   else if (regno == E_PSEUDO_EXR_REGNUM)
1111b725ae77Skettenis     regcache_raw_write (regcache, E_EXR_REGNUM, buf);
1112b725ae77Skettenis   else
1113b725ae77Skettenis     regcache_raw_write (regcache, regno, buf);
1114b725ae77Skettenis }
1115b725ae77Skettenis 
1116b725ae77Skettenis static int
h8300_dbg_reg_to_regnum(int regno)1117b725ae77Skettenis h8300_dbg_reg_to_regnum (int regno)
1118b725ae77Skettenis {
1119b725ae77Skettenis   if (regno == E_CCR_REGNUM)
1120b725ae77Skettenis     return E_PSEUDO_CCR_REGNUM;
1121b725ae77Skettenis   return regno;
1122b725ae77Skettenis }
1123b725ae77Skettenis 
1124b725ae77Skettenis static int
h8300s_dbg_reg_to_regnum(int regno)1125b725ae77Skettenis h8300s_dbg_reg_to_regnum (int regno)
1126b725ae77Skettenis {
1127b725ae77Skettenis   if (regno == E_CCR_REGNUM)
1128b725ae77Skettenis     return E_PSEUDO_CCR_REGNUM;
1129b725ae77Skettenis   if (regno == E_EXR_REGNUM)
1130b725ae77Skettenis     return E_PSEUDO_EXR_REGNUM;
1131b725ae77Skettenis   return regno;
1132b725ae77Skettenis }
1133b725ae77Skettenis 
1134b725ae77Skettenis static CORE_ADDR
h8300_extract_struct_value_address(struct regcache * regcache)1135b725ae77Skettenis h8300_extract_struct_value_address (struct regcache *regcache)
1136b725ae77Skettenis {
1137b725ae77Skettenis   ULONGEST addr;
1138b725ae77Skettenis   regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
1139b725ae77Skettenis   return addr;
1140b725ae77Skettenis }
1141b725ae77Skettenis 
1142b725ae77Skettenis const static unsigned char *
h8300_breakpoint_from_pc(CORE_ADDR * pcptr,int * lenptr)1143b725ae77Skettenis h8300_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
1144b725ae77Skettenis {
1145b725ae77Skettenis   /*static unsigned char breakpoint[] = { 0x7A, 0xFF };*/	/* ??? */
1146b725ae77Skettenis   static unsigned char breakpoint[] = { 0x01, 0x80 };		/* Sleep */
1147b725ae77Skettenis 
1148b725ae77Skettenis   *lenptr = sizeof (breakpoint);
1149b725ae77Skettenis   return breakpoint;
1150b725ae77Skettenis }
1151b725ae77Skettenis 
1152b725ae77Skettenis static CORE_ADDR
h8300_push_dummy_code(struct gdbarch * gdbarch,CORE_ADDR sp,CORE_ADDR funaddr,int using_gcc,struct value ** args,int nargs,struct type * value_type,CORE_ADDR * real_pc,CORE_ADDR * bp_addr)1153b725ae77Skettenis h8300_push_dummy_code (struct gdbarch *gdbarch,
1154b725ae77Skettenis 		       CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc,
1155b725ae77Skettenis 		       struct value **args, int nargs,
1156b725ae77Skettenis 		       struct type *value_type,
1157b725ae77Skettenis 		       CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
1158b725ae77Skettenis {
1159b725ae77Skettenis   /* Allocate space sufficient for a breakpoint.  */
1160b725ae77Skettenis   sp = (sp - 2) & ~1;
1161b725ae77Skettenis   /* Store the address of that breakpoint */
1162b725ae77Skettenis   *bp_addr = sp;
1163b725ae77Skettenis   /* h8300 always starts the call at the callee's entry point.  */
1164b725ae77Skettenis   *real_pc = funaddr;
1165b725ae77Skettenis   return sp;
1166b725ae77Skettenis }
1167b725ae77Skettenis 
1168b725ae77Skettenis static void
h8300_print_float_info(struct gdbarch * gdbarch,struct ui_file * file,struct frame_info * frame,const char * args)1169b725ae77Skettenis h8300_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
1170b725ae77Skettenis 			struct frame_info *frame, const char *args)
1171b725ae77Skettenis {
1172b725ae77Skettenis   fprintf_filtered (file, "\
1173b725ae77Skettenis No floating-point info available for this processor.\n");
1174b725ae77Skettenis }
1175b725ae77Skettenis 
1176b725ae77Skettenis static struct gdbarch *
h8300_gdbarch_init(struct gdbarch_info info,struct gdbarch_list * arches)1177b725ae77Skettenis h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
1178b725ae77Skettenis {
1179b725ae77Skettenis   struct gdbarch_tdep *tdep = NULL;
1180b725ae77Skettenis   struct gdbarch *gdbarch;
1181b725ae77Skettenis 
1182b725ae77Skettenis   arches = gdbarch_list_lookup_by_info (arches, &info);
1183b725ae77Skettenis   if (arches != NULL)
1184b725ae77Skettenis     return arches->gdbarch;
1185b725ae77Skettenis 
1186b725ae77Skettenis #if 0
1187b725ae77Skettenis   tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
1188b725ae77Skettenis #endif
1189b725ae77Skettenis 
1190b725ae77Skettenis   if (info.bfd_arch_info->arch != bfd_arch_h8300)
1191b725ae77Skettenis     return NULL;
1192b725ae77Skettenis 
1193b725ae77Skettenis   gdbarch = gdbarch_alloc (&info, 0);
1194b725ae77Skettenis 
1195b725ae77Skettenis   switch (info.bfd_arch_info->mach)
1196b725ae77Skettenis     {
1197b725ae77Skettenis     case bfd_mach_h8300:
1198b725ae77Skettenis       set_gdbarch_num_regs (gdbarch, 13);
1199b725ae77Skettenis       set_gdbarch_num_pseudo_regs (gdbarch, 1);
1200b725ae77Skettenis       set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
1201b725ae77Skettenis       set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
1202b725ae77Skettenis       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
1203b725ae77Skettenis       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
1204b725ae77Skettenis       set_gdbarch_register_name (gdbarch, h8300_register_name);
1205b725ae77Skettenis       set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1206b725ae77Skettenis       set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1207b725ae77Skettenis       set_gdbarch_extract_return_value (gdbarch, h8300_extract_return_value);
1208b725ae77Skettenis       set_gdbarch_store_return_value (gdbarch, h8300_store_return_value);
1209b725ae77Skettenis       set_gdbarch_print_insn (gdbarch, print_insn_h8300);
1210b725ae77Skettenis       break;
1211b725ae77Skettenis     case bfd_mach_h8300h:
1212b725ae77Skettenis     case bfd_mach_h8300hn:
1213b725ae77Skettenis       set_gdbarch_num_regs (gdbarch, 13);
1214b725ae77Skettenis       set_gdbarch_num_pseudo_regs (gdbarch, 1);
1215b725ae77Skettenis       set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
1216b725ae77Skettenis       set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
1217b725ae77Skettenis       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
1218b725ae77Skettenis       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
1219b725ae77Skettenis       set_gdbarch_register_name (gdbarch, h8300_register_name);
1220b725ae77Skettenis       if(info.bfd_arch_info->mach != bfd_mach_h8300hn)
1221b725ae77Skettenis         {
1222b725ae77Skettenis           set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1223b725ae77Skettenis           set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1224b725ae77Skettenis         }
1225b725ae77Skettenis       else
1226b725ae77Skettenis         {
1227b725ae77Skettenis           set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1228b725ae77Skettenis           set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1229b725ae77Skettenis         }
1230b725ae77Skettenis       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
1231b725ae77Skettenis       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
1232b725ae77Skettenis       set_gdbarch_print_insn (gdbarch, print_insn_h8300h);
1233b725ae77Skettenis       break;
1234b725ae77Skettenis     case bfd_mach_h8300s:
1235b725ae77Skettenis     case bfd_mach_h8300sn:
1236b725ae77Skettenis       set_gdbarch_num_regs (gdbarch, 16);
1237b725ae77Skettenis       set_gdbarch_num_pseudo_regs (gdbarch, 2);
1238b725ae77Skettenis       set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
1239b725ae77Skettenis       set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
1240b725ae77Skettenis       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
1241b725ae77Skettenis       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
1242b725ae77Skettenis       set_gdbarch_register_name (gdbarch, h8300s_register_name);
1243b725ae77Skettenis       if(info.bfd_arch_info->mach != bfd_mach_h8300sn)
1244b725ae77Skettenis         {
1245b725ae77Skettenis           set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1246b725ae77Skettenis           set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1247b725ae77Skettenis         }
1248b725ae77Skettenis       else
1249b725ae77Skettenis         {
1250b725ae77Skettenis           set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1251b725ae77Skettenis           set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1252b725ae77Skettenis         }
1253b725ae77Skettenis       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
1254b725ae77Skettenis       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
1255b725ae77Skettenis       set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
1256b725ae77Skettenis       break;
1257b725ae77Skettenis     case bfd_mach_h8300sx:
1258b725ae77Skettenis     case bfd_mach_h8300sxn:
1259b725ae77Skettenis       set_gdbarch_num_regs (gdbarch, 18);
1260b725ae77Skettenis       set_gdbarch_num_pseudo_regs (gdbarch, 2);
1261b725ae77Skettenis       set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
1262b725ae77Skettenis       set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
1263b725ae77Skettenis       set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
1264b725ae77Skettenis       set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
1265b725ae77Skettenis       set_gdbarch_register_name (gdbarch, h8300sx_register_name);
1266b725ae77Skettenis       if(info.bfd_arch_info->mach != bfd_mach_h8300sxn)
1267b725ae77Skettenis         {
1268b725ae77Skettenis           set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1269b725ae77Skettenis           set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1270b725ae77Skettenis         }
1271b725ae77Skettenis       else
1272b725ae77Skettenis         {
1273b725ae77Skettenis           set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1274b725ae77Skettenis           set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1275b725ae77Skettenis         }
1276b725ae77Skettenis       set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
1277b725ae77Skettenis       set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
1278b725ae77Skettenis       set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
1279b725ae77Skettenis       break;
1280b725ae77Skettenis     }
1281b725ae77Skettenis 
1282b725ae77Skettenis   set_gdbarch_pseudo_register_read (gdbarch, h8300_pseudo_register_read);
1283b725ae77Skettenis   set_gdbarch_pseudo_register_write (gdbarch, h8300_pseudo_register_write);
1284b725ae77Skettenis 
1285b725ae77Skettenis   /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
1286b725ae77Skettenis      ready to unwind the PC first (see frame.c:get_prev_frame()).  */
1287b725ae77Skettenis   set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
1288b725ae77Skettenis 
1289b725ae77Skettenis   /*
1290b725ae77Skettenis    * Basic register fields and methods.
1291b725ae77Skettenis    */
1292b725ae77Skettenis 
1293b725ae77Skettenis   set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
1294b725ae77Skettenis   set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
1295b725ae77Skettenis   set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
1296b725ae77Skettenis   set_gdbarch_register_type (gdbarch, h8300_register_type);
1297b725ae77Skettenis   set_gdbarch_print_registers_info (gdbarch, h8300_print_registers_info);
1298b725ae77Skettenis   set_gdbarch_print_float_info (gdbarch, h8300_print_float_info);
1299b725ae77Skettenis 
1300b725ae77Skettenis   /*
1301b725ae77Skettenis    * Frame Info
1302b725ae77Skettenis    */
1303b725ae77Skettenis   set_gdbarch_skip_prologue (gdbarch, h8300_skip_prologue);
1304b725ae77Skettenis 
1305b725ae77Skettenis   set_gdbarch_deprecated_frame_init_saved_regs (gdbarch,
1306b725ae77Skettenis 						h8300_frame_init_saved_regs);
1307b725ae77Skettenis   set_gdbarch_deprecated_init_extra_frame_info (gdbarch,
1308b725ae77Skettenis 						h8300_init_extra_frame_info);
1309b725ae77Skettenis   set_gdbarch_deprecated_frame_chain (gdbarch, h8300_frame_chain);
1310b725ae77Skettenis   set_gdbarch_deprecated_saved_pc_after_call (gdbarch,
1311b725ae77Skettenis 					      h8300_saved_pc_after_call);
1312b725ae77Skettenis   set_gdbarch_deprecated_frame_saved_pc (gdbarch, h8300_frame_saved_pc);
1313b725ae77Skettenis   set_gdbarch_deprecated_pop_frame (gdbarch, h8300_pop_frame);
1314b725ae77Skettenis 
1315b725ae77Skettenis   /*
1316b725ae77Skettenis    * Miscelany
1317b725ae77Skettenis    */
1318b725ae77Skettenis   /* Stack grows up. */
1319b725ae77Skettenis   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
1320b725ae77Skettenis 
1321b725ae77Skettenis   set_gdbarch_deprecated_extract_struct_value_address (gdbarch, h8300_extract_struct_value_address);
1322*63addd46Skettenis   set_gdbarch_deprecated_use_struct_convention (gdbarch, always_use_struct_convention);
1323b725ae77Skettenis   set_gdbarch_breakpoint_from_pc (gdbarch, h8300_breakpoint_from_pc);
1324b725ae77Skettenis   set_gdbarch_push_dummy_code (gdbarch, h8300_push_dummy_code);
1325b725ae77Skettenis   set_gdbarch_push_dummy_call (gdbarch, h8300_push_dummy_call);
1326b725ae77Skettenis 
1327b725ae77Skettenis   set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
1328b725ae77Skettenis   set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1329b725ae77Skettenis   set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
1330b725ae77Skettenis   set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1331b725ae77Skettenis   set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
1332b725ae77Skettenis 
1333b725ae77Skettenis   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
1334b725ae77Skettenis 
1335b725ae77Skettenis   /* Char is unsigned.  */
1336b725ae77Skettenis   set_gdbarch_char_signed (gdbarch, 0);
1337b725ae77Skettenis 
1338b725ae77Skettenis   return gdbarch;
1339b725ae77Skettenis }
1340b725ae77Skettenis 
1341b725ae77Skettenis extern initialize_file_ftype _initialize_h8300_tdep; /* -Wmissing-prototypes */
1342b725ae77Skettenis 
1343b725ae77Skettenis void
_initialize_h8300_tdep(void)1344b725ae77Skettenis _initialize_h8300_tdep (void)
1345b725ae77Skettenis {
1346b725ae77Skettenis   register_gdbarch_init (bfd_arch_h8300, h8300_gdbarch_init);
1347b725ae77Skettenis }
1348b725ae77Skettenis 
1349b725ae77Skettenis static int
is_h8300hmode(struct gdbarch * gdbarch)1350b725ae77Skettenis is_h8300hmode (struct gdbarch *gdbarch)
1351b725ae77Skettenis {
1352b725ae77Skettenis   return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
1353b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
1354b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
1355b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
1356b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300h
1357b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
1358b725ae77Skettenis }
1359b725ae77Skettenis 
1360b725ae77Skettenis static int
is_h8300smode(struct gdbarch * gdbarch)1361b725ae77Skettenis is_h8300smode (struct gdbarch *gdbarch)
1362b725ae77Skettenis {
1363b725ae77Skettenis   return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
1364b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
1365b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
1366b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn;
1367b725ae77Skettenis }
1368b725ae77Skettenis 
1369b725ae77Skettenis static int
is_h8300sxmode(struct gdbarch * gdbarch)1370b725ae77Skettenis is_h8300sxmode (struct gdbarch *gdbarch)
1371b725ae77Skettenis {
1372b725ae77Skettenis   return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
1373b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn;
1374b725ae77Skettenis }
1375b725ae77Skettenis 
1376b725ae77Skettenis static int
is_h8300_normal_mode(struct gdbarch * gdbarch)1377b725ae77Skettenis is_h8300_normal_mode (struct gdbarch *gdbarch)
1378b725ae77Skettenis {
1379b725ae77Skettenis   return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
1380b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
1381b725ae77Skettenis 	 || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
1382b725ae77Skettenis }
1383b725ae77Skettenis 
1384