From 0619d27b8d738d175306b11b2a37f127e228887e Mon Sep 17 00:00:00 2001 From: ceriel Date: Thu, 16 Jul 1987 13:27:37 +0000 Subject: [PATCH] use new C_insertpart mechanism, other minor changes --- lang/cem/cemcom/BigPars | 2 +- lang/cem/cemcom/Makefile | 19 +++- lang/cem/cemcom/Parameters | 2 +- lang/cem/cemcom/blocks.c | 48 ++++---- lang/cem/cemcom/ch7mon.c | 1 - lang/cem/cemcom/code.c | 166 +++++++++++++++------------- lang/cem/cemcom/def.str | 4 +- lang/cem/cemcom/dumpidf.c | 1 - lang/cem/cemcom/error.c | 9 +- lang/cem/cemcom/eval.c | 71 +++--------- lang/cem/cemcom/field.c | 31 +++--- lang/cem/cemcom/idf.c | 41 +++++-- lang/cem/cemcom/main.c | 60 +--------- lang/cem/cemcom/options.c | 19 +--- lang/cem/cemcom/program.g | 4 +- lang/cem/cemcom/stack.c | 40 +------ lang/cem/cemcom/statement.g | 6 +- lang/cem/cemcom/util.c | 211 ++++++++++++++++++++++++++++++++++++ lang/cem/cemcom/util.str | 10 ++ 19 files changed, 428 insertions(+), 317 deletions(-) create mode 100644 lang/cem/cemcom/util.c create mode 100644 lang/cem/cemcom/util.str diff --git a/lang/cem/cemcom/BigPars b/lang/cem/cemcom/BigPars index 6df5e2d82..1671e564d 100644 --- a/lang/cem/cemcom/BigPars +++ b/lang/cem/cemcom/BigPars @@ -97,7 +97,7 @@ !File: inputtype.h -#undef INP_READ_IN_ONE 1 /* read input file in one */ +#define INP_READ_IN_ONE 1 /* read input file in one */ !File: nopp.h diff --git a/lang/cem/cemcom/Makefile b/lang/cem/cemcom/Makefile index fd23d7791..bc358ff46 100644 --- a/lang/cem/cemcom/Makefile +++ b/lang/cem/cemcom/Makefile @@ -58,7 +58,7 @@ CSRC = main.c idf.c declarator.c decspecs.c struct.c \ tokenname.c LLlex.c LLmessage.c \ input.c domacro.c replace.c init.c options.c \ scan.c skip.c stack.c type.c ch7mon.c label.c eval.c \ - switch.c conversion.c \ + switch.c conversion.c util.c \ blocks.c dataflow.c Version.c COBJ = main.o idf.o declarator.o decspecs.o struct.o \ expr.o ch7.o ch7bin.o cstoper.o arith.o \ @@ -66,7 +66,7 @@ COBJ = main.o idf.o declarator.o decspecs.o struct.o \ tokenname.o LLlex.o LLmessage.o \ input.o domacro.o replace.o init.o options.o \ scan.o skip.o stack.o type.o ch7mon.o label.o eval.o \ - switch.o conversion.o \ + switch.o conversion.o util.o \ blocks.o dataflow.o Version.o # Objects of other generated C files @@ -74,11 +74,11 @@ GCSRC = char.c symbol2str.c next.c GOBJ = char.o symbol2str.o next.o STRSRC = code.str declar.str decspecs.str def.str expr.str field.str \ - estack.str \ + estack.str util.str \ idf.str macro.str stack.str stmt.str struct.str switch.str type.str # generated source files GHSTRSRC = code.h declar.h decspecs.h def.h expr.h field.h \ - estack.h \ + estack.h util.h \ idf.h macro.h stack.h stmt.h struct.h switch.h type.h GSRC = $(GCSRC) $(GHSTRSRC) @@ -185,6 +185,7 @@ struct.h: make.allocd switch.h: make.allocd type.h: make.allocd estack.h: make.allocd +util.h: make.allocd depend: Cfiles sed '/^#AUTOAUTO/,$$d' makefile >makefile.new @@ -441,7 +442,6 @@ error.o: nofloat.h error.o: nopp.h error.o: spec_arith.h error.o: tokenname.h -error.o: use_tmp.h field.o: Lpars.h field.o: arith.h field.o: assert.h @@ -677,6 +677,15 @@ conversion.o: sizes.h conversion.o: spec_arith.h conversion.o: target_sizes.h conversion.o: type.h +util.o: align.h +util.o: atw.h +util.o: nocross.h +util.o: nofloat.h +util.o: sizes.h +util.o: stack.h +util.o: target_sizes.h +util.o: use_tmp.h +util.o: util.h blocks.o: align.h blocks.o: arith.h blocks.o: atw.h diff --git a/lang/cem/cemcom/Parameters b/lang/cem/cemcom/Parameters index 6df5e2d82..1671e564d 100644 --- a/lang/cem/cemcom/Parameters +++ b/lang/cem/cemcom/Parameters @@ -97,7 +97,7 @@ !File: inputtype.h -#undef INP_READ_IN_ONE 1 /* read input file in one */ +#define INP_READ_IN_ONE 1 /* read input file in one */ !File: nopp.h diff --git a/lang/cem/cemcom/blocks.c b/lang/cem/cemcom/blocks.c index 255ade376..d7fc24493 100644 --- a/lang/cem/cemcom/blocks.c +++ b/lang/cem/cemcom/blocks.c @@ -6,6 +6,7 @@ /* B L O C K S T O R I N G A N D L O A D I N G */ #include +#include #include "arith.h" #include "sizes.h" #include "atw.h" @@ -13,7 +14,8 @@ #ifndef STB #include "label.h" #include "stack.h" -extern arith tmp_pointer_var(); +extern arith NewLocal(); +#define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, 0) #endif STB /* Because EM does not support the loading and storing of @@ -58,22 +60,20 @@ store_block(sz, al) C_sti(sz); else { #ifndef STB - arith src, dst, src_offs, dst_offs; + arith src, dst; /* allocate two pointer temporaries */ - src = tmp_pointer_var(&src_offs); - dst = tmp_pointer_var(&dst_offs); + src = LocalPtrVar(); + dst = LocalPtrVar(); /* load the addresses */ - C_lal(dst); - C_sti(pointer_size); + StoreLocal(dst, pointer_size); C_lor((arith)1); /* push current sp */ - C_lal(src); - C_sti(pointer_size); + StoreLocal(src, pointer_size); copy_loop(sz, src, dst); C_asp(ATW(sz)); - free_tmp_var(dst_offs); - free_tmp_var(src_offs); + FreeLocal(dst); + FreeLocal(src); #else STB /* address of destination lies on the stack */ @@ -103,21 +103,19 @@ load_block(sz, al) C_loi(esz); else { #ifndef STB - arith src, dst, src_offs, dst_offs; + arith src, dst; /* allocate two pointer temporaries */ - src = tmp_pointer_var(&src_offs); - dst = tmp_pointer_var(&dst_offs); + src = LocalPtrVar(); + dst = LocalPtrVar(); - C_lal(src); - C_sti(pointer_size); + StoreLocal(src, pointer_size); C_asp(-esz); /* allocate stack block */ C_lor((arith)1); /* push & of stack block as dst */ - C_lal(dst); - C_sti(pointer_size); + StoreLocal(dst, pointer_size); copy_loop(sz, src, dst); - free_tmp_var(dst_offs); - free_tmp_var(src_offs); + FreeLocal(dst); + FreeLocal(src); #else STB C_asp(-(esz - pointer_size)); /* allocate stack block */ C_lor((arith)1); /* push & of stack block as dst */ @@ -143,19 +141,15 @@ copy_loop(sz, src, dst) C_dup(word_size); C_zle(l_stop); C_dec(); - C_lal(src); - C_loi(pointer_size); + LoadLocal(src, pointer_size); C_dup(pointer_size); C_adp((arith)1); - C_lal(src); - C_sti(pointer_size); + StoreLocal(src, pointer_size); C_loi((arith)1); - C_lal(dst); - C_loi(pointer_size); + LoadLocal(dst, pointer_size); C_dup(pointer_size); C_adp((arith)1); - C_lal(dst); - C_sti(pointer_size); + StoreLocal(dst, pointer_size); C_sti((arith)1); C_bra(l_cont); C_df_ilb(l_stop); diff --git a/lang/cem/cemcom/ch7mon.c b/lang/cem/cemcom/ch7mon.c index 3ed80fe47..102f72561 100644 --- a/lang/cem/cemcom/ch7mon.c +++ b/lang/cem/cemcom/ch7mon.c @@ -86,7 +86,6 @@ ch7mon(oper, expp) "& on register variable not allowed"); break; /* break case '&' */ } - def->df_register = REG_NONE; } (*expp)->ex_type = pointer_to((*expp)->ex_type); (*expp)->ex_lvalue = 0; diff --git a/lang/cem/cemcom/code.c b/lang/cem/cemcom/code.c index 30825dc6e..dc2ffd3b9 100644 --- a/lang/cem/cemcom/code.c +++ b/lang/cem/cemcom/code.c @@ -40,6 +40,12 @@ label datlab_count = 1; int fp_used; #endif NOFLOAT +#ifdef USE_TMP +static int tmp_id; +static int pro_id; +static char *pro_name; +#endif USE_TMP + extern char options[]; char *symbol2str(); @@ -52,16 +58,11 @@ init_code(dst_file) C_init(word_size, pointer_size); /* initialise EM module */ if (C_open(dst_file) == 0) fatal("cannot write to %s\n", dst_file); -#ifdef USE_TMP - if (options['N']) -#endif USE_TMP - famous_first_words(); -} - -famous_first_words() -{ C_magic(); C_ms_emx(word_size, pointer_size); +#ifdef USE_TMP + C_insertpart(tmp_id = C_getid()); +#endif USE_TMP } static struct string_cst *str_list = 0; @@ -84,11 +85,13 @@ code_string(val, len, dlb) def_strings(sc) register struct string_cst *sc; { - if (sc) { - def_strings(sc->next); + while (sc) { + struct string_cst *sc1 = sc; + C_df_dlb(sc->sc_dlb); str_cst(sc->sc_value, sc->sc_len); - free_string_cst(sc); + sc = sc->next; + free_string_cst(sc1); } } @@ -97,6 +100,12 @@ end_code() /* end_code() performs the actions to be taken when closing the output stream. */ +#ifndef NOFLOAT + if (fp_used) { + /* floating point used */ + C_ms_flt(); + } +#endif NOFLOAT def_strings(str_list); str_list = 0; C_ms_src((int)(LineNumber - 2), FileName); @@ -104,18 +113,15 @@ end_code() } #ifdef USE_TMP -prepend_scopes(dst_file) - char *dst_file; +prepend_scopes() { /* prepend_scopes() runs down the list of global idf's and generates those exa's, exp's, ina's and inp's - that superior hindsight has provided, on the file dst_file. + that superior hindsight has provided. */ register struct stack_entry *se = local_level->sl_entry; - if (C_open(dst_file) == 0) - fatal("cannot create %s", dst_file ? dst_file : "stdout"); - famous_first_words(); + C_beginpart(tmp_id); while (se != 0) { register struct idf *id = se->se_idf; register struct def *df = id->id_def; @@ -124,7 +130,7 @@ prepend_scopes(dst_file) code_scope(id->id_text, df); se = se->next; } - C_close(); + C_endpart(tmp_id); } #endif USE_TMP @@ -156,8 +162,9 @@ code_scope(text, def) } static label return_label; -static char return_expr_occurred; +/* static char return_expr_occurred; */ static struct type *func_tp; +static arith func_size; static label func_res_label; static char *last_fn_given = ""; static label file_name_label; @@ -174,12 +181,9 @@ begin_proc(name, def) /* to be called when entering a procedure */ does not fit in the return area - a fil pseudo instruction */ - arith size; register struct type *tp = def->df_type; -#ifdef USE_TMP - if (options['N']) code_scope(name,def); -#else USE_TMP +#ifndef USE_TMP code_scope(name, def); #endif USE_TMP #ifdef DATAFLOW @@ -194,11 +198,16 @@ begin_proc(name, def) /* to be called when entering a procedure */ else tp = tp->tp_up; func_tp = tp; - size = ATW(tp->tp_size); + func_size = ATW(tp->tp_size); +#ifndef USE_TMP C_pro_narg(name); +#else + pro_name = name; + C_insertpart(pro_id = C_getid()); +#endif if (is_struct_or_union(tp->tp_fund)) { C_df_dlb(func_res_label = data_label()); - C_bss_cst(size, (arith)0, 1); + C_bss_cst(func_size, (arith)0, 1); } else func_res_label = 0; @@ -208,7 +217,8 @@ begin_proc(name, def) /* to be called when entering a procedure */ */ lab_count = (label) 1; return_label = text_label(); - return_expr_occurred = 0; + /* return_expr_occurred = 0; */ + LocalInit(); prc_entry(name); if (! options['L']) { /* profiling */ if (strcmp(last_fn_given, FileName) != 0) { @@ -223,8 +233,8 @@ begin_proc(name, def) /* to be called when entering a procedure */ } } -end_proc(fbytes, nbytes) - arith fbytes, nbytes; +end_proc(fbytes) + arith fbytes; { /* end_proc() deals with the code to be generated at the end of a function, as there is: @@ -238,47 +248,57 @@ end_proc(fbytes, nbytes) - use of special identifiers such as "setjmp" - "end" + number of bytes used for local variables */ - static int mes_flt_given = 0; /* once for the whole program */ + arith nbytes; #ifdef DATAFLOW if (options['d']) DfaEndFunction(); #endif DATAFLOW prc_exit(); - C_ret((arith)0); - if (return_expr_occurred != 0) { - C_df_ilb(return_label); - prc_exit(); - if (func_res_label != 0) { - C_lae_dlb(func_res_label, (arith)0); - store_block(func_tp->tp_size, func_tp->tp_align); - C_lae_dlb(func_res_label, (arith)0); - C_ret(pointer_size); - } - else - C_ret(ATW(func_tp->tp_size)); - } -#ifndef NOFLOAT - if (fp_used && mes_flt_given == 0) { - /* floating point used */ - C_ms_flt(); - mes_flt_given++; + C_asp(-func_size); /* arbitrary return value */ + C_df_ilb(return_label); + prc_exit(); + if (func_res_label != 0) { + C_lae_dlb(func_res_label, (arith)0); + store_block(func_size, func_tp->tp_align); + C_lae_dlb(func_res_label, (arith)0); + C_ret(pointer_size); } -#endif NOFLOAT + else + C_ret(func_size); + + /* 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 + L_LOCAL is already unstacked. Therefore, "unstack_level" must + also pass "sl_max_block" to the level above L_LOCAL. + */ + nbytes = ATW(- local_level->sl_max_block); +#ifdef USE_TMP + C_beginpart(pro_id); + C_pro(pro_name, nbytes); +#endif C_ms_par(fbytes); /* # bytes for formals */ if (sp_occurred[SP_SETJMP]) { /* indicate use of "setjmp" */ C_ms_gto(); sp_occurred[SP_SETJMP] = 0; } - C_end(ATW(nbytes)); +#ifdef USE_TMP + C_endpart(pro_id); +#endif + LocalFinish(); + C_end(nbytes); } do_return() { - /* do_return generates a direct return */ - /* isn't a jump to the return label smarter ??? */ - prc_exit(); - C_ret((arith)0); + /* do_return handles the case of a return without expression. + This version branches to the return label, which is + probably smarter than generating a direct return. + Return sequences may be expensive. + */ + C_asp(-func_size); /* arbitrary return value */ + C_bra(return_label); } do_return_expr(expr) @@ -290,7 +310,7 @@ do_return_expr(expr) ch7cast(&expr, RETURN, func_tp); code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL); C_bra(return_label); - return_expr_occurred = 1; + /* return_expr_occurred = 1; */ } code_declaration(idf, expr, lvl, sc) @@ -322,7 +342,6 @@ code_declaration(idf, expr, lvl, sc) while at the same time forbidding extern int a = 5; */ - char *text = idf->id_text; register struct def *def = idf->id_def; register arith size = def->df_type->tp_size; int def_sc = def->df_sc; @@ -330,7 +349,7 @@ code_declaration(idf, expr, lvl, sc) if (def_sc == TYPEDEF) /* no code for typedefs */ return; if (sc == EXTERN && expr && !is_anon_idf(idf)) - error("%s is extern; cannot initialize", text); + error("%s is extern; cannot initialize", idf->id_text); if (lvl == L_GLOBAL) { /* global variable */ /* is this an allocating declaration? */ if ( (sc == 0 || sc == STATIC) @@ -339,12 +358,11 @@ code_declaration(idf, expr, lvl, sc) ) def->df_alloc = ALLOC_SEEN; if (expr) { /* code only if initialized */ -#ifdef USE_TMP - if (options['N']) +#ifndef USE_TMP + code_scope(idf->id_text, def); #endif USE_TMP - code_scope(text, def); def->df_alloc = ALLOC_DONE; - C_df_dnam(text); + C_df_dnam(idf->id_text); } } else @@ -364,7 +382,7 @@ code_declaration(idf, expr, lvl, sc) } else { /* produce blank space */ if (size <= 0) { - error("size of %s unknown", text); + error("size of %s unknown", idf->id_text); size = (arith)0; } C_bss_cst(ATW(size), (arith)0, 1); @@ -374,10 +392,9 @@ code_declaration(idf, expr, lvl, sc) case GLOBAL: case IMPLICIT: /* we are sure there is no expression */ -#ifdef USE_TMP - if (options['N']) +#ifndef USE_TMP + code_scope(idf->id_text, def); #endif USE_TMP - code_scope(text, def); break; case AUTO: case REGISTER: @@ -399,8 +416,8 @@ loc_init(expr, id) expression expr to the local variable described by id. It frees the expression afterwards. */ - register struct type *tp = id->id_def->df_type; register struct expr *e = expr; + register struct type *tp = id->id_def->df_type; ASSERT(id->id_def->df_sc != STATIC); switch (tp->tp_fund) { @@ -446,10 +463,9 @@ bss(idf) */ arith size = idf->id_def->df_type->tp_size; -#ifdef USE_TMP - if (options['N']) -#endif USE_TMP +#ifndef USE_TMP code_scope(idf->id_text, idf->id_def); +#endif USE_TMP /* Since bss() is only called if df_alloc is non-zero, and since df_alloc is only non-zero if size >= 0, we have: */ @@ -475,13 +491,11 @@ formal_cvt(df) if (tp->tp_size != int_size && (tp->tp_fund == CHAR || tp->tp_fund == SHORT) ) { - C_lol(df->df_address); + LoadLocal(df->df_address, int_size); /* conversion(int_type, df->df_type); ??? No, you can't do this on the stack! (CJ) */ - C_lal(df->df_address); - C_sti(tp->tp_size); - df->df_register = REG_NONE; + StoreLocal(df->df_address, tp->tp_size); } } @@ -563,15 +577,15 @@ unstack_stmt() free_stmt_block(sbp); } -static label l1; +static label prc_name; prc_entry(name) char *name; { if (options['p']) { - C_df_dlb(l1 = data_label()); + C_df_dlb(prc_name = data_label()); C_rom_scon(name, (arith) (strlen(name) + 1)); - C_lae_dlb(l1, (arith) 0); + C_lae_dlb(prc_name, (arith) 0); C_cal("procentry"); C_asp(pointer_size); } @@ -580,7 +594,7 @@ prc_entry(name) prc_exit() { if (options['p']) { - C_lae_dlb(l1, (arith) 0); + C_lae_dlb(prc_name, (arith) 0); C_cal("procexit"); C_asp(pointer_size); } diff --git a/lang/cem/cemcom/def.str b/lang/cem/cemcom/def.str index 637b9ea04..592d2d548 100644 --- a/lang/cem/cemcom/def.str +++ b/lang/cem/cemcom/def.str @@ -15,7 +15,6 @@ struct def { /* for ordinary tags */ FORMAL, AUTO, ENUM, LABEL */ - int df_register; /* REG_NONE, REG_DEFAULT or REG_BONUS */ char df_initialized; /* an initialization has been generated */ char df_alloc; /* 0, ALLOC_SEEN or ALLOC_DONE */ char df_used; /* set if idf is used */ @@ -26,8 +25,7 @@ struct def { /* for ordinary tags */ #define ALLOC_SEEN 1 /* an allocating declaration has been seen */ #define ALLOC_DONE 2 /* the allocating declaration has been done */ -#define REG_NONE 0 /* no register candidate */ -#define REG_DEFAULT 1 /* register candidate, not declared as such */ +#define REG_DEFAULT 0 /* register candidate, not declared as such */ #define REG_BONUS 10 /* register candidate, declared as such */ /* ALLOCDEF "def" 50 */ diff --git a/lang/cem/cemcom/dumpidf.c b/lang/cem/cemcom/dumpidf.c index ad99909cc..a22df8737 100644 --- a/lang/cem/cemcom/dumpidf.c +++ b/lang/cem/cemcom/dumpidf.c @@ -167,7 +167,6 @@ dumpdefs(def, opt) print("L%d: %s %s%s%s%s%s %lo;", def->df_level, symbol2str(def->df_sc), - (def->df_register != REG_NONE) ? "reg " : "", def->df_initialized ? "init'd " : "", def->df_used ? "used " : "", type2str(def->df_type), diff --git a/lang/cem/cemcom/error.c b/lang/cem/cemcom/error.c index 94227a71e..2bed0bd8d 100644 --- a/lang/cem/cemcom/error.c +++ b/lang/cem/cemcom/error.c @@ -9,7 +9,6 @@ #include #include "nopp.h" -#include "use_tmp.h" #include "errout.h" #include "debug.h" @@ -116,13 +115,7 @@ fatal(fmt, args) char *fmt; int args; { -#ifdef USE_TMP - extern char *tmpfile; /* main.c */ - - if (tmpfile) - sys_remove(tmpfile); /* may not successful! */ -#endif USE_TMP - + if (C_busy()) C_close(); _error(FATAL, NILEXPR, fmt, &args); sys_stop(S_EXIT); } diff --git a/lang/cem/cemcom/eval.c b/lang/cem/cemcom/eval.c index 1111a2d51..fbf930c20 100644 --- a/lang/cem/cemcom/eval.c +++ b/lang/cem/cemcom/eval.c @@ -7,6 +7,7 @@ #include "nofloat.h" #include +#include #include "debug.h" #include "nobitfield.h" #include "dataflow.h" @@ -31,7 +32,8 @@ char *symbol2str(); char *long2str(); -arith tmp_pointer_var(); +arith NewLocal(); /* util.c */ +#define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, 0) /* EVAL() is the main expression-tree evaluator, which turns any legal expression tree into EM code. Parameters: @@ -366,7 +368,7 @@ EVAL(expr, val, code, true_label, false_label) case PLUSPLUS: case MINMIN: { - arith old_offset, tmp; + arith tmp; int compl; /* Complexity of left operand */ int newcode = left->ex_type->tp_size > 0; /* CJ */ #ifndef NOBITFIELD @@ -389,10 +391,9 @@ EVAL(expr, val, code, true_label, false_label) compl = 2; /* otherwise */ EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL); if (newcode) { - tmp = tmp_pointer_var(&old_offset); + tmp = LocalPtrVar(); C_dup(pointer_size); - C_lal(tmp); - C_sti(pointer_size); + StoreLocal(tmp, pointer_size); C_loi(left->ex_type->tp_size); } } @@ -423,15 +424,13 @@ EVAL(expr, val, code, true_label, false_label) } } else { - C_lal(tmp); /* always init'd */ - C_loi(pointer_size); + LoadLocal(tmp, pointer_size); C_sti(left->ex_type->tp_size); if (dupval) { - C_lal(tmp); - C_loi(pointer_size); + LoadLocal(tmp, pointer_size); C_loi(left->ex_type->tp_size); } - free_tmp_var(old_offset); + FreeLocal(tmp); } } break; @@ -477,7 +476,7 @@ EVAL(expr, val, code, true_label, false_label) if (gencode) { if (is_struct_or_union(tp->tp_fund)) { C_lfr(pointer_size); - load_block(tp->tp_size, tp->tp_align); + load_block(tp->tp_size, word_align); } else C_lfr(ATW(tp->tp_size)); @@ -758,33 +757,6 @@ assop(type, oper) } } -/* tmp_pointer_var() returns the EM address of a new temporary - pointer variable needed at increment, decrement and assignment - operations to store the address of some variable or lvalue-expression. -*/ -arith -tmp_pointer_var(oldoffset) - arith *oldoffset; /* previous allocated address */ -{ - register struct stack_level *stl = local_level; - - *oldoffset = stl->sl_local_offset; - stl->sl_local_offset = - - align(-stl->sl_local_offset + pointer_size, pointer_align); - if (stl->sl_local_offset < stl->sl_max_block) - stl->sl_max_block = stl->sl_local_offset; - return stl->sl_local_offset; -} - -/* free_tmp_var() returns the address allocated by tmp_pointer_var() - and resets the last allocated address. -*/ -free_tmp_var(oldoffset) - arith oldoffset; -{ - local_level->sl_local_offset = oldoffset; -} - /* store_val() generates code for a store operation. There are four ways of storing data: - into a global variable @@ -828,15 +800,11 @@ store_val(vl, tp) } else { ASSERT(df->df_sc != STATIC); - if (inword) - C_stl(df->df_address + val); - else - if (indword) - C_sdl(df->df_address + val); + if (inword || indword) + StoreLocal(df->df_address + val, size); else { - C_lal(df->df_address + val); + AddrLocal(df->df_address + val); store_block(size, tpalign); - df->df_register = REG_NONE; } } } @@ -943,21 +911,16 @@ load_val(expr, rlval) else { ASSERT(df->df_sc != STATIC); if (rvalue) { - if (inword) - C_lol(df->df_address + val); - else - if (indword) - C_ldl(df->df_address + val); + if (inword || indword) + LoadLocal(df->df_address + val, size); else { - C_lal(df->df_address + val); + AddrLocal(df->df_address + val); load_block(size, tpalign); - df->df_register = REG_NONE; } } else { - C_lal(df->df_address); + AddrLocal(df->df_address); C_adp(val); - df->df_register = REG_NONE; } } } diff --git a/lang/cem/cemcom/field.c b/lang/cem/cemcom/field.c index 021196d20..aed937565 100644 --- a/lang/cem/cemcom/field.c +++ b/lang/cem/cemcom/field.c @@ -9,6 +9,7 @@ #ifndef NOBITFIELD #include +#include #include "debug.h" #include "arith.h" #include "type.h" @@ -18,10 +19,11 @@ #include "assert.h" #include "expr.h" #include "sizes.h" +#include "align.h" #include "Lpars.h" #include "field.h" -arith tmp_pointer_var(); /* eval.c */ +arith NewLocal(); /* util.c */ char *symbol2str(); /* symbol2str.c */ /* Eval_field() evaluates expressions involving bit fields. @@ -45,7 +47,7 @@ eval_field(expr, code) register struct expr *rightop = expr->OP_RIGHT; register struct field *fd = leftop->ex_type->tp_field; struct type *tp = leftop->ex_type->tp_up; - arith old_offset, tmpvar; + arith tmpvar; struct type *atype = tp->tp_unsigned ? uword_type : word_type; arith asize = atype->tp_size; @@ -75,18 +77,17 @@ eval_field(expr, code) store_val(&(leftop->ex_object.ex_value), atype); } else { /* complex case */ - tmpvar = tmp_pointer_var(&old_offset); + tmpvar = NewLocal(pointer_size, pointer_align, + reg_pointer, 0); EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL); C_dup(pointer_size); - C_lal(tmpvar); - C_sti(pointer_size); + StoreLocal(tmpvar, pointer_size); C_loi(asize); C_and(asize); C_ior(asize); - C_lal(tmpvar); - C_loi(pointer_size); + LoadLocal(tmpvar, pointer_size); C_sti(asize); - free_tmp_var(old_offset); + FreeLocal(tmpvar); } } else { /* treat ++F as F += 1 and --F as F -= 1 */ @@ -96,11 +97,11 @@ eval_field(expr, code) if (leftop->ex_depth == 0) /* simple case */ load_val(leftop, RVAL); else { /* complex case */ - tmpvar = tmp_pointer_var(&old_offset); + tmpvar = NewLocal(pointer_size, pointer_align, + reg_pointer, 0); EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL); C_dup(pointer_size); - C_lal(tmpvar); - C_sti(pointer_size); + StoreLocal(tmpvar, pointer_size); C_loi(asize); } if (atype->tp_unsigned) { @@ -146,15 +147,13 @@ eval_field(expr, code) store_val(&(leftop->ex_object.ex_value), atype); } else { - C_lal(tmpvar); - C_loi(pointer_size); + LoadLocal(tmpvar, pointer_size); C_loi(asize); C_and(asize); C_ior(asize); - C_lal(tmpvar); - C_loi(pointer_size); + LoadLocal(tmpvar, pointer_size); C_sti(asize); - free_tmp_var(old_offset); + FreeLocal(tmpvar); } } if (code == TRUE) { diff --git a/lang/cem/cemcom/idf.c b/lang/cem/cemcom/idf.c index c47c3eeed..4512dbaa7 100644 --- a/lang/cem/cemcom/idf.c +++ b/lang/cem/cemcom/idf.c @@ -5,6 +5,7 @@ /* $Header$ */ /* IDENTIFIER FIDDLING & SYMBOL TABLE HANDLING */ +#include #include "nofloat.h" #include "debug.h" #include "idfsize.h" @@ -31,6 +32,7 @@ int idfsize = IDFSIZE; extern char options[]; +extern arith NewLocal(); char sp_occurred[SP_TOTAL]; /* indicate occurrence of special id */ @@ -292,7 +294,6 @@ declare_idf(ds, dc, lvl) def->df_formal_array = formal_array; def->df_sc = sc; def->df_level = L_FORMAL2; /* CJ */ - if (sc == REGISTER) def->df_register = REG_BONUS; } else if ( lvl >= L_LOCAL && @@ -318,8 +319,6 @@ declare_idf(ds, dc, lvl) newdef->df_level = lvl; newdef->df_type = type; newdef->df_sc = sc; - if (lvl == L_FORMAL1) /* CJ */ - newdef->df_register = REG_DEFAULT; /* link it into the name list in the proper place */ idf->id_def = newdef; update_ahead(idf); @@ -340,14 +339,13 @@ declare_idf(ds, dc, lvl) idf->id_text); /** type = idf->id_def->df_type = int_type; **/ } - newdef->df_register = - (sc == REGISTER) ? REG_BONUS - : REG_DEFAULT; newdef->df_address = - stl->sl_max_block = - stl->sl_local_offset = - -align(-stl->sl_local_offset + - type->tp_size, type->tp_align); + NewLocal(type->tp_size, + type->tp_align, + regtype(type), + (sc == REGISTER) ? REG_BONUS + : REG_DEFAULT + ); break; case STATIC: newdef->df_address = (arith) data_label(); @@ -615,10 +613,33 @@ declare_formals(fp) formal_cvt(def); /* cvt int to char or short, if necessary */ se = se->next; def->df_level = L_FORMAL2; /* CJ */ + RegisterAccount(def->df_address, def->df_type->tp_size, + regtype(def->df_type), + (def->df_sc == REGISTER ? REG_BONUS + : REG_DEFAULT) + ); } *fp = f_offset; } +int +regtype(tp) + struct type *tp; +{ + switch(tp->tp_fund) { + case INT: + return reg_any; +#ifndef NOFLOAT + case FLOAT: + case DOUBLE: + return reg_float; +#endif NOFLOAT + case POINTER: + return reg_pointer; + } + return -1; +} + add_def(idf, sc, tp, lvl) struct idf *idf; struct type *tp; diff --git a/lang/cem/cemcom/main.c b/lang/cem/cemcom/main.c index 3f93e8534..a909e7265 100644 --- a/lang/cem/cemcom/main.c +++ b/lang/cem/cemcom/main.c @@ -125,20 +125,9 @@ char *source = 0; char *nmlist = 0; -#ifdef USE_TMP -extern char *strcpy(), *strcat(); -extern char *mktemp(); /* library routine */ -char *tmpfdir = "/tmp"; /* where to keep the temporary file */ -static char *tmpfname = "/Cem.XXXXXX"; -char *tmpfile = 0; -#endif USE_TMP - compile(argc, argv) char *argv[]; { -#ifdef USE_TMP - char tmpf[256]; -#endif char *result; register char *destination = 0; @@ -175,14 +164,6 @@ compile(argc, argv) FileName = "standard input"; } -#ifdef USE_TMP - if (! options['N']) { - strcpy(tmpf, tmpfdir); - strcat(tmpf, tmpfname); - tmpfile = mktemp(tmpf); - } -#endif USE_TMP - if (destination && strcmp(destination, "-") == 0) destination = 0; if (!InsertFile(source, (char **) 0, &result)) /* read the source file */ @@ -204,25 +185,15 @@ compile(argc, argv) #endif DEBUG { -#ifdef USE_TMP - if (!options['N']) { - init_code(tmpfile); - } - else -#endif USE_TMP init_code(destination); /* compile the source text */ C_program(); - end_code(); #ifdef USE_TMP - if (! options['N']) { - prepend_scopes(destination); - AppendFile(tmpfile, destination); - sys_remove(tmpfile); - } + prepend_scopes(); #endif USE_TMP + end_code(); #ifdef DEBUG if (options['u']) { @@ -399,33 +370,6 @@ preprocess() #endif NOPP #endif DEBUG -#ifdef USE_TMP -AppendFile(src, dst) - char *src, *dst; -{ - File *fp_src, *fp_dst; - char buf[BUFSIZ]; - int n; - - if (sys_open(src, OP_READ, &fp_src) == 0) - fatal("cannot read %s", src); - if (dst) { - if (sys_open(dst, OP_APPEND, &fp_dst) == 0) - fatal("cannot write to %s", src); - } - else - fp_dst = STDOUT; - while (sys_read(fp_src, buf, BUFSIZ, &n) != 0 && n > 0) - if (sys_write(fp_dst, buf, n) == 0) - fatal("(AppendFile) write error"); - if (n != 0) - fatal("(AppendFile) read error"); - sys_close(fp_src); - if (fp_dst != STDOUT) - sys_close(fp_dst); -} -#endif USE_TMP - No_Mem() { fatal("out of memory"); diff --git a/lang/cem/cemcom/options.c b/lang/cem/cemcom/options.c index 4b68653a4..b333734dd 100644 --- a/lang/cem/cemcom/options.c +++ b/lang/cem/cemcom/options.c @@ -30,9 +30,6 @@ extern int inc_total; extern char options[]; extern int idfsize; -#ifdef USE_TMP -extern char *tmpfdir; /* main.c */ -#endif USE_TMP int txt2int(); @@ -163,14 +160,6 @@ deleted, is now a debug-flag fatal("maximum identifier length is %d", IDFSIZE); break; - case 'N' : -#ifdef USE_TMP - options['N'] = 1; -#else USE_TMP - warning("-N option ignored"); -#endif USE_TMP - break; - #ifdef ___XXX___ case 'P' : /* run preprocessor stand-alone, without #'s */ #ifndef NOPP @@ -183,15 +172,17 @@ deleted, is now a debug-flag #endif ___XXX___ #ifdef USE_TMP - case 'T' : + case 'T' : { + extern char *C_tmpdir; if (*text) - tmpfdir = text; + C_tmpdir = text; else - tmpfdir = "."; + C_tmpdir = "."; #else USE_TMP warning("-T option ignored"); #endif USE_TMP break; + } case 'U' : { /* -Uname : undefine predefined */ #ifndef NOPP diff --git a/lang/cem/cemcom/program.g b/lang/cem/cemcom/program.g index 2aeaac01a..4d8d05c20 100644 --- a/lang/cem/cemcom/program.g +++ b/lang/cem/cemcom/program.g @@ -180,10 +180,10 @@ function(struct declarator *dc;) { declare_formals(&fbytes); } - compound_statement(&nbytes) + compound_statement { + end_proc(fbytes); unstack_level(); /* L_FORMAL2 declarations */ unstack_level(); /* L_FORMAL1 declarations */ - end_proc(fbytes, nbytes); } ; diff --git a/lang/cem/cemcom/stack.c b/lang/cem/cemcom/stack.c index e29ecf63b..f1e1c0e8b 100644 --- a/lang/cem/cemcom/stack.c +++ b/lang/cem/cemcom/stack.c @@ -8,7 +8,6 @@ #include "nofloat.h" #include #include -#include #include "debug.h" #include "botch_free.h" #include @@ -50,8 +49,7 @@ stack_level() { loclev->sl_next = stl; stl->sl_previous = loclev; stl->sl_level = ++level; - stl->sl_local_offset = - stl->sl_max_block = loclev->sl_local_offset; + stl->sl_max_block = loclev->sl_max_block; local_level = stl; } @@ -115,36 +113,8 @@ unstack_level() /* unlink it from the def list under the idf block */ if (def->df_sc == LABEL) unstack_label(idf); - else - if (level == L_LOCAL || level == L_FORMAL1) { - if ( def->df_register != REG_NONE && - def->df_sc != STATIC && - def->df_type->tp_size > 0 && - options['n'] == 0 - ) { - int reg; - - switch (def->df_type->tp_fund) { - - case POINTER: - reg = reg_pointer; - break; -#ifndef NOFLOAT - case FLOAT: - case DOUBLE: - reg = reg_float; - break; -#endif NOFLOAT - default: - reg = reg_any; - break; - } - C_ms_reg(def->df_address, - def->df_type->tp_size, - reg, def->df_register - ); - } - } + else if (def->df_sc == REGISTER || def->df_sc == AUTO) + FreeLocal(def->df_address); idf->id_def = def->next; free_def(def); update_ahead(idf); @@ -173,9 +143,7 @@ unstack_level() */ lastlvl = local_level; local_level = local_level->sl_previous; - if ( level > L_LOCAL - && lastlvl->sl_max_block < local_level->sl_max_block - ) { + if (level >= L_LOCAL) { local_level->sl_max_block = lastlvl->sl_max_block; } free_stack_level(lastlvl); diff --git a/lang/cem/cemcom/statement.g b/lang/cem/cemcom/statement.g index 50c4c8983..4257c9b47 100644 --- a/lang/cem/cemcom/statement.g +++ b/lang/cem/cemcom/statement.g @@ -37,7 +37,7 @@ statement | label ':' statement | - compound_statement((arith *)0) + compound_statement | if_statement | @@ -353,7 +353,7 @@ jump } ; -compound_statement(arith *nbytes;): +compound_statement: '{' { stack_level(); @@ -366,8 +366,6 @@ compound_statement(arith *nbytes;): ]* '}' { - if (nbytes) - *nbytes = (- local_level->sl_max_block); unstack_level(); } ; diff --git a/lang/cem/cemcom/util.c b/lang/cem/cemcom/util.c new file mode 100644 index 000000000..c41cda4dc --- /dev/null +++ b/lang/cem/cemcom/util.c @@ -0,0 +1,211 @@ +/* + * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands. + * See the copyright notice in the ACK home directory, in the file "Copyright". + */ + +/* M I S C E L L A N E O U S U T I L I T I E S */ + +/* $Header$ */ + +/* Code for the allocation and de-allocation of temporary variables, + allowing re-use. +*/ + +#include +#include +#include +#include + +#include "util.h" +#include "use_tmp.h" +#include "sizes.h" +#include "align.h" +#include "stack.h" + +static struct localvar *FreeTmps; +#ifdef USE_TMP +static int loc_id; +#endif USE_TMP + +extern char options[]; + +LocalInit() +{ +#ifdef USE_TMP + C_insertpart(loc_id = C_getid()); +#endif USE_TMP +} + +arith +LocalSpace(sz, al) + arith sz; +{ + register struct stack_level *stl = local_level; + + stl->sl_max_block = - align(sz - stl->sl_max_block, al); + return stl->sl_max_block; +} + +#define TABSIZ 32 +static struct localvar *regs[TABSIZ]; + +arith +NewLocal(sz, al, regtype, init) + arith sz; +{ + register struct localvar *tmp = FreeTmps; + struct localvar *prev = 0; + register int index; + + while (tmp) { + if (tmp->t_align >= al && + tmp->t_size >= sz && + tmp->t_regtype == regtype) { + if (prev) { + prev->next = tmp->next; + } + else FreeTmps = tmp->next; + break; + } + prev = tmp; + tmp = tmp->next; + } + if (! tmp) { + tmp = new_localvar(); + tmp->t_offset = LocalSpace(sz, al); + tmp->t_align = al; + tmp->t_size = sz; + tmp->t_regtype = regtype; + tmp->t_count = init; + } + index = (int) (tmp->t_offset >> 2) & (TABSIZ - 1); + tmp->next = regs[index]; + regs[index] = tmp; + return tmp->t_offset; +} + +FreeLocal(off) + arith off; +{ + int index = (int) (off >> 2) & (TABSIZ - 1); + register struct localvar *tmp = regs[index]; + struct localvar *prev = 0; + + while (tmp && tmp->t_offset != off) { + prev = tmp; + tmp = tmp->next; + } + if (tmp) { + if (prev) prev->next = tmp->next; + else regs[index] = tmp->next; + tmp->next = FreeTmps; + FreeTmps = tmp; + } +} + +LocalFinish() +{ + register struct localvar *tmp, *tmp1; + register int i; + +#ifdef USE_TMP + C_beginpart(loc_id); +#endif + tmp = FreeTmps; + while (tmp) { + tmp1 = tmp; + if (! options['n'] && tmp->t_regtype >= 0) { + C_ms_reg(tmp->t_offset, tmp->t_size, tmp->t_regtype, tmp->t_count); + } + tmp = tmp->next; + free_localvar(tmp1); + } + FreeTmps = 0; + for (i = 0; i < TABSIZ; i++) { + tmp = regs[i]; + while (tmp) { + tmp1 = tmp; + if (! options['n'] && tmp->t_regtype >= 0) { + C_ms_reg(tmp->t_offset, + tmp->t_size, + tmp->t_regtype, + tmp->t_count); + } + tmp = tmp->next; + free_localvar(tmp1); + } + regs[i] = 0; + } +#ifdef USE_TMP + C_mes_begin(ms_reg); + C_mes_end(); + C_endpart(loc_id); +#endif +} + +RegisterAccount(offset, size, regtype, init) + arith offset, size; +{ + register struct localvar *p; + int index; + + if (regtype < 0) return; + + p = new_localvar(); + index = (int) (offset >> 2) & (TABSIZ - 1); + p->t_offset = offset; + p->t_regtype = regtype; + p->t_count = init; + p->t_size = size; + p->next = regs[index]; + regs[index] = p; +} + +static struct localvar * +find_reg(off) + arith off; +{ + register struct localvar *p = regs[(int)(off >> 2) & (TABSIZ - 1)]; + + while (p && p->t_offset != off) p = p->next; + return p; +} + +LoadLocal(off, sz) + arith off, sz; +{ + register struct localvar *p = find_reg(off); + + if (p) p->t_count++; + if (sz == word_size) C_lol(off); + else if (sz == dword_size) C_ldl(off); + else { + if (p) p->t_regtype = -1; + C_lal(off); + C_loi(sz); + } +} + +StoreLocal(off, sz) + arith off, sz; +{ + register struct localvar *p = find_reg(off); + + if (p) p->t_count++; + if (sz == word_size) C_stl(off); + else if (sz == dword_size) C_sdl(off); + else { + if (p) p->t_regtype = -1; + C_lal(off); + C_sti(sz); + } +} + +AddrLocal(off) + arith off; +{ + register struct localvar *p = find_reg(off); + + if (p) p->t_regtype = -1; + C_lal(off); +} diff --git a/lang/cem/cemcom/util.str b/lang/cem/cemcom/util.str new file mode 100644 index 000000000..88ec0b8a1 --- /dev/null +++ b/lang/cem/cemcom/util.str @@ -0,0 +1,10 @@ +struct localvar { + struct localvar *next; + arith t_offset; /* offset from LocalBase */ + arith t_size; + int t_align; + int t_regtype; + int t_count; +}; + +/* ALLOCDEF "localvar" 10 */ -- 2.34.1