* valops.c (value_cast): Cehck for cast to array type *before*

we coerce array to pointer (in case arg2 is already array).

	* valops.c (call_function_by_hand):  Set using_gcc to 2 if using
	gcc2.  Needed for REG_STRUCT_HAS_ADDR to work on sparc.
	Also check REG_STRUCT_HAS_ADDR for union, array and string types.

	* valops.c (call_function_by_hand):  Re-arrange code for pushing
	paramaters on the stack so we can do better STACK_ALIGN.

	* valops.c (call_function_by_hand):  Call error if the number
	of arguments is fewer than parameter types in function type.
This commit is contained in:
Per Bothner 1995-03-04 02:24:26 +00:00
parent 732ff6aff3
commit f7a69ed795
2 changed files with 100 additions and 67 deletions

View File

@ -1,3 +1,18 @@
Fri Mar 3 17:42:48 1995 Per Bothner <bothner@kalessin.cygnus.com>
* valops.c (value_cast): Cehck for cast to array type *before*
we coerce array to pointer (in case arg2 is already array).
* valops.c (call_function_by_hand): Set using_gcc to 2 if using
gcc2. Needed for REG_STRUCT_HAS_ADDR to work on sparc.
Also check REG_STRUCT_HAS_ADDR for union, array and string types.
* valops.c (call_function_by_hand): Re-arrange code for pushing
paramaters on the stack so we can do better STACK_ALIGN.
* valops.c (call_function_by_hand): Call error if the number
of arguments is fewer than parameter types in function type.
Fri Mar 3 17:13:05 1995 Doug Evans <dje@canuck.cygnus.com>
* sparc-tdep.c (sparc_extract_struct_value_address): Move

View File

@ -117,29 +117,14 @@ value_cast (type, arg2)
struct type *type;
register value_ptr arg2;
{
register enum type_code code1;
register enum type_code code1 = TYPE_CODE (type);
register enum type_code code2;
register int scalar;
if (VALUE_TYPE (arg2) == type)
return arg2;
/* Coerce arrays but not enums. Enums will work as-is
and coercing them would cause an infinite recursion. */
if (TYPE_CODE (VALUE_TYPE (arg2)) != TYPE_CODE_ENUM)
COERCE_ARRAY (arg2);
COERCE_VARYING_ARRAY (arg2);
code1 = TYPE_CODE (type);
code2 = TYPE_CODE (VALUE_TYPE (arg2));
if (code1 == TYPE_CODE_COMPLEX)
return cast_into_complex (type, arg2);
if (code1 == TYPE_CODE_BOOL)
code1 = TYPE_CODE_INT;
if (code2 == TYPE_CODE_BOOL)
code2 = TYPE_CODE_INT;
COERCE_REF(arg2);
/* A cast to an undetermined-length array_type, such as (TYPE [])OBJECT,
is treated like a cast to (TYPE [N])OBJECT,
@ -163,6 +148,25 @@ value_cast (type, arg2)
return arg2;
}
if (current_language->c_style_arrays
&& (VALUE_REPEATED (arg2)
|| TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_ARRAY))
arg2 = value_coerce_array (arg2); \
if (TYPE_CODE (VALUE_TYPE (arg2)) == TYPE_CODE_FUNC) \
arg2 = value_coerce_function (arg2);
COERCE_VARYING_ARRAY (arg2);
code2 = TYPE_CODE (VALUE_TYPE (arg2));
if (code1 == TYPE_CODE_COMPLEX)
return cast_into_complex (type, arg2);
if (code1 == TYPE_CODE_BOOL)
code1 = TYPE_CODE_INT;
if (code2 == TYPE_CODE_BOOL)
code2 = TYPE_CODE_INT;
scalar = (code2 == TYPE_CODE_INT || code2 == TYPE_CODE_FLT
|| code2 == TYPE_CODE_ENUM || code2 == TYPE_CODE_RANGE);
@ -999,7 +1003,7 @@ call_function_by_hand (function, nargs, args)
{
struct block *b = block_for_pc (funaddr);
/* If compiled without -g, assume GCC. */
using_gcc = b == NULL || BLOCK_GCC_COMPILED (b);
using_gcc = b == NULL ? 0 : BLOCK_GCC_COMPILED (b);
}
/* Are we returning a value using a structure return or a normal
@ -1065,6 +1069,9 @@ call_function_by_hand (function, nargs, args)
sp = old_sp; /* It really is used, for some ifdef's... */
#endif
if (nargs < TYPE_NFIELDS (ftype))
error ("too few arguments in function call");
for (i = nargs - 1; i >= 0; i--)
{
struct type *param_type;
@ -1075,17 +1082,71 @@ call_function_by_hand (function, nargs, args)
args[i] = value_arg_coerce (args[i], param_type);
}
#if defined (REG_STRUCT_HAS_ADDR)
{
/* This is a machine like the sparc, where we may need to pass a pointer
to the structure, not the structure itself. */
for (i = nargs - 1; i >= 0; i--)
if ((TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_UNION
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_ARRAY
|| TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRING)
&& REG_STRUCT_HAS_ADDR (using_gcc, VALUE_TYPE (args[i])))
{
CORE_ADDR addr;
int len = TYPE_LENGTH (VALUE_TYPE (args[i]));
#ifdef STACK_ALIGN
int aligned_len = STACK_ALIGN (len);
#else
int aligned_len = len;
#endif
#if !(1 INNER_THAN 2)
/* The stack grows up, so the address of the thing we push
is the stack pointer before we push it. */
addr = sp;
#else
sp -= aligned_len;
#endif
/* Push the structure. */
write_memory (sp, VALUE_CONTENTS (args[i]), len);
#if 1 INNER_THAN 2
/* The stack grows down, so the address of the thing we push
is the stack pointer after we push it. */
addr = sp;
#else
sp += aligned_len;
#endif
/* The value we're going to pass is the address of the thing
we just pushed. */
args[i] = value_from_longest (lookup_pointer_type (value_type),
(LONGEST) addr);
}
}
#endif /* REG_STRUCT_HAS_ADDR. */
/* Reserve space for the return structure to be written on the
stack, if necessary */
if (struct_return)
{
int len = TYPE_LENGTH (value_type);
#ifdef STACK_ALIGN
len = STACK_ALIGN (len);
#endif
#if 1 INNER_THAN 2
sp -= len;
struct_addr = sp;
#else
struct_addr = sp;
sp += len;
#endif
}
#ifdef STACK_ALIGN
/* If stack grows down, we must leave a hole at the top. */
{
int len = 0;
/* Reserve space for the return structure to be written on the
stack, if necessary */
if (struct_return)
len += TYPE_LENGTH (value_type);
for (i = nargs - 1; i >= 0; i--)
len += TYPE_LENGTH (VALUE_TYPE (args[i]));
#ifdef CALL_DUMMY_STACK_ADJUST
@ -1099,49 +1160,6 @@ call_function_by_hand (function, nargs, args)
}
#endif /* STACK_ALIGN */
/* Reserve space for the return structure to be written on the
stack, if necessary */
if (struct_return)
{
#if 1 INNER_THAN 2
sp -= TYPE_LENGTH (value_type);
struct_addr = sp;
#else
struct_addr = sp;
sp += TYPE_LENGTH (value_type);
#endif
}
#if defined (REG_STRUCT_HAS_ADDR)
{
/* This is a machine like the sparc, where we may need to pass a pointer
to the structure, not the structure itself. */
for (i = nargs - 1; i >= 0; i--)
if (TYPE_CODE (VALUE_TYPE (args[i])) == TYPE_CODE_STRUCT
&& REG_STRUCT_HAS_ADDR (using_gcc, VALUE_TYPE (args[i])))
{
CORE_ADDR addr;
#if !(1 INNER_THAN 2)
/* The stack grows up, so the address of the thing we push
is the stack pointer before we push it. */
addr = sp;
#endif
/* Push the structure. */
sp = value_push (sp, args[i]);
#if 1 INNER_THAN 2
/* The stack grows down, so the address of the thing we push
is the stack pointer after we push it. */
addr = sp;
#endif
/* The value we're going to pass is the address of the thing
we just pushed. */
args[i] = value_from_longest (lookup_pointer_type (value_type),
(LONGEST) addr);
}
}
#endif /* REG_STRUCT_HAS_ADDR. */
#ifdef PUSH_ARGUMENTS
PUSH_ARGUMENTS(nargs, args, sp, struct_return, struct_addr);
#else /* !PUSH_ARGUMENTS */