123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- #ifndef NORCSID
- static char rcsid[] = "$Header$";
- #endif
- /*
- * (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 == TEM_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;
- {
- if (score == 0) return -1;
- 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 TEM_BSIZE;
- static long nlocals;
- prolog(n)
- { nlocals = n; }
- i_regsave()
- {
- regnr = 0;
- nr_a_regs = 0;
- nr_d_regs = 0;
- TEM_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);
- if (nr_d_regs == 0 && nr_a_regs == 0) {
- fprintf(codefile,"clr.w -(sp)\n");
- } else {
- fprintf(codefile,"move.w #%d,-(sp)\n",
- nr_d_regs + (nr_a_regs<<3));
- }
- /* Compute AB - LB */
- TEM_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 + TEM_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 */
- };
|