mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-23 03:29:47 +08:00
* mn10200-tdep.c (mn10200_push_arguments): Handle new calling
conventions. (mn10200_store_struct_return): Likewise.
This commit is contained in:
@ -1,3 +1,19 @@
|
|||||||
|
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>
|
Mon Mar 3 12:29:20 1997 Doug Evans <dje@canuck.cygnus.com>
|
||||||
|
|
||||||
* defs.h (LONGEST): Move #ifndef LONGEST to outside.
|
* defs.h (LONGEST): Move #ifndef LONGEST to outside.
|
||||||
|
@ -532,6 +532,7 @@ mn10200_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
|||||||
int argnum = 0;
|
int argnum = 0;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
int stack_offset = 0;
|
int stack_offset = 0;
|
||||||
|
int regsused = struct_return ? 1 : 0;
|
||||||
|
|
||||||
/* This should be a nop, but align the stack just in case something
|
/* This should be a nop, but align the stack just in case something
|
||||||
went wrong. Stacks are two byte aligned on the mn10200. */
|
went wrong. Stacks are two byte aligned on the mn10200. */
|
||||||
@ -542,19 +543,45 @@ mn10200_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
|||||||
XXX This doesn't appear to handle pass-by-invisible reference
|
XXX This doesn't appear to handle pass-by-invisible reference
|
||||||
arguments. */
|
arguments. */
|
||||||
for (argnum = 0; argnum < nargs; argnum++)
|
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. */
|
/* Allocate stack space. */
|
||||||
sp -= len;
|
sp -= len;
|
||||||
|
|
||||||
|
regsused = struct_return ? 1 : 0;
|
||||||
/* Push all arguments onto the stack. */
|
/* Push all arguments onto the stack. */
|
||||||
for (argnum = 0; argnum < nargs; argnum++)
|
for (argnum = 0; argnum < nargs; argnum++)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *val;
|
char *val;
|
||||||
|
|
||||||
/* XXX Check this. What about UNIONS? Size check looks
|
/* XXX Check this. What about UNIONS? */
|
||||||
wrong too. */
|
|
||||||
if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
|
if (TYPE_CODE (VALUE_TYPE (*args)) == TYPE_CODE_STRUCT
|
||||||
&& TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
|
&& TYPE_LENGTH (VALUE_TYPE (*args)) > 8)
|
||||||
{
|
{
|
||||||
@ -568,14 +595,30 @@ mn10200_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
|||||||
val = (char *)VALUE_CONTENTS (*args);
|
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_register (regsused, extract_unsigned_integer (val, 4));
|
||||||
write_memory (sp + stack_offset, val, 2);
|
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;
|
len -= 2;
|
||||||
val += 2;
|
val += 2;
|
||||||
stack_offset += 2;
|
stack_offset += 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
args++;
|
args++;
|
||||||
}
|
}
|
||||||
@ -608,19 +651,9 @@ mn10200_store_struct_return (addr, sp)
|
|||||||
CORE_ADDR addr;
|
CORE_ADDR addr;
|
||||||
CORE_ADDR sp;
|
CORE_ADDR sp;
|
||||||
{
|
{
|
||||||
unsigned char buf1[4];
|
/* The structure return address is passed as the first argument. */
|
||||||
unsigned char buf2[4];
|
write_register (0, addr);
|
||||||
|
return sp;
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Function: frame_saved_pc
|
/* Function: frame_saved_pc
|
||||||
|
Reference in New Issue
Block a user