diff options
author | Martin Hunt <hunt@redhat.com> | 1996-11-07 23:23:57 +0000 |
---|---|---|
committer | Martin Hunt <hunt@redhat.com> | 1996-11-07 23:23:57 +0000 |
commit | 81a6f5b20817317609a20f6c255520a95355846e (patch) | |
tree | 01c1d581f6a60c22d6b31e6d0d348b1fd745577c /gdb/d10v-tdep.c | |
parent | f8b8cdf8cc12180f3eab0579116447e6f1b6e3e5 (diff) | |
download | fsf-binutils-gdb-81a6f5b20817317609a20f6c255520a95355846e.zip fsf-binutils-gdb-81a6f5b20817317609a20f6c255520a95355846e.tar.gz fsf-binutils-gdb-81a6f5b20817317609a20f6c255520a95355846e.tar.bz2 |
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.c | 87 |
1 files changed, 62 insertions, 25 deletions
diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index be4c5de..7920c4f 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)); } |