* sparc64-tdep.h (sparc64_regnum): Fix comment.
[deliverable/binutils-gdb.git] / gdb / x86-64-tdep.c
index 0fe24853f837e7958b89bba5b8629a0dd3dbc8a0..78d06d36e5ee9af7f454c4ce1ef05d443db4c270 100644 (file)
 #include "x86-64-tdep.h"
 #include "i387-tdep.h"
 
-/* Register numbers of various important registers.  */
-
-#define X86_64_RAX_REGNUM      0 /* %rax */
-#define X86_64_RDX_REGNUM      3 /* %rdx */
-#define X86_64_RDI_REGNUM      5 /* %rdi */
-#define X86_64_RBP_REGNUM      6 /* %rbp */
-#define X86_64_RSP_REGNUM      7 /* %rsp */
-#define X86_64_RIP_REGNUM      16 /* %rip */
-#define X86_64_EFLAGS_REGNUM   17 /* %eflags */
-#define X86_64_ST0_REGNUM      22 /* %st0 */
-#define X86_64_XMM0_REGNUM     38 /* %xmm0 */
-#define X86_64_XMM1_REGNUM     39 /* %xmm1 */
+/* Register information.  */
 
 struct x86_64_register_info
 {
@@ -155,7 +144,7 @@ x86_64_register_type (struct gdbarch *gdbarch, int regnum)
 static int x86_64_dwarf_regmap[] =
 {
   /* General Purpose Registers RAX, RDX, RCX, RBX, RSI, RDI.  */
-  X86_64_RAX_REGNUM, X86_64_RDX_REGNUM, 3, 2, 
+  X86_64_RAX_REGNUM, X86_64_RDX_REGNUM, 2, 1,
   4, X86_64_RDI_REGNUM,
 
   /* Frame Pointer Register RBP.  */
@@ -183,7 +172,7 @@ static int x86_64_dwarf_regmap[] =
   X86_64_XMM0_REGNUM + 14, X86_64_XMM0_REGNUM + 15,
 
   /* Floating Point Registers 0-7.  */
-  X86_64_ST0_REGNUM + 0, X86_64_ST0_REGNUM + 1,        
+  X86_64_ST0_REGNUM + 0, X86_64_ST0_REGNUM + 1,
   X86_64_ST0_REGNUM + 2, X86_64_ST0_REGNUM + 3,
   X86_64_ST0_REGNUM + 4, X86_64_ST0_REGNUM + 5,
   X86_64_ST0_REGNUM + 6, X86_64_ST0_REGNUM + 7
@@ -597,13 +586,14 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
 {
   int intreg = 0;
   int ssereg = 0;
-  /* For varargs functions we have to pass the total number of SSE arguments
-     in %rax.  So, let's count this number.  */
+  /* For varargs functions we have to pass the total number of SSE
+     registers used in %rax.  So, let's count this number.  */
   int total_sse_args = 0;
   /* Once an SSE/int argument is passed on the stack, all subsequent
      arguments are passed there.  */
   int sse_stack = 0;
   int int_stack = 0;
+  unsigned total_sp;
   int i;
   char buf[8];
   static int int_parameter_registers[INT_REGS] =
@@ -623,6 +613,7 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
   int stack_values_count = 0;
   int *stack_values;
   stack_values = alloca (nargs * sizeof (int));
+
   for (i = 0; i < nargs; i++)
     {
       enum x86_64_reg_class class[MAX_CLASSES];
@@ -644,7 +635,8 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
            int_stack = 1;
          if (ssereg / 2 + needed_sseregs > SSE_REGS)
            sse_stack = 1;
-         total_sse_args += needed_sseregs;
+         if (!sse_stack)
+           total_sse_args += needed_sseregs;
 
          for (j = 0; j < n; j++)
            {
@@ -720,13 +712,29 @@ x86_64_push_arguments (struct regcache *regcache, int nargs,
        }
     }
 
+  /* We have to make sure that the stack is 16-byte aligned after the
+     setup.  Let's calculate size of arguments first, align stack and
+     then fill in the arguments.  */
+  total_sp = 0;
+  for (i = 0; i < stack_values_count; i++)
+    {
+      struct value *arg = args[stack_values[i]];
+      int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
+      total_sp += (len + 7) & ~7;
+    }
+  /* total_sp is now a multiple of 8, if it is not a multiple of 16,
+     change the stack pointer so that it will be afterwards correctly
+     aligned.  */
+  if (total_sp & 15)
+    sp -= 8;
+    
   /* Push any remaining arguments onto the stack.  */
   while (--stack_values_count >= 0)
     {
       struct value *arg = args[stack_values[stack_values_count]];
       int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
 
-      /* Make sure the stack stays eightbyte-aligned.  */
+      /* Make sure the stack is 8-byte-aligned.  */
       sp -= (len + 7) & ~7;
       write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
     }
@@ -781,7 +789,8 @@ x86_64_store_return_value (struct type *type, struct regcache *regcache,
   else if (TYPE_CODE_FLT == TYPE_CODE (type))
     {
       /* Handle double and float variables.  */
-      regcache_cooked_write (regcache,  X86_64_XMM0_REGNUM, valbuf);
+      regcache_cooked_write_part (regcache, X86_64_XMM0_REGNUM,
+                                 0, len, valbuf);
     }
   /* XXX: What about complex floating point types?  */
   else
@@ -1069,7 +1078,7 @@ static const struct frame_unwind x86_64_frame_unwind =
 };
 
 static const struct frame_unwind *
-x86_64_frame_p (CORE_ADDR pc)
+x86_64_frame_sniffer (struct frame_info *next_frame)
 {
   return &x86_64_frame_unwind;
 }
@@ -1141,8 +1150,9 @@ static const struct frame_unwind x86_64_sigtramp_frame_unwind =
 };
 
 static const struct frame_unwind *
-x86_64_sigtramp_frame_p (CORE_ADDR pc)
+x86_64_sigtramp_frame_sniffer (struct frame_info *next_frame)
 {
+  CORE_ADDR pc = frame_pc_unwind (next_frame);
   char *name;
 
   find_pc_partial_function (pc, &name, NULL, NULL);
@@ -1186,6 +1196,14 @@ x86_64_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return frame_id_build (fp + 16, frame_pc_unwind (next_frame));
 }
 
+/* 16 byte align the SP per frame requirements.  */
+
+static CORE_ADDR
+x86_64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
+{
+  return sp & -(CORE_ADDR)16;
+}
+
 void
 x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -1229,6 +1247,8 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   /* Call dummy code.  */
   set_gdbarch_push_dummy_call (gdbarch, x86_64_push_dummy_call);
+  set_gdbarch_frame_align (gdbarch, x86_64_frame_align);
+  set_gdbarch_frame_red_zone_size (gdbarch, 128);
 
   set_gdbarch_convert_register_p (gdbarch, x86_64_convert_register_p);
   set_gdbarch_register_to_value (gdbarch, i387_register_to_value);
@@ -1252,8 +1272,8 @@ x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
      in the future.  */
   set_gdbarch_in_solib_call_trampoline (gdbarch, in_plt_section);
 
-  frame_unwind_append_predicate (gdbarch, x86_64_sigtramp_frame_p);
-  frame_unwind_append_predicate (gdbarch, x86_64_frame_p);
+  frame_unwind_append_sniffer (gdbarch, x86_64_sigtramp_frame_sniffer);
+  frame_unwind_append_sniffer (gdbarch, x86_64_frame_sniffer);
   frame_base_set_default (gdbarch, &x86_64_frame_base);
 }
 \f
This page took 0.039065 seconds and 4 git commands to generate.