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