+Wed Mar 5 12:59:27 1997 Jeffrey A Law (law@cygnus.com)
+
+ * mn10200-tdep.c (mn10200_push_arguments): Handle new calling
+ conventions.
+ (mn10200_store_struct_return): Likewise.
+
+Tue Mar 4 10:31:02 1997 Mark Alexander <marka@cygnus.com>
+
+ * mips-tdep.c (mips_fetch_instruction): New function; replace
+ common code throughout with calls to it.
+ (mips_find_saved_regs): Examine MIPS16 entry instruction to determine
+ correct saved addresses of $s0 and $s1.
+ (mips_find_saved_regs, mips16_heuristic_proc_desc): Use MIPS_REGSIZE
+ instead of hardcoded 4.
+ (mips16_skip_prologue): Handle extended instructions correctly.
+
Mon Mar 3 12:29:20 1997 Doug Evans <dje@canuck.cygnus.com>
* defs.h (LONGEST): Move #ifndef LONGEST to outside.
int argnum = 0;
int len = 0;
int stack_offset = 0;
+ int regsused = struct_return ? 1 : 0;
/* This should be a nop, but align the stack just in case something
went wrong. Stacks are two byte aligned on the mn10200. */
XXX This doesn't appear to handle pass-by-invisible reference
arguments. */
for (argnum = 0; argnum < nargs; argnum++)
- len += ((TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 1) & ~1);
+ {
+ int arg_length = (TYPE_LENGTH (VALUE_TYPE (args[argnum])) + 1) & ~1;
+
+ /* If we've used all argument registers, then this argument is
+ pushed. */
+ if (regsused >= 2 || arg_length > 4)
+ {
+ regsused = 2;
+ len += arg_length;
+ }
+ /* We know we've got some arg register space left. If this argument
+ will fit entirely in regs, then put it there. */
+ else if (arg_length <= 2
+ || TYPE_CODE (VALUE_TYPE (args[argnum])) == TYPE_CODE_PTR)
+ {
+ regsused++;
+ }
+ else if (regsused == 0)
+ {
+ regsused = 2;
+ }
+ else
+ {
+ regsused = 2;
+ len += arg_length;
+ }
+ }
/* Allocate stack space. */
sp -= len;
+ regsused = struct_return ? 1 : 0;
/* Push all arguments onto the stack. */
for (argnum = 0; argnum < nargs; argnum++)
{
int len;
char *val;
- /* XXX Check this. What about UNIONS? Size check looks
- wrong too. */
+ /* XXX Check this. What about UNIONS? */
if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
&& TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
{
val = (char *)VALUE_CONTENTS (*args);
}
- while (len > 0)
+ if (regsused < 2
+ && (len <= 2
+ || TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_PTR))
{
- /* XXX This looks wrong; we can have one and two byte args. */
- write_memory (sp + stack_offset, val, 2);
+ write_register (regsused, extract_unsigned_integer (val, 4));
+ regsused++;
+ }
+ else if (regsused == 0 && len == 4)
+ {
+ write_register (regsused, extract_unsigned_integer (val, 2));
+ write_register (regsused + 1, extract_unsigned_integer (val + 2, 2));
+ regsused = 2;
+ }
+ else
+ {
+ regsused = 2;
+ while (len > 0)
+ {
+ write_memory (sp + stack_offset, val, 2);
- len -= 2;
- val += 2;
- stack_offset += 2;
+ len -= 2;
+ val += 2;
+ stack_offset += 2;
+ }
}
args++;
}
CORE_ADDR addr;
CORE_ADDR sp;
{
- unsigned char buf1[4];
- unsigned char buf2[4];
-
- /* Get the saved PC and hold onto it. */
- target_read_memory (sp, buf1, 4);
-
- /* Now push the structure value address. */
- store_unsigned_integer (buf2, 4, addr);
- write_memory (sp, buf2, 4);
-
- /* Now push the saved PC back onto the stack. */
- target_write_memory (sp - 4, buf1, 4);
- return sp - 4;
+ /* The structure return address is passed as the first argument. */
+ write_register (0, addr);
+ return sp;
}
/* Function: frame_saved_pc