use new C_insertpart mechanism, other minor changes
This commit is contained in:
parent
2381b2e136
commit
0619d27b8d
19 changed files with 428 additions and 317 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
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);
|
||||
}
|
||||
#ifndef NOFLOAT
|
||||
if (fp_used && mes_flt_given == 0) {
|
||||
/* floating point used */
|
||||
C_ms_flt();
|
||||
mes_flt_given++;
|
||||
}
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#ifndef NOBITFIELD
|
||||
#include <em.h>
|
||||
#include <em_reg.h>
|
||||
#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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
;
|
||||
|
|
211
lang/cem/cemcom/util.c
Normal file
211
lang/cem/cemcom/util.c
Normal 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
10
lang/cem/cemcom/util.str
Normal 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 */
|
Loading…
Reference in a new issue