From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8886 invoked by alias); 14 Nov 2004 16:23:35 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 8725 invoked from network); 14 Nov 2004 16:23:23 -0000 Received: from unknown (HELO mitou.ysato.dip.jp) (218.219.247.150) by sourceware.org with SMTP; 14 Nov 2004 16:23:23 -0000 Received: from mitou.localdomain (unknown [192.168.16.2]) by mitou.ysato.dip.jp (Postfix) with ESMTP id B31771C19E for ; Mon, 15 Nov 2004 01:23:21 +0900 (JST) Date: Sun, 14 Nov 2004 16:23:00 -0000 Message-ID: From: Yoshinori Sato To: gdb-patches@sources.redhat.com Subject: [PATCH] new frame code for h8300 target User-Agent: Wanderlust/2.11.30 (Wonderwall) SEMI/1.14.6 (Maruoka) FLIM/1.14.6 (Marutamachi) APEL/10.6 Emacs/21.3 (i386-pc-linux-gnu) MULE/5.0 (SAKAKI) MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-SW-Source: 2004-11/txt/msg00305.txt.bz2 It is a new frame code patch for a gdb-6.3 h8300 target. Because I still use it, I am at a loss very that it is deleted. ===File ~/gdb-6.3/gdb/h8300-tdep.c.diff===================== --- h8300-tdep.c~ 2004-08-03 04:44:40.000000000 +0900 +++ h8300-tdep.c 2004-11-15 01:03:08.000000000 +0900 @@ -36,6 +36,10 @@ #include "gdbcmd.h" #include "gdb_assert.h" #include "dis-asm.h" +#include "dwarf2-frame.h" +#include "frame.h" +#include "frame-base.h" +#include "frame-unwind.h" /* Extra info which is saved in each frame_info. */ struct frame_extra_info @@ -81,6 +85,8 @@ E_VBR_REGNUM }; +#define H8300_MAX_NUM_REGS 18 + #define E_PSEUDO_CCR_REGNUM (NUM_REGS) #define E_PSEUDO_EXR_REGNUM (NUM_REGS+1) @@ -286,281 +292,409 @@ return start_pc; } -/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or - is not the address of a valid instruction, the address of the next - instruction beyond ADDR otherwise. *PWORD1 receives the first word - of the instruction. */ - static CORE_ADDR -h8300_next_prologue_insn (CORE_ADDR addr, - CORE_ADDR lim, - unsigned short* pword1) +h8300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - char buf[2]; - if (addr < lim + 8) - { - read_memory (addr, buf, 2); - *pword1 = extract_signed_integer (buf, 2); + char buf[8]; - return addr + 2; - } - return 0; + frame_unwind_register (next_frame, E_PC_REGNUM, buf); + return extract_typed_address (buf, builtin_type_void_func_ptr); } -/* Examine the prologue of a function. `ip' points to the first instruction. - `limit' is the limit of the prologue (e.g. the addr of the first - linenumber, or perhaps the program counter if we're stepping through). - `frame_sp' is the stack pointer value in use in this frame. - `fsr' is a pointer to a frame_saved_regs structure into which we put - info about the registers saved by this frame. - `fi' is a struct frame_info pointer; we fill in various fields in it - to reflect the offsets of the arg pointer and the locals pointer. */ - -/* Any function with a frame looks like this - SECOND ARG - FIRST ARG - RET PC - SAVED R2 - SAVED R3 - SAVED FP <-FP POINTS HERE - LOCALS0 - LOCALS1 <-SP POINTS HERE - */ +static struct frame_id +h8300_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +{ + char buf[4]; + CORE_ADDR fp; -static CORE_ADDR -h8300_examine_prologue (CORE_ADDR ip, CORE_ADDR limit, - CORE_ADDR after_prolog_fp, CORE_ADDR *fsr, - struct frame_info *fi) -{ - CORE_ADDR next_ip; - int r; - int have_fp = 0; - unsigned short insn_word; - /* Number of things pushed onto stack, starts at 2/4, 'cause the - PC is already there */ - unsigned int reg_save_depth = BINWORD; + frame_unwind_register (next_frame, E_FP_REGNUM, buf); + fp = extract_unsigned_integer (buf, 4); - unsigned int auto_depth = 0; /* Number of bytes of autos */ + return frame_id_build (fp, frame_pc_unwind (next_frame)); +} - char in_frame[11]; /* One for each reg */ +struct h8300_frame_cache +{ + /* Base address. */ + CORE_ADDR base; + CORE_ADDR sp_offset; + CORE_ADDR pc; - int adjust = 0; + /* Saved registers. */ + CORE_ADDR saved_regs[H8300_MAX_NUM_REGS]; + CORE_ADDR saved_sp; - memset (in_frame, 1, 11); - for (r = 0; r < 8; r++) - { - fsr[r] = 0; - } - if (after_prolog_fp == 0) - { - after_prolog_fp = read_register (E_SP_REGNUM); - } + /* Stack space reserved for local variables. */ + long locals; +}; - /* If the PC isn't valid, quit now. */ - if (ip == 0 || ip & (is_h8300hmode (current_gdbarch) && - !is_h8300_normal_mode (current_gdbarch) ? ~0xffffff : ~0xffff)) - return 0; +/* Normal frames. */ - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); +/* Allocate and initialize a frame cache. */ - if (insn_word == 0x0100) /* mov.l */ - { - insn_word = read_memory_unsigned_integer (ip + 2, 2); - adjust = 2; - } +static struct h8300_frame_cache * +h8300_alloc_frame_cache (void) +{ + struct h8300_frame_cache *cache; + int i; - /* Skip over any fp push instructions */ - fsr[E_FP_REGNUM] = after_prolog_fp; - while (next_ip && IS_PUSH_FP (insn_word)) - { - ip = next_ip + adjust; + cache = FRAME_OBSTACK_ZALLOC (struct h8300_frame_cache); - in_frame[insn_word & 0x7] = reg_save_depth; - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); - reg_save_depth += 2 + adjust; - } + /* Base address. */ + cache->base = 0; + cache->sp_offset = -4; + cache->pc = 0; - /* Is this a move into the fp */ - if (next_ip && IS_MOV_SP_FP (insn_word)) - { - ip = next_ip; - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); - have_fp = 1; - } + /* Saved registers. We initialize these to -1 since zero is a valid + offset (that's where %fp is supposed to be stored). */ + for (i = 0; i < NUM_REGS; i++) + cache->saved_regs[i] = -1; - /* Skip over any stack adjustment, happens either with a number of - sub#2,sp or a mov #x,r5 sub r5,sp */ + /* Frameless until proven otherwise. */ + cache->locals = -1; - if (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word))) - { - while (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word))) - { - auto_depth += IS_SUB2_SP (insn_word) ? 2 : 4; - ip = next_ip; - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); - } - } - else + return cache; +} + +/* Check whether PC points at a code that sets up a new stack frame. + If so, it updates CACHE and returns the address of the first + instruction after the sequence that sets removes the "hidden" + argument from the stack or CURRENT_PC, whichever is smaller. + Otherwise, return PC. */ + +static CORE_ADDR +h8300_analyze_frame_setup (CORE_ADDR pc, CORE_ADDR current_pc, + struct h8300_frame_cache *cache) +{ + unsigned int op; + int subs_count; + + if (pc >= current_pc) + return current_pc; + + op = read_memory_unsigned_integer (pc, 4); + + if (op == 0x6df60d76) { - if (next_ip && IS_MOVK_R5 (insn_word)) + /* mov.w r6,@-sp; mov.w sp,r6 */ + cache->saved_regs[E_FP_REGNUM] = 0; + cache->sp_offset += 2; + op = read_memory_unsigned_integer (pc + 4, 4); + if (((op >> 16) & 0xfff0) == 0x7900) { - ip = next_ip; - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); - auto_depth += insn_word; - - next_ip = h8300_next_prologue_insn (next_ip, limit, &insn_word); - auto_depth += insn_word; + /* mov.w #imm,rN */ + cache->locals = -(short)(op & 0xffff); + return pc + 8; } - if (next_ip && IS_SUBL_SP (insn_word)) + else if((op >> 16) == 0x1b87) { - ip = next_ip; - auto_depth += read_memory_unsigned_integer (ip, 4); - ip += 4; - - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); + /* subs #2,sp */ + for (cache->locals = 0, pc += 4; + read_memory_unsigned_integer (pc, 2) == 0x1b87; + pc += 2, cache->locals += 2); + return pc; } } - - /* Now examine the push insns to determine where everything lives - on the stack. */ - while (1) + else if (op == 0x01006df6) { - adjust = 0; - if (!next_ip) - break; - - if (insn_word == 0x0100) + /* mov.l er6,@-sp */ + op = read_memory_unsigned_integer (pc+4, 2); + if (op == 0x0ff6) { - ip = next_ip; - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); - adjust = 2; + /* mov.l sp,er6 */ + op = read_memory_unsigned_integer (pc+6, 2); + if (op == 0x7a17) + { + /* add.l #-n,sp */ + cache->locals = -read_memory_unsigned_integer (pc+8, 4); + return pc + 12; + } + else if (op == 0x1b97) + { + /* subs #4,sp */ + for (cache->locals = 0, pc += 6; + read_memory_unsigned_integer (pc, 2) == 0x1b97; + pc += 2, cache->locals += 2); + return pc; + } } + } - if (IS_PUSH (insn_word)) - { - auto_depth += 2 + adjust; - fsr[insn_word & 0x7] = after_prolog_fp - auto_depth; - ip = next_ip; - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); - continue; - } + return pc; +} - /* Now check for push multiple insns. */ - if (insn_word == 0x0110 || insn_word == 0x0120 || insn_word == 0x0130) - { - int count = ((insn_word >> 4) & 0xf) + 1; - int start, i; +/* Check whether PC points at code that saves registers on the stack. + If so, it updates CACHE and returns the address of the first + instruction after the register saves or CURRENT_PC, whichever is + smaller. Otherwise, return PC. */ - ip = next_ip; - next_ip = h8300_next_prologue_insn (ip, limit, &insn_word); - start = insn_word & 0x7; +static CORE_ADDR +h8300_analyze_register_saves (CORE_ADDR pc, CORE_ADDR current_pc, + struct h8300_frame_cache *cache) +{ + if (cache->locals >= 0) + { + CORE_ADDR offset; + int op; + int i, regno; - for (i = start; i < start + count; i++) + offset = - cache->locals; + while (pc < current_pc) + { + op = read_memory_unsigned_integer (pc, 2); + if ((op & 0xfff0) == 0x6df0) + { + /* mov.w rN,@-sp*/ + regno = op & 0x000f; + cache->saved_regs[regno] = offset; + offset -= 2; + pc += 2; + } + else if (op == 0x0100) + { + op = read_memory_unsigned_integer (pc+2, 2); + if ((op & 0xfff0) == 0x6df0) + { + /* mov.l erN,@-sp*/ + regno = op & 0x000f; + cache->saved_regs[regno] = offset; + offset -= 4; + pc += 4; + } + else + break ; + } + else if ((op & 0xffcf) == 0x0100) { - auto_depth += 4; - fsr[i] = after_prolog_fp - auto_depth; + int op1; + op1 = read_memory_unsigned_integer (pc+2, 2); + if ((op1 & 0xfff0) == 0x6df0) + { + /* stm.l reglist,@-sp*/ + i = ((op & 0x0030) >> 4) + 1; + regno = op1 & 0x000f; + for (; i > 0; regno++, --i) { + cache->saved_regs[regno] = offset; + offset -= 4; + } + pc += 4; + } + else + break ; } + else + break; } - break; } + return pc; +} - /* The PC is at a known place */ - get_frame_extra_info (fi)->from_pc = - read_memory_unsigned_integer (after_prolog_fp + BINWORD, BINWORD); - - /* Rememeber any others too */ - in_frame[E_PC_REGNUM] = 0; - - if (have_fp) - /* We keep the old FP in the SP spot */ - fsr[E_SP_REGNUM] = read_memory_unsigned_integer (fsr[E_FP_REGNUM], - BINWORD); - else - fsr[E_SP_REGNUM] = after_prolog_fp + auto_depth; - return (ip); +/* Do a full analysis of the prologue at PC and update CACHE + accordingly. Bail out early if CURRENT_PC is reached. Return the + address where the analysis stopped. + + We handle all cases that can be generated by gcc. + + For allocating a stack frame: + + mov.w r6,@-sp + mov.w sp,r6 + mov.w #-n,rN + add.w rN,sp + + mov.w r6,@-sp + mov.w sp,r6 + subs #2,sp + (repeat) + + mov.l er6,@-sp + mov.l sp,er6 + add.l #-n,sp + + mov.w r6,@-sp + mov.w sp,r6 + subs #4,sp + (repeat) + + For saving registers: + + mov.w rN,@-sp + mov.l erN,@-sp + stm.l reglist,@-sp + + For setting up the PIC register: + + Future equivalence... + + */ + +static CORE_ADDR +h8300_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, + struct h8300_frame_cache *cache) +{ + unsigned int op; + + pc = h8300_analyze_frame_setup (pc, current_pc, cache); + pc = h8300_analyze_register_saves (pc, current_pc, cache); + if (pc >= current_pc) + return current_pc; + + /* PIC support */ + + return pc; } -static void -h8300_frame_init_saved_regs (struct frame_info *fi) +static struct h8300_frame_cache * +h8300_frame_cache (struct frame_info *next_frame, void **this_cache) { - CORE_ADDR func_addr, func_end; + struct h8300_frame_cache *cache; + char buf[4]; + int i; + + if (*this_cache) + return *this_cache; + + cache = h8300_alloc_frame_cache (); + *this_cache = cache; + + /* In principle, for normal frames, %fp holds the frame pointer, + which holds the base address for the current stack frame. + However, for functions that don't need it, the frame pointer is + optional. For these "frameless" functions the frame pointer is + actually the frame pointer of the calling frame. Signal + trampolines are just a special case of a "frameless" function. + They (usually) share their frame pointer with the frame that was + in progress when the signal occurred. */ - if (!deprecated_get_frame_saved_regs (fi)) + frame_unwind_register (next_frame, E_FP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 4); + if (cache->base == 0) + return cache; + + /* For normal frames, %pc is stored at 4(%fp). */ + cache->saved_regs[E_PC_REGNUM] = 4; + + cache->pc = frame_func_unwind (next_frame); + if (cache->pc != 0) + h8300_analyze_prologue (cache->pc, frame_pc_unwind (next_frame), cache); + + if (cache->locals < 0) { - frame_saved_regs_zalloc (fi); + /* We didn't find a valid frame, which means that CACHE->base + currently holds the frame pointer for our calling frame. If + we're at the start of a function, or somewhere half-way its + prologue, the function's frame probably hasn't been fully + setup yet. Try to reconstruct the base address for the stack + frame by looking at the stack pointer. For truly "frameless" + functions this might work too. */ - /* Find the beginning of this function, so we can analyze its - prologue. */ - if (find_pc_partial_function (get_frame_pc (fi), NULL, - &func_addr, &func_end)) - { - struct symtab_and_line sal = find_pc_line (func_addr, 0); - CORE_ADDR limit = (sal.end && sal.end < get_frame_pc (fi)) - ? sal.end : get_frame_pc (fi); - /* This will fill in fields in fi. */ - h8300_examine_prologue (func_addr, limit, get_frame_base (fi), - deprecated_get_frame_saved_regs (fi), fi); - } - /* Else we're out of luck (can't debug completely stripped code). - FIXME. */ + frame_unwind_register (next_frame, E_SP_REGNUM, buf); + cache->base = extract_unsigned_integer (buf, 4) + cache->sp_offset; } -} -/* Given a GDB frame, determine the address of the calling function's - frame. This will be used to create a new GDB frame struct, and - then DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_INIT_FRAME_PC - will be called for the new frame. + /* Now that we have the base address for the stack frame we can + calculate the value of %sp in the calling frame. */ + cache->saved_sp = cache->base; - For us, the frame address is its stack pointer value, so we look up - the function prologue to determine the caller's sp value, and - return it. */ + /* Adjust all the saved registers such that they contain addresses + instead of offsets. */ + for (i = 0; i < NUM_REGS; i++) + if (cache->saved_regs[i] != -1) + cache->saved_regs[i] += cache->base; -static CORE_ADDR -h8300_frame_chain (struct frame_info *thisframe) + return cache; +} + +static void +h8300_frame_this_id (struct frame_info *next_frame, void **this_cache, + struct frame_id *this_id) { - if (deprecated_pc_in_call_dummy (get_frame_pc (thisframe))) - { /* initialize the from_pc now */ - get_frame_extra_info (thisframe)->from_pc = - deprecated_read_register_dummy (get_frame_pc (thisframe), - get_frame_base (thisframe), - E_PC_REGNUM); - return get_frame_base (thisframe); - } - return deprecated_get_frame_saved_regs (thisframe)[E_SP_REGNUM]; + struct h8300_frame_cache *cache = h8300_frame_cache (next_frame, this_cache); + + /* This marks the outermost frame. */ + if (cache->base == 0) + return; + + /* See the end of m68k_push_dummy_call. */ + *this_id = frame_id_build (cache->base , cache->pc); } -/* Return the saved PC from this frame. +static void +h8300_frame_prev_register (struct frame_info *next_frame, void **this_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *valuep) +{ + struct h8300_frame_cache *cache = h8300_frame_cache (next_frame, this_cache); + + gdb_assert (regnum >= 0); + + if (regnum == E_SP_REGNUM && cache->saved_sp) + { + *optimizedp = 0; + *lvalp = not_lval; + *addrp = 0; + *realnump = -1; + if (valuep) + { + /* Store the value. */ + store_unsigned_integer (valuep, 4, cache->saved_sp); + } + return; + } + + if (regnum < NUM_REGS && cache->saved_regs[regnum] != -1) + { + *optimizedp = 0; + *lvalp = lval_memory; + *addrp = cache->saved_regs[regnum]; + *realnump = -1; + if (valuep) + { + /* Read the value in from memory. */ + read_memory (*addrp, valuep, + register_size (current_gdbarch, regnum)); + } + return; + } - If the frame has a memory copy of SRP_REGNUM, use that. If not, - just use the register SRP_REGNUM itself. */ + frame_register_unwind (next_frame, regnum, + optimizedp, lvalp, addrp, realnump, valuep); +} -static CORE_ADDR -h8300_frame_saved_pc (struct frame_info *frame) +static const struct frame_unwind h8300_frame_unwind = { - if (deprecated_pc_in_call_dummy (get_frame_pc (frame))) - return deprecated_read_register_dummy (get_frame_pc (frame), - get_frame_base (frame), - E_PC_REGNUM); - else - return get_frame_extra_info (frame)->from_pc; + NORMAL_FRAME, + h8300_frame_this_id, + h8300_frame_prev_register +}; + +static const struct frame_unwind * +h8300_frame_sniffer (struct frame_info *next_frame) +{ + return &h8300_frame_unwind; } -static void -h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi) +/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or + is not the address of a valid instruction, the address of the next + instruction beyond ADDR otherwise. *PWORD1 receives the first word + of the instruction. */ + +static CORE_ADDR +h8300_next_prologue_insn (CORE_ADDR addr, + CORE_ADDR lim, + unsigned short* pword1) { - if (!get_frame_extra_info (fi)) + char buf[2]; + if (addr < lim + 8) { - frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info)); - get_frame_extra_info (fi)->from_pc = 0; - - if (!get_frame_pc (fi)) - { - if (get_next_frame (fi)) - deprecated_update_frame_pc_hack (fi, h8300_frame_saved_pc (get_next_frame (fi))); - } - h8300_frame_init_saved_regs (fi); + read_memory (addr, buf, 2); + *pword1 = extract_signed_integer (buf, 2); + + return addr + 2; } + return 0; } /* Function: push_dummy_call @@ -724,41 +858,6 @@ return sp; } -/* Function: h8300_pop_frame - Restore the machine to the state it had before the current frame - was created. Usually used either by the "RETURN" command, or by - call_function_by_hand after the dummy_frame is finished. */ - -static void -h8300_pop_frame (void) -{ - unsigned regno; - struct frame_info *frame = get_current_frame (); - - if (deprecated_pc_in_call_dummy (get_frame_pc (frame))) - { - deprecated_pop_dummy_frame (); - } - else - { - for (regno = 0; regno < 8; regno++) - { - /* Don't forget E_SP_REGNUM is a frame_saved_regs struct is the - actual value we want, not the address of the value we want. */ - if (deprecated_get_frame_saved_regs (frame)[regno] && regno != E_SP_REGNUM) - write_register (regno, - read_memory_integer - (deprecated_get_frame_saved_regs (frame)[regno], BINWORD)); - else if (deprecated_get_frame_saved_regs (frame)[regno] && regno == E_SP_REGNUM) - write_register (regno, get_frame_base (frame) + 2 * BINWORD); - } - - /* Don't forget to update the PC too! */ - write_register (E_PC_REGNUM, get_frame_extra_info (frame)->from_pc); - } - flush_cached_frames (); -} - /* Function: extract_return_value Figure out where in REGBUF the called function has left its return value. Copy that into VALBUF. Be sure to account for CPU type. */ @@ -1282,10 +1381,6 @@ set_gdbarch_pseudo_register_read (gdbarch, h8300_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, h8300_pseudo_register_write); - /* NOTE: cagney/2002-12-06: This can be deleted when this arch is - ready to unwind the PC first (see frame.c:get_prev_frame()). */ - set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default); - /* * Basic register fields and methods. */ @@ -1302,15 +1397,12 @@ */ set_gdbarch_skip_prologue (gdbarch, h8300_skip_prologue); - set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, - h8300_frame_init_saved_regs); - set_gdbarch_deprecated_init_extra_frame_info (gdbarch, - h8300_init_extra_frame_info); - set_gdbarch_deprecated_frame_chain (gdbarch, h8300_frame_chain); - set_gdbarch_deprecated_saved_pc_after_call (gdbarch, - h8300_saved_pc_after_call); - set_gdbarch_deprecated_frame_saved_pc (gdbarch, h8300_frame_saved_pc); - set_gdbarch_deprecated_pop_frame (gdbarch, h8300_pop_frame); + /* Frame unwinder. */ + set_gdbarch_unwind_dummy_id (gdbarch, h8300_unwind_dummy_id); + set_gdbarch_unwind_pc (gdbarch, h8300_unwind_pc); + + /* Hook in the DWARF CFI frame unwinder. */ + frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer); /* * Miscelany @@ -1335,7 +1427,10 @@ /* Char is unsigned. */ set_gdbarch_char_signed (gdbarch, 0); + frame_unwind_append_sniffer (gdbarch, h8300_frame_sniffer); + return gdbarch; + } extern initialize_file_ftype _initialize_h8300_tdep; /* -Wmissing-prototypes */ ============================================================ -- Yoshinori Sato