ack/mach/proto/as/comm7.c

462 lines
7 KiB
C
Raw Normal View History

1994-06-24 14:02:31 +00:00
/* $Id$ */
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
*/
2019-02-10 13:19:18 +00:00
#include <errno.h>
2018-09-10 20:37:04 +00:00
#include "comm0.h"
#include "comm1.h"
#include "y.tab.h"
#include <stdarg.h>
#include <object.h>
valu_t load(const item_t* ip)
1985-04-12 16:56:43 +00:00
{
#ifdef ASLD
int typ;
1985-04-12 16:56:43 +00:00
typ = ip->i_type & S_TYP;
2018-09-10 20:37:04 +00:00
if ((typ -= S_MIN) < 0) /* S_UND or S_ABS */
return (ip->i_valu);
return (ip->i_valu + sect[typ].s_base);
1985-04-12 16:56:43 +00:00
#else
2018-09-10 20:37:04 +00:00
if ((ip->i_type & S_TYP) == S_UND || (ip->i_type & S_COM))
{
if (pass == PASS_3)
{
1985-04-12 16:56:43 +00:00
if (relonami != 0)
2015-03-22 23:07:59 +00:00
serror("relocation error (relonami=%d, type=%08x)", relonami, ip->i_type);
2018-09-10 20:37:04 +00:00
relonami = ip->i_valu + 1;
1985-04-12 16:56:43 +00:00
}
2018-09-10 20:37:04 +00:00
return (0);
1985-04-12 16:56:43 +00:00
}
2018-09-10 20:37:04 +00:00
return (ip->i_valu);
1985-04-12 16:56:43 +00:00
#endif
}
2018-09-10 20:37:04 +00:00
int store(item_t* ip, valu_t val)
1985-04-12 16:56:43 +00:00
{
#ifdef ASLD
int typ;
1985-04-12 16:56:43 +00:00
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)
2018-09-10 20:37:04 +00:00
return (0);
1985-04-12 16:56:43 +00:00
#endif
assert(pass != PASS_3 || (ip->i_type & S_VAR) || ip->i_valu == val);
ip->i_valu = val;
2018-09-10 20:37:04 +00:00
return (1);
1985-04-12 16:56:43 +00:00
}
2018-09-10 20:37:04 +00:00
char* remember(char* s)
1985-04-12 16:56:43 +00:00
{
2018-09-10 20:37:04 +00:00
char* p;
int n;
static int nleft = 0;
2018-09-10 20:37:04 +00:00
static char* next;
1985-04-12 16:56:43 +00:00
p = s;
n = 0;
do
n++;
while (*p++);
2018-09-10 20:37:04 +00:00
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;
2018-09-10 20:37:04 +00:00
return (s);
1985-04-12 16:56:43 +00:00
}
2018-09-10 20:37:04 +00:00
int combine(int typ1, int typ2, int op)
1985-04-12 16:56:43 +00:00
{
2018-09-10 20:37:04 +00:00
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;
1985-04-12 16:56:43 +00:00
}
if (pass != PASS_1)
serror("illegal operator");
2018-09-10 20:37:04 +00:00
return (S_UND);
1985-04-12 16:56:43 +00:00
}
#ifdef LISTING
2018-09-10 20:37:04 +00:00
int printx(int ndig, valu_t val)
1985-04-12 16:56:43 +00:00
{
static char buf[8];
2018-09-10 20:37:04 +00:00
char* p;
int c, n;
1985-04-12 16:56:43 +00:00
2018-09-10 20:37:04 +00:00
p = buf;
n = ndig;
do
{
*p++ = (int)val & 017;
1985-04-12 16:56:43 +00:00
val >>= 4;
} while (--n);
2018-09-10 20:37:04 +00:00
do
{
1985-04-12 16:56:43 +00:00
c = "0123456789ABCDEF"[*--p];
putchar(c);
} while (p > buf);
2018-09-10 20:37:04 +00:00
return (ndig);
1985-04-12 16:56:43 +00:00
}
2018-09-10 20:37:04 +00:00
void listline(int textline)
1985-04-12 16:56:43 +00:00
{
int c;
1985-04-12 16:56:43 +00:00
2018-09-10 20:37:04 +00:00
if ((listflag & 4) && (c = getc(listfile)) != '\n' && textline)
{
1985-04-12 16:56:43 +00:00
if (listcolm >= 24)
printf(" \\\n\t\t\t");
else
2018-09-10 20:37:04 +00:00
do
{
1985-04-12 16:56:43 +00:00
putchar('\t');
listcolm += 8;
} while (listcolm < 24);
2018-09-10 20:37:04 +00:00
do
{
1985-04-12 16:56:43 +00:00
assert(c != EOF);
putchar(c);
} while ((c = getc(listfile)) != '\n');
}
2018-09-10 20:37:04 +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 */
1985-04-12 16:56:43 +00:00
/* ---------- code optimization ---------- */
#ifdef THREE_PASS
2018-09-10 20:37:04 +00:00
#define PBITTABSZ 128
static char* pbittab[PBITTABSZ];
1988-06-16 13:24:10 +00:00
2018-09-10 20:37:04 +00:00
int small(int fitsmall, int gain)
1985-04-12 16:56:43 +00:00
{
int bit;
2018-09-10 20:37:04 +00:00
char* p;
1985-04-12 16:56:43 +00:00
if (DOTSCT == NULL)
nosect();
if (bflag)
2018-09-10 20:37:04 +00:00
return (0);
if (nbits == BITCHUNK)
{
1988-06-16 13:24:10 +00:00
bitindex++;
nbits = 0;
2018-09-10 20:37:04 +00:00
if (bitindex == PBITTABSZ)
{
1988-06-16 13:24:10 +00:00
static int w_given;
2018-09-10 20:37:04 +00:00
if (pass == PASS_1 && !w_given)
{
1988-06-16 13:24:10 +00:00
w_given = 1;
warning("bit table overflow");
}
2018-09-10 20:37:04 +00:00
return (0);
1988-06-13 18:01:47 +00:00
}
2018-09-10 20:37:04 +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;
2018-09-10 20:37:04 +00:00
if (!w2_given)
{
1988-06-16 13:24:10 +00:00
w2_given = 1;
warning("out of space for bit table");
}
}
}
if (pbittab[bitindex] == 0)
return (0);
1985-04-12 16:56:43 +00:00
}
2018-09-10 20:37:04 +00:00
bit = 1 << (nbits & 7);
p = pbittab[bitindex] + (nbits >> 3);
1988-06-13 17:57:39 +00:00
nbits++;
2018-09-10 20:37:04 +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);
1985-04-12 16:56:43 +00:00
}
1986-12-01 15:41:29 +00:00
/*NOTREACHED*/
1985-04-12 16:56:43 +00:00
}
#endif
/* ---------- output ---------- */
2018-09-10 20:37:04 +00:00
void emit1(int arg)
1985-04-12 16:56:43 +00:00
{
static int olddottyp = -1;
1985-04-12 16:56:43 +00:00
#ifdef LISTING
2018-09-10 20:37:04 +00:00
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)
2018-09-10 20:37:04 +00:00
listcolm += printx(2, (valu_t)arg);
1985-04-12 16:56:43 +00:00
#endif
2018-09-10 20:37:04 +00:00
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;
1985-04-12 16:56:43 +00:00
}
DOTVAL++;
}
2018-09-10 20:37:04 +00:00
void emit2(int arg)
1985-04-12 16:56:43 +00:00
{
#ifdef BYTES_REVERSED
2018-09-10 20:37:04 +00:00
emit1((arg >> 8));
emit1(arg);
1985-04-12 16:56:43 +00:00
#else
2018-09-10 20:37:04 +00:00
emit1(arg);
emit1((arg >> 8));
1985-04-12 16:56:43 +00:00
#endif
}
2018-09-10 20:37:04 +00:00
void emit4(long arg)
1985-04-12 16:56:43 +00:00
{
#ifdef WORDS_REVERSED
2018-09-10 20:37:04 +00:00
emit2((int)(arg >> 16));
emit2((int)(arg));
1985-04-12 16:56:43 +00:00
#else
2018-09-10 20:37:04 +00:00
emit2((int)(arg));
emit2((int)(arg >> 16));
1985-04-12 16:56:43 +00:00
#endif
}
2018-09-10 20:37:04 +00:00
void emitx(valu_t val, int n)
1985-04-12 16:56:43 +00:00
{
2018-09-10 20:37:04 +00:00
switch (n)
{
case RELO1:
emit1((int)val);
break;
case RELO2:
#ifdef BYTES_REVERSED
2018-09-10 20:37:04 +00:00
emit1(((int)val >> 8));
emit1((int)val);
#else
2018-09-10 20:37:04 +00:00
emit1((int)val);
emit1(((int)val >> 8));
#endif
2018-09-10 20:37:04 +00:00
break;
case RELO4:
#ifdef WORDS_REVERSED
2018-09-10 20:37:04 +00:00
emit2((int)(val >> 16));
emit2((int)(val));
#else
2018-09-10 20:37:04 +00:00
emit2((int)(val));
emit2((int)(val >> 16));
#endif
2018-09-10 20:37:04 +00:00
break;
default:
assert(0);
1985-04-12 16:56:43 +00:00
}
}
2018-09-10 20:37:04 +00:00
void emitstr(int zero)
1985-04-12 16:56:43 +00:00
{
int i;
2018-09-10 20:37:04 +00:00
char* p;
1985-04-12 16:56:43 +00:00
p = stringbuf;
1990-08-01 14:30:45 +00:00
i = stringlen;
1985-04-12 16:56:43 +00:00
while (--i >= 0)
emit1(*p++);
if (zero)
emit1(0);
}
#define CODE_EXPANDER
#if !defined IEEEFLOAT && !defined PDPFLOAT
#define IEEEFLOAT
#endif
#if defined WORDS_REVERSED
#define FL_MSL_AT_LOW_ADDRESS 1
#define FL_MSW_AT_LOW_ADDRESS 1
#else
#define FL_MSL_AT_LOW_ADDRESS 0
#define FL_MSW_AT_LOW_ADDRESS 0
#endif
#if defined BYTES_REVERSED
#define FL_MSB_AT_LOW_ADDRESS 1
#else
#define FL_MSB_AT_LOW_ADDRESS 0
#endif
#define gen1 emit1
#include <con_float>
void emitf(int size, int negative)
{
char buffer[40];
if (stringlen > sizeof(buffer)-1)
fatal("floating point constant too long");
if (negative)
{
buffer[0] = '-';
strcpy(buffer+1, stringbuf);
con_float(buffer, size);
}
else
con_float(stringbuf, size);
}
1985-04-12 16:56:43 +00:00
/* ---------- Error handling ---------- */
/* ARGSUSED */
2018-09-10 20:37:04 +00:00
void yyerror(const char* message)
{
} /* we will do our own error printing */
1985-04-12 16:56:43 +00:00
2018-09-10 20:37:04 +00:00
void nosect(void)
1985-04-12 16:56:43 +00:00
{
fatal("no sections");
}
2018-09-10 20:37:04 +00:00
void wr_fatal(void)
1985-04-12 16:56:43 +00:00
{
fatal("write error");
}
static void diag(const char* tail, const char* s, va_list ap)
2015-03-22 23:07:59 +00:00
{
fflush(stdout);
if (modulename)
fprintf(stderr, "\"%s\", line %ld: ", modulename, lineno);
else
fprintf(stderr, "%s: ", progname);
vfprintf(stderr, s, ap);
fprintf(stderr, "%s", tail);
}
1985-04-12 16:56:43 +00:00
/* VARARGS1 */
2015-03-22 23:07:59 +00:00
void fatal(const char* s, ...)
1985-04-12 16:56:43 +00:00
{
2015-03-22 23:07:59 +00:00
va_list ap;
va_start(ap, s);
1985-04-12 16:56:43 +00:00
nerrors++;
2015-03-22 23:07:59 +00:00
diag(" (fatal)\n", s, ap);
1985-04-12 16:56:43 +00:00
stop();
2015-03-22 23:07:59 +00:00
va_end(ap);
1985-04-12 16:56:43 +00:00
}
/* VARARGS1 */
2015-03-22 23:07:59 +00:00
void serror(const char* s, ...)
1985-04-12 16:56:43 +00:00
{
2015-03-22 23:07:59 +00:00
va_list ap;
va_start(ap, s);
1985-04-12 16:56:43 +00:00
nerrors++;
2015-03-22 23:07:59 +00:00
diag("\n", s, ap);
stop();
1985-04-12 16:56:43 +00:00
2015-03-22 23:07:59 +00:00
va_end(ap);
1985-04-12 16:56:43 +00:00
}
/* VARARGS1 */
2015-03-22 23:07:59 +00:00
void warning(const char* s, ...)
1985-04-12 16:56:43 +00:00
{
2015-03-22 23:07:59 +00:00
va_list ap;
va_start(ap, s);
nerrors++;
diag(" (warning)\n", s, ap);
stop();
va_end(ap);
1985-04-12 16:56:43 +00:00
}
2018-09-10 20:37:04 +00:00
void nofit(void)
1985-04-12 16:56:43 +00:00
{
if (pass == PASS_3)
warning("too big");
}