* h8300s now new target, not alias of h8300h
[deliverable/binutils-gdb.git] / gdb / mn10300-tdep.c
index dd7674edc8d5faf7848056ebb214a4ca90e51ec2..0a5704b17045c82516074bd7242ea967430afabd 100644 (file)
@@ -1,6 +1,7 @@
 /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
 /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger.
-   Copyright 1996, 1997, 1998, 1999, 2000, 2001
-   Free Software Foundation, Inc.
+
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software
+   Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
 #include "regcache.h"
 #include "arch-utils.h"
 
 #include "regcache.h"
 #include "arch-utils.h"
 
+#define D0_REGNUM 0
+#define D2_REGNUM 2
+#define D3_REGNUM 3
+#define A0_REGNUM 4
+#define A2_REGNUM 6
+#define A3_REGNUM 7
+#define MDR_REGNUM 10
+#define PSW_REGNUM 11
+#define LIR_REGNUM 12
+#define LAR_REGNUM 13
+#define MDRQ_REGNUM 14
+#define E0_REGNUM 15
+#define MCRH_REGNUM 26
+#define MCRL_REGNUM 27
+#define MCVF_REGNUM 28
+
+enum movm_register_bits {
+  movm_exother_bit = 0x01,
+  movm_exreg1_bit  = 0x02,
+  movm_exreg0_bit  = 0x04,
+  movm_other_bit   = 0x08,
+  movm_a3_bit      = 0x10,
+  movm_a2_bit      = 0x20,
+  movm_d3_bit      = 0x40,
+  movm_d2_bit      = 0x80
+};
+
 extern void _initialize_mn10300_tdep (void);
 static CORE_ADDR mn10300_analyze_prologue (struct frame_info *fi,
                                           CORE_ADDR pc);
 extern void _initialize_mn10300_tdep (void);
 static CORE_ADDR mn10300_analyze_prologue (struct frame_info *fi,
                                           CORE_ADDR pc);
@@ -160,7 +188,7 @@ mn10300_use_struct_convention (int gcc_p, struct type *type)
    so we need a single byte breakpoint.  Matsushita hasn't defined
    one, so we defined it ourselves.  */
 
    so we need a single byte breakpoint.  Matsushita hasn't defined
    one, so we defined it ourselves.  */
 
-static unsigned char *
+const static unsigned char *
 mn10300_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
 {
   static char breakpoint[] =
 mn10300_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size)
 {
   static char breakpoint[] =
@@ -264,16 +292,63 @@ set_movm_offsets (struct frame_info *fi, int movm_args)
 /* The main purpose of this file is dealing with prologues to extract
    information about stack frames and saved registers.
 
 /* The main purpose of this file is dealing with prologues to extract
    information about stack frames and saved registers.
 
-   For reference here's how prologues look on the mn10300:
+   In gcc/config/mn13000/mn10300.c, the expand_prologue prologue
+   function is pretty readable, and has a nice explanation of how the
+   prologue is generated.  The prologues generated by that code will
+   have the following form (NOTE: the current code doesn't handle all
+   this!):
+
+   + If this is an old-style varargs function, then its arguments
+     need to be flushed back to the stack:
+     
+        mov d0,(4,sp)
+        mov d1,(4,sp)
+
+   + If we use any of the callee-saved registers, save them now.
+     
+        movm [some callee-saved registers],(sp)
+
+   + If we have any floating-point registers to save:
+
+     - Decrement the stack pointer to reserve space for the registers.
+       If the function doesn't need a frame pointer, we may combine
+       this with the adjustment that reserves space for the frame.
+
+        add -SIZE, sp
+
+     - Save the floating-point registers.  We have two possible
+       strategies:
 
 
-   With frame pointer:
-   movm [d2,d3,a2,a3],sp
-   mov sp,a3
-   add <size>,sp
+       . Save them at fixed offset from the SP:
 
 
-   Without frame pointer:
-   movm [d2,d3,a2,a3],sp (if needed)
-   add <size>,sp
+        fmov fsN,(OFFSETN,sp)
+        fmov fsM,(OFFSETM,sp)
+        ...
+
+       Note that, if OFFSETN happens to be zero, you'll get the
+       different opcode: fmov fsN,(sp)
+
+       . Or, set a0 to the start of the save area, and then use
+       post-increment addressing to save the FP registers.
+
+        mov sp, a0
+        add SIZE, a0
+        fmov fsN,(a0+)
+        fmov fsM,(a0+)
+        ...
+
+   + If the function needs a frame pointer, we set it here.
+
+        mov sp, a3
+
+   + Now we reserve space for the stack frame proper.  This could be
+     merged into the `add -SIZE, sp' instruction for FP saves up
+     above, unless we needed to set the frame pointer in the previous
+     step, or the frame is so large that allocating the whole thing at
+     once would put the FP register save slots out of reach of the
+     addressing mode (128 bytes).
+      
+        add -SIZE, sp        
 
    One day we might keep the stack pointer constant, that won't
    change the code for prologues, but it will make the frame
 
    One day we might keep the stack pointer constant, that won't
    change the code for prologues, but it will make the frame
@@ -303,7 +378,7 @@ set_movm_offsets (struct frame_info *fi, int movm_args)
    save instructions.
 
    MY_FRAME_IN_FP: The base of the current frame is in the
    save instructions.
 
    MY_FRAME_IN_FP: The base of the current frame is in the
-   frame pointer register ($a2).
+   frame pointer register ($a3).
 
    NO_MORE_FRAMES: Set this if the current frame is "start" or
    if the first instruction looks like mov <imm>,sp.  This tells
 
    NO_MORE_FRAMES: Set this if the current frame is "start" or
    if the first instruction looks like mov <imm>,sp.  This tells
@@ -389,8 +464,9 @@ mn10300_analyze_prologue (struct frame_info *fi, CORE_ADDR pc)
       return addr;
     }
 
       return addr;
     }
 
-  /* First see if this insn sets the stack pointer; if so, it's something
-     we won't understand, so quit now.   */
+  /* First see if this insn sets the stack pointer from a register; if
+     so, it's probably the initialization of the stack pointer in _start,
+     so mark this as the bottom-most frame.  */
   if (buf[0] == 0xf2 && (buf[1] & 0xf3) == 0xf0)
     {
       if (fi)
   if (buf[0] == 0xf2 && (buf[1] & 0xf3) == 0xf0)
     {
       if (fi)
@@ -844,8 +920,10 @@ mn10300_frame_init_saved_regs (struct frame_info *frame)
    plus any necessary offset to be applied to the register before
    any frame pointer offsets.  */
 
    plus any necessary offset to be applied to the register before
    any frame pointer offsets.  */
 
-void
-mn10300_virtual_frame_pointer (CORE_ADDR pc, long *reg, long *offset)
+static void
+mn10300_virtual_frame_pointer (CORE_ADDR pc,
+                              int *reg,
+                              LONGEST *offset)
 {
   struct frame_info *dummy = analyze_dummy_frame (pc, 0);
   /* Set up a dummy frame_info, Analyze the prolog and fill in the
 {
   struct frame_info *dummy = analyze_dummy_frame (pc, 0);
   /* Set up a dummy frame_info, Analyze the prolog and fill in the
@@ -933,7 +1011,7 @@ mn10300_print_register (const char *name, int regnum, int reg_width)
     printf_filtered ("%s: ", name);
 
   /* Get the data */
     printf_filtered ("%s: ", name);
 
   /* Get the data */
-  if (read_relative_register_raw_bytes (regnum, raw_buffer))
+  if (!frame_register_read (selected_frame, regnum, raw_buffer))
     {
       printf_filtered ("[invalid]");
       return;
     {
       printf_filtered ("[invalid]");
       return;
@@ -941,7 +1019,7 @@ mn10300_print_register (const char *name, int regnum, int reg_width)
   else
     {
       int byte;
   else
     {
       int byte;
-      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
        {
          for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
               byte < REGISTER_RAW_SIZE (regnum);
        {
          for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
               byte < REGISTER_RAW_SIZE (regnum);
@@ -1072,7 +1150,10 @@ mn10300_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_register_virtual_type (gdbarch, mn10300_register_virtual_type);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mn10300_dwarf2_reg_to_regnum);
   set_gdbarch_do_registers_info (gdbarch, mn10300_do_registers_info);
   set_gdbarch_register_virtual_type (gdbarch, mn10300_register_virtual_type);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mn10300_dwarf2_reg_to_regnum);
   set_gdbarch_do_registers_info (gdbarch, mn10300_do_registers_info);
+  set_gdbarch_sp_regnum (gdbarch, 8);
+  set_gdbarch_pc_regnum (gdbarch, 9);
   set_gdbarch_fp_regnum (gdbarch, 31);
   set_gdbarch_fp_regnum (gdbarch, 31);
+  set_gdbarch_virtual_frame_pointer (gdbarch, mn10300_virtual_frame_pointer);
 
   /* Breakpoints.  */
   set_gdbarch_breakpoint_from_pc (gdbarch, mn10300_breakpoint_from_pc);
 
   /* Breakpoints.  */
   set_gdbarch_breakpoint_from_pc (gdbarch, mn10300_breakpoint_from_pc);
@@ -1086,6 +1167,7 @@ mn10300_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
   set_gdbarch_saved_pc_after_call (gdbarch, mn10300_saved_pc_after_call);
   set_gdbarch_init_extra_frame_info (gdbarch, mn10300_init_extra_frame_info);
   set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid);
   set_gdbarch_saved_pc_after_call (gdbarch, mn10300_saved_pc_after_call);
   set_gdbarch_init_extra_frame_info (gdbarch, mn10300_init_extra_frame_info);
+  set_gdbarch_init_frame_pc (gdbarch, init_frame_pc_noop);
   set_gdbarch_frame_init_saved_regs (gdbarch, mn10300_frame_init_saved_regs);
   set_gdbarch_frame_chain (gdbarch, mn10300_frame_chain);
   set_gdbarch_frame_saved_pc (gdbarch, mn10300_frame_saved_pc);
   set_gdbarch_frame_init_saved_regs (gdbarch, mn10300_frame_init_saved_regs);
   set_gdbarch_frame_chain (gdbarch, mn10300_frame_chain);
   set_gdbarch_frame_saved_pc (gdbarch, mn10300_frame_saved_pc);
This page took 0.026234 seconds and 4 git commands to generate.