ack/mach/proto/as/comm7.c

433 lines
6.6 KiB
C
Raw Normal View History

1987-03-10 11:49:39 +00:00
/* $Header$ */
1987-03-09 19:15:41 +00:00
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
1985-04-12 16:56:43 +00:00
/* @(#)comm7.c 1.10 */
/*
* miscellaneous
*/
#include "comm0.h"
#include "comm1.h"
#include "y.tab.h"
#ifndef __STDC__
extern char *sprintf();
#else
/* sprintf should be declared in stdio.h, as returning an int */
#endif
1988-06-28 13:43:54 +00:00
1985-04-12 16:56:43 +00:00
valu_t
load(ip)
register item_t *ip;
{
#ifdef ASLD
register short 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
}
store(ip, val)
register item_t *ip;
valu_t val;
{
#ifdef ASLD
register short 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(s)
register char *s;
{
register char *p;
register n;
static nleft = 0;
static char *next;
p = s;
n = 0;
do
n++;
while (*p++);
if ((nleft -= n) < 0) {
1987-08-06 13:04:20 +00:00
next = malloc(MEMINCR);
if (next == 0)
1985-04-12 16:56:43 +00:00
fatal("out of memory");
nleft = (MEMINCR / sizeof(char)) - n;
assert(nleft >= 0);
}
p = next;
while (*p++ = *s++)
;
s = next;
next = p;
return(s);
}
combine(typ1, typ2, op)
register typ1, typ2;
{
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
printx(ndig, val)
valu_t val;
{
static char buf[8];
register char *p;
register c, n;
p = buf; n = ndig;
do {
*p++ = (int) val & 017;
val >>= 4;
} while (--n);
do {
c = "0123456789ABCDEF"[*--p];
putchar(c);
} while (p > buf);
return(ndig);
}
#endif
#ifdef LISTING
listline(textline)
{
register 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');
}
1988-06-16 09:57:59 +00:00
if (listflag & 7) {
1985-04-12 16:56:43 +00:00
putchar('\n');
1988-06-16 09:57:59 +00:00
fflush(stdout);
}
1985-04-12 16:56:43 +00:00
listeoln = 1;
listcolm = 0;
listflag = listtemp;
}
#endif LISTING
/* ---------- code optimization ---------- */
#ifdef THREE_PASS
1988-06-16 13:24:10 +00:00
#define PBITTABSZ 128
static char *pbittab[PBITTABSZ];
1985-04-12 16:56:43 +00:00
small(fitsmall, gain)
{
register bit;
register char *p;
if (DOTSCT == NULL)
nosect();
if (bflag)
return(0);
1988-06-16 13:24:10 +00:00
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);
1988-06-13 18:01:47 +00:00
}
1988-06-16 13:24:10 +00:00
if (pbittab[bitindex] == 0 && pass == PASS_1) {
if ((pbittab[bitindex] = calloc(MEMINCR, 1)) == 0) {
1988-06-16 13:24:10 +00:00
static int w2_given;
if (!w2_given) {
w2_given = 1;
warning("out of space for bit table");
}
}
}
if (pbittab[bitindex] == 0)
return (0);
1985-04-12 16:56:43 +00:00
}
1988-06-16 13:24:10 +00:00
bit = 1 << (nbits&7);
p = pbittab[bitindex]+(nbits>>3);
1988-06-13 17:57:39 +00:00
nbits++;
1985-04-12 16:56:43 +00:00
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);
}
1986-12-01 15:41:29 +00:00
/*NOTREACHED*/
1985-04-12 16:56:43 +00:00
}
#endif
/* ---------- output ---------- */
emit1(arg)
{
#ifdef LISTING
if (listeoln) {
if (listflag & 1) {
1989-01-19 16:41:55 +00:00
listcolm += printx(VALWIDTH, (valu_t)DOTVAL);
1985-04-12 16:56:43 +00:00
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:
1986-12-01 15:41:29 +00:00
wr_outsect(DOTTYP-S_MIN);
1985-04-12 16:56:43 +00:00
while (DOTSCT->s_zero) {
1986-12-01 15:41:29 +00:00
wr_putc(0);
1985-04-12 16:56:43 +00:00
DOTSCT->s_zero--;
}
1986-12-01 15:41:29 +00:00
wr_putc(arg);
1985-04-12 16:56:43 +00:00
break;
}
DOTVAL++;
}
emit2(arg)
1989-01-19 13:48:09 +00:00
int arg;
1985-04-12 16:56:43 +00:00
{
#ifdef BYTES_REVERSED
1989-01-19 13:48:09 +00:00
emit1((arg>>8)); emit1(arg);
1985-04-12 16:56:43 +00:00
#else
1989-01-19 13:48:09 +00:00
emit1(arg); emit1((arg>>8));
1985-04-12 16:56:43 +00:00
#endif
}
emit4(arg)
long arg;
{
#ifdef WORDS_REVERSED
1989-01-19 16:41:55 +00:00
emit2((int)(arg>>16)); emit2((int)(arg));
1985-04-12 16:56:43 +00:00
#else
1989-01-19 16:41:55 +00:00
emit2((int)(arg)); emit2((int)(arg>>16));
1985-04-12 16:56:43 +00:00
#endif
}
emitx(val, n)
valu_t val;
1986-12-01 15:41:29 +00:00
int n;
1985-04-12 16:56:43 +00:00
{
switch (n) {
case 1:
1989-01-19 13:48:09 +00:00
emit1((int)val); break;
1985-04-12 16:56:43 +00:00
case 2:
1989-01-19 13:48:09 +00:00
emit2((int)val); break;
1985-04-12 16:56:43 +00:00
case 4:
emit4((long)val); break;
default:
assert(0);
}
}
emitstr(zero)
{
register i;
register char *p;
p = stringbuf;
i = *p++ & 0377;
while (--i >= 0)
emit1(*p++);
if (zero)
emit1(0);
}
/* ---------- Error checked file I/O ---------- */
ffreopen(s, f)
char *s;
FILE *f;
{
if (freopen(s, "r", f) == NULL)
fatal("can't reopen %s", s);
}
FILE *
ffcreat(s)
char *s;
{
FILE *f;
if ((f = fopen(s, "w")) == NULL)
fatal("can't create %s", s);
return(f);
}
1988-06-16 09:57:59 +00:00
#ifndef TMPDIR
#define TMPDIR "/tmp"
#endif
char *tmp_dir = TMPDIR;
1985-04-12 16:56:43 +00:00
FILE *
fftemp(path, tail)
1986-12-01 15:41:29 +00:00
char *path, *tail;
1985-04-12 16:56:43 +00:00
{
register char *dir;
if ((dir = getenv("TMPDIR")) == NULL)
1988-06-16 09:57:59 +00:00
dir = tmp_dir;
1985-04-12 16:56:43 +00:00
sprintf(path, "%s/%s", dir, tail);
return(ffcreat(mktemp(path)));
}
/* ---------- Error handling ---------- */
1988-06-28 13:55:25 +00:00
/*VARARGS*/
1985-04-12 16:56:43 +00:00
yyerror(){} /* we will do our own error printing */
nosect()
{
fatal("no sections");
}
1986-12-01 15:41:29 +00:00
wr_fatal()
1985-04-12 16:56:43 +00:00
{
fatal("write error");
}
/* VARARGS1 */
fatal(s, a1, a2, a3, a4)
char *s;
{
nerrors++;
diag(" (fatal)\n", s, a1, a2, a3, a4);
stop();
}
#if DEBUG == 2
assert2(file, line)
char *file;
{
fatal("assertion failed (%s, %d)", file, line);
}
#endif
#if DEBUG == 1
assert1()
{
diag(" (fatal)\n", "assertion failed");
abort();
}
#endif
/* VARARGS1 */
serror(s, a1, a2, a3, a4)
char *s;
{
nerrors++;
diag("\n", s, a1, a2, a3, a4);
}
/* VARARGS1 */
warning(s, a1, a2, a3, a4)
char *s;
{
diag(" (warning)\n", s, a1, a2, a3, a4);
}
/* VARARGS1 */
diag(tail, s, a1, a2, a3, a4)
char *tail, *s;
{
fflush(stdout);
if (modulename)
1988-06-13 15:28:19 +00:00
fprintf(stderr, "\"%s\", line %ld: ", modulename, lineno);
1985-04-12 16:56:43 +00:00
else
fprintf(stderr, "%s: ", progname);
fprintf(stderr, s, a1, a2, a3, a4);
fprintf(stderr, tail);
}
nofit()
{
if (pass == PASS_3)
warning("too big");
}