Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20050917075840

Diff

Diff from 1.50 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/arch/i386/local2.c

Annotated File View

ragge
1.50
1 /*      $Id: local2.c,v 1.50 2005/09/17 07:58:40 ragge Exp $    */
ragge
1.1
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29
30 # include "pass2.h"
31 # include <ctype.h>
32
33 void acon(NODE *p);
34 int argsize(NODE *p);
35 void genargs(NODE *p);
ragge
1.40
36 static void sconv(NODE *p);
ragge
1.1
37
38 void
39 lineid(int lchar *fn)
40 {
41         /* identify line l and file fn */
42         printf("#       line %d, file %s\n"lfn);
43 }
44
45 void
46 deflab(int label)
47 {
48         printf(LABFMT ":\n"label);
49 }
50
ragge
1.48
51 static int regoff[7];
ragge
1.28
52 static TWORD ftype;
ragge
1.1
53
ragge
1.45
54 /*
55  * Print out the prolog assembler.
56  * addto and regoff are already calculated.
57  */
58 static void
59 prtprolog(struct interpass_prolog *ippint addto)
60 {
ragge
1.48
61         int ij;
ragge
1.45
62
63         printf("        pushl %%ebp\n");
64         printf("        movl %%esp,%%ebp\n");
65         if (addto)
66                 printf("        subl $%d,%%esp\n"addto);
ragge
1.48
67         for (i = ipp->ipp_regsj = 0ii >>= 1j++)
68                 if (i & 1)
69                         fprintf(stdout"       movl %s,-%d(%s)\n",
70                             rnames[j], regoff[j], rnames[FPREG]);
ragge
1.45
71 }
72
73 /*
74  * calculate stack size and offsets */
75 static int
76 offcalc(struct interpass_prolog *ipp)
77 {
ragge
1.48
78         int ijaddto;
ragge
1.45
79
80         addto = p2maxautooff;
81         if (addto >= AUTOINIT)
82                 addto -= AUTOINIT;
83         addto /= SZCHAR;
ragge
1.48
84         for (i = ipp->ipp_regsj = 0i ; i >>= 1j++) {
85                 if (i & 1) {
86                         addto += SZINT/SZCHAR;
87                         regoff[j] = addto;
88                 }
ragge
1.45
89         }
90         return addto;
91 }
92
ragge
1.49
93 void
94 prologue(struct interpass_prolog *ipp)
95 {
96         int addto;
97
98         ftype = ipp->ipp_type;
99         if (ipp->ipp_vis)
100                 printf("        .globl %s\n"ipp->ipp_name);
101         printf("        .align 4\n");
102         printf("%s:\n"ipp->ipp_name);
103         /*
104          * We here know what register to save and how much to 
105          * add to the stack.
106          */
107         addto = offcalc(ipp);
108         prtprolog(ippaddto);
109 }
110
111 void
112 eoftn(struct interpass_prolog *ipp)
113 {
114         int ij;
115
116         if (ipp->ipp_ip.ip_lbl == 0)
117                 return/* no code needs to be generated */
118
119         /* return from function code */
120         for (i = ipp->ipp_regsj = 0i ; i >>= 1j++) {
121                 if (i & 1)
122                         fprintf(stdout"       movl -%d(%s),%s\n",
123                             regoff[j], rnames[FPREG], rnames[j]);
124                         
125         }
126
127         /* struct return needs special treatment */
128         if (ftype == STRTY || ftype == UNIONTY) {
129                 printf("        movl 8(%%ebp),%%eax\n");
130                 printf("        leave\n");
131                 printf("        ret $4\n");
132         } else {
133                 printf("        leave\n");
134                 printf("        ret\n");
135         }
136 }
ragge
1.1
137
138 /*
139  * add/sub/...
140  *
141  * Param given:
142  */
143 void
144 hopcode(int fint o)
145 {
146         char *str;
147
148         switch (o) {
149         case PLUS:
150                 str = "add";
151                 break;
152         case MINUS:
153                 str = "sub";
154                 break;
155         case AND:
156                 str = "and";
157                 break;
158         case OR:
ragge
1.10
159                 str = "or";
ragge
1.1
160                 break;
161         case ER:
162                 str = "xor";
163                 break;
164         default:
ragge
1.14
165                 comperr("hopcode2: %d"o);
ragge
1.32
166                 str = 0/* XXX gcc */
ragge
1.1
167         }
ragge
1.7
168         printf("%s%c"strf);
ragge
1.1
169 }
170
171 char *
172 rnames[] = {  /* keyed to register number tokens */
ragge
1.17
173         "%eax""%edx""%ecx""%esi""%edi""%ebx""%ebp""%esp",
ragge
1.1
174 };
175
176 int
177 tlen(pNODE *p;
178 {
179         switch(p->n_type) {
180                 case CHAR:
181                 case UCHAR:
182                         return(1);
183
184                 case SHORT:
185                 case USHORT:
186                         return(SZSHORT/SZCHAR);
187
188                 case DOUBLE:
189                         return(SZDOUBLE/SZCHAR);
190
191                 case INT:
192                 case UNSIGNED:
193                 case LONG:
194                 case ULONG:
195                         return(SZINT/SZCHAR);
196
197                 case LONGLONG:
198                 case ULONGLONG:
199                         return SZLONGLONG/SZCHAR;
200
201                 default:
202                         if (!ISPTR(p->n_type))
ragge
1.14
203                                 comperr("tlen type %d not pointer");
ragge
1.39
204                         return SZPOINT(p->n_type)/SZCHAR;
ragge
1.1
205                 }
206 }
207
ragge
1.17
208 /*
209  * Emit code to compare two longlong numbers.
210  */
211 static void
212 twollcomp(NODE *p)
213 {
214         int o = p->n_op;
215         int s = getlab();
216         int e = p->n_label;
217         int cb1cb2;
218
219         if (o >= ULE)
220                 o -= (ULE-LE);
221         switch (o) {
222         case NE:
223                 cb1 = 0;
224                 cb2 = NE;
225                 break;
226         case EQ:
227                 cb1 = NE;
228                 cb2 = 0;
229                 break;
230         case LE:
231         case LT:
232                 cb1 = GT;
233                 cb2 = LT;
234                 break;
235         case GE:
236         case GT:
237                 cb1 = LT;
238                 cb2 = GT;
239                 break;
240         
ragge
1.32
241         default:
242                 cb1 = cb2 = 0/* XXX gcc */
ragge
1.17
243         }
244         if (p->n_op >= ULE)
245                 cb1 += 4cb2 += 4;
246         expand(p0"  cmpl UR,UL\n");
247         if (cb1cbgen(cb1s);
248         if (cb2cbgen(cb2e);
249         expand(p0"  cmpl AR,AL\n");
250         cbgen(p->n_ope);
251         deflab(s);
252 }
253
ragge
1.22
254 /*
255  * Assign to a bitfield.
256  * Clumsy at least, but what to do?
257  */
258 static void
259 bfasg(NODE *p)
260 {
261         NODE *fn = p->n_left;
262         int shift = UPKFOFF(fn->n_rval);
263         int fsz = UPKFSZ(fn->n_rval);
ragge
1.36
264         int andvaltch = 0;
265
266         /* get instruction size */
267         switch (p->n_type) {
268         case CHARcase UCHARtch = 'b'break;
269         case SHORTcase USHORTtch = 'w'break;
270         case INTcase UNSIGNEDtch = 'l'break;
271         defaultcomperr("bfasg");
272         }
ragge
1.22
273
274         /* put src into a temporary reg */
ragge
1.36
275         fprintf(stdout"       mov%c "tch);
276         zzzcode(p'R');
ragge
1.22
277         fprintf(stdout",");
ragge
1.36
278         zzzcode(p'1');
ragge
1.22
279         fprintf(stdout"\n");
280
281         /* AND away the bits from dest */
ragge
1.27
282         andval = ~(((1 << fsz) - 1) << shift);
ragge
1.36
283         fprintf(stdout"       and%c $%d,"tchandval);
ragge
1.22
284         adrput(stdoutfn->n_left);
285         fprintf(stdout"\n");
286
287         /* AND away unwanted bits from src */
288         andval = ((1 << fsz) - 1);
ragge
1.36
289         fprintf(stdout"       and%c $%d,"tchandval);
290         zzzcode(p'1');
ragge
1.22
291         fprintf(stdout"\n");
292
293         /* SHIFT left src number of bits */
294         if (shift) {
ragge
1.36
295                 fprintf(stdout"       sal%c $%d,"tchshift);
296                 zzzcode(p'1');
ragge
1.22
297                 fprintf(stdout"\n");
298         }
299
300         /* OR in src to dest */
ragge
1.36
301         fprintf(stdout"       or%c "tch);
302         zzzcode(p'1');
ragge
1.22
303         fprintf(stdout",");
304         adrput(stdoutfn->n_left);
305         fprintf(stdout"\n");
306 }
307
ragge
1.23
308 /*
309  * Push a structure on stack as argument.
310  * the scratch registers are already free here
311  */
312 static void
313 starg(NODE *p)
314 {
315         FILE *fp = stdout;
316
ragge
1.28
317         if (p->n_left->n_op == REG && p->n_left->n_type == PTR+STRTY)
318                 return/* already on stack */
ragge
1.23
319         fprintf(fp"   subl $%d,%%esp\n"p->n_stsize);
320         fprintf(fp"   pushl $%d\n"p->n_stsize);
321         expand(p0"  pushl AL\n");
322         expand(p0"  leal 8(%esp),A1\n");
323         expand(p0"  pushl A1\n");
324         fprintf(fp"   call memcpy\n");
325         fprintf(fp"   addl $12,%%esp\n");
326 }
327
ragge
1.25
328 /*
329  * Compare two floating point numbers.
330  */
331 static void
332 fcomp(NODE *p)  
333 {
334         
335         if (p->n_left->n_op == REG)
336                 expand(p0"  fucompp\n");    /* emit compare insn  */
ragge
1.27
337         else if (p->n_left->n_type == DOUBLE)
338                 expand(p0"  fcompl AL\n");  /* emit compare insn  */
339         else if (p->n_left->n_type == FLOAT)
340                 expand(p0"  fcomp AL\n");   /* emit compare insn  */
ragge
1.25
341         else
ragge
1.27
342                 comperr("bad compare %p\n"p);
ragge
1.25
343         expand(p0"  fnstsw %ax\n"); /* move status reg to ax */
344         
345         switch (p->n_op) {
346         case EQ:
347                 expand(p0"  andb $64,%ah\n  jne LC\n");
348                 break;
349         case NE:
350                 expand(p0"  andb $64,%ah\n  je LC\n");
351                 break;
352         case LE:
ragge
1.27
353                 expand(p0"  andb $65,%ah\n  cmpb $1,%ah\n   jne LC\n");
ragge
1.25
354                 break;
355         case LT:
ragge
1.27
356                 expand(p0"  andb $65,%ah\n  je LC\n");
ragge
1.25
357                 break;
358         case GT:
ragge
1.27
359                 expand(p0"  andb $1,%ah\n   jne LC\n");
ragge
1.25
360                 break;
361         case GE:
ragge
1.27
362                 expand(p0"  andb $65,%ah\n  jne LC\n");
ragge
1.25
363                 break;
364         default:
365                 comperr("fcomp op %d\n"p->n_op);
366         }
367 }
368
ragge
1.29
369 /*
370  * Convert an unsigned long long to floating point number.
371  */
372 static void
373 ulltofp(NODE *p)
374 {
375         static int loadlab;
376         int jmplab;
377
378         if (loadlab == 0) {
379                 loadlab = getlab();
380                 expand(p0"  .data\n");
381                 printf(LABFMT ":        .long 0,0x80000000,0x403f\n"loadlab);
382                 expand(p0"  .text\n");
383         }
384         jmplab = getlab();
385         expand(p0"  pushl UL\n      pushl AL\n");
386         expand(p0"  fildq (%esp)\n");
387         expand(p0"  addl $8,%esp\n");
388         expand(p0"  cmpl $0,UL\n");
389         printf("        jge " LABFMT "\n"jmplab);
390         printf("        fldt " LABFMT "\n"loadlab);
391         printf("        faddp %%st,%%st(1)\n");
392         printf(LABFMT ":\n"jmplab);
393 }
394
ragge
1.1
395 void
396 zzzcode(NODE *pint c)
397 {
ragge
1.9
398         NODE *r;
ragge
1.1
399
400         switch (c) {
401         case 'A':
ragge
1.7
402                 /*
403                  * Shift operations. Either the right node is a constant
404                  * or a register, in the latter case it must be %cl.
405                  */
406                 p = p->n_right;
407                 if (p->n_op == ICON)
408                         printf("$" CONFMTp->n_lval);
409                 else if (p->n_op != REG || p->n_rval != 2/* CX */
ragge
1.14
410                         comperr("bad shift reg");
ragge
1.7
411                 else
412                         printf("%%cl"); 
ragge
1.1
413                 break;
ragge
1.7
414
ragge
1.9
415         case 'B':
416                 /*
417                  * Print conversion chars for loading into register.
418                  */
419                 p = getlr(p'R');
420                 switch (p->n_type) {
421                 case SHORTprintf("swl"); break;
422                 case USHORTprintf("zwl"); break;
423                 case CHARprintf("sbl"); break;
424                 case UCHARprintf("zbl"); break;
ragge
1.14
425                 defaultcomperr("ZB: %d"p->n_type);
ragge
1.9
426                 }
427                 break;
428
ragge
1.12
429         case 'C':  /* remove from stack after subroutine call */
430                 if (p->n_rval)
431                         printf("        addl $%d, %s\n",
ragge
1.25
432                             p->n_rval*4rnames[STKREG]);
ragge
1.12
433                 break;
ragge
1.17
434
435         case 'D'/* Long long comparision */
436                 twollcomp(p);
437                 break;
ragge
1.12
438
ragge
1.22
439         case 'E'/* Assign to bitfield */
440                 bfasg(p);
441                 break;
442
ragge
1.23
443         case 'F'/* Structure argument */
444                 starg(p);
445                 break;
446
ragge
1.25
447         case 'G'/* Floating point compare */
448                 fcomp(p);
449                 break;
450
451         case 'H'/* Fix correct order of sub from stack */
452                 /* Check which leg was evaluated first */
453                 if ((p->n_su & DORIGHT) == 0)
454                         putchar('r');
455                 break;
456
ragge
1.27
457         case 'I'/* high part of init constant */
458                 if (p->n_name[0] != '\0')
459                         comperr("named highword");
460                 fprintf(stdoutCONFMT, (p->n_lval >> 32) & 0xffffffff);
461                 break;
462
ragge
1.29
463         case 'J'/* convert unsigned long long to floating point */
464                 ulltofp(p);
465                 break;
466
ragge
1.40
467         case 'K'/* do scalar casts */
468                 sconv(p);
469                 break;
470
ragge
1.9
471         case 'L':
472         case 'R':
473         case '1':
474                 /*
475                  * Prints out a register of small type, like %al.
476                  * Type is determined by op.
477                  */
478                 r = getlr(pc);
ragge
1.24
479                 if (r->n_op != REG && r->n_op != MOVE)
ragge
1.12
480                         adrput(stdoutr);
ragge
1.16
481                 else if (r->n_type == SHORT || r->n_type == USHORT)
ragge
1.9
482                         printf("%%%cx"rnames[r->n_rval][2]);
ragge
1.16
483                 else if (r->n_type == CHAR || r->n_type == UCHAR)
484                         printf("%%%cl"rnames[r->n_rval][2]);
ragge
1.9
485                 else
ragge
1.16
486                         printf("%s"rnames[r->n_rval]);
ragge
1.1
487                 break;
488
489         default:
ragge
1.14
490                 comperr("zzzcode %c"c);
ragge
1.1
491         }
492 }
493
ragge
1.40
494 /*
495  * Generate scalar cast code.
496  */
497 void
498 sconv(NODE *p)
499 {
500         NODE *q = p->n_left;
501         int s,d;
502
503         s = 0d = 0;
504         switch (p->n_type) {
505         case CHAR:
506         case UCHAR:
507                 d = 'b';
508                 break;
509
510         case SHORT:
511         case USHORT:
512                 d = 'w';
513                 break;
514
515         case INT:
516         case UNSIGNED:
517                 d = 'l';
518                 break;
519         default:
520                 comperr("unsupported sconv, type %x"p->n_type);
521         }
522         switch (q->n_type) {
523         case CHAR:
524         case UCHAR:
525                 s = 'b';
526                 break;
527
528         case SHORT:
529         case USHORT:
530                 s = 'w';
531                 break;
532
533         case INT:
534         case UNSIGNED:
535                 s = 'l';
536                 break;
537         default:
538                 comperr("unsupported sconv src, type %x"q->n_type);
539         }
540
541         printf("        mov%c%c%c "ISUNSIGNED(p->n_type) ? 'z' : 's'sd);
542         zzzcode(p'L');
543         putchar(',');
544         adrput(stdoutgetlr(p'1'));
545         putchar('\n');
546 }
547
ragge
1.1
548 /* set up temporary registers */
549 void
550 setregs()
551 {
ragge
1.17
552         fregs = 3;      /* 3 free regs on x86 (0-2) */
ragge
1.1
553 }
554
555 /*ARGSUSED*/
556 int
557 rewfld(NODE *p)
558 {
559         return(1);
560 }
561
562 int canaddr(NODE *);
563 int
564 canaddr(NODE *p)
565 {
566         int o = p->n_op;
567
568         if (o==NAME || o==REG || o==ICON || o==OREG ||
ragge
1.12
569             (o==UMUL && shumul(p->n_left)))
ragge
1.1
570                 return(1);
571         return(0);
572 }
573
ragge
1.21
574 /*
575  * Does the bitfield shape match?
576  */
ragge
1.1
577 int
578 flshape(NODE *p)
579 {
ragge
1.22
580         int o = p->n_op;
581
582         if (o == OREG || o == REG || o == NAME)
583                 return SRDIR/* Direct match */
584         if (o == UMUL && shumul(p->n_left))
585                 return SROREG/* Convert into oreg */
586         return SRREG/* put it into a register */
ragge
1.1
587 }
588
589 /* INTEMP shapes must not contain any temporary registers */
ragge
1.15
590 /* XXX should this go away now? */
ragge
1.1
591 int
592 shtemp(NODE *p)
593 {
ragge
1.15
594         return 0;
595 #if 0
ragge
1.1
596         int r;
597
598         if (p->n_op == STARG )
599                 p = p->n_left;
600
601         switch (p->n_op) {
602         case REG:
603                 return (!istreg(p->n_rval));
604
605         case OREG:
606                 r = p->n_rval;
607                 if (R2TEST(r)) {
608                         if (istreg(R2UPK1(r)))
609                                 return(0);
610                         r = R2UPK2(r);
611                 }
612                 return (!istreg(r));
613
ragge
1.12
614         case UMUL:
ragge
1.1
615                 p = p->n_left;
ragge
1.12
616                 return (p->n_op != UMUL && shtemp(p));
ragge
1.1
617         }
618
619         if (optype(p->n_op) != LTYPE)
620                 return(0);
621         return(1);
ragge
1.15
622 #endif
ragge
1.1
623 }
624
625 void
626 adrcon(CONSZ val)
627 {
ragge
1.2
628         printf("$" CONFMTval);
ragge
1.1
629 }
630
631 void
ragge
1.14
632 conput(FILE *fpNODE *p)
ragge
1.1
633 {
ragge
1.17
634         int val = p->n_lval;
635
ragge
1.1
636         switch (p->n_op) {
637         case ICON:
ragge
1.17
638                 if (p->n_name[0] != '\0') {
ragge
1.14
639                         fprintf(fp"%s"p->n_name);
ragge
1.17
640                         if (val)
641                                 fprintf(fp"+%d"val);
642                 } else
643                         fprintf(fp"%d"val);
ragge
1.1
644                 return;
645
646         default:
ragge
1.14
647                 comperr("illegal conput");
ragge
1.1
648         }
649 }
650
651 /*ARGSUSED*/
652 void
653 insput(NODE *p)
654 {
ragge
1.14
655         comperr("insput");
ragge
1.1
656 }
657
658 /*
659  * Write out the upper address, like the upper register of a 2-register
660  * reference, or the next memory location.
661  */
662 void
663 upput(NODE *pint size)
664 {
665
ragge
1.17
666         size /= SZCHAR;
ragge
1.1
667         switch (p->n_op) {
668         case REG:
ragge
1.17
669                 fputs(rnames[p->n_rval + 1], stdout);
ragge
1.1
670                 break;
671
672         case NAME:
673         case OREG:
674                 p->n_lval += size;
ragge
1.12
675                 adrput(stdoutp);
ragge
1.1
676                 p->n_lval -= size;
677                 break;
678         case ICON:
ragge
1.17
679                 fprintf(stdout"$" CONFMTp->n_lval >> 32);
ragge
1.1
680                 break;
681         default:
ragge
1.14
682                 comperr("upput bad op %d size %d"p->n_opsize);
ragge
1.1
683         }
684 }
685
686 void
ragge
1.12
687 adrput(FILE *ioNODE *p)
ragge
1.1
688 {
689         int r;
690         /* output an address, with offsets, from p */
691
692         if (p->n_op == FLD)
693                 p = p->n_left;
694
695         switch (p->n_op) {
696
697         case NAME:
ragge
1.13
698                 if (p->n_name[0] != '\0')
699                         fputs(p->n_nameio);
700                 if (p->n_lval != 0)
701                         fprintf(io"+" CONFMTp->n_lval);
ragge
1.1
702                 return;
703
704         case OREG:
705                 r = p->n_rval;
ragge
1.17
706                 if (p->n_lval)
707                         fprintf(io"%d", (int)p->n_lval);
ragge
1.12
708                 fprintf(io"(%s)"rnames[p->n_rval]);
ragge
1.1
709                 return;
710         case ICON:
711                 /* addressable value of the constant */
ragge
1.14
712                 fputc('$'io);
713                 conput(iop);
ragge
1.1
714                 return;
715
ragge
1.19
716         case MOVE:
ragge
1.1
717         case REG:
ragge
1.20
718                 fprintf(io"%s"rnames[p->n_rval]);
ragge
1.1
719                 return;
720
721         default:
ragge
1.26
722                 comperr("illegal address, op %d, node %p"p->n_opp);
ragge
1.1
723                 return;
724
725         }
726 }
727
ragge
1.6
728 static char *
729 ccbranches[] = {
730         "je",           /* jumpe */
731         "jne",          /* jumpn */
732         "jle",          /* jumple */
733         "jl",           /* jumpl */
734         "jge",          /* jumpge */
735         "jg",           /* jumpg */
736         "jbe",          /* jumple (jlequ) */
737         "jb",           /* jumpl (jlssu) */
738         "jae",          /* jumpge (jgequ) */
739         "ja",           /* jumpg (jgtru) */
740 };
741
ragge
1.1
742
743 /*   printf conditional and unconditional branches */
744 void
ragge
1.6
745 cbgen(int oint lab)
ragge
1.1
746 {
ragge
1.6
747         if (o < EQ || o > UGT)
ragge
1.14
748                 comperr("bad conditional branch: %s"opst[o]);
ragge
1.6
749         printf("        %s " LABFMT "\n"ccbranches[o-EQ], lab);
ragge
1.1
750 }
751
ragge
1.28
752 #if 0
ragge
1.1
753 /*
754  * Do some local optimizations that must be done after optim is called.
755  */
756 static void
757 optim2(NODE *p)
758 {
759         int op = p->n_op;
760         int mml;
761         NODE *l;
762
763         /* Remove redundant PCONV's */
764         if (op == PCONV) {
765                 l = p->n_left;
766                 m = BTYPE(p->n_type);
767                 ml = BTYPE(l->n_type);
768                 if ((m == INT || m == LONG || m == LONGLONG || m == FLOAT ||
769                     m == DOUBLE || m == STRTY || m == UNIONTY || m == ENUMTY ||
770                     m == UNSIGNED || m == ULONG || m == ULONGLONG) &&
771                     (ml == INT || ml == LONG || ml == LONGLONG || ml == FLOAT ||
772                     ml == DOUBLE || ml == STRTY || ml == UNIONTY || 
773                     ml == ENUMTY || ml == UNSIGNED || ml == ULONG ||
774                     ml == ULONGLONG) && ISPTR(l->n_type)) {
775                         *p = *l;
776                         nfree(l);
777                         op = p->n_op;
778                 } else
779                 if (ISPTR(DECREF(p->n_type)) &&
780                     (l->n_type == INCREF(STRTY))) {
781                         *p = *l;
782                         nfree(l);
783                         op = p->n_op;
784                 } else
785                 if (ISPTR(DECREF(l->n_type)) &&
786                     (p->n_type == INCREF(INT) ||
787                     p->n_type == INCREF(STRTY) ||
788                     p->n_type == INCREF(UNSIGNED))) {
789                         *p = *l;
790                         nfree(l);
791                         op = p->n_op;
792                 }
793
794         }
795         /* Add constands, similar to the one in optim() */
796         if (op == PLUS && p->n_right->n_op == ICON) {
797                 l = p->n_left;
798                 if (l->n_op == PLUS && l->n_right->n_op == ICON &&
799                     (p->n_right->n_name[0] == '\0' ||
800                      l->n_right->n_name[0] == '\0')) {
801                         l->n_right->n_lval += p->n_right->n_lval;
802                         if (l->n_right->n_name[0] == '\0')
803                                 l->n_right->n_name = p->n_right->n_name;
804                         nfree(p->n_right);
805                         *p = *l;
806                         nfree(l);
807                 }
808         }
809
810         /* Convert "PTR undef" (void *) to "PTR uchar" */
811         /* XXX - should be done in MI code */
812         if (BTYPE(p->n_type) == VOID)
813                 p->n_type = (p->n_type & ~BTMASK) | UCHAR;
814 }
ragge
1.28
815 #endif
816
817 static void
818 myhardops(NODE *p)
819 {
820         int ty = optype(p->n_op);
821         NODE *l, *r, *q;
822
823         if (ty == UTYPE)
824                 return myhardops(p->n_left);
825         if (ty != BITYPE)
826                 return;
827         myhardops(p->n_right);
828         if (p->n_op != STASG)
829                 return;
830
831         /*
832          * If the structure size to copy is less than 32 byte, let it
833          * be and generate move instructions later.  Otherwise convert it 
834          * to memcpy() calls, unless it has a STCALL function as its
835          * right node, in which case it is untouched.
836          * STCALL returns are handled special.
837          */
838         if (p->n_right->n_op == STCALL || p->n_right->n_op == USTCALL)
839                 return;
840         l = p->n_left;
841         if (l->n_op == UMUL)
842                 l = nfree(l);
843         else if (l->n_op == NAME) {
844                 l->n_op = ICON/* Constant reference */
845                 l->n_type = INCREF(l->n_type);
846         } else
847                 comperr("myhardops");
848         r = p->n_right;
849         q = mkbinode(CMlr0);
850         q = mkbinode(CMqmklnode(ICONp->n_stsize0INT), 0);
851         p->n_op = CALL;
852         p->n_right = q;
853         p->n_left = mklnode(ICON000);
854         p->n_left->n_name = "memcpy";
855 }
ragge
1.1
856
857 void
858 myreader(NODE *p)
859 {
860         int e2print(NODE *pint downint *aint *b);
ragge
1.28
861 //      walkf(p, optim2);
862         myhardops(p);
ragge
1.1
863         if (x2debug) {
864                 printf("myreader final tree:\n");
865                 fwalk(pe2print0);
866         }
867 }
868
869 /*
870  * Remove some PCONVs after OREGs are created.
871  */
872 static void
873 pconv2(NODE *p)
874 {
875         NODE *q;
876
877         if (p->n_op == PLUS) {
878                 if (p->n_type == (PTR|SHORT) || p->n_type == (PTR|USHORT)) {
879                         if (p->n_right->n_op != ICON)
880                                 return;
881                         if (p->n_left->n_op != PCONV)
882                                 return;
883                         if (p->n_left->n_left->n_op != OREG)
884                                 return;
885                         q = p->n_left->n_left;
886                         nfree(p->n_left);
887                         p->n_left = q;
888                         /*
889                          * This will be converted to another OREG later.
890                          */
891                 }
892         }
893 }
894
895 void
896 mycanon(NODE *p)
897 {
898         walkf(ppconv2);
899 }
900
ragge
1.25
901 void
902 mygenregs(NODE *p)
903 {
904         if (p->n_op == MINUS && p->n_type == DOUBLE &&
905             (p->n_su & (LMASK|RMASK)) == (LREG|RREG)) {
906                 p->n_su |= DORIGHT;
907         }
ragge
1.28
908         /* Must walk down correct node first for logops to work */
ragge
1.25
909         if (p->n_op != CBRANCH)
910                 return;
911         p = p->n_left;
912         if ((p->n_su & (LMASK|RMASK)) != (LREG|RREG))
913                 return;
914         p->n_su &= ~DORIGHT;
915 }
916
ragge
1.1
917 /*
918  * Remove last goto.
919  */
920 void
921 myoptim(struct interpass *ip)
922 {
ragge
1.40
923 #if 0
ragge
1.1
924         while (ip->sqelem.sqe_next->type != IP_EPILOG)
925                 ip = ip->sqelem.sqe_next;
926         if (ip->type != IP_NODE || ip->ip_node->n_op != GOTO)
ragge
1.14
927                 comperr("myoptim");
ragge
1.1
928         tfree(ip->ip_node);
929         *ip = *ip->sqelem.sqe_next;
ragge
1.40
930 #endif
ragge
1.1
931 }
ragge
1.17
932
933 struct hardops hardops[] = {
934         { MULLONGLONG"__muldi3" },
ragge
1.30
935         { MULULONGLONG"__muldi3" },
ragge
1.17
936         { DIVLONGLONG"__divdi3" },
937         { DIVULONGLONG"__udivdi3" },
938         { MODLONGLONG"__moddi3" },
939         { MODULONGLONG"__umoddi3" },
ragge
1.26
940         { RSLONGLONG"__ashrdi3" },
941         { RSULONGLONG"__lshrdi3" },
942         { LSLONGLONG"__ashldi3" },
943         { LSULONGLONG"__ashldi3" },
ragge
1.28
944 #if 0
ragge
1.18
945         { STASGPTR+STRTY"memcpy" },
ragge
1.25
946         { STASGPTR+UNIONTY"memcpy" },
ragge
1.28
947 #endif
ragge
1.17
948         { 0 },
949 };
ragge
1.46
950
951 void
952 rmove(int sint dTWORD t)
953 {
954         printf("        movl %s,%s\n"rnames[s], rnames[d]);
955 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-09-19 05:48 +0200