Pristine Ack-5.5
[Ack-5.5.git] / mach / i386 / ncg / mach.c
1 /*
2  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
3  * See the copyright notice in the ACK home directory, in the file "Copyright".
4  *
5  */
6
7 #ifndef NORCSID
8 static char rcs_m[]= "$Id: mach.c,v 1.11 1995/03/17 12:37:06 ceriel Exp $" ;
9 static char rcs_mh[]= ID_MH ;
10 #endif
11
12 #include <stb.h>
13
14 /*
15  * machine dependent back end routines for the Intel 80386
16  */
17
18 con_part(sz,w) register sz; word w; {
19
20         while (part_size % sz)
21                 part_size++;
22         if (part_size == TEM_WSIZE)
23                 part_flush();
24         if (sz == 1 || sz == 2) {
25                 w &= (sz == 1 ? 0xFF : 0xFFFF);
26                 w <<= 8 * part_size;
27                 part_word |= w;
28         } else {
29                 assert(sz == 4);
30                 part_word = w;
31         }
32         part_size += sz;
33 }
34
35 con_mult(sz) word sz; {
36         long l;
37
38         if (sz != 4)
39                 fatal("bad icon/ucon size");
40         l = atol(str);
41         fprintf(codefile,"\t.data4 %ld\n", l);
42 }
43
44 #define CODE_GENERATOR  
45 #define IEEEFLOAT  
46 #define FL_MSL_AT_LOW_ADDRESS   0
47 #define FL_MSW_AT_LOW_ADDRESS   0
48 #define FL_MSB_AT_LOW_ADDRESS   0
49 #include <con_float>
50
51 /*
52
53 string holstr(n) word n; {
54
55         sprintf(str,hol_off,n,holno);
56         return(mystrcpy(str));
57 }
58 */
59
60 #ifdef REGVARS
61 full lbytes;
62 #endif
63
64 prolog(nlocals) full nlocals; {
65
66         fputs("push ebp\nmov ebp,esp\n", codefile);
67 #ifdef REGVARS
68         lbytes = nlocals;
69 #else
70 #ifdef NOTDEF
71         probably not better on 386.
72         switch(nlocals) {
73         case 8:
74                 fputs("push eax\n", codefile);
75                 /* fall through */
76         case 4:
77                 fputs("push eax\n", codefile);
78                 break;
79         default:
80 #endif
81                 fprintf(codefile, "sub\tesp,%ld\n",nlocals);
82 #ifdef NOTDEF
83                 break;
84         }
85 #endif
86 #endif
87 }
88
89 #ifdef REGVARS
90 long si_off;
91 long di_off;
92 int firstreg;
93
94 regscore(off, size, typ, score, totyp)
95         long off;
96 {
97         if (size != 4) return -1;
98         score -= 1;
99         score += score;
100         if (typ == reg_pointer || typ == reg_loop) score += (score >> 2);
101         score -= 2;     /* cost of saving */
102         if (off >= 0) score -= 3;
103         return score;
104 }
105
106 i_regsave()
107 {
108         si_off = -1;
109         di_off = -1;
110         firstreg = 0;
111 }
112
113 f_regsave()
114 {
115         if (si_off != di_off) {
116                 if (si_off == -lbytes) lbytes -= 4;
117                 if (di_off == -lbytes) lbytes -= 4;
118                 if (si_off == -lbytes) lbytes -= 4;
119         }
120         if (lbytes) fprintf(codefile, "sub\tesp,%ld\n",(long) lbytes);
121         if (firstreg == 1) {
122                 fputs("push edi\n", codefile);
123                 if (si_off != -1) fputs("push esi\n", codefile);
124         }
125         else if (firstreg == -1) {
126                 fputs("push esi\n", codefile);
127                 if (di_off != -1) fputs("push edi\n", codefile);
128         }
129         if (si_off >= 0)
130                 fprintf(codefile, "mov esi,%ld(ebp)\n", si_off);
131         if (di_off >= 0)
132                 fprintf(codefile, "mov edi,%ld(ebp)\n", di_off);
133 }
134
135 regsave(regstr, off, size)
136         char *regstr;
137         long off;
138 {
139         if (strcmp(regstr, "esi") == 0) {
140                 if (! firstreg) firstreg = -1;
141                 si_off = off;
142         }
143         else {
144                 if (! firstreg) firstreg = 1;
145                 di_off = off;
146         }
147 }
148
149 regreturn()
150 {
151         if (firstreg == 1) {
152                 if (si_off != -1) fputs("pop esi\n", codefile);
153                 fputs("pop edi\n", codefile);
154         }
155         else if (firstreg == -1) {
156                 if (di_off != -1) fputs("pop edi\n", codefile);
157                 fputs("pop esi\n", codefile);
158         }
159         fputs("leave\nret\n", codefile);
160 }
161 #endif /* REGVARS */
162
163 #ifdef MACH_OPTIONS
164 static int gdb_flag = 0;
165 static char *fp_hook_nam;
166
167 mach_option(s)
168         char *s;
169 {
170         if (! strcmp(s, "-gdb")) {
171                 gdb_flag = 1;
172         }
173         else if (s[1] == 'F') {
174                 fp_hook_nam = &s[2];
175         }
176         else {
177                 error("Unknown flag %s", s);
178         }
179 }
180 #endif /* MACH_OPTIONS */
181
182 mes(type) word type ; {
183         int argt, a1, a2 ;
184
185         switch ( (int)type ) {
186         case ms_ext :
187                 for (;;) {
188                         switch ( argt=getarg(
189                             ptyp(sp_cend)|ptyp(sp_pnam)|sym_ptyp) ) {
190                         case sp_cend :
191                                 return ;
192                         default:
193                                 strarg(argt) ;
194                                 fprintf(codefile, ".define %s\n",argstr) ;
195                                 break ;
196                         }
197                 }
198         case ms_stb:
199                 argt = getarg(str_ptyp | cst_ptyp);
200                 if (argt == sp_cstx)
201                         fputs(".symb \"\", ", codefile);
202                 else {
203                         fprintf(codefile, ".symb \"%s\", ", str);
204                         argt = getarg(cst_ptyp);
205                 }
206                 a1 = argval;
207                 argt = getarg(cst_ptyp);
208                 a2 = argval;
209                 argt = getarg(cst_ptyp|nof_ptyp|sof_ptyp|ilb_ptyp|pro_ptyp);
210 #ifdef MACH_OPTIONS
211                 if (gdb_flag) {
212                         if (a1 == N_PSYM) {
213                                 /* Change offset from AB into offset from
214                                    the frame pointer (bp).
215                                 */
216                                 argval += 8;
217                         }
218                 }
219 #endif
220                 fprintf(codefile, "%s, 0x%x, %d\n", strarg(argt), a1, a2);
221                 argt = getarg(end_ptyp);
222                 break;
223         case ms_std:
224                 argt = getarg(str_ptyp | cst_ptyp);
225                 if (argt == sp_cstx)
226                         str[0] = '\0';
227                 else {
228                         argt = getarg(cst_ptyp);
229                 }
230                 swtxt();
231                 if (argval == N_SLINE
232 #ifdef MACH_OPTIONS
233                     && ! gdb_flag
234 #endif
235                 ) {
236                         fputs("call ___u_LiB\n", codefile);
237                         cleanregs();    /* debugger might change variables */
238                 }
239                 fprintf(codefile, ".symd \"%s\", 0x%x,", str, (int) argval);
240                 argt = getarg(cst_ptyp);
241                 fprintf(codefile, "%d\n", (int) argval);
242                 argt = getarg(end_ptyp);
243                 break;
244 #ifdef MACH_OPTIONS
245         case ms_flt:
246                 if (fp_hook_nam) {
247                         part_flush();
248                         ex_ap(fp_hook_nam);
249                 }
250                 /* fall through */
251 #endif
252         default :
253                 while ( getarg(any_ptyp) != sp_cend ) ;
254                 break ;
255         }
256 }
257
258 char    *segname[] = {
259         ".sect .text",        /* SEGTXT */
260         ".sect .data",        /* SEGCON */
261         ".sect .rom",        /* SEGROM */
262         ".sect .bss"          /* SEGBSS */
263 };