1985-01-18 15:33:44 +00:00
|
|
|
#ifndef lint
|
1984-10-09 10:36:29 +00:00
|
|
|
static char rcsid[] = "$Header$";
|
1985-01-18 15:33:44 +00:00
|
|
|
#endif lint
|
1984-10-09 10:36:29 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
*
|
|
|
|
* This product is part of the Amsterdam Compiler Kit.
|
|
|
|
*
|
|
|
|
* Permission to use, sell, duplicate or disclose this software must be
|
|
|
|
* obtained in writing. Requests for such permissions may be sent to
|
|
|
|
*
|
|
|
|
* Dr. Andrew S. Tanenbaum
|
|
|
|
* Wiskundig Seminarium
|
|
|
|
* Vrije Universiteit
|
|
|
|
* Postbox 7161
|
|
|
|
* 1007 MC Amsterdam
|
|
|
|
* The Netherlands
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* Machine dependent back end routines for the VAX using 4-byte words
|
1984-10-09 10:36:29 +00:00
|
|
|
*/
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* Byte order: | 3 | 2 | 1 | 0 |
|
|
|
|
*/
|
|
|
|
con_part(sz, w)
|
|
|
|
register int sz;
|
|
|
|
word w;
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Align new bytes on boundary of its on size.
|
|
|
|
*/
|
1984-10-09 10:36:29 +00:00
|
|
|
while (part_size % sz) part_size++;
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
if (part_size == TEM_WSIZE)
|
1984-10-09 10:36:29 +00:00
|
|
|
part_flush();
|
|
|
|
if (sz == 1 || sz == 2) {
|
|
|
|
/* Smaller than a machineword. */
|
|
|
|
w &= (sz == 1 ? 0xFF : 0xFFFF);
|
|
|
|
w <<= 8 * part_size;
|
|
|
|
part_word |= w;
|
|
|
|
} else {
|
|
|
|
assert(sz == 4);
|
|
|
|
part_word = w;
|
|
|
|
}
|
|
|
|
part_size += sz;
|
1985-01-18 15:33:44 +00:00
|
|
|
}
|
1984-10-09 10:36:29 +00:00
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
con_mult(sz)
|
|
|
|
word sz;
|
|
|
|
{
|
1984-10-09 10:36:29 +00:00
|
|
|
if (sz != 4)
|
|
|
|
fatal("bad icon/ucon size");
|
|
|
|
fprintf(codefile,".long\t%s\n",str);
|
|
|
|
}
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
mes(mesno)
|
|
|
|
word mesno;
|
|
|
|
{
|
1984-10-09 10:36:29 +00:00
|
|
|
while (getarg(any_ptyp) != sp_cend );
|
|
|
|
}
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
con_float()
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Insert a dot at the right position, if it is not present,
|
1984-10-09 10:36:29 +00:00
|
|
|
* to make the floating point constant acceptable to the assembler.
|
|
|
|
*/
|
1985-01-18 15:33:44 +00:00
|
|
|
register char *c;
|
|
|
|
extern char *index();
|
1984-10-09 10:36:29 +00:00
|
|
|
|
|
|
|
if (argval != 4 && argval != 8)
|
|
|
|
fatal("bad fcon size");
|
|
|
|
if (argval == 8)
|
|
|
|
fprintf(codefile,".double\t0d");
|
|
|
|
else fprintf(codefile,".float\t0f");
|
|
|
|
|
|
|
|
if (index(str,'.') != (char *) 0) {
|
|
|
|
fprintf(codefile,"%s\n",str);
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* There must be a dot after the `e' or - if the `e' is not present -
|
1984-10-09 10:36:29 +00:00
|
|
|
* at the end.
|
|
|
|
*/
|
|
|
|
} else if ((c = index(str,'e')) != (char *) 0) {
|
|
|
|
*c++ = '\0';
|
|
|
|
fprintf(codefile,"%s.e%s\n",str,c--);
|
|
|
|
*c = 'e';
|
|
|
|
} else fprintf(codefile,"%s.\n",str);
|
1985-01-18 15:33:44 +00:00
|
|
|
}
|
1984-10-09 10:36:29 +00:00
|
|
|
|
|
|
|
#ifndef REGVARS
|
1985-01-18 15:33:44 +00:00
|
|
|
prolog(nlocals)
|
|
|
|
full nlocals;
|
|
|
|
{
|
|
|
|
fprintf(codefile,".word 00\n");
|
1984-10-09 10:36:29 +00:00
|
|
|
if (nlocals == 0)
|
|
|
|
return;
|
|
|
|
if (nlocals == 4)
|
|
|
|
fprintf(codefile,"\tclrl\t-(sp)\n");
|
|
|
|
else if (nlocals == 8)
|
|
|
|
fprintf(codefile,"\tclrq\t-(sp)\n");
|
|
|
|
else
|
|
|
|
fprintf(codefile,"\tsubl2\t$%ld,sp\n",nlocals);
|
|
|
|
}
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
#endif not REGVARS
|
1984-10-09 10:36:29 +00:00
|
|
|
|
|
|
|
char *segname[] = {
|
|
|
|
".text", /* SEGTXT */
|
|
|
|
".data", /* SEGCON */
|
|
|
|
".data", /* SEGROM */
|
|
|
|
".data" /* SEGBSS */
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef REGVARS
|
1985-01-18 15:33:44 +00:00
|
|
|
static full nlocals; /* Number of local variables. */
|
1984-10-09 10:36:29 +00:00
|
|
|
|
|
|
|
#define NR_REG 8 /* Number of registers. */
|
|
|
|
#define FIRST_REG 4
|
|
|
|
#define LAST_REG (FIRST_REG + NR_REG - 1)
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* Save number of locals.
|
|
|
|
*/
|
|
|
|
prolog(n)
|
|
|
|
{
|
1984-10-09 10:36:29 +00:00
|
|
|
nlocals = n;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Structure to store information about the registers to be stored.
|
|
|
|
*/
|
|
|
|
static struct s_reg {
|
1985-01-18 15:33:44 +00:00
|
|
|
char *sr_str; /* Name of register used. */
|
|
|
|
long sr_off; /* Offset from LB. */
|
|
|
|
int sr_size; /* Size in bytes. */
|
1984-10-09 10:36:29 +00:00
|
|
|
} a_reg[NR_REG + 1], *p_reg;
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* Initialize saving of registers.
|
|
|
|
*/
|
|
|
|
i_regsave()
|
|
|
|
{
|
1984-10-09 10:36:29 +00:00
|
|
|
p_reg = a_reg;
|
|
|
|
}
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* Called for each register to be saved.
|
|
|
|
* Save the parameters in the struct.
|
|
|
|
*/
|
|
|
|
regsave(str, off, size)
|
|
|
|
char *str;
|
|
|
|
long off;
|
|
|
|
int size;
|
|
|
|
{
|
1984-10-09 10:36:29 +00:00
|
|
|
p_reg->sr_str = str;
|
|
|
|
p_reg->sr_off = off;
|
|
|
|
(p_reg++)->sr_size = size;
|
|
|
|
fprintf(codefile,
|
|
|
|
"\t# Local %ld, size %d, to register %s\n",
|
|
|
|
off, size, str
|
1985-01-18 15:33:44 +00:00
|
|
|
);
|
1984-10-09 10:36:29 +00:00
|
|
|
}
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* Generate code to save the registers.
|
|
|
|
*/
|
|
|
|
f_regsave()
|
|
|
|
{
|
|
|
|
register struct s_reg *p;
|
1984-10-09 10:36:29 +00:00
|
|
|
register int mask;
|
|
|
|
register int i;
|
|
|
|
register int count;
|
|
|
|
|
|
|
|
mask = 0;
|
|
|
|
count = p_reg - a_reg;
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* For each register to be saved, set a bit in the
|
|
|
|
* mask corresponding to its number.
|
|
|
|
*/
|
1984-10-09 10:36:29 +00:00
|
|
|
for (p = a_reg; p < p_reg; p++) {
|
|
|
|
i = atoi(p->sr_str + 1);
|
|
|
|
if (p->sr_size <= 4)
|
|
|
|
mask |= (1 << i);
|
|
|
|
else {
|
|
|
|
mask |= (3 << i);
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
}
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* Now generate code to save registers.
|
|
|
|
*/
|
|
|
|
fprintf(codefile, ".word 0%o\n", mask);
|
|
|
|
/*
|
|
|
|
* Emit code to initialize parameters in registers.
|
|
|
|
*/
|
|
|
|
for (p = a_reg; p < p_reg; p++)
|
|
|
|
if (p->sr_off >= 0)
|
|
|
|
fprintf(codefile,
|
|
|
|
"mov%c\t%ld(ap), %s\n,
|
|
|
|
p->sr_size == 4 ? 'l' : 'q',
|
|
|
|
p->sr_off,
|
|
|
|
p->sr_str
|
|
|
|
);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Generate room for locals.
|
1984-10-09 10:36:29 +00:00
|
|
|
*/
|
|
|
|
if (nlocals == 0)
|
|
|
|
return;
|
|
|
|
if (nlocals == 4)
|
|
|
|
fprintf(codefile,"clrl\t-(sp)\n");
|
|
|
|
else if (nlocals == 8)
|
|
|
|
fprintf(codefile,"clrq\t-(sp)\n");
|
|
|
|
else
|
|
|
|
fprintf(codefile,"subl2\t$%ld,sp\n",nlocals);
|
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
}
|
1984-10-09 10:36:29 +00:00
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
regreturn() { }
|
1984-10-09 10:36:29 +00:00
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
regscore(off, size, typ, score, totyp)
|
|
|
|
long off;
|
|
|
|
int size, typ, totyp, score;
|
|
|
|
{
|
|
|
|
register int i = score;
|
1984-10-09 10:36:29 +00:00
|
|
|
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* If the offset doesn't fit in a byte, word-offset is used,
|
1984-10-09 10:36:29 +00:00
|
|
|
* which is one byte more expensive.
|
|
|
|
*/
|
1985-01-18 15:33:44 +00:00
|
|
|
if (off > 127 || off < -128) i *= 2;
|
|
|
|
/*
|
|
|
|
* Compute cost of initialization for parameters.
|
1984-10-09 10:36:29 +00:00
|
|
|
*/
|
1985-01-18 15:33:44 +00:00
|
|
|
if (off > 127) i -= 5;
|
|
|
|
else if (off >= 0) i -= 4;
|
|
|
|
/*
|
|
|
|
* Storing a pointer in a register sometimes saves an instruction.
|
1984-10-09 10:36:29 +00:00
|
|
|
*/
|
1985-01-18 15:33:44 +00:00
|
|
|
if (typ == reg_pointer) i += score;
|
|
|
|
else if (typ == reg_loop) i += 5;
|
|
|
|
/*
|
|
|
|
* Now adjust for the saving of the register.
|
|
|
|
* But this costs no space at all.
|
|
|
|
*/
|
|
|
|
return i - 1;
|
|
|
|
}
|
1984-10-09 10:36:29 +00:00
|
|
|
|
|
|
|
#endif REGVARS
|