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
|
!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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
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…
Add table
Reference in a new issue