comparison mc-code-powerpc.c @ 89:917947ffeb7c

power pc version
author kono
date Thu, 06 Mar 2003 23:47:42 +0900
parents
children 07e3113c3c13
comparison
equal deleted inserted replaced
88:5c8553d7f984 89:917947ffeb7c
1 /* Micro-C Code Generatation Part for Power PC (Mac OS X) */
2 /* $Id$ */
3
4 #define EXTERN extern
5 #include "mc.h"
6 #include "mc-codegen.h"
7
8 #define TEXT_EMIT_MODE 0
9 #define DATA_EMIT_MODE 1
10 #define RODATA_EMIT_MODE 2
11
12 static int output_mode = TEXT_EMIT_MODE;
13 static int data_alignment = 0;
14
15 static int code_disp_label;
16 static int func_disp_label;
17
18 /*
19 -16 -8 local2 <-- r30
20 -12 -4 local1
21 -8 8 arg3
22 -4 4 arg2
23 0 0 arg1
24 local2 -20 4 0 (r5)
25 local1 <-- -16 0 local variable 0 (r4)
26 -12 <- disp_offset %ebp
27 r30 (sp) -8
28 0 <- r1
29 r1 (fp) 8 <- arg_offset
30 arg1 8 0
31 arg2 12 4
32 see enter/enter1/leave see code_enter
33
34 r0 link register
35 r30 stack pointer
36 r31 0
37 r1 frame pointer
38 */
39 int arg_offset = 8;
40 int disp_offset = -12;
41 int func_disp_offset = -12;
42 int code_disp_offset = 0;
43 int jump_offset = 0;
44
45 int size_of_int = 4;
46 int size_of_float = 4;
47 int size_of_double = 8;
48 int size_of_longlong = 8;
49 int endian = 0;
50 int MAX_REGISTER=30; /* PowerPCのレジスタを10個まで使う*/
51 int REAL_MAX_REGISTER=32; /* PowerPCのレジスタが32ということ*/
52 int MAX_REGISTGER_VAR=30-10;
53 int MAX_FREGISTER=30;
54
55 #define REG_fp 1
56 #define REG_sp 30
57 #define REG_VAR_BASE 30
58 #define REG_ARG_BASE 3
59 #define REG_ARG_MAX 10
60 #define FREG_ARG_BASE 1
61 #define FREG_ARG_MAX 13
62
63 int reg_sp=REG_sp;
64
65 static char *reg_name[] = {
66 "r0","r1","r2","r3","r4","r5","r6","r7","r8","r9",
67 "r10","r11","r12","r13","r14","r15","r16","r17","r18","r19",
68 "r20","r21","r22","r23","r24","r25","r26","r27","r28","r29",
69 "r30","r31"
70 };
71
72 static char *freg_name[] = {
73 "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9",
74 "f10","f11","f12","f13","f14","f15","f16","f17","f18","f19",
75 "f20","f21","f22","f23","f24","f25","f26","f27","f28","f29",
76 "f30","f31"
77 };
78
79 static char *creg_name[] = {
80 "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7"
81 };
82
83 void use_register(int virt, int real, int move);
84 void code_preinc(int e1,int e2) ;
85 void code_cmp_register(int e2) ;
86 void code_assign_gvar(int e2,int byte) ;
87 void tosop(int op,int oreg);
88 void edx_cleanup();
89 void shift(char *op, int reg);
90 void ld_indexx(int byte, int n, int xreg);
91 void jmp(int l);
92 void local_table(void);
93 void text_mode(void);
94 void data_mode(char *name);
95
96 char *register_name(int i,int byte);
97 int register_var(int r);
98 int get_register_var(void);
99 void emit_push(void);
100 int emit_pop(int type);
101 void code_crlvar(int e2);
102 void code_preinc(int e1,int e2);
103 void code_postinc(int e1,int e2);
104 void code_bool(int e1);
105 void string(int e1);
106 void emit_copy(int from,int to,int length,int offset,int value,int det);
107 int struct_push(int e4,int t);
108 void function(int e1);
109 void code_assop(int op,int byte);
110 int edx_setup();
111 void code_opening(char *filename);
112 void code_closing();
113 void code_leave(char *name);
114 int lvar(int l);
115 void global_table(void);
116
117 char * fstore(int d);
118 char * fload(int d);
119 int code_d1(double d);
120 int code_d2(double d);
121
122 void
123 code_init(void)
124 {
125 arg_offset = 8;
126 func_disp_offset = -12;
127 disp_offset = -12;
128 size_of_int = 4;
129 endian = 1;
130 }
131
132 #define register_name(i) reg_name[i]
133
134 void
135 gexpr_code_init(void){
136 regv[creg]=0;
137 }
138
139 int virtual(int real);
140 char * fload(int d);
141 int code_d1(double d);
142 int code_d2(double d);
143
144
145 int
146 get_register(void)
147 { /* 使われていないレジスタを調べる */
148 int i;
149 for(i=0;i<MAX_REGISTER;i++) {
150 if (! regs[i]) { /* 使われていないなら */
151 regs[i]=1; /* そのレジスタを使うことを宣言し */
152 return i; /* その場所を表す番号を返す */
153 }
154 }
155 return -1; /* 空いている場所がないなら、それを表す -1 を返す */
156 }
157
158 void
159 free_register(int i) { /* いらなくなったレジスタを開放 */
160 regv[i]=regs[i]=0;
161 }
162
163 int
164 register_full(void)
165 {
166 int i;
167 for(i=0;i<MAX_REGISTER;i++) {
168 if (! regs[i]) {
169 return 0;
170 }
171 }
172 return 1;
173 }
174
175 int
176 free_register_count(void)
177 {
178 int i,count;
179 count = 0;
180 for(i=0;i<MAX_REGISTER;i++) {
181 if (! regs[i] && ! regv[i]) count++;
182 }
183 return count;
184 }
185
186 void
187 free_all_register(void)
188 {
189 int i;
190 for(i=0;i<MAX_REGISTER;i++) {
191 regs[i]=regv[i]=0;
192 }
193 creg = get_register();
194 dreg = get_register();
195 return;
196 }
197
198 void
199 use_register_var(int i) {
200 regv[i]=1;
201 }
202
203 void
204 set_register_var() {
205 }
206
207 void
208 code_arg_register(int args)
209 {
210 NMTBL *n;
211 if (args) {
212 /* process in reverse order */
213 n = (NMTBL*)caddr(args);
214 if(n->sc==REGISTER) {
215 if ((n->dsp = get_register_var()) <0) {
216 error(-1); return;
217 }
218 use_register_var(n->dsp); /* it has now value in it */
219 }
220 code_arg_register(cadr(args));
221 }
222 }
223
224
225 void
226 register_usage(char *s)
227 {
228 int i;
229 if (chk) return;
230 printf("# %d: %s:",lineno,s);
231 printf(" creg=%s dreg=%s ",register_name(creg,0),register_name(dreg,0));
232 for(i=0;i<MAX_REGISTER;i++) {
233 printf("%d",regs[i]);
234 }
235 printf(":");
236 for(i=0;i<MAX_REGISTER;i++) {
237 printf("%d",regv[i]);
238 }
239 #if 0
240 printf(" regs_stack",register_name(creg,0),register_name(dreg,0));
241 for(i=reg_sp;i>=0;i--) {
242 if(reg_stack[i]>=0)
243 printf(" %s",register_name(reg_stack[i],0));
244 }
245 #endif
246 printf("\n");
247 }
248
249 void
250 gexpr_init(void)
251 {
252 while(reg_sp > 0) {
253 free_register(reg_stack[--reg_sp]);
254 }
255 text_mode();
256 gexpr_code_init();
257 register_usage("gexpr_init");
258 }
259
260
261 void
262 emit_init(void)
263 {
264 int i;
265 for(i=0;i<MAX_REGISTER;i++) { regs[i]=0; regv[i]=0;rname[i]=i;}
266 free_all_register();
267 reg_sp = 0;
268 text_mode();
269 }
270
271 int
272 register_var(int r) {
273 return virtual(REG_VAR_BASE-r);
274 }
275
276 int
277 get_register_var(void)
278 {
279 int i;
280 for(i=0;i<MAX_REGISTGER_VAR;i++) {
281 if (REG_VAR_Base-i<=REG_ARG_MAX)
282 return -1;
283 if (! regs[REG_VAR_Base-i]) { /* 使われていないなら */
284 regs[REG_VAR_Base-i]=1; /* そのレジスタを使うことを宣言し */
285 regv[REG_VAR_Base-i]=0;
286 return i; /* その場所を表す番号を返す */
287 }
288 }
289 return -1;
290 }
291
292 void
293 emit_push(void)
294 {
295 int new_reg;
296 new_reg = get_register();
297 if(new_reg<0) { /* もうレジスタがない */
298 if (reg_sp>=MAX_MAX) error(-1);
299 reg_stack[reg_sp++] = -1;
300 printf("\tstwu %s,-%d(%s)\n",register_name(creg),
301 size_of_int,register_name(reg_sp));
302 /* creg is used soon, don't regv[creg]=0 */
303 } else {
304 reg_stack[reg_sp++] = creg; /* push するかわりにレジスタを使う */
305 creg = new_reg;
306 regv[creg]=1;
307 }
308 }
309
310 int
311 emit_pop()
312 {
313 int xreg;
314 if ((xreg=pop_register())==-1) {
315 xreg=get_register();
316 if(!xreg) error(-1);
317 printf("\tlwz %s,(%s)\n",register_name(xreg),register_name(reg_sp);
318 printf("\taddis %s,%s,%d\n",
319 register_name(reg_sp),register_name(reg_sp),size_of_int;
320 regv[xreg]=1;
321 }
322 return xreg;
323 }
324
325 static char *code_base;
326
327 #define MAX_PTR_CACHE 10
328
329 int ptr_cache=0;
330
331 int
332 clear_ptr_cache()
333 {
334 int ptcptr=ptr_cache;
335 while(ptcptr) {
336 if(car(ptcptr))
337 free_register(caddr(ptcptr));
338 car(ptcptr)=0;
339 caddr(ptcptr)=0;
340 ptcptr=cadr(ptcptr);
341 }
342 }
343
344 int
345 init_ptr_cache()
346 {
347 int i;
348 for(i=0;i<MAX_PTR_CACHE;i++) {
349 ptr_cache=glist3(0,ptr_cache,0);
350 }
351 }
352
353
354 int
355 get_ptr_cache(char *name)
356 {
357 int r;
358 int ptcptr=ptr_cache;
359 int cache;
360 int i = 0;
361 int g = (int)name;
362 int p,p1;
363
364 while(ptcptr) {
365 if(car(ptcptr)==g) return caddr(ptcptr);
366 p1=p; p=ptcptr;
367 ptcptr=cadr(ptcptr);
368 }
369 cadr(p1)=0; /* remove the last one */
370 cadr(p) = ptr_cache; /* connect current queue to the last one */
371 ptr_cache = p; /* now the last one is the top */
372 if (!caddr(p)) {
373 if((r=get_register())) {
374 caddr(p)=r;
375 else
376 r=creg;
377 }
378 rrn = register_name(r);
379 printf("\taddis %s,r31,ha16(L_%s$non_lazy_ptr-%s)\n",
380 rrn,(char *)g,code_base);
381 printf("\tlzw %s,lo16(L_%s$non_lazy_ptr-%s)(%s)\n",
382 rrn,(char *)g,code_base,rrn);
383 return r;
384 }
385
386 void
387 code_gvar(int e1) {
388 int r;
389 r = get_ptr_cache((char*)caddr(e1));
390 if(r!=creg)
391 printf("\tmr %s,%s\n",register_name(creg),register_name(r));
392 return;
393 }
394
395 void
396 code_rgvar(int e1) {
397 printf("\tlwz %s,(%s)\n",register_name(creg),
398 register_name(get_ptr_cache((char*)caddr(e1))));
399 }
400
401 void
402 code_crgvar(e1){
403 printf("\tlbz %s,(%s)\n",register_name(creg),
404 register_name(get_ptr_cache((char*)caddr(e1))));
405 printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
406 }
407
408 void
409 code_lvar(int e2) {
410 printf("\tla %d(r1),%s\n",e2,register_name(creg));
411 }
412
413
414 void
415 code_register(int e2) {
416 printf("\tmr %s,%s\n",register_name(creg),register_name(e2));
417 }
418
419
420 void
421 code_rlvar(int e2) {
422 printf("\tlwz %d(r1),%s\n",e2,register_name(creg));
423 }
424
425
426 void
427 code_crlvar(int e2) {
428 printf("\tlbz %d(r1),%s\n",e2,register_name(creg));
429 printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
430 }
431
432
433 void
434 code_fname(char *e2) {
435 int r;
436 r = get_ptr_cache(e2);
437 if(r!=creg)
438 printf("\tmr %s,%s\n",register_name(creg),register_name(e2));
439 return;
440 }
441
442
443 void
444 code_const(int e2) {
445 char *crn = register_name(creg);
446 if (-32768<e2&&e2<32768)
447 printf("\tli %s,%d\n",crn,e2);
448 else {
449 printf("\tlis %s,ha16(%d)\n",crn,e2);
450 printf("\taddi %s,%s,lo16(%d)\n",crn,crn,e2);
451 }
452 }
453
454
455 void
456 code_neg() {
457 printf("\tneg %s,%s\n", register_name(creg), register_name(creg);
458 }
459
460
461 void
462 code_not() {
463 printf("\tnor %s,%s,%s\n",
464 register_name(creg), register_name(creg),register_name(creg));
465 }
466
467
468 void
469 code_lnot() {
470 printf("\tsubfic r0,%s,0\n", register_name(creg));
471 printf("\tadde %s,r0,%s\n", register_name(creg),register_name(creg));
472 }
473
474 void
475 code_preinc(int e1,int e2) {
476 char *xrn,*drn;
477 int i,dreg;
478 if (car(e2)==REGISTER) {
479 printf("\taddi %s,%s,%d\n", register_name(cadr(e2)));
480 printf("\tmr %s,%s\n",register_name(cadr(creg)),register_name(e2));
481 return;
482 }
483 g_expr(e2);
484 xrn = register_name(creg);
485 dreg=get_register(); if (!dreg) error(-1);
486 drn = register_name(dreg);
487 printf("\tlwz %s,(%s)\n",drn,xrn);
488 printf("\taddi %s,%s,%d\n",drn,drn,caddr(e1));
489 printf("\tstw %s,(%s)\n",drn,xrn);
490 i=creg;creg=dreg;dreg=i;
491 regv[creg=1];
492 free_register(dreg);
493 }
494
495
496 void
497 code_postinc(int e1,int e2) {
498 char *xrn,*crn,*nrn;
499 int dreg,nreg;
500 if (car(e2)==REGISTER) {
501 printf("\tmr %s,%s\n",register_name(creg),register_name(cadr(e2)));
502 printf("\taddi %s,%s,%d\n",
503 register_name(cadr(e2)),register_name(cadr(e2)));
504 return;
505 }
506 g_expr(e2);
507 dreg=get_register(); if (!dreg) error(-1);
508 xrn = register_name(dreg);
509 nreg=get_register(); if (!nreg) error(-1);
510 nrn = register_name(nreg);
511 printf("\tlwz %s,(%s)\n",xrn,crn);
512 printf("\taddi %s,%s,%d\n",nrn,xrn,caddr(e1));
513 printf("\tstw %s,(%s)\n",nrn,crn);
514 i=creg;creg=dreg;dreg=i;
515 free_register(nreg);
516 free_register(dreg);
517 regv[creg]=1;
518 }
519
520
521 void
522 code_cpostinc(int e1,int e2) {
523 char *xrn,*crn;
524 int i,nreg,dreg;
525 if (car(e2)==REGISTER) {
526 printf("\tlbz %s,(%s)\n",register_name(creg),register_name(cadr(e2)));
527 printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
528 printf("\taddi %s,%s,%d\n",
529 register_name(cadr(e2)),register_name(cadr(e2)),caddr(e1));
530 return;
531 }
532 g_expr(e2);
533 crn = register_name(creg);
534 dreg=get_register(); if (!dreg) error(-1);
535 xrn = register_name(dreg);
536 nreg=get_register(); if (!nreg) error(-1);
537 nrn = register_name(nreg);
538 printf("\tlwz %s,(%s)\n",xrn,crn);
539 printf("\tlbz %s,(%s)\n",nrn,xrn);
540 printf("\textsb %s,%s\n",nrn,nrn);
541 printf("\taddi %s,%s,%d\n", xrn,xrn);
542 printf("\tstw %s,(%s)\n",xrn,crn);
543 i=creg;creg=nreg;nreg=i;
544 free_register(nreg);
545 free_register(dreg);
546 regv[creg]=1;
547 }
548
549
550 void
551 code_cpreinc(int e1,int e2) {
552 char *xrn,*crn;
553 int i,nreg,dreg;
554 if (car(e2)==REGISTER) {
555 printf("\tlbzu %s,%d(%s)\n",register_name(creg),caddr(e1),register_name(cadr(e2)));
556 printf("\textsb %s,%s\n",register_name(creg),register_name(creg));
557 return;
558 }
559 g_expr(e2);
560 crn = register_name(creg);
561 dreg=get_register(); if (!dreg) error(-1);
562 xrn = register_name(dreg);
563 nreg=get_register(); if (!nreg) error(-1);
564 nrn = register_name(nreg);
565 printf("\tlwz %s,(%s)\n",xrn,crn);
566 printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn);
567 printf("\tstw %s,(%s)\n",xrn,crn);
568 printf("\textsb %s,%s\n",nrn,nrn);
569 i=creg;creg=nreg;nreg=i;
570 free_register(nreg);
571 free_register(dreg);
572 regv[creg]=1;
573 }
574
575
576 void
577 code_cpostdec(int e1,int e2) {
578 char *xrn,*crn;
579 int i,nreg,dreg;
580 if (car(e2)==REGISTER) {
581 crn=register_name(creg);
582 xrn=register_name(cadr(e2));
583 printf("\tlbz %s,(%s)\n",crn,xrn);
584 printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1));
585 printf("\textsb %s,%s\n",crn,crn);
586 return;
587 }
588 g_expr(e2);
589 crn = register_name(creg);
590 dreg=get_register(); if (!dreg) error(-1);
591 xrn = register_name(dreg);
592 nreg=get_register(); if (!nreg) error(-1);
593 nrn = register_name(nreg);
594 printf("\tlwz %s,(%s)\n",xrn,crn);
595 printf("\tlbz %s,(%s)\n",nrn,xrn);
596 printf("\taddi %s,%s,%d\n",xrn,xrn,caddr(e1));
597 printf("\tstw %s,(%s)\n",xrn,crn);
598 printf("\textsb %s,%s\n",nrn,nrn);
599 i=creg;creg=nreg;nreg=i;
600 free_register(nreg);
601 free_register(dreg);
602 regv[creg]=1;
603 }
604
605
606 void
607 code_cpredec(int e1,int e2) {
608 char *xrn,*crn;
609 int i,nreg,dreg;
610 if (car(e2)==REGISTER) {
611 crn=register_name(creg);
612 xrn=register_name(cadr(e2));
613 printf("\tlbzu %s,%d(%s)\n",crn,caddr(e1),xrn);
614 printf("\textsb %s,%s\n",crn,crn);
615 return;
616 }
617 g_expr(e2);
618 crn = register_name(creg);
619 dreg=get_register(); if (!dreg) error(-1);
620 xrn = register_name(dreg);
621 nreg=get_register(); if (!nreg) error(-1);
622 nrn = register_name(nreg);
623 printf("\tlwz %s,(%s)\n",xrn,crn);
624 printf("\tlbzu %s,%d(%s)\n",nrn,caddr(e1),xrn);
625 printf("\tstw %s,(%s)\n",xrn,crn);
626 printf("\textsb %s,%s\n",nrn,nrn);
627 i=creg;creg=nreg;nreg=i;
628 free_register(nreg);
629 free_register(dreg);
630 regv[creg]=1;
631 }
632
633
634 void
635 code_return() {
636 int r;
637 printf("\taddis %s,r31,ha16(_%d-%s)\n",crn,retcont,code_base);
638 printf("\tla %s,lo16(_%d-%s)(%s)\n",crn,retcont,code_base,crn);
639 }
640
641
642 void
643 code_environment() {
644 printf("\tmr %s,r1\n",register_name(creg));
645 }
646
647
648 void
649 code_bool(int e1) {
650 char *xrn;
651 int e2,e3;
652 b_expr(e1,1,e2=fwdlabel(),1); /* including > < ... */
653 xrn = register_name(creg);
654 printf("\tli %s,0\n",xrn);
655 jmp(e3=fwdlabel());
656 fwddef(e2);
657 printf("\tli %s,1\n",xrn);
658 fwddef(e3);
659 }
660
661 char *
662 code_gt(int cond) {
663 return (cond?"gt":"le");
664 }
665
666 char *
667 code_ugt(int cond) {
668 return (cond?"gt":"le");
669 }
670
671 char *
672 code_ge(int cond) {
673 return (cond?"ge":"lt");
674 }
675
676 char *
677 code_uge(int cond) {
678 return (cond?"ge":"lt");
679 }
680
681 char *
682 code_eq(int cond) {
683 return (cond?"eq":"ne");
684 }
685
686 void
687 code_cmp_crgvar(int e1) {
688 int r;
689 char *crn = register_name(creg);
690 r = get_ptr_cache((char *)caddr(e1));
691 printf("\tlbz %s,(%s)\n",crn,register_name(r));
692 printf("\tcmpwi cr0,%s,0\n",crn);
693 }
694
695
696 void
697 code_cmp_crlvar(int e1) {
698 char *crn = register_name(creg);
699 printf("\tlbz %s,%d(r1)\n",crn,e1);
700 printf("\tcmpwi cr0,%s,0\n",crn);
701 }
702
703
704 void
705 code_cmp_rgvar(int e1) {
706 int r;
707 char *crn = register_name(creg);
708 r = get_ptr_cache((char *)caddr(e1));
709 printf("\tlwz %s,(%s)\n",crn,register_name(r));
710 code_cmp_register(creg);
711 }
712
713
714 void
715 code_cmp_rlvar(int e1) {
716 char *crn = register_name(creg);
717 printf("\tlwz %s,%d(r1)\n",crn,e1);
718 code_cmp_register(creg);
719 }
720
721
722 void
723 code_cmp_register(int e2) {
724 printf("\tcmpwi cr0,%s,0\n",register_name(e2));
725 }
726
727
728 void
729 ascii(char *s)
730 {
731 printf("\t.ascii \"");
732 while(*s) {
733 if (*s=='\n')
734 printf("%cn",92);
735 else if (*s<' ')
736 printf("%c%03o",92,*s);
737 else if (*s==34)
738 printf("%c%c",92,34);
739 else
740 printf("%c",*s);
741 s++;
742 }
743 printf("\\0%c\n",34);
744 }
745
746 void
747 string(int e1)
748 {
749 char *s;
750 int i,lb;
751
752 s=(char *)cadr(e1);
753 printf(".data\t.cstring\n\t.align 2\n");
754 lb=fwdlabel();
755 printf("_%d:\n",lb);
756 ascii(s);
757 if (output_mode==TEXT_EMIT_MODE) {
758 printf(".text\n");
759 } else {
760 text_mode();
761 }
762 printf("\taddis %s,r31,ha16(_%d-%s)\n",crn,lb,code_base);
763 printf("\tla %s,lo16(_%d-%s)(%s)\n",crn,lb,code_base,crn);
764 }
765
766 #define MAX_COPY_LEN 20
767
768 void
769 emit_copy(int from,int to,int length,int offset,int value,int det)
770 {
771 char *frn = register_name(from);
772 char *trn = register_name(to);
773 char *drn;
774 int fix = 0;
775 char *bcopy = "bcopy";
776 int dreg = get_regiter(); if (!dreg) error(-1);
777 drn = register_name(dreg);
778
779 /* length <0 means upward direction copy */
780 switch (length) {
781 case 0: break;
782 case 1: case -1:
783 printf("\tlbz %s,%d(%s)\n",drn,offset,frn);
784 printf("\tstb %s,%d(%s)\n",drn,offset,trn);
785 break;
786 case 2: case -2:
787 printf("\tlhz %s,%d(%s)\n",drn,offset,frn);
788 printf("\tsth %s,%d(%s)\n",drn,offset,trn);
789 break;
790 case 4: case -4:
791 printf("\tlwz %s,%d(%s)\n",drn,offset,frn);
792 printf("\tstw %s,%d(%s)\n",drn,offset,trn);
793 break;
794 default:
795 if (-MAX_COPY_LEN<length && length <0) {
796 for(;length<=4;length+=4,offset-=4)
797 emit_copy(from,to,4,offset,0,det);
798 for(;length<=2;length+=2,offset-=2)
799 emit_copy(from,to,2,offset,0,det);
800 if(length>0)
801 emit_copy(from,to,length,offset,0,det);
802 break;
803 } else if (length <=MAX_COPY_LEN) {
804 for(;length>=4;length-=4,offset+=4)
805 emit_copy(from,to,4,offset,0,det);
806 for(;length>=2;length-=2,offset+=2)
807 emit_copy(from,to,2,offset,0,det);
808 if(length>0)
809 emit_copy(from,to,length,offset,0,det);
810 break;
811 }
812 if (det) {
813 printf("\tli r5,%d\n",length);
814 printf("\tmr r4,%s\n",trn);
815 printf("\tmr r3,%s\n",frn);
816 printf("\tbl L_%s$stub\n",bcopy);
817 regist_extern_function(bcopy);
818 break;
819 }
820 }
821 if (value) {
822 /* creg must point top of the destination data */
823 /* this code is necessary for the value of assignment or function call */
824 /* otherwise we don't need this */
825 if (fix) printf("\taddi %s,%s,%d\n",trn,trn,fix);
826 if(creg!=to) {
827 free_register(creg); creg=to;
828 }
829 }
830 free_register(dreg);
831 regv[from]=regv[to]=regv[dreg]=0;
832 regv[creg]=1;
833 }
834
835 int
836 struct_push(int e4,int t)
837 {
838 int length,save,count;
839 int dreg; char *drn,*crn,*srn;
840 g_expr(e4);
841 length=size(t);
842 if(length%size_of_int) {
843 length += size_of_int - (length%size_of_int);
844 }
845 dreg = get_regiter(); if (!dreg) error(-1);
846 drn = register_name(dreg);
847 crn = register_name(dreg);
848 srn = register_name(reg_sp);
849 for(count=0;length<MAX_COPY_LEN;count++,length-=size_of_int) {
850 if (length==0) {
851 free_register(dreg);
852 return count;
853 } else {
854 printf("\tlwz %s,%d(%s)\n",drn,length-size_of_int,crn);
855 printf("\tstwu %s,%d(%s)\n",drn,-size_of_int,srn);
856 }
857 }
858 printf("\taddis %s,%s,ha16(%d)\n",srn,,srn,length);
859 printf("\taddi %s,%s,lo16(%d)\n",srn,,srn,length);
860 /* downward direction copy */
861 printf("\tmr %s,%s\n",drn,srn);
862 emit_copy(creg,dreg,length,0,0,1);
863 /* we have value in creg, it may be changed */
864 if (dreg!=creg) free_register(dreg);
865 return length/size_of_int;
866 }
867
868 int
869 arg_offset(int arg)
870 {
871 }
872
873 void
874 function(int e1)
875 {
876 int e2,e3,e4,e5,nargs,t;
877 int reg_arg,freg_arg;
878 NMTBL *n;
879 e2 = cadr(e1);
880 nargs = 0;
881 reg_arg = REG_ARG_BASE;
882 freg_arg = FREG_ARG_BASE;
883 for (e3 = caddr(e1); e3; e3 = cadr(e3)) {
884 t=caddr(e3);
885 n=(NMTBL *)(e5=(cadr(e4 = car(e3))));
886 if(scalar(t)) {
887 g_expr(e4);
888 if (reg_arg<REG_ARG_MAX)
889 printf("\tmr %s,%s\n",register_name(reg_arg),
890 register_name(creg));
891 else {
892 printf("\tstw %s,%d(r1)\n",register_name(creg),
893 arg_offset(nargs));
894 }
895 nargs ++ ; reg_arg++;
896 } else if (t==DOUBLE||t==FLOAT) {
897 g_expr(e4);
898 nargs += size_of_double/size_of_int;
899 if (fregv[freg_arg])
900 save_freg(freg_arg);
901 fregv[freg_arg]=1;
902 if (freg_arg<FREG_ARG_MAX)
903 printf("\tmr %s,%s\n",register_name(reg_arg++),
904 register_name(freg));
905 else if(t==DOUBLE) {
906 printf("\tstfd %s,%d(r1)\n",register_name(freg),
907 arg_offset(nargs));
908 nargs+=size_of_double/size_of_int;
909 } else {
910 printf("\tstfs %s,%d(r1)\n",register_name(freg),
911 arg_offset(nargs));
912 nargs+=size_of_float/size_of_int;
913 }
914 freg_arg++;
915 continue;
916 } else if (car(t)==STRUCT||car(t)==UNION) {
917 nargs += struct_push(e4,t);
918 continue;
919 } else {
920 error(TYERR);
921 }
922 ++nargs;
923 }
924 if (car(e2) == FNAME) {
925 n=(NMTBL *)cadr(e2);
926 regv[creg]=0;
927 } else {
928 g_expr(e2);
929 regv[creg]=1;
930 }
931
932 if (car(e2) == FNAME) {
933 printf("\tbl\tL_%s$stub\n",n->nm);
934 } else {
935 jmp=get_tmp_register();
936 jrn = register_name(jmp);
937 printf("\tmr %s,%s\n",jrn,crn);
938 printf("\tmtctr %s\n",jrn);
939 printf("\tbctrl\n");
940 free_register(jmp);
941 }
942 regv[creg]=1;
943 }
944
945 void
946 code_frame_pointer(int e3) {
947 printf("\tmovl %s,r1\n",register_name(e3,0));
948 }
949
950
951 void
952 code_fix_frame_pointer(int disp_offset) {
953 printf("\tla r1,%d(r1)\n",disp_offset);
954 }
955
956
957 void
958 code_jmp(char *s) {
959 printf("\tb L_%s$stub\n",s);
960 }
961
962
963 void
964 code_indirect_jmp(int e2) {
965 printf("\tmtctr %s\n",register_name(e2));
966 printf("\tbctr\n");
967 }
968
969 void
970 rindirect(int e1) /* *(p +5 ) */
971 {
972 char *op;
973 int e2,e3,byte;
974 e3 = cadr(e2 = cadr(e1));
975 g_expr(e2);
976 switch (car(e1)) {
977 case FRINDIRECT: case DRINDIRECT:
978 printf("\t%s (%s)\n",fload(car(e1)==DRINDIRECT),register_name(creg));
979 break;
980 case CRINDIRECT: case RINDIRECT:
981 op = ((byte = (car(e1) == CRINDIRECT)) ? "movsbl" : "movl");
982 printf("\t%s (%s),%s\n",op,register_name(creg),register_name(creg));
983 }
984 }
985
986
987 void
988 code_assign_gvar(int e2,int byte) {
989 if (byte) use_data_reg(creg,1);
990 printf("\t%s %s,%s\n",move(byte),register_name(creg,byte),(char *)caddr(e2));
991 }
992
993 void
994 code_assign_lvar(int e2,int byte) {
995 if (byte) use_data_reg(creg,1);
996 printf("\t%s %s,%d(%%ebp)\n",move(byte),register_name(creg,byte),e2);
997 }
998
999 void
1000 code_assign_register(int e2,int byte) {
1001 printf("\tmovl %s,%s\n",register_name(creg),register_name(e2,0));
1002 }
1003
1004 void
1005 code_assign(int e2,int byte) {
1006 printf("\t%s %s,(%s)\n",move(byte),register_name(creg,byte),register_name(e2,0));
1007 }
1008
1009
1010 void
1011 code_register_assop(int e2,int op,int byte) {
1012 int reg;
1013 int xreg = creg;
1014 creg = reg = e2;
1015 tosop(op,xreg);
1016 creg = xreg;
1017 printf("\tmovl %s,%s\n",register_name(reg,0),register_name(creg));
1018 }
1019
1020
1021 void
1022 code_assop(int op,int byte) {
1023 char *xrn;
1024 int xreg;
1025 int edx = edx_setup();
1026 xrn = register_name(xreg = emit_pop(0),0); /* pop e3 value */
1027 regv[xreg]=regs[xreg]=1;
1028 printf("\tmovl %s,%s # assop \n",register_name(creg),register_name(edx,0));
1029 regv[edx]=1;
1030 ld_indexx(byte,0,edx);
1031 tosop(op,xreg);
1032 printf("\t%s %s,(%s)\n",byte ? "movb" : "movl",register_name(creg,byte),register_name(edx,0));
1033 edx_cleanup();
1034 emit_pop_free(xreg);
1035 }
1036
1037
1038 void
1039 tosop(int op,int oreg)
1040 {
1041 int dx;
1042 char *orn,*crn;
1043
1044 switch(op) {
1045 case LSHIFT:
1046 case ULSHIFT:
1047 shift("sall",oreg);
1048 return;
1049 case RSHIFT:
1050 shift("sarl",oreg);
1051 return;
1052 case URSHIFT:
1053 shift("shrl",oreg);
1054 return;
1055 }
1056 if(oreg==-1) {
1057 printf("\tpopl %s\n",register_name(dreg,0));
1058 oreg = dreg;
1059 regv[dreg]=1;
1060 }
1061 regv[oreg]=1; regs[oreg]=1;
1062 orn = register_name(oreg,0);
1063 crn = register_name(creg);
1064 switch(op) {
1065 case ADD:
1066 printf("\taddl %s,%s\n",orn,crn);
1067 break;
1068 case SUB:
1069 printf("\tsubl %s,%s\n",orn,crn);
1070 break;
1071 case BAND:
1072 printf("\tandl %s,%s\n",orn,crn);
1073 break;
1074 case EOR:
1075 printf("\txorl %s,%s\n",orn,crn);
1076 break;
1077 case BOR:
1078 printf("\torl %s,%s\n",orn,crn);
1079 break;
1080 case MUL:
1081 case UMUL:
1082 printf("\t%s %s,%s\n","imull",orn,crn);
1083 break;
1084 case DIV:
1085 case UDIV:
1086 use_register(creg,REG_EAX,1);
1087 edx_setup();
1088 orn = register_name(oreg,0);
1089 if (op==DIV)
1090 printf("\tcltd\n\tdivl %s\n",orn);
1091 else
1092 printf("\txor %%edx,%%edx\n\tidivl %s\n",orn);
1093 edx_cleanup();
1094 break;
1095 case MOD:
1096 case UMOD:
1097 use_register(creg,REG_EAX,1);
1098 edx_setup();
1099 orn = register_name(oreg,0);
1100 if (op==DIV)
1101 printf("\tcltd\n\tdivl %s\n",orn);
1102 else
1103 printf("\txor %%edx,%%edx\n\tidivl %s\n",orn);
1104 dx = virtual(REG_EDX);
1105 if (dx!=creg) {
1106 rname[dx]=rname[creg];
1107 rname[creg]=REG_EDX;
1108 }
1109 edx_cleanup();
1110 break;
1111 }
1112 if (oreg!=dreg&&oreg>=0)
1113 free_register(oreg);
1114 }
1115
1116 static int edx_stack=0;
1117
1118 int
1119 edx_setup()
1120 {
1121 int edx_save;
1122 /* make real EDX register empty */
1123 if (free_register_count()<1) {
1124 for(edx_save = 0;edx_save==dreg||edx_save==creg;edx_save++);
1125 printf("\tpushl %s\n",register_name(edx_save,0));
1126 edx_stack = list3(edx_save,edx_stack,0);
1127 } else {
1128 edx_save = get_register();
1129 edx_stack = list3(edx_save,edx_stack,1);
1130 }
1131 regv[edx_save]=0;
1132 use_register(edx_save,REG_EDX,0);
1133 return edx_save;
1134 }
1135
1136
1137 void
1138 edx_cleanup()
1139 {
1140 if (caddr(edx_stack)==0) {
1141 printf("\tpopl %s\n",register_name(car(edx_stack),0));
1142 } else
1143 free_register(car(edx_stack));
1144 edx_stack = cadr(edx_stack);
1145 }
1146
1147 void
1148 shift(char *op, int reg)
1149 {
1150 if (reg>=0) {
1151 use_register(reg,REG_ECX,1);
1152 } else {
1153 use_register(dreg,REG_ECX,0);
1154 printf("\tpopl %%ecx\n");
1155 }
1156 printf("\t%s %%cl,%s\n",op,register_name(creg));
1157 }
1158
1159 void
1160 ld_indexx(int byte, int n, int xreg)
1161 {
1162 char *op;
1163
1164 op = byte ? "movsbl" : "movl";
1165 if (n)
1166 printf("\t%s %d(%s),%s\n",op,n,register_name(xreg,0),register_name(creg,byte));
1167 else
1168 printf("\t%s (%s),%s\n",op,register_name(xreg,0),register_name(creg,byte));
1169 }
1170
1171 void
1172 cmpdimm(int e, int csreg)
1173 {
1174 /* used in dosiwtch() */
1175 if(chk) return;
1176 use_register(creg,csreg,0);
1177 printf("\tcmpl $%d,%s\n",e,register_name(creg));
1178 }
1179
1180 void
1181 code_opening(char *filename)
1182 {
1183 printf("\t.file \"%s\"\n",filename);
1184 printf("\t.version\t\"01.01\"\n");
1185 /* printf("gcc2_compiled.:\n"); */
1186 printf(".text\n");
1187 }
1188
1189 void
1190 code_closing()
1191 {
1192 global_table();
1193 printf("\t.ident \"Micro-C compiled\"\n");
1194 }
1195
1196 void
1197 rexpr(int e1, int l1, char *s)
1198 {
1199 g_expr(list3(SUB,cadr(e1),caddr(e1)));
1200 printf("\tj%s\t_%d\n",s,l1);
1201 }
1202
1203
1204 void
1205 jcond(int l, char cond)
1206 {
1207 if (chk) return;
1208 printf("\tj%s\t_%d\n",cond?"ne":"e",l);
1209 }
1210
1211 void
1212 jmp(int l)
1213 {
1214 control=0;
1215 if (chk) return;
1216 printf("\tjmp\t_%d\n",l);
1217 /* align? */
1218 /*
1219 this is not allowed because of ? operator
1220 regv[creg]=regv[dreg]=0;
1221 use_register(creg,REG_EAX,0);
1222 use_register(dreg,REG_EBX,0);
1223 */
1224 }
1225
1226 void
1227 gen_comment(char *s)
1228 {
1229 if (chk) return;
1230 printf("## %s",s);
1231 }
1232
1233
1234 void
1235 code_enter(char *name)
1236 {
1237 printf("\t.align 4\n");
1238 if (stmode!=STATIC)
1239 printf(".globl %s\n",name);
1240 printf("\t.type\t%s,@function\n",name);
1241 printf("%s:\n",name);
1242 }
1243
1244
1245 void
1246 code_enter1(int args)
1247 {
1248 code_disp_label=fwdlabel();
1249 printf("\tlea _%d(%%ebp),%%esp\n",code_disp_label);
1250
1251 printf("## args %d disp %d code_arg_offset=%d code_disp_offset=%d\n",args,disp,code_arg_offset,code_disp_offset);
1252 }
1253
1254 void
1255 code_leave(char *name)
1256 {
1257 disp&= -size_of_int;
1258 printf("\t.set _%d,%d\n",code_disp_label,disp+code_disp_offset);
1259 printf("_%d:\n",labelno);
1260 printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
1261 local_table();
1262 labelno++;
1263 free_all_register();
1264 }
1265
1266 void
1267 enter(char *name)
1268 {
1269 printf("\t.align 2\n");
1270 if (stmode!=STATIC)
1271 printf(".globl %s\n",name);
1272 printf("%s:\n",name);
1273 printf("\t.type\t%s,@function\n",name);
1274 printf("\tpushl %%ebp\n");
1275 printf("\tmovl %%esp,%%ebp\n");
1276 printf("\tpushl %%ebx\n");
1277 printf("\tpushl %%esi\n");
1278 printf("\tpushl %%edi\n");
1279 }
1280
1281 void
1282 enter1()
1283 {
1284 func_disp_label=fwdlabel();
1285 printf("\tlea _%d(%%ebp),%%esp\n",func_disp_label);
1286 /* if(disp) printf("\tsubl $%d,%%esp\n",-disp); */
1287 }
1288
1289 void
1290 leave(int control, char *name)
1291 {
1292 if (control)
1293 use_register(creg,REG_EAX,1);
1294 if (retcont) {
1295 if (control)
1296 jmp(retlabel);
1297 fwddef(retcont);
1298 use_register(creg,REG_EAX,0);
1299 printf("\tmovl %s,%s\n",reg_name[REG_ESI],register_name(creg));
1300 /* printf("\tleave\n"); */
1301 }
1302 fwddef(retlabel);
1303 /* use_register(creg,REG_EAX,0); too late */
1304 /* if(disp) printf("\taddl $%d,%%esp\n",-disp); */
1305 disp &= -size_of_int;
1306
1307 printf("\tlea %d(%%ebp),%%esp\n",disp_offset);
1308 printf("\tpopl %%edi\n");
1309 printf("\tpopl %%esi\n");
1310 printf("\tpopl %%ebx\n");
1311 printf("\tleave\n");
1312 printf("\tret\n");
1313 printf("\t.set _%d,%d\n",func_disp_label,disp+disp_offset);
1314 printf("_%d:\n",labelno);
1315 printf("\t.size\t%s,_%d-%s\n",name,labelno,name);
1316 local_table();
1317 labelno++;
1318 free_all_register();
1319 }
1320
1321
1322 void
1323 code_set_fixed_creg(int mode) {
1324 use_register(creg,REG_EAX,mode);
1325 }
1326
1327 void
1328 gen_gdecl(char *n, int gpc)
1329 {
1330 /*
1331 if (stmode!=STATIC)
1332 printf(".globl %s\n",n);
1333 */
1334 }
1335
1336 void
1337 align(int t)
1338 {
1339 if (t!=CHAR) {
1340 if (data_alignment & 1)
1341 printf("\t.align 2\n");
1342 data_alignment = 0;
1343 }
1344 }
1345
1346 void
1347 emit_data(int e, int t, NMTBL *n)
1348 {
1349 int l;
1350 double d;
1351 float f;
1352 char *name;
1353 name = n->nm;
1354 if(mode!=GDECL) {
1355 error(-1); return;
1356 }
1357 if (chk) return;
1358 if (n->dsp != -1) {
1359 n->dsp = -1; /* initiallized flag */
1360 printf(".globl\t%s\n",name);
1361 data_mode(name);
1362 align(t);
1363 printf("%s:\n",name);
1364 } else {
1365 data_mode(0);
1366 }
1367 if(car(e)==CONST) {
1368 if (t==CHAR) {
1369 printf("\t.byte %d\n",cadr(e));
1370 if (data_alignment>0)
1371 data_alignment++;
1372 gpc += 1;
1373 } else if (t==SHORT) {
1374 printf("\t.word %d\n",cadr(e));
1375 if (data_alignment>0) data_alignment++;
1376 gpc += 2;
1377 } else {
1378 printf("\t.long %d\n",cadr(e));
1379 gpc += size_of_int;
1380 }
1381 } else if(t==DOUBLE) {
1382 d = dcadr(e);
1383 printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d));
1384 } else if(t==FLOAT) {
1385 f = dcadr(e);
1386 printf("\t.long\t0x%x\n",*(int *)&f);
1387 } else if(t!=CHAR) {
1388 gpc += size_of_int;
1389 if(car(e)==ADDRESS&&car(cadr(e))==GVAR) {
1390 printf("\t.long %s\n",(char *)caddr(cadr(e)));
1391 } else if(car(e)==FNAME) {
1392 printf("\t.long %s\n",((NMTBL *)cadr(e))->nm);
1393 } else if(car(e)==STRING) {
1394 if (car(n->ty)!=ARRAY || cadr(n->ty)!=CHAR) {
1395 l = fwdlabel();
1396 printf("\t.long _%d\n",l);
1397 printf(".section\t.rodata\n");
1398 printf("_%d:\n",l);
1399 output_mode = RODATA_EMIT_MODE;
1400 }
1401 ascii((char *)cadr(e));
1402 } else error(TYERR);
1403 }
1404 }
1405
1406 void
1407 emit_data_closing(NMTBL *n)
1408 {
1409 int lb;
1410 if (chk) return;
1411 if (mode==GDECL) {
1412 data_mode(0);
1413 lb=fwdlabel();
1414 printf("_%d:\n",lb);
1415 printf("\t.size\t%s,_%d-%s\n",n->nm,lb,n->nm);
1416 }
1417 }
1418
1419 void
1420 global_table(void)
1421 {
1422 NMTBL *n;
1423 int init;
1424 init=0;
1425 for(n=ntable;n < &ntable[GSYMS];n++) {
1426 if (n->sc == GVAR && n->dsp != -1) {
1427 /* n->dsp = -1 means initialized global */
1428 if (init==0) {
1429 data_mode(0);
1430 init=1;
1431 }
1432 printf(".comm %s,%d\n",n->nm,size(n->ty));
1433 }
1434 }
1435 }
1436
1437 void
1438 local_table(void)
1439 {
1440 NMTBL *n;
1441 int init;
1442 init=0;
1443 /* static local variables */
1444 for(n=ntable+GSYMS;n < &ntable[GSYMS+LSYMS];n++) {
1445 if (n->sc == GVAR) {
1446 if (init==0) {
1447 data_mode(0);
1448 init=1;
1449 }
1450 printf(".lcomm %s,%d\n",n->nm,size(n->ty));
1451 }
1452 }
1453 }
1454
1455 void
1456 text_mode(void)
1457 {
1458 if (output_mode!=TEXT_EMIT_MODE) {
1459 printf(".text\n");
1460 printf("\t.align 2\n");
1461 output_mode = TEXT_EMIT_MODE;
1462 }
1463 }
1464
1465 void
1466 data_mode(char *name)
1467 {
1468 if (output_mode!=DATA_EMIT_MODE) {
1469 printf(".data\n");
1470 output_mode = DATA_EMIT_MODE;
1471 }
1472 if (name)
1473 printf("\t.type\t%s,@object\n",name);
1474 }
1475
1476 int
1477 lvar(int l)
1478 {
1479 if (fnptr->sc==CODE) {
1480 return l+code_disp_offset;
1481 } else if (l<0) {
1482 return l+disp_offset;
1483 } else {
1484 return l+arg_offset;
1485 }
1486 }
1487
1488 /* floating point */
1489
1490
1491 char *
1492 fstore(int d)
1493 {
1494 return use?
1495 (d?"fstl":"fsts"):
1496 (d?"fstpl":"fstps")
1497 ;
1498 }
1499
1500 char *
1501 fstore_u(int d)
1502 {
1503 return d?"fstpl":"fstps";
1504 }
1505
1506 char *
1507 fload(int d)
1508 {
1509 return d?"fldl":"flds";
1510 }
1511
1512
1513 void code_dassign_gvar(int e2,int d)
1514 {
1515 printf("\t%s %s\n",fstore(d),(char *)caddr(e2)) ;
1516 }
1517
1518 void code_dassign_lvar(int e2,int d)
1519 {
1520 printf("\t%s %d(%%ebp)\n",fstore(d),e2);
1521 }
1522
1523 void code_dassign(int e2,int d)
1524 {
1525 printf("\t%s (%s)\n",fstore(d),register_name(e2,0));
1526 }
1527
1528 static double d0 = 1.0;
1529
1530 int
1531 code_d1(double d)
1532 {
1533 int *i = (int *)&d0; int *j = (int *)&d;
1534 return (i[1] == 0x3ff00000)?j[0]:j[1];
1535 }
1536
1537 int
1538 code_d2(double d)
1539 {
1540 int *i = (int *)&d0; int *j = (int *)&d;
1541 return (i[1] == 0x3ff00000)?j[1]:j[0];
1542 }
1543
1544 void code_dconst(int e2)
1545 {
1546 int lb;
1547 double d = dcadr(e2);
1548
1549 if (d==0.0) {
1550 printf("\tfldz\n"); return;
1551 }
1552 if (d==1.0) {
1553 printf("\tfld1\n"); return;
1554 }
1555 printf(" \t.section\t.rodata\n\t.align 8\n");
1556 lb=fwdlabel();
1557 printf("_%d:\n",lb);
1558 printf("\t.long\t0x%x,0x%x\n",code_d1(d),code_d2(d));
1559 if (output_mode==TEXT_EMIT_MODE) {
1560 printf(".text\n");
1561 } else {
1562 text_mode();
1563 }
1564 printf("\tfldl _%d\n",lb);
1565 }
1566
1567 void code_dneg()
1568 {
1569 printf("\tfchs\n");
1570 }
1571
1572 void code_d2i()
1573 {
1574 /* fuck you! */
1575 printf("\tlea -%d(%%esp),%%esp\n",size_of_int*2);
1576 printf("\tfnstcw (%%esp)\n");
1577 printf("\tmovl (%%esp), %s\n",register_name(creg));
1578 printf("\tmovb $12, 1(%%esp)\n");
1579 printf("\tfldcw (%%esp)\n");
1580 printf("\tmovl %s, (%%ebp)\n",register_name(creg));
1581 printf("\tfistpl %d(%%esp)\n",size_of_int);
1582 printf("\tfldcw (%%esp)\n");
1583 printf("\tpopl %s\n",register_name(creg));
1584 printf("\tpopl %s\n",register_name(creg));
1585 }
1586
1587 void code_i2d()
1588 {
1589 printf("\tpushl %s\n",register_name(creg));
1590 printf("\tfildl (%%esp)\n");
1591 printf("\tlea %d(%%esp),%%esp\n",size_of_int);
1592 }
1593
1594 void code_d2u()
1595 {
1596 /* fuck you! */
1597 printf("\tlea -%d(%%esp),%%esp\n",size_of_int*3);
1598 printf("\tfnstcw (%%esp)\n");
1599 printf("\tmovl (%%esp), %s\n",register_name(creg));
1600 printf("\tmovb $12, 1(%%esp)\n");
1601 printf("\tfldcw (%%esp)\n");
1602 printf("\tmovl %s, (%%ebp)\n",register_name(creg));
1603 printf("\tfistpll %d(%%esp)\n",size_of_int);
1604 printf("\tfldcw (%%esp)\n");
1605 printf("\tmovl %d(%%esp),%s\n",size_of_int,register_name(creg));
1606 printf("\tlea %d(%%esp),%%esp\n",size_of_int*3);
1607 }
1608
1609 void code_u2d()
1610 {
1611 printf("\tpushl %s\n",register_name(creg));
1612 printf("\tpushl %s\n",register_name(creg));
1613 printf("\tmovl $0, %d(%%esp)\n",size_of_int);
1614 printf("\tfildll (%%esp)\n");
1615 printf("\tlea %d(%%esp),%%esp\n",size_of_int*2);
1616 }
1617
1618 void code_drgvar(int e2,int d)
1619 {
1620 printf("\t%s %s\n",fload(d),(char *)caddr(e2)) ;
1621 }
1622
1623
1624 void code_drlvar(int e2,int d)
1625 {
1626 printf("\t%s %d(%%ebp)\n",fload(d),e2);
1627 }
1628
1629 void code_cmp_drgvar(int e2)
1630 {
1631 printf("\tfcomp %s\n",(char *)caddr(e2)) ;
1632 }
1633
1634 void code_cmp_drlvar(int e2)
1635 {
1636 printf("\tfcomp %d(%%ebp)\n",e2);
1637 }
1638
1639 void dtosop(int op,int e1)
1640 {
1641 switch(op) {
1642 case DADD: printf("\tfaddp %%st,%%st(1)\n"); break;
1643 case DSUB: printf("\tfsubp %%st,%%st(1)\n"); break;
1644 case DDIV: printf("\tfdivp %%st,%%st(1)\n"); break;
1645 case DMUL: printf("\tfmulp %%st,%%st(1)\n"); break;
1646 case DCOMP:
1647 /* printf("\tfxch\t%%st(1)\n"); */
1648 printf("\tfucompp\n");
1649 printf("\tfnstsw\t%%ax\n");
1650 break;
1651 }
1652 }
1653
1654 void
1655 code_dassop(int op,int d) {
1656 /* we have lvalue in creg, applied floating value is in %st(0) */
1657 printf("\t%s (%s)\n",fload(d),register_name(creg));
1658 dtosop(op,0);
1659 printf("\t%s (%s)\n",fstore(d),register_name(creg));
1660 }
1661
1662 void
1663 code_dpreinc(int e1,int e2,int d) {
1664 g_expr(e2);
1665 printf("\t%s (%s)\n",fload(d),register_name(creg));
1666 printf("\tfld1\n");
1667 if (caddr(e1)>0)
1668 printf("\tfaddp %%st,%%st(1)\n");
1669 else
1670 printf("\tfsubrp %%st,%%st(1)\n");
1671 printf("\t%s (%s)\n",fstore(d),register_name(creg));
1672 }
1673
1674 void
1675 code_dpostinc(int e1,int e2,int d) {
1676 g_expr(e2);
1677 printf("\t%s (%s)\n",fload(d),register_name(creg));
1678 if (use)
1679 printf("\t%s (%s)\n",fload(d),register_name(creg));
1680 printf("\tfld1\n");
1681 if (caddr(e1)>0)
1682 printf("\tfaddp %%st,%%st(1)\n");
1683 else
1684 printf("\tfsubrp %%st,%%st(1)\n");
1685 printf("\t%s (%s)\n",(use?fstore_u(d):fstore(d)),register_name(creg));
1686 }
1687
1688 void
1689 drexpr(int e1, int e2,int l1, int op)
1690 {
1691 g_expr(list3(DCOMP,e1,e2));
1692 switch(op) {
1693 case DOP+GE:
1694 printf("\ttestb\t$5,%%ah\n");
1695 printf("\tjne\t_%d\n",l1);
1696 break;
1697 case DOP+GT:
1698 printf("\ttestb\t$69,%%ah\n");
1699 printf("\tjne\t_%d\n",l1);
1700 break;
1701 case DOP+EQ:
1702 printf("\tandb\t$69,%%ah\n");
1703 printf("\txorb\t$64,%%ah\n");
1704 printf("\tjne\t_%d\n",l1);
1705 break;
1706 case DOP+NEQ:
1707 printf("\tandb\t$69,%%ah\n");
1708 printf("\txorb\t$64,%%ah\n");
1709 printf("\tje\t_%d\n",l1);
1710 break;
1711 }
1712 }
1713
1714 int dpop_register()
1715 {
1716 return 1;
1717 }
1718
1719 int emit_dpop(int e1)
1720 {
1721 return 1;
1722 }
1723
1724 void emit_dpop_free(int e1)
1725 {
1726 }
1727
1728 void emit_dpush()
1729 {
1730 }
1731
1732 /* end */
1733