diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:34:07 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:34:07 +0000 |
commit | 071ea11e85eb9d529cc5eb3d35f6247466a21b99 (patch) | |
tree | 5deda65b8d7b04d1f4cbc534c3206d328e1267ec /gdb/h8500-tdep.c | |
parent | 1730ec6b1848f0f32154277f788fb29f88d8475b (diff) | |
download | gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.zip gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.gz gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.bz2 |
Initial creation of sourceware repository
Diffstat (limited to 'gdb/h8500-tdep.c')
-rw-r--r-- | gdb/h8500-tdep.c | 653 |
1 files changed, 0 insertions, 653 deletions
diff --git a/gdb/h8500-tdep.c b/gdb/h8500-tdep.c deleted file mode 100644 index 49fab2d..0000000 --- a/gdb/h8500-tdep.c +++ /dev/null @@ -1,653 +0,0 @@ -/* Target-dependent code for Hitachi H8/500, for GDB. - Copyright 1993, 1994, 1995 Free Software Foundation, Inc. - -This file is part of GDB. - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* - Contributed by Steve Chamberlain - sac@cygnus.com - */ - -#include "defs.h" -#include "frame.h" -#include "obstack.h" -#include "symtab.h" -#include "gdbtypes.h" -#include "gdbcmd.h" -#include "value.h" -#include "dis-asm.h" -#include "gdbcore.h" - -#define UNSIGNED_SHORT(X) ((X) & 0xffff) - -static int code_size = 2; - -static int data_size = 2; - -/* Shape of an H8/500 frame : - - arg-n - .. - arg-2 - arg-1 - return address <2 or 4 bytes> - old fp <2 bytes> - auto-n - .. - auto-1 - saved registers - -*/ - -/* an easy to debug H8 stack frame looks like: -0x6df6 push r6 -0x0d76 mov.w r7,r6 -0x6dfn push reg -0x7905 nnnn mov.w #n,r5 or 0x1b87 subs #2,sp -0x1957 sub.w r5,sp - - */ - -#define IS_PUSH(x) (((x) & 0xff00)==0x6d00) -#define IS_LINK_8(x) ((x) == 0x17) -#define IS_LINK_16(x) ((x) == 0x1f) -#define IS_MOVE_FP(x) ((x) == 0x0d76) -#define IS_MOV_SP_FP(x) ((x) == 0x0d76) -#define IS_SUB2_SP(x) ((x) == 0x1b87) -#define IS_MOVK_R5(x) ((x) == 0x7905) -#define IS_SUB_R5SP(x) ((x) == 0x1957) - -#define LINK_8 0x17 -#define LINK_16 0x1f - -int minimum_mode = 1; - -CORE_ADDR -h8500_skip_prologue (start_pc) - CORE_ADDR start_pc; -{ - short int w; - - w = read_memory_integer (start_pc, 1); - if (w == LINK_8) - { - start_pc += 2; - w = read_memory_integer (start_pc, 1); - } - - if (w == LINK_16) - { - start_pc += 3; - w = read_memory_integer (start_pc, 2); - } - - return start_pc; -} - -CORE_ADDR -h8500_addr_bits_remove (addr) - CORE_ADDR addr; -{ - return ((addr) & 0xffffff); -} - -/* 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 - INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. - - 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. */ - -CORE_ADDR -h8500_frame_chain (thisframe) - struct frame_info *thisframe; -{ - if (!inside_entry_file (thisframe->pc)) - return (read_memory_integer (FRAME_FP (thisframe), PTR_SIZE)); - else - return 0; -} - -/* 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.*/ - -CORE_ADDR -NEXT_PROLOGUE_INSN (addr, lim, pword1) - CORE_ADDR addr; - CORE_ADDR lim; - char *pword1; -{ - if (addr < lim + 8) - { - read_memory (addr, pword1, 1); - read_memory (addr, pword1 + 1, 1); - return 1; - } - return 0; -} - -/* 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. */ - -/* Return the saved PC from this frame. */ - -CORE_ADDR -frame_saved_pc (frame) - struct frame_info *frame; -{ - return read_memory_integer (FRAME_FP (frame) + 2, PTR_SIZE); -} - -void -h8500_pop_frame () -{ - unsigned regnum; - struct frame_saved_regs fsr; - struct frame_info *frame = get_current_frame (); - - get_frame_saved_regs (frame, &fsr); - - for (regnum = 0; regnum < 8; regnum++) - { - if (fsr.regs[regnum]) - write_register (regnum, read_memory_short (fsr.regs[regnum])); - - flush_cached_frames (); - } -} - -void -print_register_hook (regno) - int regno; -{ - if (regno == CCR_REGNUM) - { - /* CCR register */ - - int C, Z, N, V; - unsigned char b[2]; - unsigned char l; - - read_relative_register_raw_bytes (regno, b); - l = b[1]; - printf_unfiltered ("\t"); - printf_unfiltered ("I-%d - ", (l & 0x80) != 0); - N = (l & 0x8) != 0; - Z = (l & 0x4) != 0; - V = (l & 0x2) != 0; - C = (l & 0x1) != 0; - printf_unfiltered ("N-%d ", N); - printf_unfiltered ("Z-%d ", Z); - printf_unfiltered ("V-%d ", V); - printf_unfiltered ("C-%d ", C); - if ((C | Z) == 0) - printf_unfiltered ("u> "); - if ((C | Z) == 1) - printf_unfiltered ("u<= "); - if ((C == 0)) - printf_unfiltered ("u>= "); - if (C == 1) - printf_unfiltered ("u< "); - if (Z == 0) - printf_unfiltered ("!= "); - if (Z == 1) - printf_unfiltered ("== "); - if ((N ^ V) == 0) - printf_unfiltered (">= "); - if ((N ^ V) == 1) - printf_unfiltered ("< "); - if ((Z | (N ^ V)) == 0) - printf_unfiltered ("> "); - if ((Z | (N ^ V)) == 1) - printf_unfiltered ("<= "); - } -} - -int -h8500_register_size (regno) - int regno; -{ - switch (regno) - { - case SEG_C_REGNUM: - case SEG_D_REGNUM: - case SEG_E_REGNUM: - case SEG_T_REGNUM: - return 1; - case R0_REGNUM: - case R1_REGNUM: - case R2_REGNUM: - case R3_REGNUM: - case R4_REGNUM: - case R5_REGNUM: - case R6_REGNUM: - case R7_REGNUM: - case CCR_REGNUM: - return 2; - - case PR0_REGNUM: - case PR1_REGNUM: - case PR2_REGNUM: - case PR3_REGNUM: - case PR4_REGNUM: - case PR5_REGNUM: - case PR6_REGNUM: - case PR7_REGNUM: - case PC_REGNUM: - return 4; - default: - abort (); - } -} - -struct type * -h8500_register_virtual_type (regno) - int regno; -{ - switch (regno) - { - case SEG_C_REGNUM: - case SEG_E_REGNUM: - case SEG_D_REGNUM: - case SEG_T_REGNUM: - return builtin_type_unsigned_char; - case R0_REGNUM: - case R1_REGNUM: - case R2_REGNUM: - case R3_REGNUM: - case R4_REGNUM: - case R5_REGNUM: - case R6_REGNUM: - case R7_REGNUM: - case CCR_REGNUM: - return builtin_type_unsigned_short; - case PR0_REGNUM: - case PR1_REGNUM: - case PR2_REGNUM: - case PR3_REGNUM: - case PR4_REGNUM: - case PR5_REGNUM: - case PR6_REGNUM: - case PR7_REGNUM: - case PC_REGNUM: - return builtin_type_unsigned_long; - default: - abort (); - } -} - -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. */ - -void -frame_find_saved_regs (frame_info, frame_saved_regs) - struct frame_info *frame_info; - struct frame_saved_regs *frame_saved_regs; -{ - register int regnum; - register int regmask; - register CORE_ADDR next_addr; - register CORE_ADDR pc; - unsigned char thebyte; - - memset (frame_saved_regs, '\0', sizeof *frame_saved_regs); - - if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4 - && (frame_info)->pc <= (frame_info)->frame) - { - next_addr = (frame_info)->frame; - pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 4; - } - else - { - pc = get_pc_function_start ((frame_info)->pc); - /* Verify we have a link a6 instruction next; - if not we lose. If we win, find the address above the saved - regs using the amount of storage from the link instruction. - */ - - thebyte = read_memory_integer (pc, 1); - if (0x1f == thebyte) - next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 2), pc += 2; - else if (0x17 == thebyte) - next_addr = (frame_info)->frame + read_memory_integer (pc += 1, 1), pc += 1; - else - goto lose; -#if 0 - /* FIXME steve */ - /* If have an add:g.waddal #-n, sp next, adjust next_addr. */ - if ((0x0c0177777 & read_memory_integer (pc, 2)) == 0157774) - next_addr += read_memory_integer (pc += 2, 4), pc += 4; -#endif - } - - thebyte = read_memory_integer (pc, 1); - if (thebyte == 0x12) - { - /* Got stm */ - pc++; - regmask = read_memory_integer (pc, 1); - pc++; - for (regnum = 0; regnum < 8; regnum++, regmask >>= 1) - { - if (regmask & 1) - { - (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2; - } - } - thebyte = read_memory_integer (pc, 1); - } - /* Maybe got a load of pushes */ - while (thebyte == 0xbf) - { - pc++; - regnum = read_memory_integer (pc, 1) & 0x7; - pc++; - (frame_saved_regs)->regs[regnum] = (next_addr += 2) - 2; - thebyte = read_memory_integer (pc, 1); - } - -lose:; - - /* Remember the address of the frame pointer */ - (frame_saved_regs)->regs[FP_REGNUM] = (frame_info)->frame; - - /* This is where the old sp is hidden */ - (frame_saved_regs)->regs[SP_REGNUM] = (frame_info)->frame; - - /* And the PC - remember the pushed FP is always two bytes long */ - (frame_saved_regs)->regs[PC_REGNUM] = (frame_info)->frame + 2; -} - -CORE_ADDR -saved_pc_after_call () -{ - int x; - int a = read_register (SP_REGNUM); - - x = read_memory_integer (a, code_size); - if (code_size == 2) - { - /* Stick current code segement onto top */ - x &= 0xffff; - x |= read_register (SEG_C_REGNUM) << 16; - } - x &= 0xffffff; - return x; -} - -void -h8500_set_pointer_size (newsize) - int newsize; -{ - static int oldsize = 0; - - if (oldsize != newsize) - { - printf_unfiltered ("pointer size set to %d bits\n", newsize); - oldsize = newsize; - if (newsize == 32) - { - minimum_mode = 0; - } - else - { - minimum_mode = 1; - } - _initialize_gdbtypes (); - } -} - -static void -big_command () -{ - h8500_set_pointer_size (32); - code_size = 4; - data_size = 4; -} - -static void -medium_command () -{ - h8500_set_pointer_size (32); - code_size = 4; - data_size = 2; -} - -static void -compact_command () -{ - h8500_set_pointer_size (32); - code_size = 2; - data_size = 4; -} - -static void -small_command () -{ - h8500_set_pointer_size (16); - code_size = 2; - data_size = 2; -} - -static struct cmd_list_element *setmemorylist; - -static void -set_memory (args, from_tty) - char *args; - int from_tty; -{ - printf_unfiltered ("\"set memory\" must be followed by the name of a memory subcommand.\n"); - help_list (setmemorylist, "set memory ", -1, gdb_stdout); -} - -/* See if variable name is ppc or pr[0-7] */ - -int -h8500_is_trapped_internalvar (name) - char *name; -{ - if (name[0] != 'p') - return 0; - - if (strcmp (name + 1, "pc") == 0) - return 1; - - if (name[1] == 'r' - && name[2] >= '0' - && name[2] <= '7' - && name[3] == '\000') - return 1; - else - return 0; -} - -value_ptr -h8500_value_of_trapped_internalvar (var) - struct internalvar *var; -{ - LONGEST regval; - unsigned char regbuf[4]; - int page_regnum, regnum; - - regnum = var->name[2] == 'c' ? PC_REGNUM : var->name[2] - '0'; - - switch (var->name[2]) - { - case 'c': - page_regnum = SEG_C_REGNUM; - break; - case '0': - case '1': - case '2': - case '3': - page_regnum = SEG_D_REGNUM; - break; - case '4': - case '5': - page_regnum = SEG_E_REGNUM; - break; - case '6': - case '7': - page_regnum = SEG_T_REGNUM; - break; - } - - get_saved_register (regbuf, NULL, NULL, selected_frame, page_regnum, NULL); - regval = regbuf[0] << 16; - - get_saved_register (regbuf, NULL, NULL, selected_frame, regnum, NULL); - regval |= regbuf[0] << 8 | regbuf[1]; /* XXX host/target byte order */ - - free (var->value); /* Free up old value */ - - var->value = value_from_longest (builtin_type_unsigned_long, regval); - release_value (var->value); /* Unchain new value */ - - VALUE_LVAL (var->value) = lval_internalvar; - VALUE_INTERNALVAR (var->value) = var; - return var->value; -} - -void -h8500_set_trapped_internalvar (var, newval, bitpos, bitsize, offset) - struct internalvar *var; - int offset, bitpos, bitsize; - value_ptr newval; -{ - char *page_regnum, *regnum; - char expression[100]; - unsigned new_regval; - struct type *type; - enum type_code newval_type_code; - - type = check_typedef (VALUE_TYPE (newval)); - newval_type_code = TYPE_CODE (type); - - if ((newval_type_code != TYPE_CODE_INT - && newval_type_code != TYPE_CODE_PTR) - || TYPE_LENGTH (type) != sizeof (new_regval)) - error ("Illegal type (%s) for assignment to $%s\n", - TYPE_NAME (VALUE_TYPE (newval)), var->name); - - new_regval = *(long *) VALUE_CONTENTS_RAW (newval); - - regnum = var->name + 1; - - switch (var->name[2]) - { - case 'c': - page_regnum = "cp"; - break; - case '0': - case '1': - case '2': - case '3': - page_regnum = "dp"; - break; - case '4': - case '5': - page_regnum = "ep"; - break; - case '6': - case '7': - page_regnum = "tp"; - break; - } - - sprintf (expression, "$%s=%d", page_regnum, new_regval >> 16); - parse_and_eval (expression); - - sprintf (expression, "$%s=%d", regnum, new_regval & 0xffff); - parse_and_eval (expression); -} - -CORE_ADDR -h8500_read_sp () -{ - return read_register (PR7_REGNUM); -} - -void -h8500_write_sp (v) - CORE_ADDR v; -{ - write_register (PR7_REGNUM, v); -} - -CORE_ADDR -h8500_read_pc (pid) - int pid; -{ - return read_register (PC_REGNUM); -} - -void -h8500_write_pc (v, pid) - CORE_ADDR v; - int pid; -{ - write_register (PC_REGNUM, v); -} - -CORE_ADDR -h8500_read_fp () -{ - return read_register (PR6_REGNUM); -} - -void -h8500_write_fp (v) - CORE_ADDR v; -{ - write_register (PR6_REGNUM, v); -} - -void -_initialize_h8500_tdep () -{ - tm_print_insn = print_insn_h8500; - - add_prefix_cmd ("memory", no_class, set_memory, - "set the memory model", &setmemorylist, "set memory ", 0, - &setlist); - - add_cmd ("small", class_support, small_command, - "Set small memory model. (16 bit code, 16 bit data)", &setmemorylist); - - add_cmd ("big", class_support, big_command, - "Set big memory model. (32 bit code, 32 bit data)", &setmemorylist); - - add_cmd ("medium", class_support, medium_command, - "Set medium memory model. (32 bit code, 16 bit data)", &setmemorylist); - - add_cmd ("compact", class_support, compact_command, - "Set compact memory model. (16 bit code, 32 bit data)", &setmemorylist); - -} |