use new C_insertpart mechanism, other minor changes
authorceriel <none@none>
Thu, 16 Jul 1987 13:27:37 +0000 (13:27 +0000)
committerceriel <none@none>
Thu, 16 Jul 1987 13:27:37 +0000 (13:27 +0000)
19 files changed:
lang/cem/cemcom/BigPars
lang/cem/cemcom/Makefile
lang/cem/cemcom/Parameters
lang/cem/cemcom/blocks.c
lang/cem/cemcom/ch7mon.c
lang/cem/cemcom/code.c
lang/cem/cemcom/def.str
lang/cem/cemcom/dumpidf.c
lang/cem/cemcom/error.c
lang/cem/cemcom/eval.c
lang/cem/cemcom/field.c
lang/cem/cemcom/idf.c
lang/cem/cemcom/main.c
lang/cem/cemcom/options.c
lang/cem/cemcom/program.g
lang/cem/cemcom/stack.c
lang/cem/cemcom/statement.g
lang/cem/cemcom/util.c [new file with mode: 0644]
lang/cem/cemcom/util.str [new file with mode: 0644]

index 6df5e2d..1671e56 100644 (file)
@@ -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
index fd23d77..bc358ff 100644 (file)
@@ -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
index 6df5e2d..1671e56 100644 (file)
@@ -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
index 255ade3..d7fc244 100644 (file)
@@ -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 <em.h>
+#include <em_reg.h>
 #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);
index 3ed80fe..102f725 100644 (file)
@@ -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;
index 30825dc..dc2ffd3 100644 (file)
@@ -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);
        }
index 637b9ea..592d2d5 100644 (file)
@@ -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 */
index ad99909..a22df87 100644 (file)
@@ -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),
index 94227a7..2bed0bd 100644 (file)
@@ -9,7 +9,6 @@
 #include       <em.h>
 
 #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);
 }
index 1111a2d..fbf930c 100644 (file)
@@ -7,6 +7,7 @@
 
 #include       "nofloat.h"
 #include       <em.h>
+#include       <em_reg.h>
 #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;
                        }
                }
        }
index 021196d..aed9375 100644 (file)
@@ -9,6 +9,7 @@
 
 #ifndef NOBITFIELD
 #include       <em.h>
+#include       <em_reg.h>
 #include       "debug.h"
 #include       "arith.h"
 #include       "type.h"
 #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) {
index c47c3ee..4512dba 100644 (file)
@@ -5,6 +5,7 @@
 /* $Header$ */
 /*     IDENTIFIER  FIDDLING & SYMBOL TABLE HANDLING    */
 
+#include       <em_reg.h>
 #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;
index 3f93e85..a909e72 100644 (file)
@@ -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");
index 4b68653..b333734 100644 (file)
@@ -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
index 2aeaac0..4d8d05c 100644 (file)
@@ -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);
        }
 ;
index e29ecf6..f1e1c0e 100644 (file)
@@ -8,7 +8,6 @@
 #include       "nofloat.h"
 #include       <system.h>
 #include       <em.h>
-#include       <em_reg.h>
 #include       "debug.h"
 #include       "botch_free.h"
 #include       <alloc.h>
@@ -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);
index 50c4c89..4257c9b 100644 (file)
@@ -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 (file)
index 0000000..c41cda4
--- /dev/null
@@ -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       <em.h>
+#include       <em_reg.h>
+#include       <alloc.h>
+#include       <em_mes.h>
+
+#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 (file)
index 0000000..88ec0b8
--- /dev/null
@@ -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 */