No more global space for structure returns

This commit is contained in:
ceriel 1993-01-28 10:09:51 +00:00
parent ebf5153f35
commit de58173e36
3 changed files with 26 additions and 17 deletions

View file

@ -46,6 +46,7 @@
label lab_count = 1; label lab_count = 1;
label datlab_count = 1; label datlab_count = 1;
arith fbytes;
int fp_used; int fp_used;
extern arith NewLocal(); /* util.c */ extern arith NewLocal(); /* util.c */
@ -212,7 +213,7 @@ code_scope(text, def)
static label return_label, return2_label; static label return_label, return2_label;
static char return_expr_occurred; static char return_expr_occurred;
static arith func_size; static arith func_size;
static label func_res_label; static int struct_return;
static char *last_fn_given = (char *)0; static char *last_fn_given = (char *)0;
static label file_name_label; static label file_name_label;
@ -281,12 +282,11 @@ begin_proc(ds, idf) /* to be called when entering a procedure */
if (func_size <= 0) { if (func_size <= 0) {
error("unknown return type for function %s", name); error("unknown return type for function %s", name);
} else { } else {
C_df_dlb(func_res_label = data_label()); struct_return = 1;
C_bss_cst(func_size, (arith)0, 1);
} }
} }
else else
func_res_label = 0; struct_return = 0;
/* Special arrangements if the function result doesn't fit in /* 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 of the EM machine. The size of
the function return area is implementation dependent. the function return area is implementation dependent.
@ -318,8 +318,7 @@ begin_proc(ds, idf) /* to be called when entering a procedure */
#endif #endif
} }
end_proc(fbytes) end_proc()
arith fbytes;
{ {
/* end_proc() deals with the code to be generated at the end of /* end_proc() deals with the code to be generated at the end of
a function, as there is: a function, as there is:
@ -341,14 +340,14 @@ end_proc(fbytes)
DfaEndFunction(); DfaEndFunction();
#endif /* DATAFLOW */ #endif /* DATAFLOW */
C_df_ilb(return2_label); 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_asp(-func_size);
} }
C_df_ilb(return_label); C_df_ilb(return_label);
prc_exit(); prc_exit();
if (return_expr_occurred) { if (return_expr_occurred) {
if (func_res_label != 0) { if (struct_return != 0) {
C_lae_dlb(func_res_label, (arith)0); LoadLocal(fbytes, pointer_size);
C_ret(pointer_size); C_ret(pointer_size);
} }
else else
@ -357,8 +356,8 @@ end_proc(fbytes)
else C_ret((arith) 0); else C_ret((arith) 0);
/* getting the number of "local" bytes is posponed until here, /* getting the number of "local" bytes is posponed until here,
because copying the function result in "func_res_label" may because copying the function result may need temporaries!
need temporaries! However, local_level is now L_FORMAL2, because However, local_level is now L_FORMAL2, because
L_LOCAL is already unstacked. Therefore, "unstack_level" must L_LOCAL is already unstacked. Therefore, "unstack_level" must
also pass "sl_max_block" to the level above L_LOCAL. also pass "sl_max_block" to the level above L_LOCAL.
*/ */
@ -367,6 +366,7 @@ end_proc(fbytes)
C_beginpart(pro_id); C_beginpart(pro_id);
C_pro(func_name, nbytes); C_pro(func_name, nbytes);
#endif #endif
if (struct_return) fbytes += pointer_size;
if (fbytes > max_int) { if (fbytes > max_int) {
error("%s has more than %ld parameter bytes", error("%s has more than %ld parameter bytes",
func_name, (long) max_int); func_name, (long) max_int);
@ -410,8 +410,8 @@ do_return_expr(expr)
*/ */
ch3cast(&expr, RETURN, func_type); ch3cast(&expr, RETURN, func_type);
code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL); code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
if (func_res_label != 0) { if (struct_return != 0) {
C_lae_dlb(func_res_label, (arith)0); LoadLocal(fbytes, pointer_size);
store_block(func_size, func_type->tp_align); store_block(func_size, func_type->tp_align);
} }
C_bra(return_label); C_bra(return_label);

View file

@ -475,6 +475,7 @@ EVAL(expr, val, code, true_label, false_label)
register struct expr *ex; register struct expr *ex;
arith ParSize = (arith)0; arith ParSize = (arith)0;
label setjmp_label = 0; label setjmp_label = 0;
arith retspace = 0;
if (ISNAME(left)) { if (ISNAME(left)) {
if (left->VL_IDF->id_special == SP_SETJMP) { if (left->VL_IDF->id_special == SP_SETJMP) {
@ -488,6 +489,12 @@ EVAL(expr, val, code, true_label, false_label)
ParSize += pointer_size; 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) { if ((ex = right) != NILEXPR) {
/* function call with parameters*/ /* function call with parameters*/
while ( ex->ex_class == Oper && while ( ex->ex_class == Oper &&
@ -525,8 +532,10 @@ EVAL(expr, val, code, true_label, false_label)
if (gencode) { if (gencode) {
if (is_struct_or_union(tp->tp_fund)) { if (is_struct_or_union(tp->tp_fund)) {
C_lfr(pointer_size); C_lfr(pointer_size);
if (val == RVAL) if (val == RVAL) {
load_block(tp->tp_size, (int) word_size); load_block(tp->tp_size, (int) word_size);
FreeLocal(retspace);
}
} }
else else
C_lfr(ATW(tp->tp_size)); C_lfr(ATW(tp->tp_size));
@ -551,7 +560,7 @@ EVAL(expr, val, code, true_label, false_label)
break; break;
case ',': case ',':
EVAL(left, RVAL, FALSE, NO_LABEL, NO_LABEL); 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; break;
case '~': case '~':
EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL); EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);

View file

@ -67,6 +67,7 @@
extern arith ifval; extern arith ifval;
#endif /* NOPP */ #endif /* NOPP */
extern arith fbytes;
extern error(); extern error();
} }
@ -197,7 +198,6 @@ non_function(register struct decspecs *ds; register struct declarator *dc;)
/* 3.7.1 */ /* 3.7.1 */
function(struct decspecs *ds; struct declarator *dc;) function(struct decspecs *ds; struct declarator *dc;)
{ {
arith fbytes;
register struct idf *idf = dc->dc_idf; register struct idf *idf = dc->dc_idf;
} }
: :
@ -222,7 +222,7 @@ function(struct decspecs *ds; struct declarator *dc;)
} }
compound_statement compound_statement
{ {
end_proc(fbytes); end_proc();
#ifdef LINT #ifdef LINT
lint_implicit_return(); lint_implicit_return();
#endif /* LINT */ #endif /* LINT */