ack/mach/m68020/ncg/mach.c

296 lines
5.5 KiB
C
Raw Permalink Normal View History

1994-06-24 14:02:31 +00:00
/* $Id$ */
1987-01-13 09:24:13 +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".
1987-01-13 09:24:13 +00:00
*
*/
/*
* machine dependent back end routines for the Motorola 68000, 68010 or 68020
*/
#include <whichone.h>
#if TBL68020
#define SYNTAX_68020 1
#endif
1990-08-20 13:55:38 +00:00
#include <stb.h>
1987-01-13 09:24:13 +00:00
void
con_part(int sz, word w) {
1987-01-13 09:24:13 +00:00
while (part_size % sz)
part_size++;
1990-08-20 13:55:38 +00:00
if (part_size == TEM_WSIZE)
1987-01-13 09:24:13 +00:00
part_flush();
if (sz == 1) {
w &= 0xFF;
1990-08-20 13:55:38 +00:00
#if WORD_SIZE==4
1987-01-13 09:24:13 +00:00
w <<= 8*(3-part_size);
part_word |= w;
} else if (sz == 2) {
w &= 0xFFFF;
1990-08-20 13:55:38 +00:00
#endif
if (part_size == 0) {
/* Shift 8 for m68k2, 16 otherwise */
w <<= 4 * TEM_WSIZE;
}
1987-01-13 09:24:13 +00:00
part_word |= w;
} else {
1990-08-20 13:55:38 +00:00
assert(sz == TEM_WSIZE);
1987-01-13 09:24:13 +00:00
part_word = w;
}
part_size += sz;
}
void
con_mult(word sz) {
1987-01-13 09:24:13 +00:00
if (sz != 8)
1987-01-13 09:24:13 +00:00
fatal("bad icon/ucon size");
fprintf(codefile,".data8\t%s\n", str);
1987-01-13 09:24:13 +00:00
}
1989-07-31 14:45:40 +00:00
#define IEEEFLOAT
#define CODE_GENERATOR
1989-10-25 13:24:29 +00:00
#define FL_MSL_AT_LOW_ADDRESS 1
#define FL_MSW_AT_LOW_ADDRESS 1
#define FL_MSB_AT_LOW_ADDRESS 1
1989-07-10 16:52:02 +00:00
#include <con_float>
1987-01-13 09:24:13 +00:00
int
2022-08-01 20:08:23 +00:00
regscore(long off, int size, int typ, int score, int totyp)
1987-01-13 09:24:13 +00:00
{
if (score == 0) return -1;
switch(typ) {
case reg_float:
return -1;
case reg_pointer:
if (size != 4 || totyp != reg_pointer) return -1;
1987-08-12 16:19:02 +00:00
score += (score >> 1);
1987-01-13 09:24:13 +00:00
break;
case reg_loop:
score += 5;
/* fall through .. */
case reg_any:
1990-08-20 13:55:38 +00:00
if (size != TEM_WSIZE || totyp == reg_pointer) return -1;
1987-01-13 09:24:13 +00:00
break;
}
if (off >= 0) {
/* parameters must be initialised with an instruction
* like "move.l 4(a6),d0", which costs 2 words.
*/
score -= 2;
}
1987-08-12 16:19:02 +00:00
score--; /* save/restore */
1987-01-13 09:24:13 +00:00
return score;
}
struct regsav_t {
const char *rs_reg; /* e.g. "a3" or "d5" */
1987-01-13 09:24:13 +00:00
long rs_off; /* offset of variable */
int rs_size; /* 2 or 4 bytes */
} regsav[9];
int regnr;
void
1987-01-13 09:24:13 +00:00
i_regsave()
{
regnr = 0;
}
full nlocals;
void
regreturn()
{
register struct regsav_t *p;
if (regnr > 1) {
#ifdef SYNTAX_68020
1989-02-22 17:38:07 +00:00
fprintf(codefile,"movem.l (-%ld,a6),", nlocals);
#else
fprintf(codefile,"movem.l -%ld(a6),", nlocals);
1989-02-22 17:38:07 +00:00
#endif
for (p = regsav; ;) {
fputs(p->rs_reg, codefile);
if (++p == &regsav[regnr]) break;
putc('/',codefile);
}
putc('\n',codefile);
} else if (regnr == 1) {
1989-02-22 17:38:07 +00:00
p = regsav;
#ifdef SYNTAX_68020
1989-02-22 17:38:07 +00:00
fprintf(codefile,"move.l (-%ld,a6),%s\n",nlocals, p->rs_reg);
#else
fprintf(codefile,"move.l -%ld(a6),%s\n",nlocals, p->rs_reg);
#endif
}
fputs("unlk a6\nrts\n", codefile);
}
void
f_regsave()
1987-01-13 09:24:13 +00:00
{
register struct regsav_t *p;
nlocals += regnr*4;
#ifdef TBL68020
fprintf(codefile,"link\ta6,#-%ld\n",nlocals);
#else
if (nlocals > 32768) {
fprintf(codefile, "move.l a6,-(sp)\nmove.l sp,a6\nsub #%ld,sp\n", nlocals);
}
else fprintf(codefile,"link\ta6,#-%ld\n",nlocals);
#endif
#ifndef NOSTACKTEST
fprintf(codefile, "tst.b %s\n",
#ifdef SYNTAX_68020
"(-40, sp)"
#else
"-40(sp)"
#endif
);
#endif
if (regnr > 1) {
fputs("movem.l ", codefile);
1987-01-13 09:24:13 +00:00
for (p = regsav; ;) {
fputs(p->rs_reg, codefile);
1987-01-13 09:24:13 +00:00
if (++p == &regsav[regnr]) break;
putc('/',codefile);
}
fputs(",(sp)\n", codefile);
} else if (regnr == 1) {
1989-02-22 17:38:07 +00:00
p = regsav;
fprintf(codefile,"move.l %s,(sp)\n",p->rs_reg);
1987-01-13 09:24:13 +00:00
}
/* initialise register-parameters */
for (p = regsav; p < &regsav[regnr]; p++) {
if (p->rs_off >= 0) {
#ifdef SYNTAX_68020
1987-01-13 09:24:13 +00:00
fprintf(codefile,"move.%c (%ld,a6),%s\n",
#else
fprintf(codefile,"move.%c %ld(a6),%s\n",
#endif
(p->rs_size == 4 ? 'l' : 'w'),
p->rs_off,
p->rs_reg);
}
}
}
void
2022-08-01 20:08:23 +00:00
regsave(const char* s, long off, int size)
1987-01-13 09:24:13 +00:00
{
assert (regnr < 9);
1988-03-31 10:38:05 +00:00
regsav[regnr].rs_reg = s;
1987-01-13 09:24:13 +00:00
regsav[regnr].rs_off = off;
regsav[regnr++].rs_size = size;
1988-03-31 10:38:05 +00:00
fprintf(codefile, "!Local %ld into %s\n",off,s);
1987-01-13 09:24:13 +00:00
}
void
prolog(n) full n; {
1987-01-13 09:24:13 +00:00
nlocals = n;
1987-01-13 09:24:13 +00:00
}
1992-03-27 17:36:49 +00:00
#ifdef MACH_OPTIONS
static int gdb_flag = 0;
1987-01-13 09:24:13 +00:00
void
1992-03-27 17:36:49 +00:00
mach_option(s)
char *s;
{
if (! strcmp(s, "-gdb")) {
gdb_flag = 1;
}
else {
error("Unknown flag %s", s);
}
}
#endif /* MACH_OPTIONS */
1987-01-13 09:24:13 +00:00
void
1987-01-13 09:24:13 +00:00
mes(type) word type ; {
1990-08-20 13:55:38 +00:00
int argt, a1, a2 ;
1987-01-13 09:24:13 +00:00
switch ( (int)type ) {
case ms_ext :
for (;;) {
switch ( argt=getarg(
ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
case sp_cend :
return ;
default:
strarg(argt) ;
fprintf(codefile,".define %s\n",argstr) ;
break ;
}
}
1990-08-20 13:55:38 +00:00
case ms_stb:
argt = getarg(str_ptyp | cst_ptyp);
if (argt == sp_cstx)
fputs(".symb \"\", ", codefile);
else {
fprintf(codefile, ".symb \"%s\", ", str);
argt = getarg(cst_ptyp);
}
a1 = argval;
argt = getarg(cst_ptyp);
a2 = argval;
argt = getarg(cst_ptyp|nof_ptyp|sof_ptyp|ilb_ptyp|pro_ptyp);
1992-03-27 17:36:49 +00:00
#ifdef MACH_OPTIONS
if (gdb_flag) {
if (a1 == N_PSYM) {
/* Change offset from AB into offset from
the frame pointer.
*/
argval += 8;
}
}
#endif
1990-08-20 13:55:38 +00:00
fprintf(codefile, "%s, 0x%x, %d\n", strarg(argt), a1, a2);
argt = getarg(end_ptyp);
break;
case ms_std:
argt = getarg(str_ptyp | cst_ptyp);
if (argt == sp_cstx)
str[0] = '\0';
else {
argt = getarg(cst_ptyp);
}
swtxt();
1992-03-27 17:36:49 +00:00
if (argval == N_SLINE
#ifdef MACH_OPTIONS
&& ! gdb_flag
#endif
) {
#ifdef SYNTAX_68020
1990-08-20 13:55:38 +00:00
fputs("jsr (___u_LiB)\n", codefile);
#else
fputs("jsr ___u_LiB\n", codefile);
#endif
cleanregs(); /* debugger might change variables */
1990-08-20 13:55:38 +00:00
}
fprintf(codefile, ".symd \"%s\", 0x%x,", str, (int) argval);
argt = getarg(cst_ptyp);
fprintf(codefile, "%d\n", (int) argval);
argt = getarg(end_ptyp);
break;
1987-01-13 09:24:13 +00:00
default :
while ( getarg(any_ptyp) != sp_cend ) ;
break ;
}
}
char *segname[] = {
".sect .text", /* SEGTXT */
".sect .data", /* SEGCON */
".sect .rom", /* SEGROM */
".sect .bss" /* SEGBSS */
};