Pristine Ack-5.5
[Ack-5.5.git] / mach / m68020 / ncg / mach.c
1 /* $Id: mach.c,v 1.32 1994/06/24 13:07:10 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  *
6  */
7
8 /*
9  * machine dependent back end routines for the Motorola 68000, 68010 or 68020
10  */
11
12 #include <whichone.h>
13
14 #if TBL68020
15 #define SYNTAX_68020    1
16 #endif
17
18 #include <stb.h>
19
20 con_part(sz,w) register sz; word w; {
21
22         while (part_size % sz)
23                 part_size++;
24         if (part_size == TEM_WSIZE)
25                 part_flush();
26         if (sz == 1) {
27                 w &= 0xFF;
28 #if WORD_SIZE==4
29                 w <<= 8*(3-part_size);
30                 part_word |= w;
31         } else if (sz == 2) {
32                 w &= 0xFFFF;
33 #endif
34                 if (part_size == 0) {
35                         /* Shift 8 for m68k2, 16 otherwise */
36                         w <<= 4 * TEM_WSIZE;
37                 }
38                 part_word |= w;
39         } else {
40                 assert(sz == TEM_WSIZE);
41                 part_word = w;
42         }
43         part_size += sz;
44 }
45
46 con_mult(sz) word sz; {
47
48         if (sz != 4)
49                 fatal("bad icon/ucon size");
50         fprintf(codefile,".data4 %s\n",str);
51 }
52
53 #define IEEEFLOAT
54 #define CODE_GENERATOR
55 #define FL_MSL_AT_LOW_ADDRESS   1
56 #define FL_MSW_AT_LOW_ADDRESS   1
57 #define FL_MSB_AT_LOW_ADDRESS   1
58 #include <con_float>
59
60 regscore(off,size,typ,score,totyp)
61         long off;
62 {
63         if (score == 0) return -1;
64         switch(typ) {
65                 case reg_float:
66                         return -1;
67                 case reg_pointer:
68                         if (size != 4 || totyp != reg_pointer) return -1;
69                         score += (score >> 1);
70                         break;
71                 case reg_loop:
72                         score += 5;
73                         /* fall through .. */
74                 case reg_any:
75                         if (size != TEM_WSIZE || totyp == reg_pointer) return -1;
76                         break;
77         }
78         if (off >= 0) {
79                 /* parameters must be initialised with an instruction
80                  * like "move.l 4(a6),d0", which costs 2 words.
81                  */
82                 score -= 2;
83         }
84         score--;        /* save/restore */
85         return score;
86 }
87 struct regsav_t {
88         char    *rs_reg;        /* e.g. "a3" or "d5" */
89         long    rs_off;         /* offset of variable */
90         int     rs_size;        /* 2 or 4 bytes */
91 } regsav[9];
92
93
94 int regnr;
95
96 i_regsave()
97 {
98         regnr = 0;
99 }
100
101 full nlocals;
102
103 regreturn()
104 {
105         register struct regsav_t *p;
106
107         if (regnr > 1)  {
108 #ifdef SYNTAX_68020
109                 fprintf(codefile,"movem.l (-%ld,a6),", nlocals);
110 #else
111                 fprintf(codefile,"movem.l -%ld(a6),", nlocals);
112 #endif
113                 for (p = regsav; ;) {
114                         fputs(p->rs_reg, codefile);
115                         if (++p == &regsav[regnr]) break;
116                         putc('/',codefile);
117                 }
118                 putc('\n',codefile);
119         } else if (regnr == 1) {
120                 p = regsav;
121 #ifdef SYNTAX_68020
122                 fprintf(codefile,"move.l (-%ld,a6),%s\n",nlocals, p->rs_reg);
123 #else
124                 fprintf(codefile,"move.l -%ld(a6),%s\n",nlocals, p->rs_reg);
125 #endif
126         }
127         fputs("unlk a6\nrts\n", codefile);
128 }
129
130 f_regsave()
131 {
132         register struct regsav_t *p;
133
134         nlocals += regnr*4;
135 #ifdef TBL68020
136         fprintf(codefile,"link\ta6,#-%ld\n",nlocals);
137 #else
138         if (nlocals > 32768) {
139                 fprintf(codefile, "move.l a6,-(sp)\nmove.l sp,a6\nsub #%ld,sp\n", nlocals);
140         }
141         else    fprintf(codefile,"link\ta6,#-%ld\n",nlocals);
142 #endif
143 #ifndef NOSTACKTEST
144         fprintf(codefile, "tst.b %s\n",
145 #ifdef SYNTAX_68020
146                 "(-40, sp)"
147 #else
148                 "-40(sp)"
149 #endif
150         );
151 #endif
152         if (regnr > 1) {
153                 fputs("movem.l ", codefile);
154                 for (p = regsav; ;) {
155                         fputs(p->rs_reg, codefile);
156                         if (++p == &regsav[regnr]) break;
157                         putc('/',codefile);
158                 }
159                 fputs(",(sp)\n", codefile);
160         } else if (regnr == 1) {
161                 p = regsav;
162                 fprintf(codefile,"move.l %s,(sp)\n",p->rs_reg);
163         }
164         /* initialise register-parameters */
165         for (p = regsav; p < &regsav[regnr]; p++) {
166                 if (p->rs_off >= 0) {
167 #ifdef SYNTAX_68020
168                         fprintf(codefile,"move.%c (%ld,a6),%s\n",
169 #else
170                         fprintf(codefile,"move.%c %ld(a6),%s\n",
171 #endif
172                                 (p->rs_size == 4 ? 'l' : 'w'),
173                                 p->rs_off,
174                                 p->rs_reg);
175                 }
176         }
177 }
178
179 regsave(s,off,size)
180         char *s;
181         long off;
182 {
183         assert (regnr < 9);
184         regsav[regnr].rs_reg = s;
185         regsav[regnr].rs_off = off;
186         regsav[regnr++].rs_size = size;
187         fprintf(codefile, "!Local %ld into %s\n",off,s);
188 }
189
190 prolog(n) full n; {
191
192         nlocals = n;
193 }
194
195 #ifdef MACH_OPTIONS
196 static int gdb_flag = 0;
197
198 mach_option(s)
199         char *s;
200 {
201         if (! strcmp(s, "-gdb")) {
202                 gdb_flag = 1;
203         }
204         else {
205                 error("Unknown flag %s", s);
206         }
207 }
208 #endif /* MACH_OPTIONS */
209
210 mes(type) word type ; {
211         int argt, a1, a2 ;
212
213         switch ( (int)type ) {
214         case ms_ext :
215                 for (;;) {
216                         switch ( argt=getarg(
217                             ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
218                         case sp_cend :
219                                 return ;
220                         default:
221                                 strarg(argt) ;
222                                 fprintf(codefile,".define %s\n",argstr) ;
223                                 break ;
224                         }
225                 }
226         case ms_stb:
227                 argt = getarg(str_ptyp | cst_ptyp);
228                 if (argt == sp_cstx)
229                         fputs(".symb \"\", ", codefile);
230                 else {
231                         fprintf(codefile, ".symb \"%s\", ", str);
232                         argt = getarg(cst_ptyp);
233                 }
234                 a1 = argval;
235                 argt = getarg(cst_ptyp);
236                 a2 = argval;
237                 argt = getarg(cst_ptyp|nof_ptyp|sof_ptyp|ilb_ptyp|pro_ptyp);
238 #ifdef MACH_OPTIONS
239                 if (gdb_flag) {
240                         if (a1 == N_PSYM) {
241                                 /* Change offset from AB into offset from
242                                    the frame pointer.
243                                 */
244                                 argval += 8;
245                         }
246                 }
247 #endif
248                 fprintf(codefile, "%s, 0x%x, %d\n", strarg(argt), a1, a2);
249                 argt = getarg(end_ptyp);
250                 break;
251         case ms_std:
252                 argt = getarg(str_ptyp | cst_ptyp);
253                 if (argt == sp_cstx)
254                         str[0] = '\0';
255                 else {
256                         argt = getarg(cst_ptyp);
257                 }
258                 swtxt();
259                 if (argval == N_SLINE
260 #ifdef MACH_OPTIONS
261                     && ! gdb_flag
262 #endif
263                 ) {
264 #ifdef SYNTAX_68020
265                         fputs("jsr (___u_LiB)\n", codefile);
266 #else
267                         fputs("jsr ___u_LiB\n", codefile);
268 #endif
269                         cleanregs();    /* debugger might change variables */
270                 }
271                 fprintf(codefile, ".symd \"%s\", 0x%x,", str, (int) argval);
272                 argt = getarg(cst_ptyp);
273                 fprintf(codefile, "%d\n", (int) argval);
274                 argt = getarg(end_ptyp);
275                 break;
276         default :
277                 while ( getarg(any_ptyp) != sp_cend ) ;
278                 break ;
279         }
280 }
281
282
283 char    *segname[] = {
284         ".sect .text",  /* SEGTXT */
285         ".sect .data",  /* SEGCON */
286         ".sect .rom",   /* SEGROM */
287         ".sect .bss"    /* SEGBSS */
288 };