!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
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 \
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
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)
switch.h: make.allocd
type.h: make.allocd
estack.h: make.allocd
+util.h: make.allocd
depend: Cfiles
sed '/^#AUTOAUTO/,$$d' makefile >makefile.new
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
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
!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
/* 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"
#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
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 */
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 */
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);
"& 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;
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();
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;
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);
}
}
/* 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);
}
#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;
code_scope(id->id_text, df);
se = se->next;
}
- C_close();
+ C_endpart(tmp_id);
}
#endif USE_TMP
}
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;
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
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;
*/
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) {
}
}
-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:
- 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)
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)
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;
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)
)
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
}
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);
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:
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) {
*/
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:
*/
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);
}
}
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);
}
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);
}
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 */
#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 */
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),
#include <em.h>
#include "nopp.h"
-#include "use_tmp.h"
#include "errout.h"
#include "debug.h"
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);
}
#include "nofloat.h"
#include <em.h>
+#include <em_reg.h>
#include "debug.h"
#include "nobitfield.h"
#include "dataflow.h"
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:
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
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);
}
}
}
}
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;
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));
}
}
-/* 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
}
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;
}
}
}
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;
}
}
}
#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.
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;
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 */
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) {
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) {
/* $Header$ */
/* IDENTIFIER FIDDLING & SYMBOL TABLE HANDLING */
+#include <em_reg.h>
#include "nofloat.h"
#include "debug.h"
#include "idfsize.h"
int idfsize = IDFSIZE;
extern char options[];
+extern arith NewLocal();
char sp_occurred[SP_TOTAL]; /* indicate occurrence of special id */
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 &&
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);
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();
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;
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;
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 */
#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']) {
#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");
extern char options[];
extern int idfsize;
-#ifdef USE_TMP
-extern char *tmpfdir; /* main.c */
-#endif USE_TMP
int txt2int();
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
#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
{
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);
}
;
#include "nofloat.h"
#include <system.h>
#include <em.h>
-#include <em_reg.h>
#include "debug.h"
#include "botch_free.h"
#include <alloc.h>
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;
}
/* 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);
*/
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);
|
label ':' statement
|
- compound_statement((arith *)0)
+ compound_statement
|
if_statement
|
}
;
-compound_statement(arith *nbytes;):
+compound_statement:
'{'
{
stack_level();
]*
'}'
{
- if (nbytes)
- *nbytes = (- local_level->sl_max_block);
unstack_level();
}
;
--- /dev/null
+/*
+ * (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);
+}
--- /dev/null
+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 */