Commit 320aba9c by Jim Wilson

(function_arg): Add explicit checks for FIELD_DECLs.

(mips_function_value): Add explicit checks for FIELD_DECLs, and save
them in the array FIELDS.  When returning structure with 1 float field,
enclose it in a PARALLEL and set the PARALLEL mode correctly.

From-SVN: r12412
parent f7a61b83
...@@ -3070,7 +3070,8 @@ function_arg (cum, mode, type, named) ...@@ -3070,7 +3070,8 @@ function_arg (cum, mode, type, named)
/* First check to see if there is any such field. */ /* First check to see if there is any such field. */
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
if (TREE_CODE (TREE_TYPE (field)) == REAL_TYPE if (TREE_CODE (field) == FIELD_DECL
&& TREE_CODE (TREE_TYPE (field)) == REAL_TYPE
&& TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD && TYPE_PRECISION (TREE_TYPE (field)) == BITS_PER_WORD
&& (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) && (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
% BITS_PER_WORD == 0)) % BITS_PER_WORD == 0))
...@@ -3111,7 +3112,9 @@ function_arg (cum, mode, type, named) ...@@ -3111,7 +3112,9 @@ function_arg (cum, mode, type, named)
rtx reg; rtx reg;
for (; field; field = TREE_CHAIN (field)) for (; field; field = TREE_CHAIN (field))
if (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)) >= bitpos) if (TREE_CODE (field) == FIELD_DECL
&& (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field))
>= bitpos))
break; break;
if (field if (field
...@@ -5733,15 +5736,18 @@ mips_function_value (valtype, func) ...@@ -5733,15 +5736,18 @@ mips_function_value (valtype, func)
{ {
/* A struct with only one or two floating point fields is returned in /* A struct with only one or two floating point fields is returned in
the floating point registers. */ the floating point registers. */
tree field; tree field, fields[2];
int i; int i;
for (i = 0, field = TYPE_FIELDS (valtype); field; for (i = 0, field = TYPE_FIELDS (valtype); field;
field = TREE_CHAIN (field), i++) field = TREE_CHAIN (field))
{ {
/* ??? For C++, must ignore everything that isn't a FIELD_DECL. */ if (TREE_CODE (field) != FIELD_DECL)
continue;
if (TREE_CODE (TREE_TYPE (field)) != REAL_TYPE || i >= 2) if (TREE_CODE (TREE_TYPE (field)) != REAL_TYPE || i >= 2)
break; break;
fields[i++] = field;
} }
/* Must check i, so that we reject structures with no elements. */ /* Must check i, so that we reject structures with no elements. */
...@@ -5749,19 +5755,27 @@ mips_function_value (valtype, func) ...@@ -5749,19 +5755,27 @@ mips_function_value (valtype, func)
{ {
if (i == 1) if (i == 1)
{ {
mode = TYPE_MODE (TYPE_FIELDS (valtype)); /* The structure has DImode, but we don't allow DImode values
reg = FP_RETURN; in FP registers, so we use a PARALLEL even though it isn't
strictly necessary. */
enum machine_mode field_mode = TYPE_MODE (TREE_TYPE (fields[0]));
return gen_rtx (PARALLEL, mode,
gen_rtvec (1,
gen_rtx (EXPR_LIST, VOIDmode,
gen_rtx (REG, field_mode, FP_RETURN),
const0_rtx)));
} }
else if (i == 2) else if (i == 2)
{ {
enum machine_mode first_mode enum machine_mode first_mode
= TYPE_MODE (TREE_TYPE (TYPE_FIELDS (valtype))); = TYPE_MODE (TREE_TYPE (fields[0]));
enum machine_mode second_mode enum machine_mode second_mode
= TYPE_MODE (TREE_TYPE (TREE_CHAIN (TYPE_FIELDS (valtype)))); = TYPE_MODE (TREE_TYPE (fields[1]));
int first_offset int first_offset
= TREE_INT_CST_LOW (DECL_FIELD_BITPOS (TYPE_FIELDS (valtype))); = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (fields[0]));
int second_offset int second_offset
= TREE_INT_CST_LOW (DECL_FIELD_BITPOS (TREE_CHAIN (TYPE_FIELDS (valtype)))); = TREE_INT_CST_LOW (DECL_FIELD_BITPOS (fields[1]));
return gen_rtx (PARALLEL, mode, return gen_rtx (PARALLEL, mode,
gen_rtvec (2, gen_rtvec (2,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment