2003-06-01 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / ia64-tdep.c
index 5e46d6b8f408c5c0157e13e8d0d98e6880e142cb..4697574047382350c5e5b42562fe0531dda1485b 100644 (file)
@@ -96,7 +96,7 @@ static gdbarch_deprecated_extract_return_value_ftype ia64_extract_return_value;
 static gdbarch_deprecated_extract_struct_value_address_ftype ia64_extract_struct_value_address;
 static gdbarch_use_struct_convention_ftype ia64_use_struct_convention;
 static gdbarch_frameless_function_invocation_ftype ia64_frameless_function_invocation;
-static gdbarch_saved_pc_after_call_ftype ia64_saved_pc_after_call;
+static gdbarch_deprecated_saved_pc_after_call_ftype ia64_saved_pc_after_call;
 static void ia64_pop_frame_regular (struct frame_info *frame);
 static struct type *is_float_or_hfa_type (struct type *t);
 
@@ -273,7 +273,7 @@ ia64_register_convert_to_virtual (int regnum, struct type *type,
     {
       DOUBLEST val;
       floatformat_to_doublest (&floatformat_ia64_ext, from, &val);
-      store_floating(to, TYPE_LENGTH(type), val);
+      deprecated_store_floating (to, TYPE_LENGTH(type), val);
     }
   else
     error("ia64_register_convert_to_virtual called with non floating point register number");
@@ -285,7 +285,7 @@ ia64_register_convert_to_raw (struct type *type, int regnum,
 {
   if (regnum >= IA64_FR0_REGNUM && regnum <= IA64_FR127_REGNUM)
     {
-      DOUBLEST val = extract_floating (from, TYPE_LENGTH(type));
+      DOUBLEST val = deprecated_extract_floating (from, TYPE_LENGTH(type));
       floatformat_from_doublest (&floatformat_ia64_ext, &val, to);
     }
   else
@@ -543,9 +543,9 @@ fetch_instruction (CORE_ADDR addr, instruction_type *it, long long *instr)
    using the pattern seen below. */
 
 #if 0
-#define BREAKPOINT 0x00002000040LL
+#define IA64_BREAKPOINT 0x00002000040LL
 #endif
-#define BREAKPOINT 0x00003333300LL
+#define IA64_BREAKPOINT 0x00003333300LL
 
 static int
 ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
@@ -573,7 +573,7 @@ ia64_memory_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
 
   instr = slotN_contents (bundle, slotnum);
   memcpy(contents_cache, &instr, sizeof(instr));
-  replace_slotN_contents (bundle, BREAKPOINT, slotnum);
+  replace_slotN_contents (bundle, IA64_BREAKPOINT, slotnum);
   if (val == 0)
     target_write_memory (addr, bundle, BUNDLE_LEN);
 
@@ -678,8 +678,8 @@ rse_address_add(CORE_ADDR addr, int nslots)
    computationally expensive.  So, instead of making life difficult
    (and slow), we pick a more convenient representation of the frame
    chain, knowing that we'll have to make some small adjustments in
-   other places.  (E.g, note that read_fp() is actually read_sp() in
-   ia64_gdbarch_init() below.)
+   other places.  (E.g, note that deprecated_read_fp() is actually
+   read_sp() in ia64_gdbarch_init() below.)
 
    Okay, so what is the frame chain exactly?  It'll be the SP value
    at the time that the function in question was entered.
@@ -737,7 +737,7 @@ ia64_frame_saved_pc (struct frame_info *frame)
 
 /* Limit the number of skipped non-prologue instructions since examining
    of the prologue is expensive.  */
-static int max_skip_non_prologue_insns = 10;
+static int max_skip_non_prologue_insns = 40;
 
 /* Given PC representing the starting address of a function, and
    LIM_PC which is the (sloppy) limit to which to scan when looking
@@ -825,10 +825,13 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
   CORE_ADDR spill_addr = 0;
   char instores[8];
   char infpstores[8];
+  char reg_contents[256];
   int trust_limit;
+  int frameless = 0;
 
   memset (instores, 0, sizeof instores);
   memset (infpstores, 0, sizeof infpstores);
+  memset (reg_contents, 0, sizeof reg_contents);
 
   if (frame && !get_frame_saved_regs (frame))
     {
@@ -843,13 +846,14 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
     return get_frame_extra_info (frame)->after_prologue;
 
   lim_pc = refine_prologue_limit (pc, lim_pc, &trust_limit);
-
-  /* Must start with an alloc instruction */
   next_pc = fetch_instruction (pc, &it, &instr);
+
+  /* We want to check if we have a recognizable function start before we
+     look ahead for a prologue.  */
   if (pc < lim_pc && next_pc 
       && it == M && ((instr & 0x1ee0000003fLL) == 0x02c00000000LL))
     {
-      /* alloc */
+      /* alloc - start of a regular function.  */
       int sor = (int) ((instr & 0x00078000000LL) >> 27);
       int sol = (int) ((instr & 0x00007f00000LL) >> 20);
       int sof = (int) ((instr & 0x000000fe000LL) >> 13);
@@ -864,9 +868,35 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
     }
   else
     {
-      pc = lim_pc;     /* Frameless: We're done early.  */
-      if (trust_limit)
-       last_prologue_pc = lim_pc;
+      /* Look for a leaf routine.  */
+      if (pc < lim_pc && next_pc
+         && (it == I || it == M) 
+          && ((instr & 0x1ee00000000LL) == 0x10800000000LL))
+       {
+         /* adds rN = imm14, rM   (or mov rN, rM  when imm14 is 0) */
+         int imm = (int) ((((instr & 0x01000000000LL) ? -1 : 0) << 13) 
+                          | ((instr & 0x001f8000000LL) >> 20)
+                          | ((instr & 0x000000fe000LL) >> 13));
+         int rM = (int) ((instr & 0x00007f00000LL) >> 20);
+         int rN = (int) ((instr & 0x00000001fc0LL) >> 6);
+         int qp = (int) (instr & 0x0000000003fLL);
+         if (qp == 0 && rN == 2 && imm == 0 && rM == 12 && fp_reg == 0)
+           {
+             /* mov r2, r12 - beginning of leaf routine */
+             fp_reg = rN;
+             frameless = 1;
+             last_prologue_pc = next_pc;
+           }
+       } 
+
+      /* If we don't recognize a regular function or leaf routine, we are
+        done.  */
+      if (!fp_reg)
+       {
+         pc = lim_pc;  
+         if (trust_limit)
+           last_prologue_pc = lim_pc;
+       }
     }
 
   /* Loop, looking for prologue instructions, keeping track of
@@ -882,6 +912,8 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
        {
          /* Exit loop upon hitting a non-nop branch instruction 
             or a predicated instruction. */
+         if (trust_limit)
+           lim_pc = pc;
          break;
        }
       else if (it == I && ((instr & 0x1eff8000000LL) == 0x00188000000LL))
@@ -941,6 +973,20 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
              spill_reg   = rN;
              last_prologue_pc = next_pc;
            }
+         else if (qp == 0 && rM >= 32 && rM < 40 && !instores[rM] && 
+                  rN < 256 && imm == 0)
+           {
+             /* mov rN, rM where rM is an input register */
+             reg_contents[rN] = rM;
+             last_prologue_pc = next_pc;
+           }
+         else if (frameless && qp == 0 && rN == fp_reg && imm == 0 && 
+                  rM == 2)
+           {
+             /* mov r12, r2 */
+             last_prologue_pc = next_pc;
+             break;
+           }
        }
       else if (it == M 
             && (   ((instr & 0x1efc0000000LL) == 0x0eec0000000LL)
@@ -1006,6 +1052,7 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
          int rN = (int) ((instr & 0x00007f00000LL) >> 20);
          int rM = (int) ((instr & 0x000000fe000LL) >> 13);
          int qp = (int) (instr & 0x0000000003fLL);
+         int indirect = rM < 256 ? reg_contents[rM] : 0;
          if (qp == 0 && rN == spill_reg && spill_addr != 0
              && (rM == unat_save_reg || rM == pr_save_reg))
            {
@@ -1040,6 +1087,13 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
              instores[rM-32] = 1;
              last_prologue_pc = next_pc;
            }
+         else if (qp == 0 && 32 <= indirect && indirect < 40 && 
+                  !instores[indirect-32])
+           {
+             /* Allow an indirect store of an input register.  */
+             instores[indirect-32] = 1;
+             last_prologue_pc = next_pc;
+           }
        }
       else if (it == M && ((instr & 0x1ff08000000LL) == 0x08c00000000LL))
        {
@@ -1054,11 +1108,19 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
             register is permitted. */
          int rM = (int) ((instr & 0x000000fe000LL) >> 13);
          int qp = (int) (instr & 0x0000000003fLL);
+         int indirect = rM < 256 ? reg_contents[rM] : 0;
          if (qp == 0 && 32 <= rM && rM < 40 && !instores[rM-32])
            {
              instores[rM-32] = 1;
              last_prologue_pc = next_pc;
            }
+         else if (qp == 0 && 32 <= indirect && indirect < 40 && 
+                  !instores[indirect-32])
+           {
+             /* Allow an indirect store of an input register.  */
+             instores[indirect-32] = 1;
+             last_prologue_pc = next_pc;
+           }
        }
       else if (it == M && ((instr & 0x1ff88000000LL) == 0x0cc80000000LL))
         {
@@ -1147,6 +1209,10 @@ examine_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct frame_info *frame)
       get_frame_extra_info (frame)->fp_reg = fp_reg;
     }
 
+  /* Try and trust the lim_pc value whenever possible.  */
+  if (trust_limit && lim_pc >= last_prologue_pc)
+    return lim_pc;
+
   return last_prologue_pc;
 }
 
@@ -1239,13 +1305,13 @@ ia64_get_saved_register (char *raw_buffer,
   if (regnum == SP_REGNUM && get_next_frame (frame))
     {
       /* Handle SP values for all frames but the topmost. */
-      store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
-                    get_frame_base (frame));
+      store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum),
+                             get_frame_base (frame));
     }
   else if (regnum == IA64_BSP_REGNUM)
     {
-      store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), 
-                     get_frame_extra_info (frame)->bsp);
+      store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), 
+                             get_frame_extra_info (frame)->bsp);
     }
   else if (regnum == IA64_VFP_REGNUM)
     {
@@ -1255,11 +1321,11 @@ ia64_get_saved_register (char *raw_buffer,
         still provide a value since we know the size of the frame */
       CORE_ADDR vfp = (get_frame_base (frame)
                       + get_frame_extra_info (frame)->mem_stack_frame_size);
-      store_address (raw_buffer, REGISTER_RAW_SIZE (IA64_VFP_REGNUM), vfp);
+      store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (IA64_VFP_REGNUM), vfp);
     }
   else if (IA64_PR0_REGNUM <= regnum && regnum <= IA64_PR63_REGNUM)
     {
-      char *pr_raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+      char pr_raw_buffer[MAX_REGISTER_SIZE];
       int  pr_optim;
       enum lval_type pr_lval;
       CORE_ADDR pr_addr;
@@ -1282,7 +1348,7 @@ ia64_get_saved_register (char *raw_buffer,
     }
   else if (IA64_NAT0_REGNUM <= regnum && regnum <= IA64_NAT31_REGNUM)
     {
-      char *unat_raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+      char unat_raw_buffer[MAX_REGISTER_SIZE];
       int  unat_optim;
       enum lval_type unat_lval;
       CORE_ADDR unat_addr;
@@ -1338,7 +1404,7 @@ ia64_get_saved_register (char *raw_buffer,
         {
          pc = read_pc ();
        }
-      store_address (raw_buffer, REGISTER_RAW_SIZE (IA64_IP_REGNUM), pc);
+      store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (IA64_IP_REGNUM), pc);
     }
   else if (IA64_GR32_REGNUM <= regnum && regnum <= IA64_GR127_REGNUM)
     {
@@ -1681,7 +1747,7 @@ generic_elf_find_global_pointer (CORE_ADDR faddr)
                  status = target_read_memory (addr + 8, buf, sizeof (buf));
                  if (status != 0)
                    break;
-                 global_pointer = extract_address (buf, sizeof (buf));
+                 global_pointer = extract_unsigned_integer (buf, sizeof (buf));
 
                  /* The payoff... */
                  return global_pointer;
@@ -1769,8 +1835,8 @@ find_func_descr (CORE_ADDR faddr, CORE_ADDR *fdaptr)
       if (global_pointer == 0)
        global_pointer = read_register (IA64_GR1_REGNUM);
 
-      store_address (buf, 8, faddr);
-      store_address (buf + 8, 8, global_pointer);
+      store_unsigned_integer (buf, 8, faddr);
+      store_unsigned_integer (buf + 8, 8, global_pointer);
 
       write_memory (fdesc, buf, 16);
     }
@@ -1862,9 +1928,9 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
        {
          char val_buf[8];
 
-         store_address (val_buf, 8,
-           find_func_descr (extract_address (VALUE_CONTENTS (arg), 8),
-                            &funcdescaddr));
+         store_unsigned_integer (val_buf, 8,
+                                 find_func_descr (extract_unsigned_integer (VALUE_CONTENTS (arg), 8),
+                                                  &funcdescaddr));
          if (slotnum < rseslots)
            write_memory (rse_address_add (bsp, slotnum), val_buf, 8);
          else
@@ -1920,9 +1986,9 @@ ia64_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
   /* Store the struct return value in r8 if necessary. */
   if (struct_return)
     {
-      store_address (&deprecated_registers[REGISTER_BYTE (IA64_GR8_REGNUM)],
-                     REGISTER_RAW_SIZE (IA64_GR8_REGNUM),
-                    struct_addr);
+      store_unsigned_integer (&deprecated_registers[REGISTER_BYTE (IA64_GR8_REGNUM)],
+                             REGISTER_RAW_SIZE (IA64_GR8_REGNUM),
+                             struct_addr);
     }
 
   /* Sync gdb's idea of what the registers are with the target. */
@@ -2033,7 +2099,9 @@ ia64_pop_frame_regular (struct frame_info *frame)
 }
 
 static void
-ia64_remote_translate_xfer_address (CORE_ADDR memaddr, int nr_bytes,
+ia64_remote_translate_xfer_address (struct gdbarch *gdbarch,
+                                   struct regcache *regcache,
+                                   CORE_ADDR memaddr, int nr_bytes,
                                    CORE_ADDR *targ_addr, int *targ_len)
 {
   *targ_addr = memaddr;
@@ -2168,13 +2236,13 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_num_regs (gdbarch, ia64_num_regs);
   set_gdbarch_sp_regnum (gdbarch, sp_regnum);
-  set_gdbarch_fp_regnum (gdbarch, fp_regnum);
+  set_gdbarch_deprecated_fp_regnum (gdbarch, fp_regnum);
   set_gdbarch_pc_regnum (gdbarch, pc_regnum);
   set_gdbarch_fp0_regnum (gdbarch, IA64_FR0_REGNUM);
 
   set_gdbarch_register_name (gdbarch, ia64_register_name);
-  set_gdbarch_register_size (gdbarch, 8);
-  set_gdbarch_register_bytes (gdbarch, ia64_num_regs * 8 + 128*8);
+  set_gdbarch_deprecated_register_size (gdbarch, 8);
+  set_gdbarch_deprecated_register_bytes (gdbarch, ia64_num_regs * 8 + 128*8);
   set_gdbarch_register_byte (gdbarch, ia64_register_byte);
   set_gdbarch_register_raw_size (gdbarch, ia64_register_raw_size);
   set_gdbarch_deprecated_max_register_raw_size (gdbarch, 16);
@@ -2187,7 +2255,7 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
   set_gdbarch_frameless_function_invocation (gdbarch, ia64_frameless_function_invocation);
 
-  set_gdbarch_saved_pc_after_call (gdbarch, ia64_saved_pc_after_call);
+  set_gdbarch_deprecated_saved_pc_after_call (gdbarch, ia64_saved_pc_after_call);
 
   set_gdbarch_deprecated_frame_chain (gdbarch, ia64_frame_chain);
   set_gdbarch_deprecated_frame_saved_pc (gdbarch, ia64_frame_saved_pc);
@@ -2217,18 +2285,18 @@ ia64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_deprecated_push_return_address (gdbarch, ia64_push_return_address);
   set_gdbarch_deprecated_pop_frame (gdbarch, ia64_pop_frame);
 
-  set_gdbarch_call_dummy_words (gdbarch, ia64_call_dummy_words);
-  set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (ia64_call_dummy_words));
+  set_gdbarch_deprecated_call_dummy_words (gdbarch, ia64_call_dummy_words);
+  set_gdbarch_deprecated_sizeof_call_dummy_words (gdbarch, sizeof (ia64_call_dummy_words));
   set_gdbarch_deprecated_init_extra_frame_info (gdbarch, ia64_init_extra_frame_info);
   set_gdbarch_frame_args_address (gdbarch, ia64_frame_args_address);
   set_gdbarch_frame_locals_address (gdbarch, ia64_frame_locals_address);
 
-  /* We won't necessarily have a frame pointer and even if we do,
-     it winds up being extraordinarly messy when attempting to find
-     the frame chain.  So for the purposes of creating frames (which
-     is all read_fp() is used for), simply use the stack pointer value
-     instead.  */
-  set_gdbarch_read_fp (gdbarch, generic_target_read_sp);
+  /* We won't necessarily have a frame pointer and even if we do, it
+     winds up being extraordinarly messy when attempting to find the
+     frame chain.  So for the purposes of creating frames (which is
+     all deprecated_read_fp() is used for), simply use the stack
+     pointer value instead.  */
+  set_gdbarch_deprecated_target_read_fp (gdbarch, generic_target_read_sp);
 
   /* Settings that should be unnecessary.  */
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
@@ -2251,6 +2319,6 @@ _initialize_ia64_tdep (void)
 {
   register_gdbarch_init (bfd_arch_ia64, ia64_gdbarch_init);
 
-  tm_print_insn = print_insn_ia64;
-  tm_print_insn_info.bytes_per_line = SLOT_MULTIPLIER;
+  deprecated_tm_print_insn = print_insn_ia64;
+  deprecated_tm_print_insn_info.bytes_per_line = SLOT_MULTIPLIER;
 }
This page took 0.042996 seconds and 4 git commands to generate.