Commit 45261626 by Eric Botcazou Committed by Eric Botcazou

sparc.c (scan_record_type): Handle vector types.

	* config/sparc/sparc.c (scan_record_type): Handle vector types.
	(function_arg_slotno): Handle vector types specially.
	(function_arg_record_value_1): Split fields with vector type and
	BLKmode into their subparts.
	(function_arg_record_value_2): Likewise.  Be prepared to handle
	more than 2 registers per field.
	(function_arg_union_value): Increment regno inside the loop.
	(function_arg_vector_value): New function.
	(function_arg): Use it to split fields with vector type and
	BLKmode into their subparts and build a PARALLEL.  Treat
	other vector types like floats.
	(function_value): Likewise.
	(sparc_pass_by_reference): Handle vector types.
	(sparc_return_in_memory): Likewise.

From-SVN: r90179
parent 8d43449b
2004-11-06 Eric Botcazou <ebotcazou@libertysurf.fr>
* config/sparc/sparc.c (scan_record_type): Handle vector types.
(function_arg_slotno): Handle vector types specially.
(function_arg_record_value_1): Split fields with vector type and
BLKmode into their subparts.
(function_arg_record_value_2): Likewise. Be prepared to handle
more than 2 registers per field.
(function_arg_union_value): Increment regno inside the loop.
(function_arg_vector_value): New function.
(function_arg): Use it to split fields with vector type and
BLKmode into their subparts and build a PARALLEL. Treat
other vector types like floats.
(function_value): Likewise.
(sparc_pass_by_reference): Handle vector types.
(sparc_return_in_memory): Likewise.
2004-11-06 Kazu Hirata <kazu@cs.umass.edu> 2004-11-06 Kazu Hirata <kazu@cs.umass.edu>
* tree-cfg.c (find_taken_edge_cond_expr): Remove an "if" * tree-cfg.c (find_taken_edge_cond_expr): Remove an "if"
......
...@@ -4928,8 +4928,7 @@ output_sibcall (rtx insn, rtx call_operand) ...@@ -4928,8 +4928,7 @@ output_sibcall (rtx insn, rtx call_operand)
_Complex double 16 memory FP reg. _Complex double 16 memory FP reg.
_Complex long double 32 memory FP reg. _Complex long double 32 memory FP reg.
vector float <=32 memory FP reg. vector float any memory memory
vector float >32 memory memory
aggregate any memory memory aggregate any memory memory
...@@ -4974,8 +4973,8 @@ implemented by the Sun compiler. ...@@ -4974,8 +4973,8 @@ implemented by the Sun compiler.
Note #2: integral vector types follow the scalar floating-point types Note #2: integral vector types follow the scalar floating-point types
conventions to match what is implemented by the Sun VIS SDK. conventions to match what is implemented by the Sun VIS SDK.
Note #3: floating-point vector types follow the complex floating-point Note #3: floating-point vector types follow the aggregate types
types conventions. */ conventions. */
/* Maximum number of int regs for args. */ /* Maximum number of int regs for args. */
...@@ -5037,7 +5036,9 @@ scan_record_type (tree type, int *intregs_p, int *fpregs_p, int *packed_p) ...@@ -5037,7 +5036,9 @@ scan_record_type (tree type, int *intregs_p, int *fpregs_p, int *packed_p)
{ {
if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE) if (TREE_CODE (TREE_TYPE (field)) == RECORD_TYPE)
scan_record_type (TREE_TYPE (field), intregs_p, fpregs_p, 0); scan_record_type (TREE_TYPE (field), intregs_p, fpregs_p, 0);
else if (FLOAT_TYPE_P (TREE_TYPE (field)) && TARGET_FPU) else if ((FLOAT_TYPE_P (TREE_TYPE (field))
|| TREE_CODE (TREE_TYPE (field)) == VECTOR_TYPE)
&& TARGET_FPU)
*fpregs_p = 1; *fpregs_p = 1;
else else
*intregs_p = 1; *intregs_p = 1;
...@@ -5072,6 +5073,7 @@ function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode, ...@@ -5072,6 +5073,7 @@ function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode,
? SPARC_INCOMING_INT_ARG_FIRST ? SPARC_INCOMING_INT_ARG_FIRST
: SPARC_OUTGOING_INT_ARG_FIRST); : SPARC_OUTGOING_INT_ARG_FIRST);
int slotno = cum->words; int slotno = cum->words;
enum mode_class mclass;
int regno; int regno;
*ppadding = 0; *ppadding = 0;
...@@ -5091,12 +5093,37 @@ function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode, ...@@ -5091,12 +5093,37 @@ function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode,
&& (slotno & 1) != 0) && (slotno & 1) != 0)
slotno++, *ppadding = 1; slotno++, *ppadding = 1;
switch (GET_MODE_CLASS (mode)) mclass = GET_MODE_CLASS (mode);
if (type && TREE_CODE (type) == VECTOR_TYPE)
{
/* Vector types deserve special treatment because they are
polymorphic wrt their mode, depending upon whether VIS
instructions are enabled. */
if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
{
/* The SPARC port defines no floating-point vector modes. */
if (mode != BLKmode)
abort ();
}
else
{
/* Integral vector types should either have a vector
mode or an integral mode, because we are guaranteed
by pass_by_reference that their size is not greater
than 16 bytes and TImode is 16-byte wide. */
if (mode == BLKmode)
abort ();
/* Vector integers are handled like floats according to
the Sun VIS SDK. */
mclass = MODE_FLOAT;
}
}
switch (mclass)
{ {
case MODE_FLOAT: case MODE_FLOAT:
case MODE_COMPLEX_FLOAT: case MODE_COMPLEX_FLOAT:
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
if (TARGET_ARCH64 && TARGET_FPU && named) if (TARGET_ARCH64 && TARGET_FPU && named)
{ {
if (slotno >= SPARC_FP_ARG_MAX) if (slotno >= SPARC_FP_ARG_MAX)
...@@ -5132,18 +5159,21 @@ function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode, ...@@ -5132,18 +5159,21 @@ function_arg_slotno (const struct sparc_args *cum, enum machine_mode mode,
&& (slotno & 1) != 0) && (slotno & 1) != 0)
slotno++, *ppadding = 1; slotno++, *ppadding = 1;
if (TARGET_ARCH32 || (type && TREE_CODE (type) == UNION_TYPE)) if (TARGET_ARCH32 || !type || (TREE_CODE (type) == UNION_TYPE))
{ {
if (slotno >= SPARC_INT_ARG_MAX) if (slotno >= SPARC_INT_ARG_MAX)
return -1; return -1;
regno = regbase + slotno; regno = regbase + slotno;
} }
else /* TARGET_ARCH64 && type && TREE_CODE (type) == RECORD_TYPE */ else /* TARGET_ARCH64 && type */
{ {
int intregs_p = 0, fpregs_p = 0, packed_p = 0; int intregs_p = 0, fpregs_p = 0, packed_p = 0;
/* First see what kinds of registers we would need. */ /* First see what kinds of registers we would need. */
scan_record_type (type, &intregs_p, &fpregs_p, &packed_p); if (TREE_CODE (type) == VECTOR_TYPE)
fpregs_p = 1;
else
scan_record_type (type, &intregs_p, &fpregs_p, &packed_p);
/* The ABI obviously doesn't specify how packed structures /* The ABI obviously doesn't specify how packed structures
are passed. These are defined to be passed in int regs are passed. These are defined to be passed in int regs
...@@ -5274,8 +5304,12 @@ function_arg_record_value_1 (tree type, HOST_WIDE_INT startbitpos, ...@@ -5274,8 +5304,12 @@ function_arg_record_value_1 (tree type, HOST_WIDE_INT startbitpos,
/* There's no need to check this_slotno < SPARC_FP_ARG MAX. /* There's no need to check this_slotno < SPARC_FP_ARG MAX.
If it wasn't true we wouldn't be here. */ If it wasn't true we wouldn't be here. */
parms->nregs += 1; if (TREE_CODE (TREE_TYPE (field)) == VECTOR_TYPE
if (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE) && DECL_MODE (field) == BLKmode)
parms->nregs += TYPE_VECTOR_SUBPARTS (TREE_TYPE (field));
else if (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE)
parms->nregs += 2;
else
parms->nregs += 1; parms->nregs += 1;
} }
else else
...@@ -5389,34 +5423,41 @@ function_arg_record_value_2 (tree type, HOST_WIDE_INT startbitpos, ...@@ -5389,34 +5423,41 @@ function_arg_record_value_2 (tree type, HOST_WIDE_INT startbitpos,
&& ! packed_p) && ! packed_p)
{ {
int this_slotno = parms->slotno + bitpos / BITS_PER_WORD; int this_slotno = parms->slotno + bitpos / BITS_PER_WORD;
int regno; int regno, nregs, pos;
enum machine_mode mode = DECL_MODE (field); enum machine_mode mode = DECL_MODE (field);
rtx reg; rtx reg;
function_arg_record_value_3 (bitpos, parms); function_arg_record_value_3 (bitpos, parms);
switch (mode)
{ if (TREE_CODE (TREE_TYPE (field)) == VECTOR_TYPE
case SCmode: mode = SFmode; break; && mode == BLKmode)
case DCmode: mode = DFmode; break; {
case TCmode: mode = TFmode; break; mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (field)));
default: break; nregs = TYPE_VECTOR_SUBPARTS (TREE_TYPE (field));
} }
else if (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE)
{
mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (field)));
nregs = 2;
}
else
nregs = 1;
regno = SPARC_FP_ARG_FIRST + this_slotno * 2; regno = SPARC_FP_ARG_FIRST + this_slotno * 2;
if (GET_MODE_SIZE (mode) <= 4 && (bitpos & 32) != 0) if (GET_MODE_SIZE (mode) <= 4 && (bitpos & 32) != 0)
regno++; regno++;
reg = gen_rtx_REG (mode, regno); reg = gen_rtx_REG (mode, regno);
pos = bitpos / BITS_PER_UNIT;
XVECEXP (parms->ret, 0, parms->stack + parms->nregs) XVECEXP (parms->ret, 0, parms->stack + parms->nregs)
= gen_rtx_EXPR_LIST (VOIDmode, reg, = gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (pos));
GEN_INT (bitpos / BITS_PER_UNIT));
parms->nregs += 1; parms->nregs += 1;
if (TREE_CODE (TREE_TYPE (field)) == COMPLEX_TYPE) while (--nregs > 0)
{ {
regno += GET_MODE_SIZE (mode) / 4; regno += GET_MODE_SIZE (mode) / 4;
reg = gen_rtx_REG (mode, regno); reg = gen_rtx_REG (mode, regno);
pos += GET_MODE_SIZE (mode);
XVECEXP (parms->ret, 0, parms->stack + parms->nregs) XVECEXP (parms->ret, 0, parms->stack + parms->nregs)
= gen_rtx_EXPR_LIST (VOIDmode, reg, = gen_rtx_EXPR_LIST (VOIDmode, reg, GEN_INT (pos));
GEN_INT ((bitpos + GET_MODE_BITSIZE (mode))
/ BITS_PER_UNIT));
parms->nregs += 1; parms->nregs += 1;
} }
} }
...@@ -5547,14 +5588,47 @@ function_arg_union_value (int size, enum machine_mode mode, int regno) ...@@ -5547,14 +5588,47 @@ function_arg_union_value (int size, enum machine_mode mode, int regno)
int nwords = ROUND_ADVANCE (size), i; int nwords = ROUND_ADVANCE (size), i;
rtx regs; rtx regs;
/* Unions are passed left-justified. */
regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords)); regs = gen_rtx_PARALLEL (mode, rtvec_alloc (nwords));
for (i = 0; i < nwords; i++) for (i = 0; i < nwords; i++)
XVECEXP (regs, 0, i) {
= gen_rtx_EXPR_LIST (VOIDmode, /* Unions are passed left-justified. */
gen_rtx_REG (word_mode, regno + i), XVECEXP (regs, 0, i)
GEN_INT (UNITS_PER_WORD * i)); = gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (word_mode, regno),
GEN_INT (UNITS_PER_WORD * i));
regno++;
}
return regs;
}
/* Used by function_arg and function_value to implement the conventions
for passing and returning large (BLKmode) vectors.
Return an expression valid as a return value for the two macros
FUNCTION_ARG and FUNCTION_VALUE.
SIZE is the size in bytes of the vector.
BASE_MODE is the argument's base machine mode.
REGNO is the FP hard register the vector will be passed in. */
static rtx
function_arg_vector_value (int size, enum machine_mode base_mode, int regno)
{
unsigned short base_mode_size = GET_MODE_SIZE (base_mode);
int nregs = size / base_mode_size, i;
rtx regs;
regs = gen_rtx_PARALLEL (BLKmode, rtvec_alloc (nregs));
for (i = 0; i < nregs; i++)
{
XVECEXP (regs, 0, i)
= gen_rtx_EXPR_LIST (VOIDmode,
gen_rtx_REG (base_mode, regno),
GEN_INT (base_mode_size * i));
regno += base_mode_size / 4;
}
return regs; return regs;
} }
...@@ -5582,6 +5656,7 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode, ...@@ -5582,6 +5656,7 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
? SPARC_INCOMING_INT_ARG_FIRST ? SPARC_INCOMING_INT_ARG_FIRST
: SPARC_OUTGOING_INT_ARG_FIRST); : SPARC_OUTGOING_INT_ARG_FIRST);
int slotno, regno, padding; int slotno, regno, padding;
enum mode_class mclass = GET_MODE_CLASS (mode);
rtx reg; rtx reg;
slotno = function_arg_slotno (cum, mode, type, named, incoming_p, slotno = function_arg_slotno (cum, mode, type, named, incoming_p,
...@@ -5615,14 +5690,29 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode, ...@@ -5615,14 +5690,29 @@ function_arg (const struct sparc_args *cum, enum machine_mode mode,
return function_arg_union_value (size, mode, regno); return function_arg_union_value (size, mode, regno);
} }
else if (type && TREE_CODE (type) == VECTOR_TYPE)
{
/* Vector types deserve special treatment because they are
polymorphic wrt their mode, depending upon whether VIS
instructions are enabled. */
HOST_WIDE_INT size = int_size_in_bytes (type);
if (size > 16)
abort (); /* shouldn't get here */
if (mode == BLKmode)
return function_arg_vector_value (size,
TYPE_MODE (TREE_TYPE (type)),
SPARC_FP_ARG_FIRST + 2*slotno);
else
mclass = MODE_FLOAT;
}
/* v9 fp args in reg slots beyond the int reg slots get passed in regs /* v9 fp args in reg slots beyond the int reg slots get passed in regs
but also have the slot allocated for them. but also have the slot allocated for them.
If no prototype is in scope fp values in register slots get passed If no prototype is in scope fp values in register slots get passed
in two places, either fp regs and int regs or fp regs and memory. */ in two places, either fp regs and int regs or fp regs and memory. */
else if ((GET_MODE_CLASS (mode) == MODE_FLOAT if ((mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT)
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| GET_MODE_CLASS (mode) == MODE_VECTOR_INT
|| GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
&& SPARC_FP_REG_P (regno)) && SPARC_FP_REG_P (regno))
{ {
reg = gen_rtx_REG (mode, regno); reg = gen_rtx_REG (mode, regno);
...@@ -5760,11 +5850,8 @@ function_arg_partial_nregs (const struct sparc_args *cum, ...@@ -5760,11 +5850,8 @@ function_arg_partial_nregs (const struct sparc_args *cum,
return 0; return 0;
} }
/* Return true if the argument should be passed by reference. /* Handle the TARGET_PASS_BY_REFERENCE target hook.
!v9: The SPARC ABI stipulates passing struct arguments (of any size) and Specify whether to pass the argument by reference. */
quad-precision floats by invisible reference.
v9: Aggregates greater than 16 bytes are passed by reference.
For Pascal, also pass arrays by reference. */
static bool static bool
sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
...@@ -5773,23 +5860,48 @@ sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED, ...@@ -5773,23 +5860,48 @@ sparc_pass_by_reference (CUMULATIVE_ARGS *cum ATTRIBUTE_UNUSED,
{ {
if (TARGET_ARCH32) if (TARGET_ARCH32)
{ {
return ((type && AGGREGATE_TYPE_P (type)) /* Original SPARC 32-bit ABI says that structures and unions,
/* Extended ABI (as implemented by the Sun compiler) says and quad-precision floats are passed by reference. For Pascal,
that all complex floats are passed in memory. */ also pass arrays by reference. All other base types are passed
in registers.
Extended ABI (as implemented by the Sun compiler) says that all
complex floats are passed by reference. Pass complex integers
in registers up to 8 bytes. More generally, enforce the 2-word
cap for passing arguments in registers.
Vector ABI (as implemented by the Sun VIS SDK) says that vector
integers are passed like floats of the same size, that is in
registers up to 8 bytes. Pass all vector floats by reference
like structure and unions. */
return ((type && (AGGREGATE_TYPE_P (type) || VECTOR_FLOAT_TYPE_P (type)))
|| mode == SCmode || mode == SCmode
/* Enforce the 2-word cap for passing arguments in registers. /* Catch CDImode, TFmode, DCmode and TCmode. */
This affects CDImode, TFmode, DCmode, TCmode and large || GET_MODE_SIZE (mode) > 8
vector modes. */ || (type
|| GET_MODE_SIZE (mode) > 8); && TREE_CODE (type) == VECTOR_TYPE
&& (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8));
} }
else else
{ {
/* Original SPARC 64-bit ABI says that structures and unions
smaller than 16 bytes are passed in registers, as well as
all other base types. For Pascal, pass arrays by reference.
Extended ABI (as implemented by the Sun compiler) says that
complex floats are passed in registers up to 16 bytes. Pass
all complex integers in registers up to 16 bytes. More generally,
enforce the 2-word cap for passing arguments in registers.
Vector ABI (as implemented by the Sun VIS SDK) says that vector
integers are passed like floats of the same size, that is in
registers (up to 16 bytes). Pass all vector floats like structure
and unions. */
return ((type && TREE_CODE (type) == ARRAY_TYPE) return ((type && TREE_CODE (type) == ARRAY_TYPE)
|| (type || (type
&& AGGREGATE_TYPE_P (type) && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == VECTOR_TYPE)
&& (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 16) && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 16)
/* Enforce the 2-word cap for passing arguments in registers. /* Catch CTImode and TCmode. */
This affects CTImode, TCmode and large vector modes. */
|| GET_MODE_SIZE (mode) > 16); || GET_MODE_SIZE (mode) > 16);
} }
} }
...@@ -5861,30 +5973,40 @@ static bool ...@@ -5861,30 +5973,40 @@ static bool
sparc_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED) sparc_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
{ {
if (TARGET_ARCH32) if (TARGET_ARCH32)
/* Original SPARC 32-bit ABI says that quad-precision floats /* Original SPARC 32-bit ABI says that structures and unions,
and all structures are returned in memory. Extended ABI and quad-precision floats are returned in memory. All other
(as implemented by the Sun compiler) says that all complex base types are returned in registers.
floats are returned in registers (8 FP registers at most
for '_Complex long double'). Return all complex integers Extended ABI (as implemented by the Sun compiler) says that
in registers (4 at most for '_Complex long long'). */ all complex floats are returned in registers (8 FP registers
at most for '_Complex long double'). Return all complex integers
in registers (4 at most for '_Complex long long').
Vector ABI (as implemented by the Sun VIS SDK) says that vector
integers are returned like floats of the same size, that is in
registers up to 8 bytes and in memory otherwise. Return all
vector floats in memory like structure and unions; note that
they always have BLKmode like the latter. */
return (TYPE_MODE (type) == BLKmode return (TYPE_MODE (type) == BLKmode
|| TYPE_MODE (type) == TFmode || TYPE_MODE (type) == TFmode
/* Integral vector types follow the scalar FP types conventions. */ || (TREE_CODE (type) == VECTOR_TYPE
|| (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_INT && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 8));
&& GET_MODE_SIZE (TYPE_MODE (type)) > 8)
/* FP vector types follow the complex FP types conventions. */
|| (GET_MODE_CLASS (TYPE_MODE (type)) == MODE_VECTOR_FLOAT
&& GET_MODE_SIZE (TYPE_MODE (type)) > 32));
else else
/* Original SPARC 64-bit ABI says that structures and unions /* Original SPARC 64-bit ABI says that structures and unions
smaller than 32 bytes are returned in registers. Extended smaller than 32 bytes are returned in registers, as well as
ABI (as implemented by the Sun compiler) says that all complex all other base types.
floats are returned in registers (8 FP registers at most
for '_Complex long double'). Return all complex integers Extended ABI (as implemented by the Sun compiler) says that all
in registers (4 at most for '_Complex TItype'). */ complex floats are returned in registers (8 FP registers at most
for '_Complex long double'). Return all complex integers in
registers (4 at most for '_Complex TItype').
Vector ABI (as implemented by the Sun VIS SDK) says that vector
integers are returned like floats of the same size, that is in
registers. Return all vector floats like structure and unions;
note that they always have BLKmode like the latter. */
return ((TYPE_MODE (type) == BLKmode return ((TYPE_MODE (type) == BLKmode
&& (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 32) && (unsigned HOST_WIDE_INT) int_size_in_bytes (type) > 32));
|| GET_MODE_SIZE (TYPE_MODE (type)) > 32);
} }
/* Handle the TARGET_STRUCT_VALUE target hook. /* Handle the TARGET_STRUCT_VALUE target hook.
...@@ -5917,9 +6039,27 @@ function_value (tree type, enum machine_mode mode, int incoming_p) ...@@ -5917,9 +6039,27 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
int regbase = (incoming_p int regbase = (incoming_p
? SPARC_OUTGOING_INT_ARG_FIRST ? SPARC_OUTGOING_INT_ARG_FIRST
: SPARC_INCOMING_INT_ARG_FIRST); : SPARC_INCOMING_INT_ARG_FIRST);
enum mode_class mclass = GET_MODE_CLASS (mode);
int regno; int regno;
if (TARGET_ARCH64 && type) if (type && TREE_CODE (type) == VECTOR_TYPE)
{
/* Vector types deserve special treatment because they are
polymorphic wrt their mode, depending upon whether VIS
instructions are enabled. */
HOST_WIDE_INT size = int_size_in_bytes (type);
if ((TARGET_ARCH32 && size > 8) || (TARGET_ARCH64 && size > 32))
abort (); /* shouldn't get here */
if (mode == BLKmode)
return function_arg_vector_value (size,
TYPE_MODE (TREE_TYPE (type)),
SPARC_FP_ARG_FIRST);
else
mclass = MODE_FLOAT;
}
else if (type && TARGET_ARCH64)
{ {
if (TREE_CODE (type) == RECORD_TYPE) if (TREE_CODE (type) == RECORD_TYPE)
{ {
...@@ -5962,13 +6102,16 @@ function_value (tree type, enum machine_mode mode, int incoming_p) ...@@ -5962,13 +6102,16 @@ function_value (tree type, enum machine_mode mode, int incoming_p)
for unions in that case. */ for unions in that case. */
if (mode == BLKmode) if (mode == BLKmode)
return function_arg_union_value (bytes, mode, regbase); return function_arg_union_value (bytes, mode, regbase);
else
mclass = MODE_INT;
} }
else if (GET_MODE_CLASS (mode) == MODE_INT else if (mclass == MODE_INT
&& GET_MODE_SIZE (mode) < UNITS_PER_WORD) && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
mode = word_mode; mode = word_mode;
} }
if (TARGET_FPU && (FLOAT_MODE_P (mode) || VECTOR_MODE_P (mode))) if ((mclass == MODE_FLOAT || mclass == MODE_COMPLEX_FLOAT)
&& TARGET_FPU)
regno = SPARC_FP_ARG_FIRST; regno = SPARC_FP_ARG_FIRST;
else else
regno = regbase; regno = regbase;
......
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