* config/d10v/tm-d10v.h (D10V_CONVERT_IADDR_TO_RAW,
authorAndrew Cagney <cagney@redhat.com>
Fri, 6 Feb 1998 07:26:11 +0000 (07:26 +0000)
committerAndrew Cagney <cagney@redhat.com>
Fri, 6 Feb 1998 07:26:11 +0000 (07:26 +0000)
  D10V_CONVERT_DADDR_TO_RAW): Define.
* d10v-tdep.c (d10v_push_arguments): Re-write.  Pass arguments in
  registers, regardless of their size, when they fit.

gdb/ChangeLog
gdb/config/d10v/tm-d10v.h
gdb/d10v-tdep.c

index 3ba4250f1a5c61163b837738415b74af73bae510..96e17e2ed64f034889dfa2320b39446d2a9414f0 100644 (file)
@@ -1,3 +1,11 @@
+Fri Feb  6 17:42:22 1998  Andrew Cagney  <cagney@b1.cygnus.com>
+
+       * config/d10v/tm-d10v.h (D10V_CONVERT_IADDR_TO_RAW,
+       D10V_CONVERT_DADDR_TO_RAW): Define.
+
+       * d10v-tdep.c (d10v_push_arguments): Re-write.  Pass arguments in
+       registers, regardless of their size, when they fit.
+
 Thu Feb  5 13:16:36 1998  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * d10v-tdep.c (d10v_extract_return_value): For function pointers
index bbcd182c63a79c9cad5919be22f0704ff1ecad20..36eb1d4e1c5bcaeef2ae18920b08527309dca5fe 100644 (file)
@@ -143,8 +143,11 @@ extern CORE_ADDR d10v_skip_prologue ();
 #define D10V_MAKE_DADDR(x) ( (x) & 0x3000000 ? (x) : ((x) | DMEM_START))
 #define D10V_MAKE_IADDR(x) ( (x) & 0x3000000 ? (x) : (((x) << 2) | IMEM_START))
 
-#define D10V_DADDR_P(x) ( ((x) & 0x3000000) == DMEM_START)
-#define D10V_IADDR_P(x) ( ((x) & 0x3000000) == IMEM_START))
+#define D10V_DADDR_P(X) (((X) & 0x3000000) == DMEM_START)
+#define D10V_IADDR_P(X) (((X) & 0x3000000) == IMEM_START)
+
+#define D10V_CONVERT_IADDR_TO_RAW(X) (((X) & ~0x3000000) >> 2)
+#define D10V_CONVERT_DADDR_TO_RAW(X) (((X) & ~0x3000000))
 
 #define ARG1_REGNUM R0_REGNUM
 #define ARGN_REGNUM 3
index fa7956bbd270c0520f0c290947ea9c08846a1426..8579e7bb73a2d4807d30edb0eaefba094ced5367 100644 (file)
@@ -536,99 +536,78 @@ d10v_push_arguments (nargs, args, sp, struct_return, struct_addr)
      int struct_return;
      CORE_ADDR struct_addr;
 {
-  int i, len;
-  int index;
+  int i;
   int regnum = ARG1_REGNUM;
-  char buffer[4], *contents;
-  LONGEST val;
-  CORE_ADDR ptrs[10];
-
-
-  /* Pass 1. Put all large args on stack, pass pointers */
-  index = 0;
-  for (i = 0; i < nargs; i++)
-    {
-      value_ptr arg = args[i];
-      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
-      len = TYPE_LENGTH (arg_type);
-      contents = VALUE_CONTENTS(arg);
-      if (len > 4)
-       {
-         /* put on word aligned stack and pass pointers */
-         sp = (sp - len) & ~1;
-         write_memory (sp, contents, len);
-         ptrs[index++] = sp;
-       }
-    }
-
-  /* Pass 2. Fill in registers and arg lists */
-  index = 0;
+  
+  /* Fill in registers and arg lists */
   for (i = 0; i < nargs; i++)
     {
       value_ptr arg = args[i];
-      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
-      len = TYPE_LENGTH (arg_type);
-      if (len > 4)
+      struct type *type = check_typedef (VALUE_TYPE (arg));
+      char *contents = VALUE_CONTENTS (arg);
+      int len = TYPE_LENGTH (type);
+      /* printf ("push: type=%d len=%d\n", type->code, len); */
+      if (TYPE_CODE (type) == TYPE_CODE_PTR)
        {
-         /* pass pointer to previously saved data */
+         /* pointers require special handling - first convert and
+            then store */
+         long val = extract_signed_integer (contents, len);
+         len = 2;
+         if (TYPE_TARGET_TYPE (type)
+             && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC))
+           {
+             /* function pointer */
+             val = D10V_CONVERT_IADDR_TO_RAW (val);
+           }
+         else if (D10V_IADDR_P (val))
+           {
+             /* also function pointer! */
+             val = D10V_CONVERT_DADDR_TO_RAW (val);
+           }
+         else
+           {
+             /* data pointer */
+             val &= 0xFFFF;
+           }
          if (regnum <= ARGN_REGNUM)
-           write_register (regnum++, ptrs[index++]);
+           write_register (regnum++, val & 0xffff);
          else
            {
-             /* no more registers available.  put it on the stack */
+             char ptr[2];
              sp -= 2;
-             store_address (buffer, 2, ptrs[index++]);
-             write_memory (sp, buffer, 2);
+             store_address (ptr, val & 0xffff, 2);
+             write_memory (sp, ptr, 2);
            }
        }
       else
        {
-         int even_regnum = (regnum + 1) & ~1;
-         contents = VALUE_CONTENTS(arg);
-         val = extract_signed_integer (contents, len);
-         /*      printf("push: type=%d len=%d val=0x%x\n",arg_type->code,len,val);  */
-         if (arg_type->code == TYPE_CODE_PTR)
+         int aligned_regnum = (regnum + 1) & ~1;
+         if (len <= 2 && regnum <= ARGN_REGNUM)
+           /* fits in a single register, do not align */
            {
-             if ( (val & 0x3000000) == 0x1000000)
+             long val = extract_unsigned_integer (contents, len);
+             write_register (regnum++, val);
+           }
+         else if (len <= (ARGN_REGNUM - aligned_regnum + 1) * 2)
+           /* value fits in remaining registers, store keeping left
+               aligned */
+           {
+             int b;
+             regnum = aligned_regnum;
+             for (b = 0; b < (len & ~1); b += 2)
                {
-                 /* function pointer */
-                 val = (val & 0x3FFFF) >> 2;
-                 len = 2;
+                 long val = extract_unsigned_integer (&contents[b], 2);
+                 write_register (regnum++, val);
                }
-             else
+             if (b < len)
                {
-                 /* data pointer */
-                 val &= 0xFFFF;
-                 len = 2;
+                 long val = extract_unsigned_integer (&contents[b], 1);
+                 write_register (regnum++, (val << 8));
                }
            }
-         
-         if (regnum <= ARGN_REGNUM && len == 1)
-           {
-             write_register (regnum++, val & 0xff);
-           }
-         if (regnum <= ARGN_REGNUM && len == 2)
-           {
-             write_register (regnum++, val & 0xffff);
-           }
-         else if (even_regnum <= ARGN_REGNUM - 1 && len == 3)
-           {
-             /* next even reg and space for two */
-             /* TARGET_BYTE_ORDER == BIG_ENDIAN */
-             regnum = even_regnum;
-             write_register (regnum++, (val >> 8) & 0xffff);
-             write_register (regnum++, (val & 0xff) << 8);
-           }
-         else if (even_regnum <= ARGN_REGNUM - 1 && len == 4)
-           {
-             /* next even reg and space for two */
-             /* TARGET_BYTE_ORDER == BIG_ENDIAN */
-             regnum = even_regnum;
-             write_register (regnum++, (val >> 16) & 0xffff);
-             write_register (regnum++, val & 0xffff);
-           }
          else
            {
+             /* arg goes straight on stack */
              regnum = ARGN_REGNUM + 1;
              sp = (sp - len) & ~1;
              write_memory (sp, contents, len);