diff --git a/mach/m68k2/cg/mach.c b/mach/m68k2/cg/mach.c new file mode 100644 index 000000000..b286cf210 --- /dev/null +++ b/mach/m68k2/cg/mach.c @@ -0,0 +1,264 @@ +/* + * (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 + * + */ + +/* + * machine dependent back end routines for the Motorola 68000 + */ + +con_part(sz,w) register sz; word w; { + + while (part_size % sz) + part_size++; + if (part_size == EM_WSIZE) + part_flush(); + if (sz == 1) { + w &= 0xFF; + if (part_size == 0) + w <<= 8; + part_word |= w; + } else { + assert(sz == 2); + part_word = w; + } + part_size += sz; +} + +con_mult(sz) word sz; { + + if (sz != 4) + fatal("bad icon/ucon size"); + fprintf(codefile,".long %s\n",str); +} + +con_float() { + +static int been_here; + if (argval != 4 && argval != 8) + fatal("bad fcon size"); + fprintf(codefile,".long\t"); + if (argval == 8) + fprintf(codefile,"F_DUM,"); + fprintf(codefile,"F_DUM\n"); + if ( !been_here++) + { + fprintf(stderr,"Warning : dummy float-constant(s)\n"); + } +} + +#ifdef REGVARS + + +regscore(off,size,typ,score,totyp) + long off; +{ + switch(typ) { + case reg_float: + return -1; + case reg_pointer: + if (size != 4 || totyp != reg_pointer) return -1; + score *= 2; + break; + case reg_loop: + score += 5; + /* fall through .. */ + case reg_any: + if (size != 2 || totyp == reg_pointer) return -1; + break; + } + if (off >= 0) { + /* parameters must be initialised with an instruction + * like "move.w 4(a6),d0", which costs 2 words. + */ + score -= 2; + } + score -= 1; /* take save/restore into account */ + return score; +} + + +struct regsav_t { + char *rs_reg; /* e.g. "a3" or "d5" */ + long rs_off; /* offset of variable */ + int rs_size; /* 2 or 4 bytes */ +} regsav[9]; + + +int regnr; +int nr_a_regs,nr_d_regs; +int EM_BSIZE; +static long nlocals; + +prolog(n) +{ nlocals = n; } + + +i_regsave() +{ + regnr = 0; + nr_a_regs = 0; + nr_d_regs = 0; + EM_BSIZE = 0; +} + +#define MOVEM_LIMIT 2 +/* If #registers to be saved exceeds MOVEM_LIMIT, we +* use the movem instruction to save registers; else +* we simply use several move.l's. +*/ + + +save() +{ + register struct regsav_t *p; + int i; + + if (regnr > MOVEM_LIMIT) { + fprintf(codefile,"movem.l "); + for (p = regsav; ;) { + fprintf(codefile,"%s",p->rs_reg); + if (++p == ®sav[regnr]) break; + putc('/',codefile); + } + fprintf(codefile,",-(sp)\n"); + } else { + /* Note that the order in which the registers are saved + * is important; it is used by gto.s. + */ + for (i = 0; i < nr_a_regs; i++) { + fprintf(codefile,"move.l a%d,-(sp)\n",5-i); + } + for (i = 0; i < nr_d_regs; i++) { + fprintf(codefile,"move.l d%d,-(sp)\n",7-i); + } + } + /* Push a mask that indicates which registers were saved */ + assert(nr_d_regs < 8 && nr_a_regs < 8); + fprintf(codefile,"move.w #%d,-(sp)\n",nr_d_regs + (nr_a_regs<<3)); + + /* Compute AB - LB */ + EM_BSIZE = 4 * (nr_d_regs + nr_a_regs) + 10; + + /* allocate space for local variables */ + fprintf(codefile,"tst.b -%D(sp)\nlink\ta6,#-%D\n",nlocals+40,nlocals); + + /* initialise register-parameters */ + for (p = regsav; p < ®sav[regnr]; p++) { + if (p->rs_off >= 0) { + fprintf(codefile,"move.%c %ld(a6),%s\n", + (p->rs_size == 4 ? 'l' : 'w'), + p->rs_off + EM_BSIZE, + p->rs_reg); + } + } +} + +restr() +{ + register struct regsav_t *p; + int i; + + fprintf(codefile,"unlk a6\n"); + fprintf(codefile,"add.l #2,sp\n"); /* pop mask */ + if (regnr > MOVEM_LIMIT) { + fprintf(codefile,"movem.l (sp)+,"); + for (p = regsav; ;) { + fprintf(codefile,"%s",p->rs_reg); + if (++p == ®sav[regnr]) break; + putc('/',codefile); + } + putc('\n',codefile); + } else { + for (i = nr_d_regs - 1; i >= 0; i--) { + fprintf(codefile,"move.l (sp)+,d%d\n",7-i); + } + for (i = nr_a_regs - 1; i >= 0; i--) { + fprintf(codefile,"move.l (sp)+,a%d\n",5-i); + } + } + fprintf(codefile,"rts\n"); +} + + +f_regsave() +{ + save(); +} + +regsave(str,off,size) + char *str; + long off; +{ + assert (regnr < 9); + regsav[regnr].rs_reg = str; + if (str[0] == 'a') { + nr_a_regs++; + } else { + assert(str[0] == 'd'); + nr_d_regs++; + } + regsav[regnr].rs_off = off; + regsav[regnr++].rs_size = size; + fprintf(codefile, "!Local %ld into %s\n",off,str); +} + +regreturn() +{ + restr(); +} + +#endif + +#ifndef REGVARS + +prolog(nlocals) full nlocals; { + + fprintf(codefile,"tst.b -%D(sp)\nlink\ta6,#-%D\n",nlocals+40,nlocals); +} + +#endif + + + +mes(type) word type ; { + int argt ; + + 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 ; + } + } + default : + while ( getarg(any_ptyp) != sp_cend ) ; + break ; + } +} + + +char *segname[] = { + ".text", /* SEGTXT */ + ".data", /* SEGCON */ + ".data", /* SEGROM */ + ".bss" /* SEGBSS */ +}; diff --git a/mach/m68k2/cg/mach.h b/mach/m68k2/cg/mach.h new file mode 100644 index 000000000..62a2e1fda --- /dev/null +++ b/mach/m68k2/cg/mach.h @@ -0,0 +1,28 @@ +#define ex_ap(y) fprintf(codefile,".extern %s\n",y) +#define in_ap(y) /* nothing */ + +#define newilb(x) fprintf(codefile,"%s:\n",x) +#define newdlb(x) fprintf(codefile,"%s:\n",x) +#define dlbdlb(x,y) fprintf(codefile,"%s = %s\n",x,y) +#define newlbss(l,x) fprintf(codefile,"%s:.space\t%D\n",l,x); + +#define pop_fmt "(sp)+" +#define cst_fmt "%D" +#define off_fmt "%D" +#define ilb_fmt "I%03x%x" +#define dlb_fmt "_%d" +#define hol_fmt "hol%d" + +#define loc_off "%d(a6)" +#define arg_off "8+%d(a6)" +#define hol_off "%d+hol%d" + +#define con_cst(x) fprintf(codefile,".short\t%d\n",x) +#define con_ilb(x) fprintf(codefile,".long\t%s\n",x) +#define con_dlb(x) fprintf(codefile,".long\t%s\n",x) + +#define modhead "" + +#define id_first '_' +#define BSS_INIT 0 +