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
|
|
|
/*
|
1987-03-10 01:26:51 +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".
|
1984-10-09 10:36:29 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
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");
|
1990-01-12 17:05:42 +00:00
|
|
|
fprintf(codefile,".data4\t%s\n",str);
|
1984-10-09 10:36:29 +00:00
|
|
|
}
|
|
|
|
|
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 );
|
|
|
|
}
|
|
|
|
|
1990-01-12 17:05:42 +00:00
|
|
|
#define PDPFLOAT
|
|
|
|
#define CODE_GENERATOR
|
|
|
|
#include <con_float>
|
1984-10-09 10:36:29 +00:00
|
|
|
|
|
|
|
#ifndef REGVARS
|
1985-01-18 15:33:44 +00:00
|
|
|
prolog(nlocals)
|
|
|
|
full nlocals;
|
|
|
|
{
|
1990-01-12 17:05:42 +00:00
|
|
|
fprintf(codefile,".data2 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[] = {
|
1990-01-12 17:05:42 +00:00
|
|
|
".sect .text", /* SEGTXT */
|
|
|
|
".sect .data", /* SEGCON */
|
|
|
|
".sect .rom", /* SEGROM */
|
|
|
|
".sect .bss" /* SEGBSS */
|
1984-10-09 10:36:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#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,
|
1990-01-12 17:05:42 +00:00
|
|
|
"\t! Local %ld, size %d, to register %s\n",
|
1984-10-09 10:36:29 +00:00
|
|
|
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.
|
|
|
|
*/
|
1990-01-12 17:05:42 +00:00
|
|
|
fprintf(codefile, ".data2 0%o\n", mask);
|
1985-01-18 15:33:44 +00:00
|
|
|
/*
|
|
|
|
* Emit code to initialize parameters in registers.
|
|
|
|
*/
|
|
|
|
for (p = a_reg; p < p_reg; p++)
|
|
|
|
if (p->sr_off >= 0)
|
|
|
|
fprintf(codefile,
|
1985-01-21 12:14:59 +00:00
|
|
|
"mov%c\t%ld(ap), %s\n",
|
1985-01-18 15:33:44 +00:00
|
|
|
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
|