123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* @(#)comm7.c 1.10 */
- /*
- * miscellaneous
- */
- #include "comm0.h"
- #include "comm1.h"
- #include "y.tab.h"
- valu_t load(item_t *ip)
- {
- #ifdef ASLD
- int typ;
- typ = ip->i_type & S_TYP;
- if ((typ -= S_MIN) < 0) /* S_UND or S_ABS */
- return(ip->i_valu);
- return(ip->i_valu + sect[typ].s_base);
- #else
- if ((ip->i_type & S_TYP) == S_UND || (ip->i_type & S_COM)) {
- if (pass == PASS_3) {
- if (relonami != 0)
- serror("relocation error");
- relonami = ip->i_valu+1;
- }
- return(0);
- }
- return(ip->i_valu);
- #endif
- }
- int store(item_t *ip, valu_t val)
- {
- #ifdef ASLD
- int typ;
- typ = ip->i_type & S_TYP;
- if ((typ -= S_MIN) >= 0)
- val -= sect[typ].s_base;
- #else
- if ((ip->i_type & S_TYP) == S_UND)
- return(0);
- #endif
- assert(pass != PASS_3 || (ip->i_type & S_VAR) || ip->i_valu == val);
- ip->i_valu = val;
- return(1);
- }
- char *remember(char *s)
- {
- char *p;
- int n;
- static nleft = 0;
- static char *next;
- p = s;
- n = 0;
- do
- n++;
- while (*p++);
- if ((nleft -= n) < 0) {
- next = malloc(MEMINCR);
- if (next == 0)
- fatal("out of memory");
- nleft = (MEMINCR / sizeof(char)) - n;
- assert(nleft >= 0);
- }
- p = next;
- while ( (*p++ = *s++) )
- ;
- s = next;
- next = p;
- return(s);
- }
- int combine(int typ1, int typ2, int op)
- {
- switch (op) {
- case '+':
- if (typ1 == S_ABS)
- return(typ2);
- if (typ2 == S_ABS)
- return(typ1);
- break;
- case '-':
- if (typ2 == S_ABS)
- return(typ1);
- if ((typ1 & ~S_DOT) == (typ2 & ~S_DOT) && typ1 != S_UND)
- return(S_ABS|S_VAR);
- break;
- case '>':
- if (typ1 == S_ABS && typ2 == S_ABS)
- return(S_ABS);
- if (
- ((typ1 & ~S_DOT) == (typ2 & ~S_DOT) && typ1 != S_UND)
- || (typ1 == S_ABS)
- || (typ2 == S_ABS)
- )
- return(S_ABS|S_VAR);
- break;
- default:
- if (typ1 == S_ABS && typ2 == S_ABS)
- return(S_ABS);
- break;
- }
- if (pass != PASS_1)
- serror("illegal operator");
- return(S_UND);
- }
- #ifdef LISTING
- int printx(int ndig, valu_t val)
- {
- static char buf[8];
- char *p;
- int c, n;
- p = buf; n = ndig;
- do {
- *p++ = (int) val & 017;
- val >>= 4;
- } while (--n);
- do {
- c = "0123456789ABCDEF"[*(unsigned char *)--p];
- putchar(c);
- } while (p > buf);
- return(ndig);
- }
- #endif
- #ifdef LISTING
- void listline(int textline)
- {
- int c;
- if ((listflag & 4) && (c = getc(listfile)) != '\n' && textline) {
- if (listcolm >= 24)
- printf(" \\\n\t\t\t");
- else
- do {
- putchar('\t');
- listcolm += 8;
- } while (listcolm < 24);
- do {
- assert(c != EOF);
- putchar(c);
- } while ((c = getc(listfile)) != '\n');
- }
- if (listflag & 7) {
- putchar('\n');
- fflush(stdout);
- }
- listeoln = 1;
- listcolm = 0;
- listflag = listtemp;
- }
- #endif /* LISTING */
- /* ---------- code optimization ---------- */
- #ifdef THREE_PASS
- #define PBITTABSZ 128
- static char *pbittab[PBITTABSZ];
- int small(int fitsmall, int gain)
- {
- int bit;
- char *p;
- if (DOTSCT == NULL)
- nosect();
- if (bflag)
- return(0);
- if (nbits == BITCHUNK) {
- bitindex++;
- nbits = 0;
- if (bitindex == PBITTABSZ) {
- static int w_given;
- if (pass == PASS_1 && ! w_given) {
- w_given = 1;
- warning("bit table overflow");
- }
- return(0);
- }
- if (pbittab[bitindex] == 0 && pass == PASS_1) {
- if ((pbittab[bitindex] = calloc(MEMINCR, 1)) == 0) {
- static int w2_given;
- if (!w2_given) {
- w2_given = 1;
- warning("out of space for bit table");
- }
- }
- }
- if (pbittab[bitindex] == 0)
- return (0);
- }
- bit = 1 << (nbits&7);
- p = pbittab[bitindex]+(nbits>>3);
- nbits++;
- switch (pass) {
- case PASS_1:
- return(0);
- case PASS_2:
- if (fitsmall) {
- DOTGAIN += gain;
- *p |= bit;
- }
- return(fitsmall);
- case PASS_3:
- assert(fitsmall || (*p & bit) == 0);
- return(*p & bit);
- }
- /*NOTREACHED*/
- return 0;
- }
- #endif
- /* ---------- output ---------- */
- void emit1(int arg)
- {
- static int olddottyp = -1;
- #ifdef LISTING
- if (listeoln) {
- if (listflag & 1) {
- listcolm += printx(VALWIDTH, (valu_t)DOTVAL);
- listcolm++;
- putchar(' ');
- }
- listeoln = 0;
- }
- if (listflag & 2)
- listcolm += printx(2, (valu_t) arg);
- #endif
- switch (pass) {
- case PASS_1:
- if (DOTSCT == NULL)
- nosect();
- /* no break */
- case PASS_2:
- DOTSCT->s_zero = 0;
- break;
- case PASS_3:
- if (DOTTYP != olddottyp) {
- wr_outsect(DOTTYP-S_MIN);
- olddottyp = DOTTYP;
- }
- while (DOTSCT->s_zero) {
- wr_putc(0);
- DOTSCT->s_zero--;
- }
- wr_putc(arg);
- break;
- }
- DOTVAL++;
- }
- void emit2(int arg)
- {
- #ifdef BYTES_REVERSED
- emit1((arg>>8)); emit1(arg);
- #else
- emit1(arg); emit1((arg>>8));
- #endif
- }
- void emit4(long arg)
- {
- #ifdef WORDS_REVERSED
- emit2((int)(arg>>16)); emit2((int)(arg));
- #else
- emit2((int)(arg)); emit2((int)(arg>>16));
- #endif
- }
- void emitx(valu_t val, int n)
- {
- switch (n) {
- case 1:
- emit1((int)val); break;
- case 2:
- #ifdef BYTES_REVERSED
- emit1(((int)val>>8)); emit1((int)val);
- #else
- emit1((int)val); emit1(((int)val>>8));
- #endif
- break;
- case 4:
- #ifdef WORDS_REVERSED
- emit2((int)(val>>16)); emit2((int)(val));
- #else
- emit2((int)(val)); emit2((int)(val>>16));
- #endif
- break;
- default:
- assert(0);
- }
- }
- void emitstr(int zero)
- {
- int i;
- char *p;
- p = stringbuf;
- i = stringlen;
- while (--i >= 0)
- emit1(*p++);
- if (zero)
- emit1(0);
- }
- /* ---------- Error checked file I/O ---------- */
- void ffreopen(char *s, FILE *f)
- {
- if (freopen(s, "r", f) == NULL)
- fatal("can't reopen %s", s);
- }
- FILE *ffcreat(char *s)
- {
- FILE *f;
- if ((f = fopen(s, "w")) == NULL)
- fatal("can't create %s", s);
- return(f);
- }
- #ifndef TMPDIR
- #define TMPDIR "/tmp"
- #endif
- char *tmp_dir = TMPDIR;
- FILE *fftemp(char *path, char *tail)
- {
- char *dir;
- if ((dir = getenv("TMPDIR")) == NULL)
- dir = tmp_dir;
- sprintf(path, "%s/%s", dir, tail);
- return(ffcreat(mktemp(path)));
- }
- /* ---------- Error handling ---------- */
- /*VARARGS*/
- void yyerror(char *str){} /* we will do our own error printing */
- /* VARARGS1 */
- static void vdiag(char *tail, char *s, va_list ap)
- {
- fflush(stdout);
- if (modulename)
- fprintf(stderr, "\"%s\", line %ld: ", modulename, lineno);
- else
- fprintf(stderr, "%s: ", progname);
- vfprintf(stderr, s, ap);
- fprintf(stderr, "%s", tail);
- }
- void nosect()
- {
- fatal("no sections");
- }
- void wr_fatal()
- {
- fatal("write error");
- }
- /* VARARGS1 */
- void fatal(char *s, ...)
- {
- va_list ap;
- nerrors++;
- va_start(ap, s);
- vdiag(" (fatal)\n", s, ap);
- va_end(ap);
- stop(0);
- }
- #if DEBUG == 2
- void assert2(char *file, int line)
- {
- fatal("assertion failed (%s, %d)", file, line);
- }
- #endif
- #if DEBUG == 1
- void assert1()
- {
- vdiag(" (fatal)\n", "assertion failed");
- abort();
- }
- #endif
- /* VARARGS1 */
- void serror(char *s, ...)
- {
- va_list ap;
- nerrors++;
- va_start(ap, s);
- vdiag("\n", s, ap);
- va_end(ap);
- }
- /* VARARGS1 */
- void warning(char *s, ...)
- {
- va_list ap;
- va_start(ap, s);
- vdiag(" (warning)\n", s, ap);
- va_end(ap);
- }
- /* VARARGS1 */
- void diag(char *tail, char *s, ...)
- {
- va_list ap;
- va_start(ap, s);
- vdiag(tail, s, ap);
- va_end(ap);
- }
- void nofit()
- {
- if (pass == PASS_3)
- warning("too big");
- }
|