* hppa-tdep.c: Include "dis-asm.h". Fixes a build failure.
[deliverable/binutils-gdb.git] / gdb / hppa-tdep.c
index fed6cb181f896e7eca055e154b108910e214ad52..6148915557e3bd7a3f3ca66e7e0d9626c9869cf9 100644 (file)
@@ -37,6 +37,7 @@
 /* For argument passing to the inferior */
 #include "symtab.h"
 #include "infcall.h"
+#include "dis-asm.h"
 
 #ifdef USG
 #include <sys/types.h>
 #include "target.h"
 #include "symfile.h"
 #include "objfiles.h"
+#include "hppa-tdep.h"
 
 /* Some local constants.  */
-static const int hppa_num_regs = 128;
+static const int hppa32_num_regs = 128;
+static const int hppa64_num_regs = 96;
+
+static const int hppa64_call_dummy_breakpoint_offset = 22 * 4;
+
+/* DEPRECATED_CALL_DUMMY_LENGTH is computed based on the size of a
+   word on the target machine, not the size of an instruction.  Since
+   a word on this target holds two instructions we have to divide the
+   instruction size by two to get the word size of the dummy.  */
+static const int hppa32_call_dummy_length = INSTRUCTION_SIZE * 28;
+static const int hppa64_call_dummy_length = INSTRUCTION_SIZE * 26 / 2;
 
 /* Get at various relevent fields of an instruction word. */
 #define MASK_5 0x1f
@@ -164,16 +176,23 @@ int hppa_in_solib_call_trampoline (CORE_ADDR pc, char *name);
 int hppa_in_solib_return_trampoline (CORE_ADDR pc, char *name);
 CORE_ADDR hppa_saved_pc_after_call (struct frame_info *frame);
 int hppa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs);
-CORE_ADDR hppa_stack_align (CORE_ADDR sp);
+CORE_ADDR hppa32_stack_align (CORE_ADDR sp);
+CORE_ADDR hppa64_stack_align (CORE_ADDR sp);
 int hppa_pc_requires_run_before_use (CORE_ADDR pc);
 int hppa_instruction_nullified (void);
 int hppa_register_raw_size (int reg_nr);
 int hppa_register_byte (int reg_nr);
-struct type * hppa_register_virtual_type (int reg_nr);
+struct type * hppa32_register_virtual_type (int reg_nr);
+struct type * hppa64_register_virtual_type (int reg_nr);
 void hppa_store_struct_return (CORE_ADDR addr, CORE_ADDR sp);
-void hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf);
-int hppa_use_struct_convention (int gcc_p, struct type *type);
-void hppa_store_return_value (struct type *type, char *valbuf);
+void hppa32_extract_return_value (struct type *type, char *regbuf,
+                                  char *valbuf);
+void hppa64_extract_return_value (struct type *type, char *regbuf,
+                                  char *valbuf);
+int hppa32_use_struct_convention (int gcc_p, struct type *type);
+int hppa64_use_struct_convention (int gcc_p, struct type *type);
+void hppa32_store_return_value (struct type *type, char *valbuf);
+void hppa64_store_return_value (struct type *type, char *valbuf);
 CORE_ADDR hppa_extract_struct_value_address (char *regbuf);
 int hppa_cannot_store_register (int regnum);
 void hppa_init_extra_frame_info (int fromleaf, struct frame_info *frame);
@@ -182,7 +201,6 @@ int hppa_frame_chain_valid (CORE_ADDR chain, struct frame_info *thisframe);
 int hppa_frameless_function_invocation (struct frame_info *frame);
 CORE_ADDR hppa_frame_saved_pc (struct frame_info *frame);
 CORE_ADDR hppa_frame_args_address (struct frame_info *fi);
-CORE_ADDR hppa_frame_locals_address (struct frame_info *fi);
 int hppa_frame_num_args (struct frame_info *frame);
 void hppa_push_dummy_frame (void);
 void hppa_pop_frame (void);
@@ -217,11 +235,19 @@ extern int exception_catchpoints_are_fragile;
 /* Should call_function allocate stack space for a struct return?  */
 
 int
-hppa_use_struct_convention (int gcc_p, struct type *type)
+hppa32_use_struct_convention (int gcc_p, struct type *type)
 {
   return (TYPE_LENGTH (type) > 2 * DEPRECATED_REGISTER_SIZE);
 }
-\f
+
+/* Same as hppa32_use_struct_convention() for the PA64 ABI.  */
+
+int
+hppa64_use_struct_convention (int gcc_p, struct type *type)
+{
+  /* RM: struct upto 128 bits are returned in registers */
+  return TYPE_LENGTH (type) > 16;
+}
 
 /* Routines to extract various sized constants out of hppa 
    instructions. */
@@ -681,7 +707,7 @@ hppa_breakpoint_from_pc (CORE_ADDR *pc, int *len)
 /* Return the name of a register.  */
 
 const char *
-hppa_register_name (int i)
+hppa32_register_name (int i)
 {
   static char *names[] = {
     "flags",  "r1",      "rp",     "r3",
@@ -4782,7 +4808,7 @@ hppa_skip_permanent_breakpoint (void)
    Called only in the context of the "return" command.  */
 
 void
-hppa_store_return_value (struct type *type, char *valbuf)
+hppa32_store_return_value (struct type *type, char *valbuf)
 {
   /* For software floating point, the return value goes into the
      integer registers.  But we do not have any flag to key this on,
@@ -4800,6 +4826,32 @@ hppa_store_return_value (struct type *type, char *valbuf)
                                     valbuf, TYPE_LENGTH (type));
 }
 
+/* Same as hppa32_store_return_value(), but for the PA64 ABI.  */
+
+void
+hppa64_store_return_value (struct type *type, char *valbuf)
+{
+  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+    deprecated_write_register_bytes
+      (REGISTER_BYTE (FP4_REGNUM)
+        + DEPRECATED_REGISTER_SIZE - TYPE_LENGTH (type),
+       valbuf, TYPE_LENGTH (type));
+  else if (is_integral_type(type))
+    deprecated_write_register_bytes
+      (REGISTER_BYTE (28)
+        + DEPRECATED_REGISTER_SIZE - TYPE_LENGTH (type),
+       valbuf, TYPE_LENGTH (type));
+  else if (TYPE_LENGTH (type) <= 8)
+    deprecated_write_register_bytes
+      (REGISTER_BYTE (28),valbuf, TYPE_LENGTH (type));
+  else if (TYPE_LENGTH (type) <= 16)
+    {
+      deprecated_write_register_bytes (REGISTER_BYTE (28),valbuf, 8);
+      deprecated_write_register_bytes
+        (REGISTER_BYTE (29), valbuf + 8, TYPE_LENGTH (type) - 8);
+    }
+}
+
 /* Copy the function's return value into VALBUF.
 
    This function is called only in the context of "target function calls",
@@ -4808,15 +4860,13 @@ hppa_store_return_value (struct type *type, char *valbuf)
    "return" command.  */
 
 void
-hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+hppa32_extract_return_value (struct type *type, char *regbuf, char *valbuf)
 {
   if (TYPE_CODE (type) == TYPE_CODE_FLT)
-    memcpy (valbuf,
-           (char *)regbuf + REGISTER_BYTE (FP4_REGNUM),
-           TYPE_LENGTH (type));
+    memcpy (valbuf, regbuf + REGISTER_BYTE (FP4_REGNUM), TYPE_LENGTH (type));
   else
     memcpy (valbuf,
-           ((char *)regbuf
+           (regbuf
             + REGISTER_BYTE (28)
             + (TYPE_LENGTH (type) > 4
                ? (8 - TYPE_LENGTH (type))
@@ -4824,6 +4874,34 @@ hppa_extract_return_value (struct type *type, char *regbuf, char *valbuf)
            TYPE_LENGTH (type));
 }
 
+/* Same as hppa32_extract_return_value but for the PA64 ABI case.  */
+
+void
+hppa64_extract_return_value (struct type *type, char *regbuf, char *valbuf)
+{
+  /* RM: Floats are returned in FR4R, doubles in FR4.
+         Integral values are in r28, padded on the left.
+         Aggregates less that 65 bits are in r28, right padded.
+         Aggregates upto 128 bits are in r28 and r29, right padded.  */ 
+  if (TYPE_CODE (type) == TYPE_CODE_FLT)
+    memcpy (valbuf,
+            regbuf + REGISTER_BYTE (FP4_REGNUM)
+             + DEPRECATED_REGISTER_SIZE - TYPE_LENGTH (type),
+            TYPE_LENGTH (type));
+  else if (is_integral_type(type))
+    memcpy (valbuf,
+            regbuf + REGISTER_BYTE (28)
+             + DEPRECATED_REGISTER_SIZE - TYPE_LENGTH (type),
+            TYPE_LENGTH (type));
+  else if (TYPE_LENGTH (type) <= 8)
+    memcpy (valbuf, regbuf + REGISTER_BYTE (28), TYPE_LENGTH (type));
+  else if (TYPE_LENGTH (type) <= 16)
+    {
+      memcpy (valbuf, regbuf + REGISTER_BYTE (28), 8);
+      memcpy (valbuf + 8, regbuf + REGISTER_BYTE (29), TYPE_LENGTH (type) - 8);
+    }
+}
+
 int
 hppa_reg_struct_has_addr (int gcc_p, struct type *type)
 {
@@ -4840,7 +4918,7 @@ hppa_inner_than (CORE_ADDR lhs, CORE_ADDR rhs)
 }
 
 CORE_ADDR
-hppa_stack_align (CORE_ADDR sp)
+hppa32_stack_align (CORE_ADDR sp)
 {
   /* elz: adjust the quantity to the next highest value which is
      64-bit aligned.  This is used in valops.c, when the sp is adjusted.
@@ -4848,6 +4926,13 @@ hppa_stack_align (CORE_ADDR sp)
   return ((sp % 8) ? (sp + 7) & -8 : sp);
 }
 
+CORE_ADDR
+hppa64_stack_align (CORE_ADDR sp)
+{
+  /* The PA64 ABI mandates a 16 byte stack alignment.  */
+  return ((sp % 16) ? (sp + 15) & -16 : sp);
+}
+
 int
 hppa_pc_requires_run_before_use (CORE_ADDR pc)
 {
@@ -4901,14 +4986,16 @@ hppa_register_raw_size (int reg_nr)
 int
 hppa_register_byte (int reg_nr)
 {
-  return reg_nr * 4;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  return reg_nr * tdep->bytes_per_address;
 }
 
 /* Return the GDB type object for the "standard" data type of data
    in register N.  */
 
 struct type *
-hppa_register_virtual_type (int reg_nr)
+hppa32_register_virtual_type (int reg_nr)
 {
    if (reg_nr < FP4_REGNUM)
      return builtin_type_int;
@@ -4916,6 +5003,18 @@ hppa_register_virtual_type (int reg_nr)
      return builtin_type_float;
 }
 
+/* Return the GDB type object for the "standard" data type of data
+   in register N.  hppa64 version.  */
+
+struct type *
+hppa64_register_virtual_type (int reg_nr)
+{
+   if (reg_nr < FP4_REGNUM)
+     return builtin_type_unsigned_long_long;
+   else
+     return builtin_type_double;
+}
+
 /* Store the address of the place in which to copy the structure the
    subroutine will return.  This is called from call_function.  */
 
@@ -4979,6 +5078,7 @@ hppa_fetch_pointer_argument (struct frame_info *frame, int argi,
 static struct gdbarch *
 hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
+  struct gdbarch_tdep *tdep;
   struct gdbarch *gdbarch;
   
   /* Try to determine the ABI of the object we are loading.  */
@@ -4995,12 +5095,70 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     return (arches->gdbarch);
 
   /* If none found, then allocate and initialize one.  */
-  gdbarch = gdbarch_alloc (&info, NULL);
+  tdep = XMALLOC (struct gdbarch_tdep);
+  gdbarch = gdbarch_alloc (&info, tdep);
+
+  /* Determine from the bfd_arch_info structure if we are dealing with
+     a 32 or 64 bits architecture.  If the bfd_arch_info is not available,
+     then default to a 32bit machine.  */
+  if (info.bfd_arch_info != NULL)
+    tdep->bytes_per_address =
+      info.bfd_arch_info->bits_per_address / info.bfd_arch_info->bits_per_byte;
+  else
+    tdep->bytes_per_address = 4;
 
-  /* Hook in ABI-specific overrides, if they have been registered.  */
-  gdbarch_init_osabi (info, gdbarch);
+  /* Some parts of the gdbarch vector depend on whether we are running
+     on a 32 bits or 64 bits target.  */
+  switch (tdep->bytes_per_address)
+    {
+      case 4:
+        set_gdbarch_num_regs (gdbarch, hppa32_num_regs);
+        set_gdbarch_register_name (gdbarch, hppa32_register_name);
+        set_gdbarch_deprecated_register_virtual_type
+          (gdbarch, hppa32_register_virtual_type);
+        set_gdbarch_deprecated_call_dummy_length
+          (gdbarch, hppa32_call_dummy_length);
+        set_gdbarch_stack_align (gdbarch, hppa32_stack_align);
+        set_gdbarch_reg_struct_has_addr (gdbarch, hppa_reg_struct_has_addr);
+        set_gdbarch_deprecated_extract_return_value
+          (gdbarch, hppa32_extract_return_value);
+        set_gdbarch_use_struct_convention
+          (gdbarch, hppa32_use_struct_convention);
+        set_gdbarch_deprecated_store_return_value
+          (gdbarch, hppa32_store_return_value);
+        break;
+      case 8:
+        set_gdbarch_num_regs (gdbarch, hppa64_num_regs);
+        set_gdbarch_register_name (gdbarch, hppa64_register_name);
+        set_gdbarch_deprecated_register_virtual_type
+          (gdbarch, hppa64_register_virtual_type);
+        set_gdbarch_deprecated_call_dummy_breakpoint_offset
+          (gdbarch, hppa64_call_dummy_breakpoint_offset);
+        set_gdbarch_deprecated_call_dummy_length
+          (gdbarch, hppa64_call_dummy_length);
+        set_gdbarch_stack_align (gdbarch, hppa64_stack_align);
+        set_gdbarch_deprecated_extract_return_value
+          (gdbarch, hppa64_extract_return_value);
+        set_gdbarch_use_struct_convention
+          (gdbarch, hppa64_use_struct_convention);
+        set_gdbarch_deprecated_store_return_value
+          (gdbarch, hppa64_store_return_value);
+        break;
+      default:
+        internal_error (__FILE__, __LINE__, "Unsupported address size: %d",
+                        tdep->bytes_per_address);
+    }
 
-  set_gdbarch_reg_struct_has_addr (gdbarch, hppa_reg_struct_has_addr);
+  /* The following gdbarch vector elements depend on other parts of this
+     vector which have been set above, depending on the ABI.  */
+  set_gdbarch_deprecated_register_bytes
+    (gdbarch, gdbarch_num_regs (gdbarch) * tdep->bytes_per_address);
+  set_gdbarch_long_bit (gdbarch, tdep->bytes_per_address * TARGET_CHAR_BIT);
+  set_gdbarch_long_long_bit (gdbarch, 64);
+  set_gdbarch_ptr_bit (gdbarch, tdep->bytes_per_address * TARGET_CHAR_BIT);
+
+  /* The following gdbarch vector elements do not depend on the address
+     size, or in any other gdbarch element previously set.  */
   set_gdbarch_function_start_offset (gdbarch, 0);
   set_gdbarch_skip_prologue (gdbarch, hppa_skip_prologue);
   set_gdbarch_skip_trampoline_code (gdbarch, hppa_skip_trampoline_code);
@@ -5009,28 +5167,19 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
                                           hppa_in_solib_return_trampoline);
   set_gdbarch_deprecated_saved_pc_after_call (gdbarch, hppa_saved_pc_after_call);
   set_gdbarch_inner_than (gdbarch, hppa_inner_than);
-  set_gdbarch_stack_align (gdbarch, hppa_stack_align);
   set_gdbarch_decr_pc_after_break (gdbarch, 0);
-  set_gdbarch_deprecated_register_size (gdbarch, 4);
-  set_gdbarch_num_regs (gdbarch, hppa_num_regs);
+  set_gdbarch_deprecated_register_size (gdbarch, tdep->bytes_per_address);
   set_gdbarch_deprecated_fp_regnum (gdbarch, 3);
   set_gdbarch_sp_regnum (gdbarch, 30);
   set_gdbarch_fp0_regnum (gdbarch, 64);
   set_gdbarch_pc_regnum (gdbarch, PCOQ_HEAD_REGNUM);
   set_gdbarch_npc_regnum (gdbarch, PCOQ_TAIL_REGNUM);
   set_gdbarch_deprecated_register_raw_size (gdbarch, hppa_register_raw_size);
-  set_gdbarch_deprecated_register_bytes (gdbarch, hppa_num_regs * 4);
   set_gdbarch_deprecated_register_byte (gdbarch, hppa_register_byte);
   set_gdbarch_deprecated_register_virtual_size (gdbarch, hppa_register_raw_size);
-  set_gdbarch_deprecated_max_register_raw_size (gdbarch, 4);
+  set_gdbarch_deprecated_max_register_raw_size (gdbarch, tdep->bytes_per_address);
   set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 8);
-  set_gdbarch_deprecated_register_virtual_type (gdbarch, hppa_register_virtual_type);
-  set_gdbarch_register_name (gdbarch, hppa_register_name);
   set_gdbarch_deprecated_store_struct_return (gdbarch, hppa_store_struct_return);
-  set_gdbarch_deprecated_extract_return_value (gdbarch,
-                                               hppa_extract_return_value);
-  set_gdbarch_use_struct_convention (gdbarch, hppa_use_struct_convention);
-  set_gdbarch_deprecated_store_return_value (gdbarch, hppa_store_return_value);
   set_gdbarch_deprecated_extract_struct_value_address
     (gdbarch, hppa_extract_struct_value_address);
   set_gdbarch_cannot_store_register (gdbarch, hppa_cannot_store_register);
@@ -5043,9 +5192,9 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_frame_args_skip (gdbarch, 0);
   set_gdbarch_deprecated_push_dummy_frame (gdbarch, hppa_push_dummy_frame);
   set_gdbarch_deprecated_pop_frame (gdbarch, hppa_pop_frame);
-  set_gdbarch_deprecated_call_dummy_length (gdbarch, INSTRUCTION_SIZE * 28);
   /* set_gdbarch_deprecated_fix_call_dummy (gdbarch, hppa_fix_call_dummy); */
   set_gdbarch_deprecated_push_arguments (gdbarch, hppa_push_arguments);
+  set_gdbarch_addr_bits_remove (gdbarch, hppa_smash_text_address);
   set_gdbarch_smash_text_address (gdbarch, hppa_smash_text_address);
   set_gdbarch_believe_pcc_promotion (gdbarch, 1);
   set_gdbarch_read_pc (gdbarch, hppa_target_read_pc);
@@ -5055,6 +5204,17 @@ hppa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Helper for function argument information.  */
   set_gdbarch_fetch_pointer_argument (gdbarch, hppa_fetch_pointer_argument);
 
+  set_gdbarch_print_insn (gdbarch, print_insn_hppa);
+
+  /* When a hardware watchpoint triggers, we'll move the inferior past
+     it by removing all eventpoints; stepping past the instruction
+     that caused the trigger; reinserting eventpoints; and checking
+     whether any watched location changed.  */
+  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
+
+  /* Hook in ABI-specific overrides, if they have been registered.  */
+  gdbarch_init_osabi (info, gdbarch);
+
   return gdbarch;
 }
 
@@ -5073,7 +5233,6 @@ _initialize_hppa_tdep (void)
   void break_at_finish_at_depth_command (char *arg, int from_tty);
 
   gdbarch_register (bfd_arch_hppa, hppa_gdbarch_init, hppa_dump_tdep);
-  deprecated_tm_print_insn = print_insn_hppa;
 
   add_cmd ("unwind", class_maintenance, unwind_command,
           "Print unwind table entry at given address.",
This page took 0.027911 seconds and 4 git commands to generate.