summaryrefslogtreecommitdiffstats
path: root/gdb/d10v-tdep.c
diff options
context:
space:
mode:
authorMartin Hunt <hunt@redhat.com>1996-11-07 23:23:57 +0000
committerMartin Hunt <hunt@redhat.com>1996-11-07 23:23:57 +0000
commit81a6f5b20817317609a20f6c255520a95355846e (patch)
tree01c1d581f6a60c22d6b31e6d0d348b1fd745577c /gdb/d10v-tdep.c
parentf8b8cdf8cc12180f3eab0579116447e6f1b6e3e5 (diff)
downloadppe42-binutils-81a6f5b20817317609a20f6c255520a95355846e.tar.gz
ppe42-binutils-81a6f5b20817317609a20f6c255520a95355846e.zip
Thu Nov 7 15:19:08 1996 Martin M. Hunt <hunt@pizza.cygnus.com>
* d10v-tdep.c: Fix some problems with inferior function calls. * config/d10v/tm-d10v.h (EXTRA_FRAME_INFO): Change dummy to be a pointer to the dummy's stack instead of just a flag.
Diffstat (limited to 'gdb/d10v-tdep.c')
-rw-r--r--gdb/d10v-tdep.c87
1 files changed, 62 insertions, 25 deletions
diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c
index be4c5ded9c..7920c4fdfb 100644
--- a/gdb/d10v-tdep.c
+++ b/gdb/d10v-tdep.c
@@ -502,7 +502,7 @@ d10v_fix_call_dummy (dummyname, start_sp, fun, nargs, args, type, gcc_p)
CORE_ADDR sp;
char buffer[MAX_REGISTER_RAW_SIZE];
struct frame_info *frame = get_current_frame ();
- frame->dummy = 1;
+ frame->dummy = start_sp;
start_sp |= DMEM_START;
sp = start_sp;
@@ -522,18 +522,15 @@ static void
d10v_pop_dummy_frame (fi)
struct frame_info *fi;
{
- CORE_ADDR sp = fi->frame;
+ CORE_ADDR sp = fi->dummy;
int regnum;
- for (regnum = NUM_REGS-1; regnum >= 0; regnum--)
+ for (regnum = 0; regnum < NUM_REGS; regnum++)
{
+ sp -= REGISTER_RAW_SIZE(regnum);
write_register(regnum, read_memory_unsigned_integer (sp, REGISTER_RAW_SIZE(regnum)));
- sp += REGISTER_RAW_SIZE(regnum);
}
- target_store_registers (-1);
- flush_cached_frames ();
-
- write_register(SP_REGNUM, sp & 0xffff);
+ flush_cached_frames (); /* needed? */
}
@@ -545,36 +542,76 @@ d10v_push_arguments (nargs, args, sp, struct_return, struct_addr)
int struct_return;
CORE_ADDR struct_addr;
{
- int i, len, regnum=2;
- char *contents;
+ int i, len, index=0, regnum=2;
+ char buffer[4], *contents;
LONGEST val;
-
+ CORE_ADDR ptrs[10];
+
+ /* Pass 1. Put all large args on stack */
for (i = 0; i < nargs; i++)
{
value_ptr arg = args[i];
struct type *arg_type = check_typedef (VALUE_TYPE (arg));
- switch (TYPE_CODE (arg_type))
- {
- case TYPE_CODE_INT:
- case TYPE_CODE_BOOL:
- case TYPE_CODE_CHAR:
- case TYPE_CODE_RANGE:
- case TYPE_CODE_ENUM:
- break;
- default:
- break;
+ len = TYPE_LENGTH (arg_type);
+ contents = VALUE_CONTENTS(arg);
+ val = extract_signed_integer (contents, len);
+ if (len > 4)
+ {
+ /* put on stack and pass pointers */
+ sp -= len;
+ write_memory (sp, contents, len);
+ ptrs[index++] = sp;
}
+ }
+
+ 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);
val = extract_signed_integer (contents, len);
- if (len == 4)
- write_register (regnum++, val>>16);
- write_register (regnum++, val & 0xffff);
+ if (len > 4)
+ {
+ /* use a pointer to previously saved data */
+ if (regnum < 6)
+ write_register (regnum++, ptrs[index++]);
+ else
+ {
+ /* no more registers available. put it on the stack */
+ sp -= 2;
+ store_address (buffer, 2, ptrs[index++]);
+ write_memory (sp, buffer, 2);
+ }
+ }
+ else
+ {
+ if (regnum < 6 )
+ {
+ if (len == 4)
+ write_register (regnum++, val>>16);
+ write_register (regnum++, val & 0xffff);
+ }
+ else
+ {
+ sp -= len;
+ store_address (buffer, len, val);
+ write_memory (sp, buffer, len);
+ }
+ }
}
return sp;
}
+/* pick an out-of-the-way place to set the return value */
+/* for an inferior function call. The link register is set to this */
+/* value and a momentary breakpoint is set there. When the breakpoint */
+/* is hit, the dummy frame is popped and the previous environment is */
+/* restored. */
+
CORE_ADDR
d10v_call_dummy_address ()
{
@@ -603,5 +640,5 @@ d10v_extract_return_value (valtype, regbuf, valbuf)
char regbuf[REGISTER_BYTES];
char *valbuf;
{
- memcpy (valbuf, regbuf + REGISTER_BYTE (2), TYPE_LENGTH (valtype));
+ memcpy (valbuf, regbuf + REGISTER_BYTE (2), TYPE_LENGTH (valtype));
}
OpenPOWER on IntegriCloud