use new C_insertpart mechanism, other minor changes

This commit is contained in:
ceriel 1987-07-16 13:27:37 +00:00
parent 2381b2e136
commit 0619d27b8d
19 changed files with 428 additions and 317 deletions

View file

@ -97,7 +97,7 @@
!File: inputtype.h !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 !File: nopp.h

View file

@ -58,7 +58,7 @@ CSRC = main.c idf.c declarator.c decspecs.c struct.c \
tokenname.c LLlex.c LLmessage.c \ tokenname.c LLlex.c LLmessage.c \
input.c domacro.c replace.c init.c options.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 \ 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 blocks.c dataflow.c Version.c
COBJ = main.o idf.o declarator.o decspecs.o struct.o \ COBJ = main.o idf.o declarator.o decspecs.o struct.o \
expr.o ch7.o ch7bin.o cstoper.o arith.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 \ tokenname.o LLlex.o LLmessage.o \
input.o domacro.o replace.o init.o options.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 \ 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 blocks.o dataflow.o Version.o
# Objects of other generated C files # Objects of other generated C files
@ -74,11 +74,11 @@ GCSRC = char.c symbol2str.c next.c
GOBJ = char.o symbol2str.o next.o GOBJ = char.o symbol2str.o next.o
STRSRC = code.str declar.str decspecs.str def.str expr.str field.str \ 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 idf.str macro.str stack.str stmt.str struct.str switch.str type.str
# generated source files # generated source files
GHSTRSRC = code.h declar.h decspecs.h def.h expr.h field.h \ 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 idf.h macro.h stack.h stmt.h struct.h switch.h type.h
GSRC = $(GCSRC) $(GHSTRSRC) GSRC = $(GCSRC) $(GHSTRSRC)
@ -185,6 +185,7 @@ struct.h: make.allocd
switch.h: make.allocd switch.h: make.allocd
type.h: make.allocd type.h: make.allocd
estack.h: make.allocd estack.h: make.allocd
util.h: make.allocd
depend: Cfiles depend: Cfiles
sed '/^#AUTOAUTO/,$$d' makefile >makefile.new sed '/^#AUTOAUTO/,$$d' makefile >makefile.new
@ -441,7 +442,6 @@ error.o: nofloat.h
error.o: nopp.h error.o: nopp.h
error.o: spec_arith.h error.o: spec_arith.h
error.o: tokenname.h error.o: tokenname.h
error.o: use_tmp.h
field.o: Lpars.h field.o: Lpars.h
field.o: arith.h field.o: arith.h
field.o: assert.h field.o: assert.h
@ -677,6 +677,15 @@ conversion.o: sizes.h
conversion.o: spec_arith.h conversion.o: spec_arith.h
conversion.o: target_sizes.h conversion.o: target_sizes.h
conversion.o: type.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: align.h
blocks.o: arith.h blocks.o: arith.h
blocks.o: atw.h blocks.o: atw.h

View file

@ -97,7 +97,7 @@
!File: inputtype.h !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 !File: nopp.h

View 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 */ /* 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.h>
#include <em_reg.h>
#include "arith.h" #include "arith.h"
#include "sizes.h" #include "sizes.h"
#include "atw.h" #include "atw.h"
@ -13,7 +14,8 @@
#ifndef STB #ifndef STB
#include "label.h" #include "label.h"
#include "stack.h" #include "stack.h"
extern arith tmp_pointer_var(); extern arith NewLocal();
#define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, 0)
#endif STB #endif STB
/* Because EM does not support the loading and storing of /* Because EM does not support the loading and storing of
@ -58,22 +60,20 @@ store_block(sz, al)
C_sti(sz); C_sti(sz);
else { else {
#ifndef STB #ifndef STB
arith src, dst, src_offs, dst_offs; arith src, dst;
/* allocate two pointer temporaries */ /* allocate two pointer temporaries */
src = tmp_pointer_var(&src_offs); src = LocalPtrVar();
dst = tmp_pointer_var(&dst_offs); dst = LocalPtrVar();
/* load the addresses */ /* load the addresses */
C_lal(dst); StoreLocal(dst, pointer_size);
C_sti(pointer_size);
C_lor((arith)1); /* push current sp */ C_lor((arith)1); /* push current sp */
C_lal(src); StoreLocal(src, pointer_size);
C_sti(pointer_size);
copy_loop(sz, src, dst); copy_loop(sz, src, dst);
C_asp(ATW(sz)); C_asp(ATW(sz));
free_tmp_var(dst_offs); FreeLocal(dst);
free_tmp_var(src_offs); FreeLocal(src);
#else STB #else STB
/* address of destination lies on the stack */ /* address of destination lies on the stack */
@ -103,21 +103,19 @@ load_block(sz, al)
C_loi(esz); C_loi(esz);
else { else {
#ifndef STB #ifndef STB
arith src, dst, src_offs, dst_offs; arith src, dst;
/* allocate two pointer temporaries */ /* allocate two pointer temporaries */
src = tmp_pointer_var(&src_offs); src = LocalPtrVar();
dst = tmp_pointer_var(&dst_offs); dst = LocalPtrVar();
C_lal(src); StoreLocal(src, pointer_size);
C_sti(pointer_size);
C_asp(-esz); /* allocate stack block */ C_asp(-esz); /* allocate stack block */
C_lor((arith)1); /* push & of stack block as dst */ C_lor((arith)1); /* push & of stack block as dst */
C_lal(dst); StoreLocal(dst, pointer_size);
C_sti(pointer_size);
copy_loop(sz, src, dst); copy_loop(sz, src, dst);
free_tmp_var(dst_offs); FreeLocal(dst);
free_tmp_var(src_offs); FreeLocal(src);
#else STB #else STB
C_asp(-(esz - pointer_size)); /* allocate stack block */ C_asp(-(esz - pointer_size)); /* allocate stack block */
C_lor((arith)1); /* push & of stack block as dst */ C_lor((arith)1); /* push & of stack block as dst */
@ -143,19 +141,15 @@ copy_loop(sz, src, dst)
C_dup(word_size); C_dup(word_size);
C_zle(l_stop); C_zle(l_stop);
C_dec(); C_dec();
C_lal(src); LoadLocal(src, pointer_size);
C_loi(pointer_size);
C_dup(pointer_size); C_dup(pointer_size);
C_adp((arith)1); C_adp((arith)1);
C_lal(src); StoreLocal(src, pointer_size);
C_sti(pointer_size);
C_loi((arith)1); C_loi((arith)1);
C_lal(dst); LoadLocal(dst, pointer_size);
C_loi(pointer_size);
C_dup(pointer_size); C_dup(pointer_size);
C_adp((arith)1); C_adp((arith)1);
C_lal(dst); StoreLocal(dst, pointer_size);
C_sti(pointer_size);
C_sti((arith)1); C_sti((arith)1);
C_bra(l_cont); C_bra(l_cont);
C_df_ilb(l_stop); C_df_ilb(l_stop);

View file

@ -86,7 +86,6 @@ ch7mon(oper, expp)
"& on register variable not allowed"); "& on register variable not allowed");
break; /* break case '&' */ break; /* break case '&' */
} }
def->df_register = REG_NONE;
} }
(*expp)->ex_type = pointer_to((*expp)->ex_type); (*expp)->ex_type = pointer_to((*expp)->ex_type);
(*expp)->ex_lvalue = 0; (*expp)->ex_lvalue = 0;

View file

@ -40,6 +40,12 @@ label datlab_count = 1;
int fp_used; int fp_used;
#endif NOFLOAT #endif NOFLOAT
#ifdef USE_TMP
static int tmp_id;
static int pro_id;
static char *pro_name;
#endif USE_TMP
extern char options[]; extern char options[];
char *symbol2str(); char *symbol2str();
@ -52,16 +58,11 @@ init_code(dst_file)
C_init(word_size, pointer_size); /* initialise EM module */ C_init(word_size, pointer_size); /* initialise EM module */
if (C_open(dst_file) == 0) if (C_open(dst_file) == 0)
fatal("cannot write to %s\n", dst_file); 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_magic();
C_ms_emx(word_size, pointer_size); 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; static struct string_cst *str_list = 0;
@ -84,11 +85,13 @@ code_string(val, len, dlb)
def_strings(sc) def_strings(sc)
register struct string_cst *sc; register struct string_cst *sc;
{ {
if (sc) { while (sc) {
def_strings(sc->next); struct string_cst *sc1 = sc;
C_df_dlb(sc->sc_dlb); C_df_dlb(sc->sc_dlb);
str_cst(sc->sc_value, sc->sc_len); 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 /* end_code() performs the actions to be taken when closing
the output stream. the output stream.
*/ */
#ifndef NOFLOAT
if (fp_used) {
/* floating point used */
C_ms_flt();
}
#endif NOFLOAT
def_strings(str_list); def_strings(str_list);
str_list = 0; str_list = 0;
C_ms_src((int)(LineNumber - 2), FileName); C_ms_src((int)(LineNumber - 2), FileName);
@ -104,18 +113,15 @@ end_code()
} }
#ifdef USE_TMP #ifdef USE_TMP
prepend_scopes(dst_file) prepend_scopes()
char *dst_file;
{ {
/* prepend_scopes() runs down the list of global idf's /* prepend_scopes() runs down the list of global idf's
and generates those exa's, exp's, ina's and inp'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; register struct stack_entry *se = local_level->sl_entry;
if (C_open(dst_file) == 0) C_beginpart(tmp_id);
fatal("cannot create %s", dst_file ? dst_file : "stdout");
famous_first_words();
while (se != 0) { while (se != 0) {
register struct idf *id = se->se_idf; register struct idf *id = se->se_idf;
register struct def *df = id->id_def; register struct def *df = id->id_def;
@ -124,7 +130,7 @@ prepend_scopes(dst_file)
code_scope(id->id_text, df); code_scope(id->id_text, df);
se = se->next; se = se->next;
} }
C_close(); C_endpart(tmp_id);
} }
#endif USE_TMP #endif USE_TMP
@ -156,8 +162,9 @@ code_scope(text, def)
} }
static label return_label; static label return_label;
static char return_expr_occurred; /* static char return_expr_occurred; */
static struct type *func_tp; static struct type *func_tp;
static arith func_size;
static label func_res_label; static label func_res_label;
static char *last_fn_given = ""; static char *last_fn_given = "";
static label file_name_label; 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 does not fit in the return area
- a fil pseudo instruction - a fil pseudo instruction
*/ */
arith size;
register struct type *tp = def->df_type; register struct type *tp = def->df_type;
#ifdef USE_TMP #ifndef USE_TMP
if (options['N']) code_scope(name,def);
#else USE_TMP
code_scope(name, def); code_scope(name, def);
#endif USE_TMP #endif USE_TMP
#ifdef DATAFLOW #ifdef DATAFLOW
@ -194,11 +198,16 @@ begin_proc(name, def) /* to be called when entering a procedure */
else else
tp = tp->tp_up; tp = tp->tp_up;
func_tp = tp; func_tp = tp;
size = ATW(tp->tp_size); func_size = ATW(tp->tp_size);
#ifndef USE_TMP
C_pro_narg(name); C_pro_narg(name);
#else
pro_name = name;
C_insertpart(pro_id = C_getid());
#endif
if (is_struct_or_union(tp->tp_fund)) { if (is_struct_or_union(tp->tp_fund)) {
C_df_dlb(func_res_label = data_label()); C_df_dlb(func_res_label = data_label());
C_bss_cst(size, (arith)0, 1); C_bss_cst(func_size, (arith)0, 1);
} }
else else
func_res_label = 0; func_res_label = 0;
@ -208,7 +217,8 @@ begin_proc(name, def) /* to be called when entering a procedure */
*/ */
lab_count = (label) 1; lab_count = (label) 1;
return_label = text_label(); return_label = text_label();
return_expr_occurred = 0; /* return_expr_occurred = 0; */
LocalInit();
prc_entry(name); prc_entry(name);
if (! options['L']) { /* profiling */ if (! options['L']) { /* profiling */
if (strcmp(last_fn_given, FileName) != 0) { 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) end_proc(fbytes)
arith fbytes, nbytes; 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:
@ -238,47 +248,57 @@ end_proc(fbytes, nbytes)
- use of special identifiers such as "setjmp" - use of special identifiers such as "setjmp"
- "end" + number of bytes used for local variables - "end" + number of bytes used for local variables
*/ */
static int mes_flt_given = 0; /* once for the whole program */ arith nbytes;
#ifdef DATAFLOW #ifdef DATAFLOW
if (options['d']) if (options['d'])
DfaEndFunction(); DfaEndFunction();
#endif DATAFLOW #endif DATAFLOW
prc_exit(); prc_exit();
C_ret((arith)0); C_asp(-func_size); /* arbitrary return value */
if (return_expr_occurred != 0) { C_df_ilb(return_label);
C_df_ilb(return_label); prc_exit();
prc_exit(); if (func_res_label != 0) {
if (func_res_label != 0) { C_lae_dlb(func_res_label, (arith)0);
C_lae_dlb(func_res_label, (arith)0); store_block(func_size, func_tp->tp_align);
store_block(func_tp->tp_size, func_tp->tp_align); C_lae_dlb(func_res_label, (arith)0);
C_lae_dlb(func_res_label, (arith)0); C_ret(pointer_size);
C_ret(pointer_size);
}
else
C_ret(ATW(func_tp->tp_size));
} }
#ifndef NOFLOAT else
if (fp_used && mes_flt_given == 0) { C_ret(func_size);
/* floating point used */
C_ms_flt(); /* getting the number of "local" bytes is posponed until here,
mes_flt_given++; because copying the function result in "func_res_label" may
} need temporaries! However, local_level is now L_FORMAL2, because
#endif NOFLOAT 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 */ C_ms_par(fbytes); /* # bytes for formals */
if (sp_occurred[SP_SETJMP]) { /* indicate use of "setjmp" */ if (sp_occurred[SP_SETJMP]) { /* indicate use of "setjmp" */
C_ms_gto(); C_ms_gto();
sp_occurred[SP_SETJMP] = 0; 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()
{ {
/* do_return generates a direct return */ /* do_return handles the case of a return without expression.
/* isn't a jump to the return label smarter ??? */ This version branches to the return label, which is
prc_exit(); probably smarter than generating a direct return.
C_ret((arith)0); Return sequences may be expensive.
*/
C_asp(-func_size); /* arbitrary return value */
C_bra(return_label);
} }
do_return_expr(expr) do_return_expr(expr)
@ -290,7 +310,7 @@ do_return_expr(expr)
ch7cast(&expr, RETURN, func_tp); ch7cast(&expr, RETURN, func_tp);
code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL); code_expr(expr, RVAL, TRUE, NO_LABEL, NO_LABEL);
C_bra(return_label); C_bra(return_label);
return_expr_occurred = 1; /* return_expr_occurred = 1; */
} }
code_declaration(idf, expr, lvl, sc) code_declaration(idf, expr, lvl, sc)
@ -322,7 +342,6 @@ code_declaration(idf, expr, lvl, sc)
while at the same time forbidding while at the same time forbidding
extern int a = 5; extern int a = 5;
*/ */
char *text = idf->id_text;
register struct def *def = idf->id_def; register struct def *def = idf->id_def;
register arith size = def->df_type->tp_size; register arith size = def->df_type->tp_size;
int def_sc = def->df_sc; int def_sc = def->df_sc;
@ -330,7 +349,7 @@ code_declaration(idf, expr, lvl, sc)
if (def_sc == TYPEDEF) /* no code for typedefs */ if (def_sc == TYPEDEF) /* no code for typedefs */
return; return;
if (sc == EXTERN && expr && !is_anon_idf(idf)) 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 */ if (lvl == L_GLOBAL) { /* global variable */
/* is this an allocating declaration? */ /* is this an allocating declaration? */
if ( (sc == 0 || sc == STATIC) if ( (sc == 0 || sc == STATIC)
@ -339,12 +358,11 @@ code_declaration(idf, expr, lvl, sc)
) )
def->df_alloc = ALLOC_SEEN; def->df_alloc = ALLOC_SEEN;
if (expr) { /* code only if initialized */ if (expr) { /* code only if initialized */
#ifdef USE_TMP #ifndef USE_TMP
if (options['N']) code_scope(idf->id_text, def);
#endif USE_TMP #endif USE_TMP
code_scope(text, def);
def->df_alloc = ALLOC_DONE; def->df_alloc = ALLOC_DONE;
C_df_dnam(text); C_df_dnam(idf->id_text);
} }
} }
else else
@ -364,7 +382,7 @@ code_declaration(idf, expr, lvl, sc)
} }
else { /* produce blank space */ else { /* produce blank space */
if (size <= 0) { if (size <= 0) {
error("size of %s unknown", text); error("size of %s unknown", idf->id_text);
size = (arith)0; size = (arith)0;
} }
C_bss_cst(ATW(size), (arith)0, 1); C_bss_cst(ATW(size), (arith)0, 1);
@ -374,10 +392,9 @@ code_declaration(idf, expr, lvl, sc)
case GLOBAL: case GLOBAL:
case IMPLICIT: case IMPLICIT:
/* we are sure there is no expression */ /* we are sure there is no expression */
#ifdef USE_TMP #ifndef USE_TMP
if (options['N']) code_scope(idf->id_text, def);
#endif USE_TMP #endif USE_TMP
code_scope(text, def);
break; break;
case AUTO: case AUTO:
case REGISTER: case REGISTER:
@ -399,8 +416,8 @@ loc_init(expr, id)
expression expr to the local variable described by id. expression expr to the local variable described by id.
It frees the expression afterwards. It frees the expression afterwards.
*/ */
register struct type *tp = id->id_def->df_type;
register struct expr *e = expr; register struct expr *e = expr;
register struct type *tp = id->id_def->df_type;
ASSERT(id->id_def->df_sc != STATIC); ASSERT(id->id_def->df_sc != STATIC);
switch (tp->tp_fund) { switch (tp->tp_fund) {
@ -446,10 +463,9 @@ bss(idf)
*/ */
arith size = idf->id_def->df_type->tp_size; arith size = idf->id_def->df_type->tp_size;
#ifdef USE_TMP #ifndef USE_TMP
if (options['N'])
#endif USE_TMP
code_scope(idf->id_text, idf->id_def); code_scope(idf->id_text, idf->id_def);
#endif USE_TMP
/* Since bss() is only called if df_alloc is non-zero, and /* Since bss() is only called if df_alloc is non-zero, and
since df_alloc is only non-zero if size >= 0, we have: 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 && if (tp->tp_size != int_size &&
(tp->tp_fund == CHAR || tp->tp_fund == SHORT) (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); ??? /* conversion(int_type, df->df_type); ???
No, you can't do this on the stack! (CJ) No, you can't do this on the stack! (CJ)
*/ */
C_lal(df->df_address); StoreLocal(df->df_address, tp->tp_size);
C_sti(tp->tp_size);
df->df_register = REG_NONE;
} }
} }
@ -563,15 +577,15 @@ unstack_stmt()
free_stmt_block(sbp); free_stmt_block(sbp);
} }
static label l1; static label prc_name;
prc_entry(name) prc_entry(name)
char *name; char *name;
{ {
if (options['p']) { 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_rom_scon(name, (arith) (strlen(name) + 1));
C_lae_dlb(l1, (arith) 0); C_lae_dlb(prc_name, (arith) 0);
C_cal("procentry"); C_cal("procentry");
C_asp(pointer_size); C_asp(pointer_size);
} }
@ -580,7 +594,7 @@ prc_entry(name)
prc_exit() prc_exit()
{ {
if (options['p']) { if (options['p']) {
C_lae_dlb(l1, (arith) 0); C_lae_dlb(prc_name, (arith) 0);
C_cal("procexit"); C_cal("procexit");
C_asp(pointer_size); C_asp(pointer_size);
} }

View file

@ -15,7 +15,6 @@ struct def { /* for ordinary tags */
FORMAL, AUTO, FORMAL, AUTO,
ENUM, LABEL ENUM, LABEL
*/ */
int df_register; /* REG_NONE, REG_DEFAULT or REG_BONUS */
char df_initialized; /* an initialization has been generated */ char df_initialized; /* an initialization has been generated */
char df_alloc; /* 0, ALLOC_SEEN or ALLOC_DONE */ char df_alloc; /* 0, ALLOC_SEEN or ALLOC_DONE */
char df_used; /* set if idf is used */ 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_SEEN 1 /* an allocating declaration has been seen */
#define ALLOC_DONE 2 /* the allocating declaration has been done */ #define ALLOC_DONE 2 /* the allocating declaration has been done */
#define REG_NONE 0 /* no register candidate */ #define REG_DEFAULT 0 /* register candidate, not declared as such */
#define REG_DEFAULT 1 /* register candidate, not declared as such */
#define REG_BONUS 10 /* register candidate, declared as such */ #define REG_BONUS 10 /* register candidate, declared as such */
/* ALLOCDEF "def" 50 */ /* ALLOCDEF "def" 50 */

View file

@ -167,7 +167,6 @@ dumpdefs(def, opt)
print("L%d: %s %s%s%s%s%s %lo;", print("L%d: %s %s%s%s%s%s %lo;",
def->df_level, def->df_level,
symbol2str(def->df_sc), symbol2str(def->df_sc),
(def->df_register != REG_NONE) ? "reg " : "",
def->df_initialized ? "init'd " : "", def->df_initialized ? "init'd " : "",
def->df_used ? "used " : "", def->df_used ? "used " : "",
type2str(def->df_type), type2str(def->df_type),

View file

@ -9,7 +9,6 @@
#include <em.h> #include <em.h>
#include "nopp.h" #include "nopp.h"
#include "use_tmp.h"
#include "errout.h" #include "errout.h"
#include "debug.h" #include "debug.h"
@ -116,13 +115,7 @@ fatal(fmt, args)
char *fmt; char *fmt;
int args; int args;
{ {
#ifdef USE_TMP if (C_busy()) C_close();
extern char *tmpfile; /* main.c */
if (tmpfile)
sys_remove(tmpfile); /* may not successful! */
#endif USE_TMP
_error(FATAL, NILEXPR, fmt, &args); _error(FATAL, NILEXPR, fmt, &args);
sys_stop(S_EXIT); sys_stop(S_EXIT);
} }

View file

@ -7,6 +7,7 @@
#include "nofloat.h" #include "nofloat.h"
#include <em.h> #include <em.h>
#include <em_reg.h>
#include "debug.h" #include "debug.h"
#include "nobitfield.h" #include "nobitfield.h"
#include "dataflow.h" #include "dataflow.h"
@ -31,7 +32,8 @@
char *symbol2str(); char *symbol2str();
char *long2str(); 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 /* EVAL() is the main expression-tree evaluator, which turns
any legal expression tree into EM code. Parameters: any legal expression tree into EM code. Parameters:
@ -366,7 +368,7 @@ EVAL(expr, val, code, true_label, false_label)
case PLUSPLUS: case PLUSPLUS:
case MINMIN: case MINMIN:
{ {
arith old_offset, tmp; arith tmp;
int compl; /* Complexity of left operand */ int compl; /* Complexity of left operand */
int newcode = left->ex_type->tp_size > 0; /* CJ */ int newcode = left->ex_type->tp_size > 0; /* CJ */
#ifndef NOBITFIELD #ifndef NOBITFIELD
@ -389,10 +391,9 @@ EVAL(expr, val, code, true_label, false_label)
compl = 2; /* otherwise */ compl = 2; /* otherwise */
EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL); EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL);
if (newcode) { if (newcode) {
tmp = tmp_pointer_var(&old_offset); tmp = LocalPtrVar();
C_dup(pointer_size); C_dup(pointer_size);
C_lal(tmp); StoreLocal(tmp, pointer_size);
C_sti(pointer_size);
C_loi(left->ex_type->tp_size); C_loi(left->ex_type->tp_size);
} }
} }
@ -423,15 +424,13 @@ EVAL(expr, val, code, true_label, false_label)
} }
} }
else { else {
C_lal(tmp); /* always init'd */ LoadLocal(tmp, pointer_size);
C_loi(pointer_size);
C_sti(left->ex_type->tp_size); C_sti(left->ex_type->tp_size);
if (dupval) { if (dupval) {
C_lal(tmp); LoadLocal(tmp, pointer_size);
C_loi(pointer_size);
C_loi(left->ex_type->tp_size); C_loi(left->ex_type->tp_size);
} }
free_tmp_var(old_offset); FreeLocal(tmp);
} }
} }
break; break;
@ -477,7 +476,7 @@ 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);
load_block(tp->tp_size, tp->tp_align); load_block(tp->tp_size, word_align);
} }
else else
C_lfr(ATW(tp->tp_size)); 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. /* store_val() generates code for a store operation.
There are four ways of storing data: There are four ways of storing data:
- into a global variable - into a global variable
@ -828,15 +800,11 @@ store_val(vl, tp)
} }
else { else {
ASSERT(df->df_sc != STATIC); ASSERT(df->df_sc != STATIC);
if (inword) if (inword || indword)
C_stl(df->df_address + val); StoreLocal(df->df_address + val, size);
else
if (indword)
C_sdl(df->df_address + val);
else { else {
C_lal(df->df_address + val); AddrLocal(df->df_address + val);
store_block(size, tpalign); store_block(size, tpalign);
df->df_register = REG_NONE;
} }
} }
} }
@ -943,21 +911,16 @@ load_val(expr, rlval)
else { else {
ASSERT(df->df_sc != STATIC); ASSERT(df->df_sc != STATIC);
if (rvalue) { if (rvalue) {
if (inword) if (inword || indword)
C_lol(df->df_address + val); LoadLocal(df->df_address + val, size);
else
if (indword)
C_ldl(df->df_address + val);
else { else {
C_lal(df->df_address + val); AddrLocal(df->df_address + val);
load_block(size, tpalign); load_block(size, tpalign);
df->df_register = REG_NONE;
} }
} }
else { else {
C_lal(df->df_address); AddrLocal(df->df_address);
C_adp(val); C_adp(val);
df->df_register = REG_NONE;
} }
} }
} }

View file

@ -9,6 +9,7 @@
#ifndef NOBITFIELD #ifndef NOBITFIELD
#include <em.h> #include <em.h>
#include <em_reg.h>
#include "debug.h" #include "debug.h"
#include "arith.h" #include "arith.h"
#include "type.h" #include "type.h"
@ -18,10 +19,11 @@
#include "assert.h" #include "assert.h"
#include "expr.h" #include "expr.h"
#include "sizes.h" #include "sizes.h"
#include "align.h"
#include "Lpars.h" #include "Lpars.h"
#include "field.h" #include "field.h"
arith tmp_pointer_var(); /* eval.c */ arith NewLocal(); /* util.c */
char *symbol2str(); /* symbol2str.c */ char *symbol2str(); /* symbol2str.c */
/* Eval_field() evaluates expressions involving bit fields. /* Eval_field() evaluates expressions involving bit fields.
@ -45,7 +47,7 @@ eval_field(expr, code)
register struct expr *rightop = expr->OP_RIGHT; register struct expr *rightop = expr->OP_RIGHT;
register struct field *fd = leftop->ex_type->tp_field; register struct field *fd = leftop->ex_type->tp_field;
struct type *tp = leftop->ex_type->tp_up; struct type *tp = leftop->ex_type->tp_up;
arith old_offset, tmpvar; arith tmpvar;
struct type *atype = tp->tp_unsigned ? uword_type : word_type; struct type *atype = tp->tp_unsigned ? uword_type : word_type;
arith asize = atype->tp_size; arith asize = atype->tp_size;
@ -75,18 +77,17 @@ eval_field(expr, code)
store_val(&(leftop->ex_object.ex_value), atype); store_val(&(leftop->ex_object.ex_value), atype);
} }
else { /* complex case */ 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); EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_dup(pointer_size); C_dup(pointer_size);
C_lal(tmpvar); StoreLocal(tmpvar, pointer_size);
C_sti(pointer_size);
C_loi(asize); C_loi(asize);
C_and(asize); C_and(asize);
C_ior(asize); C_ior(asize);
C_lal(tmpvar); LoadLocal(tmpvar, pointer_size);
C_loi(pointer_size);
C_sti(asize); C_sti(asize);
free_tmp_var(old_offset); FreeLocal(tmpvar);
} }
} }
else { /* treat ++F as F += 1 and --F as F -= 1 */ 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 */ if (leftop->ex_depth == 0) /* simple case */
load_val(leftop, RVAL); load_val(leftop, RVAL);
else { /* complex case */ 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); EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
C_dup(pointer_size); C_dup(pointer_size);
C_lal(tmpvar); StoreLocal(tmpvar, pointer_size);
C_sti(pointer_size);
C_loi(asize); C_loi(asize);
} }
if (atype->tp_unsigned) { if (atype->tp_unsigned) {
@ -146,15 +147,13 @@ eval_field(expr, code)
store_val(&(leftop->ex_object.ex_value), atype); store_val(&(leftop->ex_object.ex_value), atype);
} }
else { else {
C_lal(tmpvar); LoadLocal(tmpvar, pointer_size);
C_loi(pointer_size);
C_loi(asize); C_loi(asize);
C_and(asize); C_and(asize);
C_ior(asize); C_ior(asize);
C_lal(tmpvar); LoadLocal(tmpvar, pointer_size);
C_loi(pointer_size);
C_sti(asize); C_sti(asize);
free_tmp_var(old_offset); FreeLocal(tmpvar);
} }
} }
if (code == TRUE) { if (code == TRUE) {

View file

@ -5,6 +5,7 @@
/* $Header$ */ /* $Header$ */
/* IDENTIFIER FIDDLING & SYMBOL TABLE HANDLING */ /* IDENTIFIER FIDDLING & SYMBOL TABLE HANDLING */
#include <em_reg.h>
#include "nofloat.h" #include "nofloat.h"
#include "debug.h" #include "debug.h"
#include "idfsize.h" #include "idfsize.h"
@ -31,6 +32,7 @@
int idfsize = IDFSIZE; int idfsize = IDFSIZE;
extern char options[]; extern char options[];
extern arith NewLocal();
char sp_occurred[SP_TOTAL]; /* indicate occurrence of special id */ 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_formal_array = formal_array;
def->df_sc = sc; def->df_sc = sc;
def->df_level = L_FORMAL2; /* CJ */ def->df_level = L_FORMAL2; /* CJ */
if (sc == REGISTER) def->df_register = REG_BONUS;
} }
else else
if ( lvl >= L_LOCAL && if ( lvl >= L_LOCAL &&
@ -318,8 +319,6 @@ declare_idf(ds, dc, lvl)
newdef->df_level = lvl; newdef->df_level = lvl;
newdef->df_type = type; newdef->df_type = type;
newdef->df_sc = sc; newdef->df_sc = sc;
if (lvl == L_FORMAL1) /* CJ */
newdef->df_register = REG_DEFAULT;
/* link it into the name list in the proper place */ /* link it into the name list in the proper place */
idf->id_def = newdef; idf->id_def = newdef;
update_ahead(idf); update_ahead(idf);
@ -340,14 +339,13 @@ declare_idf(ds, dc, lvl)
idf->id_text); idf->id_text);
/** type = idf->id_def->df_type = int_type; **/ /** type = idf->id_def->df_type = int_type; **/
} }
newdef->df_register =
(sc == REGISTER) ? REG_BONUS
: REG_DEFAULT;
newdef->df_address = newdef->df_address =
stl->sl_max_block = NewLocal(type->tp_size,
stl->sl_local_offset = type->tp_align,
-align(-stl->sl_local_offset + regtype(type),
type->tp_size, type->tp_align); (sc == REGISTER) ? REG_BONUS
: REG_DEFAULT
);
break; break;
case STATIC: case STATIC:
newdef->df_address = (arith) data_label(); newdef->df_address = (arith) data_label();
@ -615,10 +613,33 @@ declare_formals(fp)
formal_cvt(def); /* cvt int to char or short, if necessary */ formal_cvt(def); /* cvt int to char or short, if necessary */
se = se->next; se = se->next;
def->df_level = L_FORMAL2; /* CJ */ 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; *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) add_def(idf, sc, tp, lvl)
struct idf *idf; struct idf *idf;
struct type *tp; struct type *tp;

View file

@ -125,20 +125,9 @@ char *source = 0;
char *nmlist = 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) compile(argc, argv)
char *argv[]; char *argv[];
{ {
#ifdef USE_TMP
char tmpf[256];
#endif
char *result; char *result;
register char *destination = 0; register char *destination = 0;
@ -175,14 +164,6 @@ compile(argc, argv)
FileName = "standard input"; 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) if (destination && strcmp(destination, "-") == 0)
destination = 0; destination = 0;
if (!InsertFile(source, (char **) 0, &result)) /* read the source file */ if (!InsertFile(source, (char **) 0, &result)) /* read the source file */
@ -204,25 +185,15 @@ compile(argc, argv)
#endif DEBUG #endif DEBUG
{ {
#ifdef USE_TMP
if (!options['N']) {
init_code(tmpfile);
}
else
#endif USE_TMP
init_code(destination); init_code(destination);
/* compile the source text */ /* compile the source text */
C_program(); C_program();
end_code();
#ifdef USE_TMP #ifdef USE_TMP
if (! options['N']) { prepend_scopes();
prepend_scopes(destination);
AppendFile(tmpfile, destination);
sys_remove(tmpfile);
}
#endif USE_TMP #endif USE_TMP
end_code();
#ifdef DEBUG #ifdef DEBUG
if (options['u']) { if (options['u']) {
@ -399,33 +370,6 @@ preprocess()
#endif NOPP #endif NOPP
#endif DEBUG #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() No_Mem()
{ {
fatal("out of memory"); fatal("out of memory");

View file

@ -30,9 +30,6 @@ extern int inc_total;
extern char options[]; extern char options[];
extern int idfsize; extern int idfsize;
#ifdef USE_TMP
extern char *tmpfdir; /* main.c */
#endif USE_TMP
int txt2int(); int txt2int();
@ -163,14 +160,6 @@ deleted, is now a debug-flag
fatal("maximum identifier length is %d", IDFSIZE); fatal("maximum identifier length is %d", IDFSIZE);
break; break;
case 'N' :
#ifdef USE_TMP
options['N'] = 1;
#else USE_TMP
warning("-N option ignored");
#endif USE_TMP
break;
#ifdef ___XXX___ #ifdef ___XXX___
case 'P' : /* run preprocessor stand-alone, without #'s */ case 'P' : /* run preprocessor stand-alone, without #'s */
#ifndef NOPP #ifndef NOPP
@ -183,15 +172,17 @@ deleted, is now a debug-flag
#endif ___XXX___ #endif ___XXX___
#ifdef USE_TMP #ifdef USE_TMP
case 'T' : case 'T' : {
extern char *C_tmpdir;
if (*text) if (*text)
tmpfdir = text; C_tmpdir = text;
else else
tmpfdir = "."; C_tmpdir = ".";
#else USE_TMP #else USE_TMP
warning("-T option ignored"); warning("-T option ignored");
#endif USE_TMP #endif USE_TMP
break; break;
}
case 'U' : { /* -Uname : undefine predefined */ case 'U' : { /* -Uname : undefine predefined */
#ifndef NOPP #ifndef NOPP

View file

@ -180,10 +180,10 @@ function(struct declarator *dc;)
{ {
declare_formals(&fbytes); declare_formals(&fbytes);
} }
compound_statement(&nbytes) compound_statement
{ {
end_proc(fbytes);
unstack_level(); /* L_FORMAL2 declarations */ unstack_level(); /* L_FORMAL2 declarations */
unstack_level(); /* L_FORMAL1 declarations */ unstack_level(); /* L_FORMAL1 declarations */
end_proc(fbytes, nbytes);
} }
; ;

View file

@ -8,7 +8,6 @@
#include "nofloat.h" #include "nofloat.h"
#include <system.h> #include <system.h>
#include <em.h> #include <em.h>
#include <em_reg.h>
#include "debug.h" #include "debug.h"
#include "botch_free.h" #include "botch_free.h"
#include <alloc.h> #include <alloc.h>
@ -50,8 +49,7 @@ stack_level() {
loclev->sl_next = stl; loclev->sl_next = stl;
stl->sl_previous = loclev; stl->sl_previous = loclev;
stl->sl_level = ++level; stl->sl_level = ++level;
stl->sl_local_offset = stl->sl_max_block = loclev->sl_max_block;
stl->sl_max_block = loclev->sl_local_offset;
local_level = stl; local_level = stl;
} }
@ -115,36 +113,8 @@ unstack_level()
/* unlink it from the def list under the idf block */ /* unlink it from the def list under the idf block */
if (def->df_sc == LABEL) if (def->df_sc == LABEL)
unstack_label(idf); unstack_label(idf);
else else if (def->df_sc == REGISTER || def->df_sc == AUTO)
if (level == L_LOCAL || level == L_FORMAL1) { FreeLocal(def->df_address);
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
);
}
}
idf->id_def = def->next; idf->id_def = def->next;
free_def(def); free_def(def);
update_ahead(idf); update_ahead(idf);
@ -173,9 +143,7 @@ unstack_level()
*/ */
lastlvl = local_level; lastlvl = local_level;
local_level = local_level->sl_previous; local_level = local_level->sl_previous;
if ( level > L_LOCAL if (level >= L_LOCAL) {
&& lastlvl->sl_max_block < local_level->sl_max_block
) {
local_level->sl_max_block = lastlvl->sl_max_block; local_level->sl_max_block = lastlvl->sl_max_block;
} }
free_stack_level(lastlvl); free_stack_level(lastlvl);

View file

@ -37,7 +37,7 @@ statement
| |
label ':' statement label ':' statement
| |
compound_statement((arith *)0) compound_statement
| |
if_statement if_statement
| |
@ -353,7 +353,7 @@ jump
} }
; ;
compound_statement(arith *nbytes;): compound_statement:
'{' '{'
{ {
stack_level(); stack_level();
@ -366,8 +366,6 @@ compound_statement(arith *nbytes;):
]* ]*
'}' '}'
{ {
if (nbytes)
*nbytes = (- local_level->sl_max_block);
unstack_level(); unstack_level();
} }
; ;

211
lang/cem/cemcom/util.c Normal file
View file

@ -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);
}

10
lang/cem/cemcom/util.str Normal file
View file

@ -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 */