aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>1998-02-06 07:26:11 +0000
committerAndrew Cagney <cagney@redhat.com>1998-02-06 07:26:11 +0000
commit608addd4404b51b7d283e095cc9bf3bb3c3895f5 (patch)
tree527fa0065b7fd127265232d985318149d5d17f15
parent1430b6ed3a210ad84f4534340e228e31b138b163 (diff)
downloadgdb-608addd4404b51b7d283e095cc9bf3bb3c3895f5.zip
gdb-608addd4404b51b7d283e095cc9bf3bb3c3895f5.tar.gz
gdb-608addd4404b51b7d283e095cc9bf3bb3c3895f5.tar.bz2
* 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.
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/config/d10v/tm-d10v.h7
-rw-r--r--gdb/d10v-tdep.c123
3 files changed, 64 insertions, 74 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3ba4250..96e17e2 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/config/d10v/tm-d10v.h b/gdb/config/d10v/tm-d10v.h
index bbcd182..36eb1d4 100644
--- a/gdb/config/d10v/tm-d10v.h
+++ b/gdb/config/d10v/tm-d10v.h
@@ -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
diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c
index fa7956b..8579e7b 100644
--- a/gdb/d10v-tdep.c
+++ b/gdb/d10v-tdep.c
@@ -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);