123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* EM CODE OUTPUT ROUTINES */
- /* I/O part of em_code module.
- Also contains C_open, C_close
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "alloc.h"
- #include "em_arith.h"
- #include "insert.h"
- #include "em_private.h"
- int C_ontmpfile = 0;
- int C_sequential = 1;
- Part *C_curr_part;
- void (*C_outpart)(int), (*C_swtout)(void), (*C_swttmp)(void);
- #ifdef INCORE
- char *C_BASE;
- #endif
- File *C_ofp;
- #ifndef INCORE
- File *C_tfr;
- char *C_tmpfile;
- char *strcpy(), *strcat();
- char *C_ibuf = 0;
- long C_current_out;
- #endif
- #if BUFSIZ <= 1024 && BIGMACHINE
- #define BUFFERSIZ 8*BUFSIZ
- #else
- #define BUFFERSIZ BUFSIZ
- #endif
- static char obuf[BUFFERSIZ];
- char *C_top = &obuf[BUFFERSIZ];
- #ifdef INCORE
- char *C_current_out = obuf;
- #else
- char *C_opp = obuf;
- #endif
- void C_flush()
- {
- #ifdef INCORE
- static unsigned int bufsiz;
- if (C_ontmpfile) {
- if (C_BASE == 0) {
- C_BASE = Malloc(BUFFERSIZ);
- bufsiz = BUFFERSIZ;
- C_current_out = C_BASE;
- }
- else {
- C_BASE = Srealloc(C_BASE, (bufsiz << 1));
- C_current_out = C_BASE + bufsiz;
- bufsiz <<= 1;
- }
- C_top = C_BASE + bufsiz;
- return;
- }
- #endif
- if (C_opp != obuf && sys_write(C_ofp, obuf, (int)(C_opp - obuf)) == 0) {
- C_ofp = 0;
- C_failed();
- }
- C_opp = obuf;
- }
- #ifndef INCORE
- #define Xputbyte(c) if (C_ontmpfile) C_current_out++; put(c)
- #else
- #define Xputbyte(c) put(c)
- #endif
- void C_putbyte(int c)
- {
- Xputbyte(c);
- }
- #if BIGMACHINE
- #define C_putbyte Xputbyte
- #endif
- /*ARGSUSED*/
- void C_init(arith w, arith p)
- {
- }
- int C_open(char *nm)
- {
- /* Open file "nm" for output
- */
- if (nm == 0)
- C_ofp = STDOUT; /* standard output */
- else
- if (sys_open(nm, OP_WRITE, &C_ofp) == 0)
- return 0;
- return 1;
- }
- void C_close()
- {
- /* Finish the code-generation.
- */
- #ifndef INCORE
- C_flush();
- if (C_tmpfile) {
- (*C_swttmp)();
- sys_close(C_ofp);
- #else
- if (C_BASE) {
- #endif
- if (C_curr_part) {
- C_curr_part->p_parts->pp_end = C_current_out - C_BASE;
- }
- (*C_swtout)();
- if (! C_sequential) {
- (*C_outpart)(0);
- }
- #ifndef INCORE
- sys_close(C_tfr);
- sys_remove(C_tmpfile);
- if (C_ibuf) free(C_ibuf);
- #else
- free(C_BASE);
- #endif
- }
- C_flush();
- if (C_ofp != STDOUT)
- sys_close(C_ofp);
- C_ofp = 0;
- }
- int C_busy()
- {
- return C_ofp != 0; /* true if code is being generated */
- }
- #ifdef READABLE_EM
- /*
- The C_pt_*() functions serve as formatting functions of the
- various EM language constructs.
- See "Description of a Machine Architecture for use with
- Block Structured Languages" par. 11.2 for the meaning of these
- names.
- */
- void C_magic()
- {
- }
- /*** the readable code generating routines ***/
- static void wrs(char *s)
- {
- while (*s) {
- C_putbyte(*s++);
- }
- }
- void C_pt_dnam(char *s)
- {
- wrs(s);
- }
- void C_pt_ilb(label l)
- {
- char buf[16];
- sprint(buf, "*%ld", (long) l);
- wrs(buf);
- }
- extern char em_mnem[][4];
- extern char em_pseu[][4];
- void C_pt_op(int x)
- {
- C_putbyte(' ');
- wrs(em_mnem[x - sp_fmnem]);
- C_putbyte(' ');
- }
- void C_pt_cst(arith l)
- {
- char buf[16];
- sprint(buf, "%ld", (long) l);
- wrs(buf);
- }
- void C_pt_scon(char *x, arith y)
- {
- char xbuf[1024];
- register char *p;
- char *bts2str();
- C_putbyte('\'');
- p = bts2str(x, (int) y, xbuf);
- while (*p) {
- if (*p == '\'') {
- C_putbyte('\\');
- }
- C_putbyte(*p++);
- }
- C_putbyte('\'');
- }
- void C_pt_ps(int x)
- {
- C_putbyte(' ');
- wrs(em_pseu[x - sp_fpseu]);
- C_putbyte(' ');
- }
- void C_pt_dlb(label l)
- {
- char buf[16];
- sprint(buf, ".%ld", (long) l);
- wrs(buf);
- }
- void C_pt_doff(label l, arith v)
- {
- char buf[16];
- C_pt_dlb(l);
- if (v != 0) {
- sprint(buf,"+%ld", (long) v);
- wrs(buf);
- }
- }
- void C_pt_noff(char *s, arith v)
- {
- char buf[16];
- wrs(s);
- if (v != 0) {
- sprint(buf,"+%ld", (long) v);
- wrs(buf);
- }
- }
- void C_pt_pnam(char *s)
- {
- C_putbyte('$');
- wrs(s);
- }
- void C_pt_dfilb(label l)
- {
- char buf[16];
- sprint(buf, "%ld", (long) l);
- wrs(buf);
- }
- void C_pt_wcon(int sp, char *v, arith sz) /* sp_icon, sp_ucon or sp_fcon with int repr */
- {
- int ch = sp == sp_icon ? 'I' : sp == sp_ucon ? 'U' : 'F';
- wrs(v);
- C_putbyte(ch);
- C_pt_cst(sz);
- }
- void C_pt_nl()
- {
- C_putbyte('\n');
- }
- void C_pt_comma()
- {
- C_putbyte(',');
- }
- void C_pt_ccend()
- {
- C_putbyte('?');
- }
- #else /* READABLE_EM */
- #define put8(x) C_putbyte(x)
- #define put16(x) put8((int) x); put8((int) (x >> 8))
- #define put32(x) put16((int) x); put16((int) (x >> 16))
- /*
- The C_pt_*() functions serve as formatting functions of the
- various EM language constructs.
- See "Description of a Machine Architecture for use with
- Block Structured Languages" par. 11.2 for the meaning of these
- names.
- */
- void C_magic()
- {
- put16(sp_magic);
- }
- /*** the compact code generating routines ***/
- #define fit16i(x) ((x) >= (long)(-0x8000) && (x) <= (long)0x7FFF)
- #define fit8u(x) ((x) <= 0xFF) /* x is already unsigned */
- void C_pt_ilb(label l)
- {
- if (fit8u(l)) {
- put8(sp_ilb1);
- put8((int)l);
- }
- else {
- put8(sp_ilb2);
- put16((int)l);
- }
- }
- void C_pt_dlb(label l)
- {
- if (fit8u(l)) {
- put8(sp_dlb1);
- put8((int)l);
- }
- else {
- put8(sp_dlb2);
- put16((int)l);
- }
- }
- void C_pt_cst(arith l)
- {
- if (l >= (arith) -sp_zcst0 && l < (arith) (sp_ncst0 - sp_zcst0)) {
- /* we can convert 'l' to an int because its value
- can be stored in a byte.
- */
- put8((int)l + (sp_zcst0 + sp_fcst0));
- }
- else
- if (fit16i(l)) { /* the cast from long to int causes no trouble here */
- put8(sp_cst2);
- put16((int) l);
- }
- else {
- put8(sp_cst4);
- put32(l);
- }
- }
- void C_pt_doff(label l, arith v)
- {
- if (v == 0) {
- C_pt_dlb(l);
- }
- else {
- put8(sp_doff);
- C_pt_dlb(l);
- C_pt_cst(v);
- }
- }
- void C_pt_str(char *s)
- {
- register int len;
- C_pt_cst((arith) (len = strlen(s)));
- while (--len >= 0) {
- put8(*s++);
- }
- }
- void C_pt_dnam(char *s)
- {
- put8(sp_dnam);
- C_pt_str(s);
- }
- void C_pt_noff(char *s, arith v)
- {
- if (v == 0) {
- C_pt_dnam(s);
- }
- else {
- put8(sp_doff);
- C_pt_dnam(s);
- C_pt_cst(v);
- }
- }
- void C_pt_pnam(char *s)
- {
- put8(sp_pnam);
- C_pt_str(s);
- }
- void C_pt_wcon(int sp, char *v, arith sz) /* sp_icon, sp_ucon or sp_fcon with int repr */
- {
- /* how 'bout signextension int --> long ??? */
- put8(sp);
- C_pt_cst(sz);
- C_pt_str(v);
- }
- void C_pt_scon(char *b, arith n)
- {
- put8(sp_scon);
- C_pt_cst(n);
- while (--n >= 0) {
- put8(*b++);
- }
- }
- #endif /* READABLE_EM */
|