2 enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 };
4 #define NODEPTR_TYPE Node
5 #define OP_LABEL(p) ((p)->op)
6 #define LEFT_CHILD(p) ((p)->kids[0])
7 #define RIGHT_CHILD(p) ((p)->kids[1])
8 #define STATE_LABEL(p) ((p)->x.state)
9 static void address ARGS((Symbol, Symbol, int));
10 static void blkfetch ARGS((int, int, int, int));
11 static void blkloop ARGS((int, int, int, int, int, int[]));
12 static void blkstore ARGS((int, int, int, int));
13 static void defaddress ARGS((Symbol));
14 static void defconst ARGS((int, Value));
15 static void defstring ARGS((int, char *));
16 static void defsymbol ARGS((Symbol));
17 static void doarg ARGS((Node));
18 static void emit2 ARGS((Node));
19 static void export ARGS((Symbol));
20 static void clobber ARGS((Node));
21 static void function ARGS((Symbol, Symbol [], Symbol [], int));
22 static void global ARGS((Symbol));
23 static void import ARGS((Symbol));
24 static void local ARGS((Symbol));
25 static void progbeg ARGS((int, char **));
26 static void progend ARGS((void));
27 static void segment ARGS((int));
28 static void space ARGS((int));
29 static void target ARGS((Node));
30 static int ckstack ARGS((Node, int));
31 static int memop ARGS((Node));
32 static int sametree ARGS((Node, Node));
33 static Symbol charreg[32], shortreg[32], intreg[32];
34 static Symbol fltreg[32];
38 static Symbol quo, rem;
42 %term ADDD=306 ADDF=305 ADDI=309 ADDP=311 ADDU=310
46 %term ARGB=41 ARGD=34 ARGF=33 ARGI=37 ARGP=39
47 %term ASGNB=57 ASGNC=51 ASGND=50 ASGNF=49 ASGNI=53 ASGNP=55 ASGNS=52
52 %term CALLB=217 CALLD=210 CALLF=209 CALLI=213 CALLV=216
53 %term CNSTC=19 CNSTD=18 CNSTF=17 CNSTI=21 CNSTP=23 CNSTS=20 CNSTU=22
55 %term CVDF=97 CVDI=101
57 %term CVIC=131 CVID=130 CVIS=132 CVIU=134
59 %term CVSI=165 CVSU=166
60 %term CVUC=179 CVUI=181 CVUP=183 CVUS=180
61 %term DIVD=450 DIVF=449 DIVI=453 DIVU=454
62 %term EQD=482 EQF=481 EQI=485
63 %term GED=498 GEF=497 GEI=501 GEU=502
64 %term GTD=514 GTF=513 GTI=517 GTU=518
65 %term INDIRB=73 INDIRC=67 INDIRD=66 INDIRF=65 INDIRI=69 INDIRP=71 INDIRS=68
68 %term LED=530 LEF=529 LEI=533 LEU=534
69 %term LOADB=233 LOADC=227 LOADD=226 LOADF=225 LOADI=229 LOADP=231 LOADS=228 LOADU=230
70 %term LSHI=341 LSHU=342
71 %term LTD=546 LTF=545 LTI=549 LTU=550
72 %term MODI=357 MODU=358
73 %term MULD=466 MULF=465 MULI=469 MULU=470
74 %term NED=562 NEF=561 NEI=565
75 %term NEGD=194 NEGF=193 NEGI=197
76 %term RETD=242 RETF=241 RETI=245
77 %term RSHI=373 RSHU=374
78 %term SUBD=322 SUBF=321 SUBI=325 SUBP=327 SUBU=326
81 reg: INDIRC(VREGP) "# read register\n"
82 reg: INDIRD(VREGP) "# read register\n"
83 reg: INDIRF(VREGP) "# read register\n"
84 reg: INDIRI(VREGP) "# read register\n"
85 reg: INDIRP(VREGP) "# read register\n"
86 reg: INDIRS(VREGP) "# read register\n"
87 stmt: ASGNC(VREGP,reg) "# write register\n"
88 stmt: ASGND(VREGP,reg) "# write register\n"
89 stmt: ASGNF(VREGP,reg) "# write register\n"
90 stmt: ASGNI(VREGP,reg) "# write register\n"
91 stmt: ASGNP(VREGP,reg) "# write register\n"
92 stmt: ASGNS(VREGP,reg) "# write register\n"
99 reg: CVIU(reg) "%0" notarget(a)
100 reg: CVPU(reg) "%0" notarget(a)
101 reg: CVUI(reg) "%0" notarget(a)
102 reg: CVUP(reg) "%0" notarget(a)
107 base: ADDI(reg,acon) "%0 + (%1)"
108 base: ADDP(reg,acon) "%0 + (%1)"
109 base: ADDU(reg,acon) "%0 + (%1)"
110 base: ADDRFP "ebp + %a"
111 base: ADDRLP "ebp + %a"
113 index: LSHI(reg,con1) "%0*2"
114 index: LSHI(reg,con2) "%0*4"
115 index: LSHI(reg,con3) "%0*8"
117 con1: CNSTI "1" range(a, 1, 1)
118 con1: CNSTU "1" range(a, 1, 1)
119 con2: CNSTI "2" range(a, 2, 2)
120 con2: CNSTU "2" range(a, 2, 2)
121 con3: CNSTI "3" range(a, 3, 3)
122 con3: CNSTU "3" range(a, 3, 3)
123 index: LSHU(reg,con1) "%0*2"
124 index: LSHU(reg,con2) "%0*4"
125 index: LSHU(reg,con3) "%0*8"
127 addr: ADDI(index,base) "[%1 + %0]"
128 addr: ADDP(index,base) "[%1 + %0]"
129 addr: ADDU(index,base) "[%1 + %0]"
131 mem: INDIRC(addr) "byte %0"
132 mem: INDIRI(addr) "dword %0"
133 mem: INDIRP(addr) "dword %0"
134 mem: INDIRS(addr) "word %0"
148 reg: addr "lea %c,%0\n" 1
149 reg: mrc0 "mov %c,%0\n" 1
150 reg: LOADC(reg) "mov %c,%0\n" move(a)
151 reg: LOADI(reg) "mov %c,%0\n" move(a)
152 reg: LOADP(reg) "mov %c,%0\n" move(a)
153 reg: LOADS(reg) "mov %c,%0\n" move(a)
154 reg: LOADU(reg) "mov %c,%0\n" move(a)
155 reg: ADDI(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1
156 reg: ADDP(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1
157 reg: ADDU(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1
158 reg: SUBI(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1
159 reg: SUBP(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1
160 reg: SUBU(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1
161 reg: BANDU(reg,mrc1) "?mov %c,%0\nand %c,%1\n" 1
162 reg: BORU(reg,mrc1) "?mov %c,%0\nor %c,%1\n" 1
163 reg: BXORU(reg,mrc1) "?mov %c,%0\nxor %c,%1\n" 1
164 stmt: ASGNI(addr,ADDI(mem,con1)) "inc %1\n" memop(a)
165 stmt: ASGNI(addr,ADDU(mem,con1)) "inc %1\n" memop(a)
166 stmt: ASGNP(addr,ADDP(mem,con1)) "inc %1\n" memop(a)
167 stmt: ASGNI(addr,SUBI(mem,con1)) "dec %1\n" memop(a)
168 stmt: ASGNI(addr,SUBU(mem,con1)) "dec %1\n" memop(a)
169 stmt: ASGNP(addr,SUBP(mem,con1)) "dec %1\n" memop(a)
170 stmt: ASGNI(addr,ADDI(mem,rc)) "add %1,%2\n" memop(a)
171 stmt: ASGNI(addr,ADDU(mem,rc)) "add %1,%2\n" memop(a)
172 stmt: ASGNI(addr,SUBI(mem,rc)) "sub %1,%2\n" memop(a)
173 stmt: ASGNI(addr,SUBU(mem,rc)) "sub %1,%2\n" memop(a)
175 stmt: ASGNI(addr,BANDU(mem,rc)) "and %1,%2\n" memop(a)
176 stmt: ASGNI(addr,BORU(mem,rc)) "or %1,%2\n" memop(a)
177 stmt: ASGNI(addr,BXORU(mem,rc)) "xor %1,%2\n" memop(a)
178 reg: BCOMU(reg) "?mov %c,%0\nnot %c\n" 2
179 reg: NEGI(reg) "?mov %c,%0\nneg %c\n" 2
181 stmt: ASGNI(addr,BCOMU(mem)) "not %1\n" memop(a)
182 stmt: ASGNI(addr,NEGI(mem)) "neg %1\n" memop(a)
183 reg: LSHI(reg,rc5) "?mov %c,%0\nsal %c,%1\n" 2
184 reg: LSHU(reg,rc5) "?mov %c,%0\nshl %c,%1\n" 2
185 reg: RSHI(reg,rc5) "?mov %c,%0\nsar %c,%1\n" 2
186 reg: RSHU(reg,rc5) "?mov %c,%0\nshr %c,%1\n" 2
188 stmt: ASGNI(addr,LSHI(mem,rc5)) "sal %1,%2\n" memop(a)
189 stmt: ASGNI(addr,LSHU(mem,rc5)) "shl %1,%2\n" memop(a)
190 stmt: ASGNI(addr,RSHI(mem,rc5)) "sar %1,%2\n" memop(a)
191 stmt: ASGNI(addr,RSHU(mem,rc5)) "shr %1,%2\n" memop(a)
193 rc5: CNSTI "%a" range(a, 0, 31)
195 reg: MULI(reg,mrc3) "?mov %c,%0\nimul %c,%1\n" 14
196 reg: MULI(con,mr) "imul %c,%1,%0\n" 13
197 reg: MULU(reg,mr) "mul %1\n" 13
198 reg: DIVU(reg,reg) "xor edx,edx\ndiv %1\n"
199 reg: MODU(reg,reg) "xor edx,edx\ndiv %1\n"
200 reg: DIVI(reg,reg) "cdq\nidiv %1\n"
201 reg: MODI(reg,reg) "cdq\nidiv %1\n"
202 reg: CVIU(reg) "mov %c,%0\n" move(a)
203 reg: CVPU(reg) "mov %c,%0\n" move(a)
204 reg: CVUI(reg) "mov %c,%0\n" move(a)
205 reg: CVUP(reg) "mov %c,%0\n" move(a)
206 reg: CVCI(INDIRC(addr)) "movsx %c,byte %0\n" 3
207 reg: CVCU(INDIRC(addr)) "movzx %c,byte %0\n" 3
208 reg: CVSI(INDIRS(addr)) "movsx %c,word %0\n" 3
209 reg: CVSU(INDIRS(addr)) "movzx %c,word %0\n" 3
210 reg: CVCI(reg) "# extend\n" 3
211 reg: CVCU(reg) "# extend\n" 3
212 reg: CVSI(reg) "# extend\n" 3
213 reg: CVSU(reg) "# extend\n" 3
215 reg: CVIC(reg) "# truncate\n" 1
216 reg: CVIS(reg) "# truncate\n" 1
217 reg: CVUC(reg) "# truncate\n" 1
218 reg: CVUS(reg) "# truncate\n" 1
219 stmt: ASGNC(addr,rc) "mov byte %0,%1\n" 1
220 stmt: ASGNI(addr,rc) "mov dword %0,%1\n" 1
221 stmt: ASGNP(addr,rc) "mov dword %0,%1\n" 1
222 stmt: ASGNS(addr,rc) "mov word %0,%1\n" 1
223 stmt: ARGI(mrc3) "push dword %0\n" 1
224 stmt: ARGP(mrc3) "push dword %0\n" 1
225 stmt: ASGNB(reg,INDIRB(reg)) "mov ecx,%a\nrep movsb\n"
226 stmt: ARGB(INDIRB(reg)) "sub esp,%a\nmov edi,esp\nmov ecx,%a\nrep movsb\n"
228 memf: INDIRD(addr) "qword %0"
229 memf: INDIRF(addr) "dword %0"
230 memf: CVFD(INDIRF(addr)) "dword %0"
231 reg: memf "fld %0\n" 3
232 stmt: ASGND(addr,reg) "fstp qword %0\n" 7
233 stmt: ASGNF(addr,reg) "fstp dword %0\n" 7
234 stmt: ASGNF(addr,CVDF(reg)) "fstp dword %0\n" 7
235 stmt: ARGD(reg) "sub esp,8\nfstp qword [esp]\n"
236 stmt: ARGF(reg) "sub esp,4\nfstp dword [esp]\n"
237 reg: NEGD(reg) "fchs\n"
238 reg: NEGF(reg) "fchs\n"
239 reg: ADDD(reg,memf) "fadd %1\n"
240 reg: ADDD(reg,reg) "faddp st1\n"
241 reg: ADDF(reg,memf) "fadd %1\n"
242 reg: ADDF(reg,reg) "faddp st1\n"
243 reg: DIVD(reg,memf) "fdiv %1\n"
244 reg: DIVD(reg,reg) "fdivp st1\n"
245 reg: DIVF(reg,memf) "fdiv %1\n"
246 reg: DIVF(reg,reg) "fdivp st1\n"
247 reg: MULD(reg,memf) "fmul %1\n"
248 reg: MULD(reg,reg) "fmulp st1\n"
249 reg: MULF(reg,memf) "fmul %1\n"
250 reg: MULF(reg,reg) "fmulp st1\n"
251 reg: SUBD(reg,memf) "fsub %1\n"
252 reg: SUBD(reg,reg) "fsubp st1\n"
253 reg: SUBF(reg,memf) "fsub %1\n"
254 reg: SUBF(reg,reg) "fsubp st1\n"
255 reg: CVFD(reg) "# CVFD\n"
256 reg: CVDF(reg) "sub esp,4\nfstp dword [esp]\nfld dword [esp]\nadd esp,4\n" 12
258 stmt: ASGNI(addr,CVDI(reg)) "fistp dword %0\n" 29
259 reg: CVDI(reg) "sub esp,4\nfistp dword [esp]\npop %c\n" 31
261 reg: CVID(INDIRI(addr)) "fild dword %0\n" 10
262 reg: CVID(reg) "push %0\nfild dword [esp]\nadd esp,4\n" 12
268 stmt: JUMPV(addrj) "jmp %0\n" 3
270 stmt: EQI(mem,rc) "cmp %0,%1\nje near %a\n" 5
271 stmt: GEI(mem,rc) "cmp %0,%1\njge near %a\n" 5
272 stmt: GTI(mem,rc) "cmp %0,%1\njg near %a\n" 5
273 stmt: LEI(mem,rc) "cmp %0,%1\njle near %a\n" 5
274 stmt: LTI(mem,rc) "cmp %0,%1\njl near %a\n" 5
275 stmt: NEI(mem,rc) "cmp %0,%1\njne near %a\n" 5
276 stmt: GEU(mem,rc) "cmp %0,%1\njae near %a\n" 5
277 stmt: GTU(mem,rc) "cmp %0,%1\nja near %a\n" 5
278 stmt: LEU(mem,rc) "cmp %0,%1\njbe near %a\n" 5
279 stmt: LTU(mem,rc) "cmp %0,%1\njb near %a\n" 5
280 stmt: EQI(reg,mrc1) "cmp %0,%1\nje near %a\n" 4
281 stmt: GEI(reg,mrc1) "cmp %0,%1\njge near %a\n" 4
282 stmt: GTI(reg,mrc1) "cmp %0,%1\njg near %a\n" 4
283 stmt: LEI(reg,mrc1) "cmp %0,%1\njle near %a\n" 4
284 stmt: LTI(reg,mrc1) "cmp %0,%1\njl near %a\n" 4
285 stmt: NEI(reg,mrc1) "cmp %0,%1\njne near %a\n" 4
287 stmt: GEU(reg,mrc1) "cmp %0,%1\njae near %a\n" 4
288 stmt: GTU(reg,mrc1) "cmp %0,%1\nja near %a\n" 4
289 stmt: LEU(reg,mrc1) "cmp %0,%1\njbe near %a\n" 4
290 stmt: LTU(reg,mrc1) "cmp %0,%1\njb near %a\n" 4
293 stmt: EQD(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nje near %a\n"
294 stmt: GED(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njbe near %a\n"
295 stmt: GTD(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njb near %a\n"
296 stmt: LED(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njae near %a\n"
297 stmt: LTD(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nja near %a\n"
298 stmt: NED(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njne near %a\n"
300 stmt: EQF(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nje near %a\n"
301 stmt: GEF(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njbe near %a\n"
302 stmt: GTF(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njb near %a\n"
303 stmt: LEF(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njae near %a\n"
304 stmt: LTF(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nja near %a\n"
305 stmt: NEF(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njne near %a\n"
306 reg: CALLI(addrj) "call %0\nadd esp,%a\n"
307 stmt: CALLV(addrj) "call %0\nadd esp,%a\n"
308 reg: CALLF(addrj) "call %0\nadd esp,%a\n"
309 reg: CALLD(addrj) "call %0\nadd esp,%a\n"
311 stmt: RETI(reg) "# ret\n"
312 stmt: RETF(reg) "# ret\n"
313 stmt: RETD(reg) "# ret\n"
315 static void progbeg(argc, argv) int argc; char *argv[]; {
325 swap = (u.i == 1) != IR->little_endian;
327 parseflags(argc, argv);
328 intreg[EAX] = mkreg("eax", EAX, 1, IREG);
329 intreg[EDX] = mkreg("edx", EDX, 1, IREG);
330 intreg[ECX] = mkreg("ecx", ECX, 1, IREG);
331 intreg[EBX] = mkreg("ebx", EBX, 1, IREG);
332 intreg[ESI] = mkreg("esi", ESI, 1, IREG);
333 intreg[EDI] = mkreg("edi", EDI, 1, IREG);
334 shortreg[EAX] = mkreg("ax", EAX, 1, IREG);
335 shortreg[ECX] = mkreg("cx", ECX, 1, IREG);
336 shortreg[EDX] = mkreg("dx", EDX, 1, IREG);
337 shortreg[EBX] = mkreg("bx", EBX, 1, IREG);
338 shortreg[ESI] = mkreg("si", ESI, 1, IREG);
339 shortreg[EDI] = mkreg("di", EDI, 1, IREG);
341 charreg[EAX] = mkreg("al", EAX, 1, IREG);
342 charreg[ECX] = mkreg("cl", ECX, 1, IREG);
343 charreg[EDX] = mkreg("dl", EDX, 1, IREG);
344 charreg[EBX] = mkreg("bl", EBX, 1, IREG);
345 for (i = 0; i < 8; i++)
346 fltreg[i] = mkreg("%d", i, 0, FREG);
347 rmap[C] = mkwildcard(charreg);
348 rmap[S] = mkwildcard(shortreg);
349 rmap[P] = rmap[B] = rmap[U] = rmap[I] = mkwildcard(intreg);
350 rmap[F] = rmap[D] = mkwildcard(fltreg);
351 tmask[IREG] = (1<<EDI) | (1<<ESI) | (1<<EBX)
352 | (1<<EDX) | (1<<ECX) | (1<<EAX);
357 quo = mkreg("eax", EAX, 1, IREG);
358 quo->x.regnode->mask |= 1<<EDX;
359 rem = mkreg("edx", EDX, 1, IREG);
360 rem->x.regnode->mask |= 1<<EAX;
362 static void segment(n) int n; {
367 print("[section .text]\n");
368 else if (cseg == DATA || cseg == LIT)
369 print("[section .data]\n");
370 else if (cseg == BSS)
371 print("[section .bss]\n");
373 static void progend() {
376 static void target(p) Node p; {
379 case RSHI: case RSHU: case LSHI: case LSHU:
380 if (generic(p->kids[1]->op) != CNST
381 && !( generic(p->kids[1]->op) == INDIR
382 && p->kids[1]->kids[0]->op == VREG+P
383 && p->kids[1]->syms[RX]->u.t.cse
384 && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST
386 rtarget(p, 1, intreg[ECX]);
387 setreg(p, intreg[EAX]);
392 rtarget(p, 0, intreg[EAX]);
394 case DIVI: case DIVU:
396 rtarget(p, 0, intreg[EAX]);
397 rtarget(p, 1, intreg[ECX]);
399 case MODI: case MODU:
401 rtarget(p, 0, intreg[EAX]);
402 rtarget(p, 1, intreg[ECX]);
405 rtarget(p, 0, intreg[EDI]);
406 rtarget(p->kids[1], 0, intreg[ESI]);
409 rtarget(p->kids[0], 0, intreg[ESI]);
411 case CALLI: case CALLV:
412 setreg(p, intreg[EAX]);
415 rtarget(p, 0, intreg[EAX]);
420 static void clobber(p) Node p; {
421 static int nstack = 0;
424 nstack = ckstack(p, nstack);
425 assert(p->count > 0 || nstack == 0);
427 case ASGNB: case ARGB:
428 spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p);
430 case EQD: case LED: case GED: case LTD: case GTD: case NED:
431 case EQF: case LEF: case GEF: case LTF: case GTF: case NEF:
432 spill(1<<EAX, IREG, p);
434 case CALLD: case CALLF:
435 spill(1<<EDX | 1<<EAX, IREG, p);
439 #define isfp(p) (optype((p)->op)==F || optype((p)->op)==D)
441 static int ckstack(p, n) Node p; int n; {
444 for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++)
445 if (isfp(p->x.kids[i]))
447 if (isfp(p) && p->count > 0)
450 error("expression too complicated\n");
451 debug(fprint(2, "(ckstack(%x)=%d)\n", p, n));
455 static int memop(p) Node p; {
457 assert(generic(p->op) == ASGN);
460 if (generic(p->kids[1]->kids[0]->op) == INDIR
461 && sametree(p->kids[0], p->kids[1]->kids[0]->kids[0]))
466 static int sametree(p, q) Node p, q; {
467 return p == NULL && q == NULL
468 || p && q && p->op == q->op && p->syms[0] == q->syms[0]
469 && sametree(p->kids[0], q->kids[0])
470 && sametree(p->kids[1], q->kids[1]);
472 static void emit2(p) Node p; {
473 #define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name)
476 print("movsx %s,%s\n", p->syms[RX]->x.name
478 else if (p->op == CVCU)
479 print("movzx %s,%s\n", p->syms[RX]->x.name
481 else if (p->op == CVSI)
482 print("movsx %s,%s\n", p->syms[RX]->x.name
484 else if (p->op == CVSU)
485 print("movzx %s,%s\n", p->syms[RX]->x.name
487 else if (p->op == CVIC || p->op == CVIS
488 || p->op == CVUC || p->op == CVUS) {
489 char *dst = shortreg[getregnum(p)]->x.name;
490 char *src = preg(shortreg);
492 print("mov %s,%s\n", dst, src);
496 static void doarg(p) Node p; {
497 assert(p && p->syms[0]);
498 mkactual(4, p->syms[0]->u.c.v.i);
500 static void blkfetch(k, off, reg, tmp)
501 int k, off, reg, tmp; {}
502 static void blkstore(k, off, reg, tmp)
503 int k, off, reg, tmp; {}
504 static void blkloop(dreg, doff, sreg, soff, size, tmps)
505 int dreg, doff, sreg, soff, size, tmps[]; {}
506 static void local(p) Symbol p; {
507 if (isfloat(p->type))
509 if (askregvar(p, rmap[ttob(p->type)]) == 0)
512 static void function(f, caller, callee, n)
513 Symbol f, callee[], caller[]; int n; {
516 print("%s:\n", f->x.name);
521 print("mov ebp,esp\n");
522 usedmask[0] = usedmask[1] = 0;
523 freemask[0] = freemask[1] = ~(unsigned)0;
525 for (i = 0; callee[i]; i++) {
526 Symbol p = callee[i];
527 Symbol q = caller[i];
529 p->x.offset = q->x.offset = offset;
530 p->x.name = q->x.name = stringf("%d", p->x.offset);
531 p->sclass = q->sclass = AUTO;
532 offset += roundup(q->type->size, 4);
534 assert(caller[i] == 0);
535 offset = maxoffset = 0;
536 gencode(caller, callee);
537 framesize = roundup(maxoffset, 4);
539 print("sub esp,%d\n", framesize);
541 print("mov esp,ebp\n");
548 static void defsymbol(p) Symbol p; {
549 if (p->scope >= LOCAL && p->sclass == STATIC)
550 p->x.name = stringf("L%d", genlabel(1));
551 else if (p->generated)
552 p->x.name = stringf("$L%s", p->name);
553 else if (p->scope == GLOBAL || p->sclass == EXTERN)
554 /* CHANGE THIS FOR a.out */
556 p->x.name = stringf("$_%s", p->name);
558 p->x.name = stringf("$%s", p->name);
560 else if (p->scope == CONSTANTS
561 && (isint(p->type) || isptr(p->type))
562 && p->name[0] == '0' && p->name[1] == 'x')
563 p->x.name = stringf("0%sH", &p->name[2]);
567 static void address(q, p, n) Symbol q, p; int n; {
568 if (p->scope == GLOBAL
569 || p->sclass == STATIC || p->sclass == EXTERN)
570 q->x.name = stringf("%s%s%d",
571 p->x.name, n >= 0 ? "+" : "", n);
573 q->x.offset = p->x.offset + n;
574 q->x.name = stringd(q->x.offset);
577 static void defconst(ty, v) int ty; Value v; {
579 case C: print("db %d\n", v.uc); return;
580 case S: print("dw %d\n", v.ss); return;
581 case I: print("dd %d\n", v.i ); return;
582 case U: print("dd 0%xH\n", v.u ); return;
583 case P: print("dd 0%xH\n", v.p ); return;
585 print("dd 0%xH\n", *(unsigned *)&v.f);
588 unsigned *p = (unsigned *)&v.d;
589 print("dd 0%xH,0%xH\n", p[swap], p[1 - swap]);
595 static void defaddress(p) Symbol p; {
596 print("dd %s\n", p->x.name);
598 static void defstring(n, str) int n; char *str; {
604 for (s = str; s < str + n; s++)
606 if ((*s & 0x7F) == *s && *s >= ' ' && *s != '\'') {
624 if (inquote) print("'");
627 static void export(p) Symbol p; {
628 print("[global %s]\n", p->x.name);
630 static void import(p) Symbol p; {
632 print("[extern %s]\n", p->x.name);
635 static void global(p) Symbol p; {
639 print("resb ($-$$) & %d\n",
640 p->type->align > 4 ? 3 : p->type->align-1);
642 print("times ($-$$) & %d nop\n",
643 p->type->align > 4 ? 3 : p->type->align-1);
644 print("%s:\n", p->x.name);
646 print("resb %d\n", p->type->size);
648 static void space(n) int n; {
652 print("times %d db 0\n", n);
654 Interface x86nasmIR = {
659 8, 4, 1, /* double */
661 0, 4, 0, /* struct; so that ARGB keeps stack aligned */
662 1, /* little_endian */
663 0, /* mulops_calls */
666 0, /* left_to_right */
687 {1, blkfetch, blkstore, blkloop,