label lab_count = 1;
label datlab_count = 1;
+arith fbytes;
int fp_used;
extern arith NewLocal(); /* util.c */
static label return_label, return2_label;
static char return_expr_occurred;
static arith func_size;
-static label func_res_label;
+static int struct_return;
static char *last_fn_given = (char *)0;
static label file_name_label;
if (func_size <= 0) {
error("unknown return type for function %s", name);
} else {
- C_df_dlb(func_res_label = data_label());
- C_bss_cst(func_size, (arith)0, 1);
+ struct_return = 1;
}
}
else
- func_res_label = 0;
+ struct_return = 0;
/* Special arrangements if the function result doesn't fit in
the function return area of the EM machine. The size of
the function return area is implementation dependent.
#endif
}
-end_proc(fbytes)
- arith fbytes;
+end_proc()
{
/* end_proc() deals with the code to be generated at the end of
a function, as there is:
DfaEndFunction();
#endif /* DATAFLOW */
C_df_ilb(return2_label);
- if (return_expr_occurred && func_res_label == 0) {
+ if (return_expr_occurred && struct_return == 0) {
C_asp(-func_size);
}
C_df_ilb(return_label);
prc_exit();
if (return_expr_occurred) {
- if (func_res_label != 0) {
- C_lae_dlb(func_res_label, (arith)0);
+ if (struct_return != 0) {
+ LoadLocal(fbytes, pointer_size);
C_ret(pointer_size);
}
else
else C_ret((arith) 0);
/* getting the number of "local" bytes is posponed until here,
- because copying the function result in "func_res_label" may
- need temporaries! However, local_level is now L_FORMAL2, because
+ because copying the function result may need temporaries!
+ However, local_level is now L_FORMAL2, because
L_LOCAL is already unstacked. Therefore, "unstack_level" must
also pass "sl_max_block" to the level above L_LOCAL.
*/
C_beginpart(pro_id);
C_pro(func_name, nbytes);
#endif
+ if (struct_return) fbytes += pointer_size;
if (fbytes > max_int) {
error("%s has more than %ld parameter bytes",
func_name, (long) max_int);
*/
ch3cast(&expr, RETURN, func_type);
code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
- if (func_res_label != 0) {
- C_lae_dlb(func_res_label, (arith)0);
+ if (struct_return != 0) {
+ LoadLocal(fbytes, pointer_size);
store_block(func_size, func_type->tp_align);
}
C_bra(return_label);
register struct expr *ex;
arith ParSize = (arith)0;
label setjmp_label = 0;
+ arith retspace = 0;
if (ISNAME(left)) {
if (left->VL_IDF->id_special == SP_SETJMP) {
ParSize += pointer_size;
}
}
+ if (is_struct_or_union(tp->tp_fund)) {
+ retspace = NewLocal(tp->tp_size, tp->tp_align,
+ -1, 0);
+ C_lal(retspace);
+ ParSize += pointer_size;
+ }
if ((ex = right) != NILEXPR) {
/* function call with parameters*/
while ( ex->ex_class == Oper &&
if (gencode) {
if (is_struct_or_union(tp->tp_fund)) {
C_lfr(pointer_size);
- if (val == RVAL)
+ if (val == RVAL) {
load_block(tp->tp_size, (int) word_size);
+ FreeLocal(retspace);
+ }
}
else
C_lfr(ATW(tp->tp_size));
break;
case ',':
EVAL(left, RVAL, FALSE, NO_LABEL, NO_LABEL);
- EVAL(right, RVAL, gencode, true_label, false_label);
+ EVAL(right, val, gencode, true_label, false_label);
break;
case '~':
EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);