ncc: print usage in ncc -h
[neatcc.git] / gen.c
blobea684d7858389d3d70aac9687308b03f508b56fa
1 /* neatcc code generation */
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include "ncc.h"
7 static struct mem ds; /* data segment */
8 static struct mem cs; /* code segment */
9 static long bsslen; /* bss segment size */
10 static struct ic *ic; /* current instruction stream */
11 static long ic_n; /* number of instructions in ic[] */
12 static long ic_i; /* current instruction */
13 static long *ic_luse; /* last instruction in which values are used */
15 static long *loc_off; /* offset of locals on the stack */
16 static long loc_n, loc_sz; /* number of locals */
17 static long loc_pos; /* current stack position */
18 static int *loc_mem; /* local was accessed on the stack */
20 static char (*ds_name)[NAMELEN];/* data section symbols */
21 static long *ds_off; /* data section offsets */
22 static long ds_n, ds_sz; /* number of data section symbols */
24 static int func_argc; /* number of arguments */
25 static int func_varg; /* varargs */
26 static int func_regs; /* used registers */
27 static int func_maxargs; /* the maximum number of arguments on the stack */
28 static long *ic_bbeg; /* whether each instruction begins a basic block */
30 static long ra_vmap[N_REGS]; /* register to intermediate value assignments */
31 static long ra_lmap[N_REGS]; /* register to local assignments */
32 static long *ra_gmask; /* the mask of good registers for each value */
33 static long ra_live[NTMPS]; /* live values */
34 static int ra_vmax; /* the number of values stored on the stack */
36 static long loc_add(long pos)
38 if (loc_n >= loc_sz) {
39 loc_sz = MAX(128, loc_sz * 2);
40 loc_off = mextend(loc_off, loc_n, loc_sz, sizeof(loc_off[0]));
42 loc_off[loc_n] = pos;
43 return loc_n++;
46 long o_mklocal(long sz)
48 loc_pos += ALIGN(sz, ULNG);
49 return loc_add(loc_pos);
52 void o_rmlocal(long addr, long sz)
56 long o_arg2loc(int i)
58 return i;
61 void o_bsnew(char *name, long size, int global)
63 out_def(name, OUT_BSS | (global ? OUT_GLOB : 0), bsslen, size);
64 bsslen += ALIGN(size, OUT_ALIGNMENT);
67 long o_dsnew(char *name, long size, int global)
69 int idx;
70 if (ds_n >= ds_sz) {
71 ds_sz = MAX(128, ds_sz * 2);
72 ds_name = mextend(ds_name, ds_n, ds_sz, sizeof(ds_name[0]));
73 ds_off = mextend(ds_off, ds_n, ds_sz, sizeof(ds_off[0]));
75 idx = ds_n++;
76 strcpy(ds_name[idx], name);
77 ds_off[idx] = mem_len(&ds);
78 out_def(name, OUT_DS | (global ? OUT_GLOB : 0), mem_len(&ds), size);
79 mem_putz(&ds, ALIGN(size, OUT_ALIGNMENT));
80 return ds_off[idx];
83 void o_dscpy(long addr, void *buf, long len)
85 mem_cpy(&ds, addr, buf, len);
88 static int dat_off(char *name)
90 int i;
91 for (i = 0; i < ds_n; i++)
92 if (!strcmp(name, ds_name[i]))
93 return ds_off[i];
94 return 0;
97 void o_dsset(char *name, long off, long bt)
99 long sym_off = dat_off(name) + off;
100 long num, roff, rsym;
101 if (!o_popnum(&num)) {
102 mem_cpy(&ds, sym_off, &num, T_SZ(bt));
103 return;
105 if (!o_popsym(&rsym, &roff)) {
106 out_rel(rsym, OUT_DS, sym_off);
107 mem_cpy(&ds, sym_off, &roff, T_SZ(bt));
111 static int ra_vreg(int val)
113 int i;
114 for (i = 0; i < LEN(ra_vmap); i++)
115 if (ra_vmap[i] == val)
116 return i;
117 return -1;
120 static int ra_lreg(int loc)
122 int i;
123 for (i = 0; i < LEN(ra_lmap); i++)
124 if (ra_lmap[i] == loc)
125 return i;
126 return -1;
129 /* mask of registers assigned to locals */
130 static long ra_lmask(void)
132 long m = 0;
133 int i;
134 for (i = 0; i < LEN(ra_lmap); i++)
135 if (ra_lmap[i] >= 0)
136 m |= (1 << i);
137 return m;
140 /* mask of registers assigned to values */
141 static long ra_vmask(void)
143 long m = 0;
144 int i;
145 for (i = 0; i < LEN(ra_vmap); i++)
146 if (ra_vmap[i] >= 0)
147 m |= (1 << i);
148 return m;
151 /* find a temporary register specified in the given mask */
152 static long ra_regscn(long mask)
154 int i;
155 for (i = 0; i < N_TMPS; i++)
156 if ((1 << tmpregs[i]) & mask)
157 return tmpregs[i];
158 return -1;
161 /* find a register, with the given good, acceptable, and bad register masks */
162 static long ra_regget(long iv, long gmask, long amask, long bmask)
164 long lmask, vmask;
165 gmask &= ~bmask & amask;
166 amask &= ~bmask;
167 if (ra_vreg(iv) >= 0 && (1 << ra_vreg(iv)) & (gmask | amask))
168 return ra_vreg(iv);
169 vmask = ra_vmask();
170 lmask = ra_lmask();
171 if (ra_regscn(gmask & ~vmask & ~lmask) >= 0)
172 return ra_regscn(gmask & ~vmask & ~lmask);
173 if (ra_regscn(amask & ~vmask & ~lmask) >= 0)
174 return ra_regscn(amask & ~vmask & ~lmask);
175 if (ra_regscn(gmask) >= 0)
176 return ra_regscn(gmask);
177 if (ra_regscn(amask) >= 0)
178 return ra_regscn(amask);
179 die("neatcc: cannot allocate an acceptable register\n");
180 return 0;
183 /* find a free and cheap register */
184 static long ra_regcheap(long mask)
186 return ra_regscn(mask & (func_regs | (R_TMPS & ~R_PERM)) &
187 ~ra_lmask() & ~ra_vmask());
190 /* allocate registers for the current instruction */
191 static void ra_map(int *rd, int *r1, int *r2, int *r3, long *mt)
193 long md, m1, m2, m3;
194 struct ic *c = &ic[ic_i];
195 long all = 0;
196 int n = ic_regcnt(c);
197 int oc = O_C(c->op);
198 int i;
199 *rd = -1;
200 *r1 = -1;
201 *r2 = -1;
202 *r3 = -1;
203 *mt = 0;
204 /* optimizing loading locals: point to local's register */
205 if (oc == (O_LD | O_LOC) && ra_lreg(c->a1) >= 0 &&
206 ra_vmap[ra_lreg(c->a1)] < 0) {
207 *rd = ra_lreg(c->a1);
208 func_regs |= 1 << *rd;
209 return;
211 /* do not use argument registers to hold call destination */
212 if (oc & O_CALL)
213 for (i = 0; i < MIN(c->a3, N_ARGS); i++)
214 all |= (1 << argregs[i]);
215 /* instructions on locals can be simplified */
216 if (oc & O_LOC) {
217 if (oc & O_MOV)
218 oc = O_ADD | O_NUM;
219 if (oc & (O_ST | O_LD))
220 oc = (oc & ~O_LOC) & O_NUM;
222 if (i_reg(c->op, &md, &m1, &m2, &m3, mt))
223 die("neatcc: instruction %08lx not supported\n", c->op);
225 * the registers used in global register allocation should not
226 * be used in the last instruction of a basic block.
228 if (c->op & (O_JZ | O_JCC))
229 for (i = 0; i < LEN(ra_lmap); i++)
230 if (reg_rmap(ic_i, i) >= 0 && ra_lmap[i] != reg_rmap(ic_i, i))
231 all |= (1 << i);
232 /* allocating registers for the operands */
233 if (n >= 2) {
234 *r2 = ra_regget(c->a2, m2, m2, all);
235 all |= (1 << *r2);
237 if (n >= 1) {
238 *r1 = ra_regget(c->a1, m1, m1, all);
239 all |= (1 << *r1);
241 if (n >= 3) {
242 *r3 = ra_regget(c->a3, m3, m3, all);
243 all |= (1 << *r3);
245 if (c->op & O_OUT) {
246 long m4 = (md ? md : m1) & ~all;
247 long a4 = md ? ic_i : c->a1;
248 if (n >= 1 && !md)
249 *rd = *r1;
250 else if (ra_gmask[ic_i] & md & ~all)
251 *rd = ra_regget(ic_i, ra_gmask[ic_i], md, 0);
252 else if (n >= 2 && md & (1 << *r2) && ic_luse[*r2] <= ic_i)
253 *rd = *r2;
254 else if (n >= 1 && md & (1 << *r1) && ic_luse[*r1] <= ic_i)
255 *rd = *r1;
256 else
257 *rd = ra_regget(ic_i, ra_gmask[ic_i], md, 0);
258 /* if overwriting a local, use another register */
259 if (ra_lmap[*rd] >= 0)
260 if (m4 & ~(1 << *rd))
261 *rd = ra_regget(a4, ra_gmask[ic_i], m4 & ~(1 << *rd), 0);
262 if (n >= 1 && !md)
263 *r1 = *rd;
264 all |= (1 << *rd);
266 func_regs |= all | *mt;
269 static long iv_rank(long iv)
271 int i;
272 for (i = 0; i < LEN(ra_live); i++)
273 if (ra_live[i] == iv)
274 return i;
275 die("neatcc: the specified value is not live\n");
276 return 0;
279 static long iv_addr(long rank)
281 return loc_pos + rank * ULNG + ULNG;
284 static void loc_toreg(long loc, long off, int reg, int bt)
286 loc_mem[loc]++;
287 i_ins(O_MK(O_LD | O_NUM, bt), reg, REG_FP, -loc_off[loc] + off, 0);
290 static void loc_tomem(long loc, long off, int reg, int bt)
292 loc_mem[loc]++;
293 i_ins(O_MK(O_ST | O_NUM, bt), 0, reg, REG_FP, -loc_off[loc] + off);
296 static void loc_toadd(long loc, long off, int reg)
298 loc_mem[loc]++;
299 i_ins(O_ADD | O_NUM, reg, REG_FP, -loc_off[loc] + off, 0);
302 /* return nonzero if the local is read at least once in this basic block */
303 static int loc_isread(long loc)
305 int i;
306 for (i = ic_i + 1; i < ic_n && !ic_bbeg[i]; i++)
307 if (ic[i].op & O_LOC)
308 return ic[i].op & O_LD;
309 return 0;
312 static void val_toreg(long val, int reg)
314 i_ins(O_MK(O_LD | O_NUM, ULNG), reg, REG_FP, -iv_addr(iv_rank(val)), 0);
317 static void val_tomem(long val, int reg)
319 long rank = iv_rank(val);
320 ra_vmax = MAX(ra_vmax, rank + 1);
321 i_ins(O_MK(O_ST | O_NUM, ULNG), 0, reg, REG_FP, -iv_addr(rank));
324 /* move the value to the stack */
325 static void ra_spill(int reg)
327 if (ra_vmap[reg] >= 0) {
328 val_tomem(ra_vmap[reg], reg);
329 ra_vmap[reg] = -1;
331 if (ra_lmap[reg] >= 0) {
332 if (ra_lmap[reg] == reg_rmap(ic_i, reg))
333 loc_tomem(ra_lmap[reg], 0, reg, ULNG);
334 ra_lmap[reg] = -1;
338 /* set the value to the given register */
339 static void ra_vsave(long iv, int reg)
341 int i;
342 ra_vmap[reg] = iv;
343 for (i = 0; i < LEN(ra_live); i++)
344 if (ra_live[i] < 0)
345 break;
346 if (i == LEN(ra_live))
347 die("neatcc: too many live values\n");
348 ra_live[i] = iv;
351 /* load the value into a register */
352 static void ra_vload(long iv, int reg)
354 if (ra_vmap[reg] == iv)
355 return;
356 if (ra_vmap[reg] >= 0 || ra_lmap[reg] >= 0)
357 ra_spill(reg);
358 if (ra_vreg(iv) >= 0) {
359 i_ins(O_MK(O_MOV, ULNG), reg, ra_vreg(iv), 0, 0);
360 ra_vmap[ra_vreg(iv)] = -1;
361 } else {
362 val_toreg(iv, reg);
364 ra_vmap[reg] = iv;
367 /* the value is no longer needed */
368 static void ra_vdrop(long iv)
370 int i;
371 for (i = 0; i < LEN(ra_live); i++)
372 if (ra_live[i] == iv)
373 ra_live[i] = -1;
374 if (ra_vreg(iv) >= 0)
375 ra_vmap[ra_vreg(iv)] = -1;
378 /* move the given value to memory or a free register */
379 static void ra_vmove(long iv, long mask)
381 int src = ra_vreg(iv);
382 int dst = ra_regcheap(mask);
383 if (dst >= 0 && ra_vmap[dst] < 0 && ra_lmap[dst] < 0) {
384 i_ins(O_MK(O_MOV, ULNG), dst, src, 0, 0);
385 ra_vmap[dst] = iv;
386 } else {
387 val_tomem(iv, src);
389 ra_vmap[src] = -1;
392 /* load the value of local loc into register reg */
393 static void ra_lload(long loc, long off, int reg, int bt)
395 int greg = reg_lmap(ic_i, loc);
396 if (greg >= 0) {
397 int lreg = ra_lreg(loc);
398 /* values using the same register */
399 if (ra_vmap[greg] >= 0)
400 ra_vmove(ra_vmap[greg],
401 ra_gmask[ra_vmap[greg]] & ~(1 << reg));
402 if (lreg >= 0) {
403 ra_lmap[lreg] = -1;
404 if (lreg != greg)
405 i_ins(O_MK(O_MOV, bt), greg, lreg, 0, 0);
406 } else {
407 loc_toreg(loc, off, greg, bt);
409 ra_lmap[greg] = loc;
411 if (ra_lreg(loc) < 0 && reg_safe(loc) && loc_isread(loc)) {
412 ra_lmap[reg] = loc;
413 loc_toreg(loc, off, reg, bt);
415 if (ra_lreg(loc) >= 0) {
416 if (ra_lreg(loc) != reg)
417 i_ins(O_MK(O_MOV, bt), reg, ra_lreg(loc), 0, 0);
418 } else {
419 loc_toreg(loc, off, reg, bt);
423 /* register reg contains the value of local loc */
424 static void ra_lsave(long loc, long off, int reg, int bt)
426 int lreg = ra_lreg(loc);
427 int greg = reg_lmap(ic_i, loc);
428 if (greg >= 0) {
429 if (lreg >= 0 && lreg != greg)
430 ra_lmap[lreg] = -1;
431 if (ra_vmap[greg] >= 0) /* values using the same register */
432 ra_vmove(ra_vmap[greg],
433 ra_gmask[ra_vmap[greg]] & ~(1 << reg));
434 i_ins(O_MK(O_MOV, bt), greg, reg, 0, 0);
435 ra_lmap[greg] = loc;
436 } else {
437 if (lreg >= 0)
438 ra_lmap[lreg] = -1;
439 loc_tomem(loc, off, reg, bt);
440 if (ra_lmap[reg] < 0 && reg_safe(loc) && loc_isread(loc))
441 ra_lmap[reg] = loc;
445 /* end of a basic block */
446 static void ra_bbend(void)
448 int i;
449 /* save values to memory */
450 for (i = 0; i < LEN(ra_vmap); i++)
451 if (ra_vmap[i] >= 0)
452 ra_spill(i);
453 /* dropping local caches */
454 for (i = 0; i < LEN(ra_lmap); i++)
455 if (ra_lmap[i] != reg_rmap(ic_i, i) && ra_lmap[i] >= 0)
456 ra_spill(i);
457 /* load global register allocations from memory */
458 for (i = 0; i < LEN(ra_lmap); i++) {
459 if (ra_lmap[i] != reg_rmap(ic_i, i)) {
460 ra_lmap[i] = reg_rmap(ic_i, i);
461 loc_toreg(ra_lmap[i], 0, i, ULNG);
466 static void ra_init(struct ic *ic, long ic_n)
468 long md, m1, m2, m3, mt;
469 int i, j;
470 ic_bbeg = calloc(ic_n, sizeof(ic_bbeg[0]));
471 ra_gmask = calloc(ic_n, sizeof(ra_gmask[0]));
472 loc_mem = calloc(loc_n, sizeof(loc_mem[0]));
473 /* ic_bbeg */
474 for (i = 0; i < ic_n; i++) {
475 if (i + 1 < ic_n && ic[i].op & (O_JXX | O_RET))
476 ic_bbeg[i + 1] = 1;
477 if (ic[i].op & O_JXX && ic[i].a3 < ic_n)
478 ic_bbeg[ic[i].a3] = 1;
480 /* ra_gmask */
481 for (i = 0; i < ic_n; i++) {
482 int n = ic_regcnt(ic + i);
483 int op = ic[i].op;
484 i_reg(op, &md, &m1, &m2, &m3, &mt);
485 if (n >= 1)
486 ra_gmask[ic[i].a1] = m1;
487 if (n >= 2)
488 ra_gmask[ic[i].a2] = m2;
489 if (n >= 3)
490 ra_gmask[ic[i].a3] = m3;
491 if (O_C(op) == (O_ST | O_LOC) && reg_lmap(i, ic[i].a2))
492 ra_gmask[ic[i].a1] = 1 << reg_lmap(i, ic[i].a2);
493 if (op & O_CALL)
494 for (j = 0; j < MIN(N_ARGS, ic[i].a3); j++)
495 ra_gmask[ic[i].args[j]] = 1 << argregs[j];
497 /* ra_vmap */
498 for (i = 0; i < LEN(ra_vmap); i++)
499 ra_vmap[i] = -1;
500 /* ra_lmap */
501 for (i = 0; i < LEN(ra_lmap); i++)
502 ra_lmap[i] = reg_rmap(0, i);
503 func_regs |= reg_mask();
504 /* ra_live */
505 for (i = 0; i < LEN(ra_live); i++)
506 ra_live[i] = -1;
507 ra_vmax = 0;
508 func_maxargs = 0;
511 static void ra_done(void)
513 free(ic_bbeg);
514 free(ra_gmask);
515 free(loc_mem);
518 static void ic_gencode(struct ic *ic, long ic_n)
520 int rd, r1, r2, r3;
521 long mt;
522 int i, j;
523 /* loading arguments in their allocated registers */
524 for (i = 0; i < LEN(ra_lmap); i++) {
525 int loc = ra_lmap[i];
526 if (loc >= 0 && loc < func_argc)
527 if (loc >= N_ARGS || i != argregs[loc])
528 loc_toreg(loc, 0, i, ULNG);
530 /* generating code */
531 for (i = 0; i < ic_n; i++) {
532 long op = ic[i].op;
533 long oc = O_C(op);
534 int n = ic_regcnt(ic + i);
535 ic_i = i;
536 i_label(i);
537 ra_map(&rd, &r1, &r2, &r3, &mt);
538 if (oc & O_CALL) {
539 int argc = ic[i].a3;
540 int aregs = MIN(N_ARGS, argc);
541 /* arguments passed via stack */
542 for (j = argc - 1; j >= aregs; --j) {
543 int v = ic[i].args[j];
544 int rx = ra_vreg(v) >= 0 ? ra_vreg(v) : rd;
545 ra_vload(v, rx);
546 i_ins(O_MK(O_ST | O_NUM, ULNG), 0,
547 rx, REG_SP, (j - aregs) * ULNG);
548 ra_vdrop(v);
550 func_maxargs = MAX(func_maxargs, argc - aregs);
551 /* arguments passed via registers */
552 for (j = aregs - 1; j >= 0; --j)
553 ra_vload(ic[i].args[j], argregs[j]);
555 /* loading the operands */
556 if (n >= 1)
557 ra_vload(ic[i].a1, r1);
558 if (n >= 2)
559 ra_vload(ic[i].a2, r2);
560 if (n >= 3)
561 ra_vload(ic[i].a3, r3);
562 /* dropping values that are no longer used */
563 for (j = 0; j < LEN(ra_live); j++)
564 if (ra_live[j] >= 0 && ic_luse[ra_live[j]] <= i)
565 ra_vdrop(ra_live[j]);
566 /* saving values stored in registers that may change */
567 for (j = 0; j < N_REGS; j++)
568 if (mt & (1 << j))
569 ra_spill(j);
570 /* overwriting a value that is needed later (unless loading a local to its register) */
571 if (oc & O_OUT)
572 if (oc != (O_LD | O_LOC) || ra_lmap[rd] != ic[i].a1 ||
573 ra_vmap[rd] >= 0)
574 ra_spill(rd);
575 /* before the last instruction of a basic block; for jumps */
576 if (i + 1 < ic_n && ic_bbeg[i + 1] && oc & O_JXX)
577 ra_bbend();
578 /* performing the instruction */
579 if (oc & O_BOP)
580 i_ins(op, rd, r1, oc & O_NUM ? ic[i].a2 : r2, 0);
581 if (oc & O_UOP)
582 i_ins(op, rd, r1, r2, 0);
583 if (oc == (O_LD | O_NUM))
584 i_ins(op, rd, r1, ic[i].a2, 0);
585 if (oc == (O_LD | O_LOC))
586 ra_lload(ic[i].a1, ic[i].a2, rd, O_T(op));
587 if (oc == (O_ST | O_NUM))
588 i_ins(op, 0, r1, r2, ic[i].a3);
589 if (oc == (O_ST | O_LOC))
590 ra_lsave(ic[i].a2, ic[i].a3, r1, O_T(op));
591 if (oc == O_RET)
592 i_ins(op, 0, r1, 0, 0);
593 if (oc == O_MOV)
594 i_ins(op, rd, r1, 0, 0);
595 if (oc == (O_MOV | O_NUM))
596 i_ins(op, rd, ic[i].a1, 0, 0);
597 if (oc == (O_MOV | O_LOC))
598 loc_toadd(ic[i].a1, ic[i].a2, rd);
599 if (oc == (O_MOV | O_SYM))
600 i_ins(op, rd, ic[i].a1, ic[i].a2, 0);
601 if (oc == O_CALL)
602 i_ins(op, rd, r1, 0, 0);
603 if (oc == (O_CALL | O_SYM))
604 i_ins(op, rd, ic[i].a1, ic[i].a2, 0);
605 if (oc == O_JMP)
606 i_ins(op, 0, 0, 0, ic[i].a3);
607 if (oc & O_JZ)
608 i_ins(op, 0, r1, 0, ic[i].a3);
609 if (oc & O_JCC)
610 i_ins(op, 0, r1, oc & O_NUM ? ic[i].a2 : r2, ic[i].a3);
611 if (oc == O_MSET)
612 i_ins(op, 0, r1, r2, r3);
613 if (oc == O_MCPY)
614 i_ins(op, 0, r1, r2, r3);
615 /* saving back the output register */
616 if (oc & O_OUT && ic_luse[i] > i)
617 ra_vsave(ic_i, rd);
618 /* after the last instruction of a basic block */
619 if (i + 1 < ic_n && ic_bbeg[i + 1] && !(oc & O_JXX))
620 ra_bbend();
622 i_label(ic_n);
625 static void ic_reset(void)
627 o_tmpdrop(-1);
628 o_back(0);
629 free(loc_off);
630 loc_off = NULL;
631 loc_n = 0;
632 loc_sz = 0;
633 loc_pos = I_LOC0;
636 void o_func_beg(char *name, int argc, int global, int varg)
638 int i;
639 func_argc = argc;
640 func_varg = varg;
641 func_regs = 0;
642 ic_reset();
643 for (i = 0; i < argc; i++)
644 loc_add(I_ARG0 + -i * ULNG);
645 out_def(name, (global ? OUT_GLOB : 0) | OUT_CS, mem_len(&cs), 0);
648 void o_code(char *name, char *c, long c_len)
650 out_def(name, OUT_CS, mem_len(&cs), 0);
651 mem_put(&cs, c, c_len);
654 void o_func_end(void)
656 long spsub;
657 long sargs = 0;
658 long sargs_last = -1;
659 long sregs_pos;
660 char *c;
661 long c_len, *rsym, *rflg, *roff, rcnt;
662 int leaf = 1;
663 int locs = 0; /* accessing locals on the stack */
664 int i;
665 ic_get(&ic, &ic_n); /* the intermediate code */
666 reg_init(ic, ic_n); /* global register allocation */
667 ra_init(ic, ic_n); /* initialize register allocation */
668 ic_luse = ic_lastuse(ic, ic_n);
669 ic_gencode(ic, ic_n); /* generating machine code */
670 free(ic_luse);
671 /* deciding which arguments to save */
672 for (i = 0; i < func_argc; i++)
673 if (loc_mem[i])
674 sargs_last = i + 1;
675 for (i = 0; i < N_ARGS && (func_varg || i < sargs_last); i++)
676 sargs |= 1 << argregs[i];
677 /* computing the amount of stack subtraction */
678 for (i = 0; i < loc_n; i++)
679 if (loc_mem[i])
680 locs = 1;
681 spsub = (locs || ra_vmax) ? loc_pos + ra_vmax * ULNG : 0;
682 for (i = 0; i < N_TMPS; i++)
683 if (((1 << tmpregs[i]) & func_regs & R_PERM) != 0)
684 spsub += ULNG;
685 sregs_pos = spsub;
686 spsub += func_maxargs * ULNG;
687 /* leaf functions */
688 for (i = 0; i < ic_n; i++)
689 if (ic[i].op & O_CALL)
690 leaf = 0;
691 /* adding function prologue and epilogue */
692 i_wrap(func_argc, sargs, spsub, spsub || locs || !leaf,
693 func_regs & R_PERM, -sregs_pos);
694 ra_done();
695 i_code(&c, &c_len, &rsym, &rflg, &roff, &rcnt);
696 for (i = 0; i < rcnt; i++) /* adding the relocations */
697 out_rel(rsym[i], rflg[i], roff[i] + mem_len(&cs));
698 mem_put(&cs, c, c_len); /* appending function code */
699 free(c);
700 free(rsym);
701 free(rflg);
702 free(roff);
703 for (i = 0; i < ic_n; i++)
704 ic_free(&ic[i]);
705 free(ic);
706 reg_done();
707 ic_reset();
710 void o_write(int fd)
712 i_done();
713 out_write(fd, mem_buf(&cs), mem_len(&cs), mem_buf(&ds), mem_len(&ds));
714 free(loc_off);
715 free(ds_name);
716 free(ds_off);
717 mem_done(&cs);
718 mem_done(&ds);