No more global space for structure returns
This commit is contained in:
parent
ebf5153f35
commit
de58173e36
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in a new issue