Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090522081802

Diff

Diff from 1.4 to:

Annotations

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

Annotated File View

ragge
1.4
1 /*      $Id: local2.c,v 1.4 2009/05/22 08:18:02 ragge Exp $     */
mickey
1.1
2 /*
3  * Copyright (c) 2008 Michael Shalayeff
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 # include "pass2.h"
31 # include <ctype.h>
32 # include <string.h>
33
34 static int stkpos;
35
36 void
37 deflab(int label)
38 {
39         printf(LABFMT ":\n"label);
40 }
41
42 static int regoff[7];
43 static TWORD ftype;
ragge
1.4
44 char *rbyte[], *rshort[], *rlong[];
mickey
1.1
45
46 /*
47  * Print out the prolog assembler.
48  * addto and regoff are already calculated.
49  */
50 static void
51 prtprolog(struct interpass_prolog *ippint addto)
52 {
ragge
1.4
53 //      static int lwnr;
mickey
1.1
54         int i;
55
mickey
1.2
56         printf("\tpushq %%rbp\n");
57         printf("\tmovq %%rsp,%%rbp\n");
mickey
1.1
58         if (addto)
mickey
1.2
59                 printf("\tsubq $%d,%%rsp\n"addto);
mickey
1.1
60         for (i = 0i < MAXREGSi++)
ragge
1.4
61                 if (TESTBIT(ipp->ipp_regsi)) {
mickey
1.2
62                         fprintf(stdout"\tmov %s,-%d(%s)\n",
mickey
1.1
63                             rnames[i], regoff[i], rnames[FPREG]);
ragge
1.4
64 }
65 #if 0
mickey
1.1
66         if (kflag == 0)
67                 return;
68
69         /* if ebx are not saved to stack, it must be moved into another reg */
70         /* check and emit the move before GOT stuff */
71         if (!TESTBIT(ipp->ipp_regsEBX)) {
72                 struct interpass *ip = (struct interpass *)ipp;
73
74                 ip = DLIST_PREV(ipqelem);
75                 ip = DLIST_PREV(ipqelem);
76                 ip = DLIST_PREV(ipqelem);
77                 if (ip->type != IP_NODE || ip->ip_node->n_op != ASSIGN ||
78                     ip->ip_node->n_left->n_op != REG)
79                         comperr("prtprolog pic error");
80                 ip = (struct interpass *)ipp;
81                 ip = DLIST_NEXT(ipqelem);
82                 if (ip->type != IP_NODE || ip->ip_node->n_op != ASSIGN ||
83                     ip->ip_node->n_left->n_op != REG)
84                         comperr("prtprolog pic error2");
85                 printf("        movl %s,%s\n",
86                     rnames[ip->ip_node->n_right->n_rval],
87                     rnames[ip->ip_node->n_left->n_rval]);
88                 tfree(ip->ip_node);
89                 DLIST_REMOVE(ipqelem);
90         }
91         printf("        call .LW%d\n", ++lwnr);
92         printf(".LW%d:\n"lwnr);
93         printf("        popl %%ebx\n");
94         printf("        addl $_GLOBAL_OFFSET_TABLE_+[.-.LW%d], %%ebx\n"lwnr);
ragge
1.4
95 #endif
mickey
1.1
96 }
97
98 /*
99  * calculate stack size and offsets
100  */
101 static int
102 offcalc(struct interpass_prolog *ipp)
103 {
104         int iaddto;
105
106         addto = p2maxautooff;
107         if (addto >= AUTOINIT/SZCHAR)
108                 addto -= AUTOINIT/SZCHAR;
109         for (i = 0i < MAXREGSi++)
110                 if (TESTBIT(ipp->ipp_regsi)) {
111                         addto += SZINT/SZCHAR;
112                         regoff[i] = addto;
113                 }
114         return addto;
115 }
116
117 void
118 prologue(struct interpass_prolog *ipp)
119 {
120         int addto;
121
122         ftype = ipp->ipp_type;
123
124 #ifdef LANG_F77
125         if (ipp->ipp_vis)
126                 printf("        .globl %s\n"ipp->ipp_name);
127         printf("        .align 4\n");
128         printf("%s:\n"ipp->ipp_name);
129 #endif
130         /*
131          * We here know what register to save and how much to 
132          * add to the stack.
133          */
134         addto = offcalc(ipp);
135         prtprolog(ippaddto);
136 }
137
138 void
139 eoftn(struct interpass_prolog *ipp)
140 {
141         int i;
142
143         if (ipp->ipp_ip.ip_lbl == 0)
144                 return/* no code needs to be generated */
145
146         /* return from function code */
147         for (i = 0i < MAXREGSi++)
148                 if (TESTBIT(ipp->ipp_regsi))
149                         fprintf(stdout"       movl -%d(%s),%s\n",
150                             regoff[i], rnames[FPREG], rnames[i]);
151
152         /* struct return needs special treatment */
153         if (ftype == STRTY || ftype == UNIONTY) {
154                 printf("        movl 8(%%ebp),%%eax\n");
155                 printf("        leave\n");
156                 printf("        ret $%d\n"4);
157         } else {
158                 printf("        leave\n");
159         }
160         printf("\t.size %s,.-%s\n"ipp->ipp_name,
161             ipp->ipp_name);
162 }
163
164 /*
165  * add/sub/...
166  *
167  * Param given:
168  */
169 void
170 hopcode(int fint o)
171 {
172         char *str;
173
174         switch (o) {
175         case PLUS:
176                 str = "add";
177                 break;
178         case MINUS:
179                 str = "sub";
180                 break;
181         case AND:
182                 str = "and";
183                 break;
184         case OR:
185                 str = "or";
186                 break;
187         case ER:
188                 str = "xor";
189                 break;
190         default:
191                 comperr("hopcode2: %d"o);
192                 str = 0/* XXX gcc */
193         }
194         printf("%s%c"strf);
195 }
196
197 /*
198  * Return type size in bytes.  Used by R2REGS, arg 2 to offset().
199  */
200 int
mickey
1.2
201 tlen(NODE *p)
mickey
1.1
202 {
203         switch(p->n_type) {
204                 case CHAR:
205                 case UCHAR:
206                         return(1);
207
208                 case SHORT:
209                 case USHORT:
210                         return(SZSHORT/SZCHAR);
211
212                 case DOUBLE:
213                         return(SZDOUBLE/SZCHAR);
214
215                 case INT:
216                 case UNSIGNED:
217                         return(SZINT/SZCHAR);
218
219                 case LONG:
220                 case ULONG:
221                 case LONGLONG:
222                 case ULONGLONG:
223                         return SZLONGLONG/SZCHAR;
224
225                 default:
226                         if (!ISPTR(p->n_type))
227                                 comperr("tlen type %d not pointer");
228                         return SZPOINT(p->n_type)/SZCHAR;
229                 }
230 }
231
gmcgarry
1.3
232 #if 0
mickey
1.1
233 /*
234  * Emit code to compare two longlong numbers.
235  */
236 static void
237 twollcomp(NODE *p)
238 {
239         int o = p->n_op;
mickey
1.2
240         int s = getlab2();
mickey
1.1
241         int e = p->n_label;
242         int cb1cb2;
243
244         if (o >= ULE)
245                 o -= (ULE-LE);
246         switch (o) {
247         case NE:
248                 cb1 = 0;
249                 cb2 = NE;
250                 break;
251         case EQ:
252                 cb1 = NE;
253                 cb2 = 0;
254                 break;
255         case LE:
256         case LT:
257                 cb1 = GT;
258                 cb2 = LT;
259                 break;
260         case GE:
261         case GT:
262                 cb1 = LT;
263                 cb2 = GT;
264                 break;
265         
266         default:
267                 cb1 = cb2 = 0/* XXX gcc */
268         }
269         if (p->n_op >= ULE)
270                 cb1 += 4cb2 += 4;
271         expand(p0"  cmpl UR,UL\n");
272         if (cb1cbgen(cb1s);
273         if (cb2cbgen(cb2e);
274         expand(p0"  cmpl AR,AL\n");
275         cbgen(p->n_ope);
276         deflab(s);
277 }
gmcgarry
1.3
278 #endif
mickey
1.1
279
280 int
281 fldexpand(NODE *pint cookiechar **cp)
282 {
283         CONSZ val;
284
285         if (p->n_op == ASSIGN)
286                 p = p->n_left;
287         switch (**cp) {
288         case 'S':
289                 printf("%d"UPKFSZ(p->n_rval));
290                 break;
291         case 'H':
292                 printf("%d"UPKFOFF(p->n_rval));
293                 break;
294         case 'M':
295         case 'N':
296                 val = (CONSZ)1 << UPKFSZ(p->n_rval);
297                 --val;
298                 val <<= UPKFOFF(p->n_rval);
299                 printf("0x%llx", (**cp == 'M' ? val : ~val) & 0xffffffff);
300                 break;
301         default:
302                 comperr("fldexpand");
303         }
304         return 1;
305 }
306
ragge
1.4
307 #if 0
mickey
1.1
308 static void
309 bfext(NODE *p)
310 {
311         int ch = 0sz = 0;
312
313         if (ISUNSIGNED(p->n_right->n_type))
314                 return;
315         switch (p->n_right->n_type) {
316         case CHAR:
317                 ch = 'b';
318                 sz = 8;
319                 break;
320         case SHORT:
321                 ch = 'w';
322                 sz = 16;
323                 break;
324         case INT:
325                 ch = 'l';
326                 sz = 32;
327                 break;
328         case LONG:
329                 ch = 'q';
330                 sz = 64;
331                 break;
332         default:
333                 comperr("bfext");
334         }
335
336         sz -= UPKFSZ(p->n_left->n_rval);
337         printf("\tshl%c $%d,"chsz);
338         adrput(stdoutgetlr(p'D'));
339         printf("\n\tsar%c $%d,"chsz);
340         adrput(stdoutgetlr(p'D'));
341         printf("\n");
342 }
343
344 /*
345  * Push a structure on stack as argument.
346  * the scratch registers are already free here
347  */
348 static void
349 starg(NODE *p)
350 {
351         FILE *fp = stdout;
352
353         fprintf(fp"   subl $%d,%%esp\n"p->n_stsize);
354         fprintf(fp"   pushl $%d\n"p->n_stsize);
355         expand(p0"  pushl AL\n");
356         expand(p0"  leal 8(%esp),A1\n");
357         expand(p0"  pushl A1\n");
358         fprintf(fp"   call memcpy\n");
359         fprintf(fp"   addl $12,%%esp\n");
360 }
361
362 /*
363  * Compare two floating point numbers.
364  */
365 static void
366 fcomp(NODE *p)  
367 {
368         
369         if (p->n_left->n_op == REG) {
370                 if (p->n_su & DORIGHT)
371                         expand(p0"  fxch\n");
372                 expand(p0"  fucompp\n");    /* emit compare insn  */
373         } else if (p->n_left->n_type == DOUBLE)
374                 expand(p0"  fcompl AL\n");  /* emit compare insn  */
375         else if (p->n_left->n_type == FLOAT)
376                 expand(p0"  fcomp AL\n");   /* emit compare insn  */
377         else
378                 comperr("bad compare %p\n"p);
379         expand(p0"  fnstsw %ax\n"); /* move status reg to ax */
380         
381         switch (p->n_op) {
382         case EQ:
383                 expand(p0"  andb $64,%ah\n  jne LC\n");
384                 break;
385         case NE:
386                 expand(p0"  andb $64,%ah\n  je LC\n");
387                 break;
388         case LE:
389                 expand(p0"  andb $65,%ah\n  cmpb $1,%ah\n   jne LC\n");
390                 break;
391         case LT:
392                 expand(p0"  andb $65,%ah\n  je LC\n");
393                 break;
394         case GT:
395                 expand(p0"  andb $1,%ah\n   jne LC\n");
396                 break;
397         case GE:
398                 expand(p0"  andb $65,%ah\n  jne LC\n");
399                 break;
400         default:
401                 comperr("fcomp op %d\n"p->n_op);
402         }
403 }
404
405 /*
406  * Convert an unsigned long long to floating point number.
407  */
408 static void
409 ulltofp(NODE *p)
410 {
411         static int loadlab;
412         int jmplab;
413
414         if (loadlab == 0) {
mickey
1.2
415                 loadlab = getlab2();
mickey
1.1
416                 expand(p0"  .data\n");
417                 printf(LABFMT ":        .long 0,0x80000000,0x403f\n"loadlab);
418                 expand(p0"  .text\n");
419         }
mickey
1.2
420         jmplab = getlab2();
mickey
1.1
421         expand(p0"  pushl UL\n      pushl AL\n");
422         expand(p0"  fildq (%esp)\n");
423         expand(p0"  addl $8,%esp\n");
424         expand(p0"  cmpl $0,UL\n");
425         printf("        jge " LABFMT "\n"jmplab);
426         printf("        fldt " LABFMT "\n"loadlab);
427         printf("        faddp %%st,%%st(1)\n");
428         printf(LABFMT ":\n"jmplab);
429 }
ragge
1.4
430 #endif
mickey
1.1
431
432 static int
433 argsiz(NODE *p)
434 {
435         TWORD t = p->n_type;
436
437         if (t < LONG || t == FLOAT || t > BTMASK)
438                 return 4;
439         if (t == LONG || t == ULONG || t == LONGLONG || t == ULONGLONG ||
440             t == DOUBLE)
441                 return 8;
442         if (t == LDOUBLE)
443                 return 16;
444         if (t == STRTY || t == UNIONTY)
445                 return p->n_stsize;
446         comperr("argsiz");
447         return 0;
448 }
449
450 void
451 zzzcode(NODE *pint c)
452 {
ragge
1.4
453 //      NODE *l;
454 //      int pr, lr, s;
mickey
1.1
455
456         switch (c) {
ragge
1.4
457 #if 0
mickey
1.1
458         case 'A'/* swap st0 and st1 if right is evaluated second */
459                 if ((p->n_su & DORIGHT) == 0) {
460                         if (logop(p->n_op))
461                                 printf("        fxch\n");
462                         else
463                                 printf("r");
464                 }
465                 break;
466
467         case 'C':  /* remove from stack after subroutine call */
468                 if (p->n_left->n_flags & FSTDCALL)
469                         break;
470                 pr = p->n_qual;
471                 if (p->n_op == STCALL || p->n_op == USTCALL)
472                         pr += 4;
473                 if (p->n_op == UCALL)
474                         return/* XXX remove ZC from UCALL */
475                 if (pr)
476                         printf("        addl $%d, %s\n"prrnames[ESP]);
477                 break;
478
479         case 'E'/* Perform bitfield sign-extension */
480                 bfext(p);
481                 break;
482
483         case 'F'/* Structure argument */
484                 if (p->n_stalign != 0/* already on stack */
485                         starg(p);
486                 break;
487
488         case 'G'/* Floating point compare */
489                 fcomp(p);
490                 break;
491
492         case 'J'/* convert unsigned long long to floating point */
493                 ulltofp(p);
494                 break;
495
496         case 'M'/* Output sconv move, if needed */
497                 l = getlr(p'L');
498                 /* XXX fixneed: regnum */
499                 pr = DECRA(p->n_reg0);
500                 lr = DECRA(l->n_reg0);
501                 if ((pr == AL && lr == EAX) || (pr == BL && lr == EBX) ||
502                     (pr == CL && lr == ECX) || (pr == DL && lr == EDX))
503                         ;
504                 else
505                         printf("        movb %%%cl,%s\n",
506                             rnames[lr][2], rnames[pr]);
507                 l->n_rval = l->n_reg = p->n_reg/* XXX - not pretty */
508                 break;
509
510         case 'N'/* output extended reg name */
511                 printf("%s"rnames[getlr(p'1')->n_rval]);
512                 break;
513
514         case 'S'/* emit eventual move after cast from longlong */
515                 pr = DECRA(p->n_reg0);
516                 lr = p->n_left->n_rval;
517                 switch (p->n_type) {
518                 case CHAR:
519                 case UCHAR:
520                         if (rnames[pr][2] == 'l' && rnames[lr][2] == 'x' &&
521                             rnames[pr][1] == rnames[lr][1])
522                                 break;
523                         if (rnames[lr][2] == 'x') {
524                                 printf("\tmovb %%%cl,%s\n",
525                                     rnames[lr][1], rnames[pr]);
526                                 break;
527                         }
528                         /* Must go via stack */
529                         s = BITOOR(freetemp(1));
530                         printf("\tmovl %%e%ci,%d(%%rbp)\n"rnames[lr][1], s);
531                         printf("\tmovb %d(%%rbp),%s\n"srnames[pr]);
532                         comperr("SCONV1 %s->%s"rnames[lr], rnames[pr]);
533                         break;
534
535                 case SHORT:
536                 case USHORT:
537                         if (rnames[lr][1] == rnames[pr][2] &&
538                             rnames[lr][2] == rnames[pr][3])
539                                 break;
540                         printf("\tmovw %%%c%c,%%%s\n",
541                             rnames[lr][1], rnames[lr][2], rnames[pr]+2);
542                         comperr("SCONV2 %s->%s"rnames[lr], rnames[pr]);
543                         break;
544                 case INT:
545                 case UNSIGNED:
546                         if (rnames[lr][1] == rnames[pr][2] &&
547                             rnames[lr][2] == rnames[pr][3])
548                                 break;
549                         printf("\tmovl %%e%c%c,%s\n",
550                                     rnames[lr][1], rnames[lr][2], rnames[pr]);
551                         comperr("SCONV3 %s->%s"rnames[lr], rnames[pr]);
552                         break;
553
554                 default:
555                         if (rnames[lr][1] == rnames[pr][2] &&
556                             rnames[lr][2] == rnames[pr][3])
557                                 break;
558                         comperr("SCONV4 %s->%s"rnames[lr], rnames[pr]);
559                         break;
560                 }
561                 break;
ragge
1.4
562 #endif
mickey
1.1
563         default:
564                 comperr("zzzcode %c"c);
565         }
566 }
567
568 /*ARGSUSED*/
569 int
570 rewfld(NODE *p)
571 {
572         return(1);
573 }
574
575 int canaddr(NODE *);
576 int
577 canaddr(NODE *p)
578 {
579         int o = p->n_op;
580
581         if (o==NAME || o==REG || o==ICON || o==OREG ||
582             (o==UMUL && shumul(p->n_leftSOREG)))
583                 return(1);
584         return(0);
585 }
586
587 /*
588  * Does the bitfield shape match?
589  */
590 int
591 flshape(NODE *p)
592 {
593         int o = p->n_op;
594
595         if (o == OREG || o == REG || o == NAME)
596                 return SRDIR/* Direct match */
597         if (o == UMUL && shumul(p->n_leftSOREG))
598                 return SROREG/* Convert into oreg */
599         return SRREG/* put it into a register */
600 }
601
602 /* INTEMP shapes must not contain any temporary registers */
603 /* XXX should this go away now? */
604 int
605 shtemp(NODE *p)
606 {
607         return 0;
608 #if 0
609         int r;
610
611         if (p->n_op == STARG )
612                 p = p->n_left;
613
614         switch (p->n_op) {
615         case REG:
616                 return (!istreg(p->n_rval));
617
618         case OREG:
619                 r = p->n_rval;
620                 if (R2TEST(r)) {
621                         if (istreg(R2UPK1(r)))
622                                 return(0);
623                         r = R2UPK2(r);
624                 }
625                 return (!istreg(r));
626
627         case UMUL:
628                 p = p->n_left;
629                 return (p->n_op != UMUL && shtemp(p));
630         }
631
632         if (optype(p->n_op) != LTYPE)
633                 return(0);
634         return(1);
635 #endif
636 }
637
638 void
639 adrcon(CONSZ val)
640 {
641         printf("$" CONFMTval);
642 }
643
644 void
645 conput(FILE *fpNODE *p)
646 {
647         int val = p->n_lval;
648
649         switch (p->n_op) {
650         case ICON:
651                 if (p->n_name[0] != '\0') {
652                         fprintf(fp"%s"p->n_name);
653                         if (val)
654                                 fprintf(fp"+%d"val);
655                 } else
656                         fprintf(fp"%d"val);
657                 return;
658
659         default:
660                 comperr("illegal conput, p %p"p);
661         }
662 }
663
664 /*ARGSUSED*/
665 void
666 insput(NODE *p)
667 {
668         comperr("insput");
669 }
670
671 /*
672  * Write out the upper address, like the upper register of a 2-register
673  * reference, or the next memory location.
674  */
675 void
676 upput(NODE *pint size)
677 {
678
679         size /= SZCHAR;
680         switch (p->n_op) {
681         case REG:
682                 fprintf(stdout"%%%s", &rnames[p->n_rval][3]);
683                 break;
684
685         case NAME:
686         case OREG:
687                 p->n_lval += size;
688                 adrput(stdoutp);
689                 p->n_lval -= size;
690                 break;
691         case ICON:
692                 fprintf(stdout"$" CONFMTp->n_lval >> 32);
693                 break;
694         default:
695                 comperr("upput bad op %d size %d"p->n_opsize);
696         }
697 }
698
699 void
700 adrput(FILE *ioNODE *p)
701 {
702         int r;
703         /* output an address, with offsets, from p */
704
705         if (p->n_op == FLD)
706                 p = p->n_left;
707
708         switch (p->n_op) {
709
710         case NAME:
711                 if (p->n_name[0] != '\0') {
712                         fputs(p->n_nameio);
713                         if (p->n_lval != 0)
714                                 fprintf(io"+" CONFMTp->n_lval);
715                 } else
716                         fprintf(ioCONFMTp->n_lval);
717                 return;
718
719         case OREG:
720                 r = p->n_rval;
721                 if (p->n_name[0])
722                         printf("%s%s"p->n_namep->n_lval ? "+" : "");
723                 if (p->n_lval)
724                         fprintf(io"%d", (int)p->n_lval);
725                 if (R2TEST(r)) {
726                         fprintf(io"(%s,%s,8)"rnames[R2UPK1(r)],
727                             rnames[R2UPK2(r)]);
728                 } else
729                         fprintf(io"(%s)"rnames[p->n_rval]);
730                 return;
731         case ICON:
732 #ifdef PCC_DEBUG
733                 /* Sanitycheck for PIC, to catch adressable constants */
734                 if (kflag && p->n_name[0]) {
735                         static int foo;
736
737                         if (foo++ == 0) {
738                                 printf("\nfailing...\n");
739                                 fwalk(pe2print0);
740                                 comperr("pass2 conput");
741                         }
742                 }
743 #endif
744                 /* addressable value of the constant */
745                 fputc('$'io);
746                 conput(iop);
747                 return;
748
749         case REG:
750                 switch (p->n_type) {
751                 case LONGLONG:
752                 case ULONGLONG:
753                         fprintf(io"%%%c%c%c"rnames[p->n_rval][0],
754                             rnames[p->n_rval][1], rnames[p->n_rval][2]);
755                         break;
756                 case SHORT:
757                 case USHORT:
758                         fprintf(io"%%%s", &rnames[p->n_rval][2]);
759                         break;
760                 default:
761                         fprintf(io"%s"rnames[p->n_rval]);
762                 }
763                 return;
764
765         default:
766                 comperr("illegal address, op %d, node %p"p->n_opp);
767                 return;
768
769         }
770 }
771
772 static char *
773 ccbranches[] = {
774         "je",           /* jumpe */
775         "jne",          /* jumpn */
776         "jle",          /* jumple */
777         "jl",           /* jumpl */
778         "jge",          /* jumpge */
779         "jg",           /* jumpg */
780         "jbe",          /* jumple (jlequ) */
781         "jb",           /* jumpl (jlssu) */
782         "jae",          /* jumpge (jgequ) */
783         "ja",           /* jumpg (jgtru) */
784 };
785
786
787 /*   printf conditional and unconditional branches */
788 void
789 cbgen(int oint lab)
790 {
791         if (o < EQ || o > UGT)
792                 comperr("bad conditional branch: %s"opst[o]);
793         printf("        %s " LABFMT "\n"ccbranches[o-EQ], lab);
794 }
795
796 static void
797 fixcalls(NODE *pvoid *arg)
798 {
799         /* Prepare for struct return by allocating bounce space on stack */
800         switch (p->n_op) {
801         case STCALL:
802         case USTCALL:
803                 if (p->n_stsize+p2autooff > stkpos)
804                         stkpos = p->n_stsize+p2autooff;
805                 break;
806         }
807 }
808
809 void
810 myreader(struct interpass *ipole)
811 {
812         struct interpass *ip;
813
814         stkpos = p2autooff;
815         DLIST_FOREACH(ipipoleqelem) {
816                 if (ip->type != IP_NODE)
817                         continue;
818                 walkf(ip->ip_nodefixcalls0);
819         }
820         if (stkpos > p2autooff)
821                 p2autooff = stkpos;
822         if (stkpos > p2maxautooff)
823                 p2maxautooff = stkpos;
824         if (x2debug)
825                 printip(ipole);
826 }
827
828 /*
829  * Remove some PCONVs after OREGs are created.
830  */
831 static void
832 pconv2(NODE *pvoid *arg)
833 {
834         NODE *q;
835
836         if (p->n_op == PLUS) {
837                 if (p->n_type == (PTR|SHORT) || p->n_type == (PTR|USHORT)) {
838                         if (p->n_right->n_op != ICON)
839                                 return;
840                         if (p->n_left->n_op != PCONV)
841                                 return;
842                         if (p->n_left->n_left->n_op != OREG)
843                                 return;
844                         q = p->n_left->n_left;
845                         nfree(p->n_left);
846                         p->n_left = q;
847                         /*
848                          * This will be converted to another OREG later.
849                          */
850                 }
851         }
852 }
853
854 void
855 mycanon(NODE *p)
856 {
857         walkf(ppconv20);
858 }
859
860 void
861 myoptim(struct interpass *ip)
862 {
863 }
864
865 void
866 rmove(int sint dTWORD t)
867 {
868
869         switch (t) {
870         case LONG:
871         case ULONG:
872         case LONGLONG:
873         case ULONGLONG:
874                 printf("        movq %s,%s\n"rnames[s], rnames[d]);
875                 break;
876         case CHAR:
877         case UCHAR:
ragge
1.4
878                 printf("        movb %s,%s\n"rbyte[s], rbyte[d]);
879                 break;
880         case SHORT:
881         case USHORT:
882                 printf("        movw %s,%s\n"rshort[s], rshort[d]);
mickey
1.1
883                 break;
884         case FLOAT:
885         case DOUBLE:
886         case LDOUBLE:
887 #ifdef notdef
888                 /* a=b()*c(); will generate this */
889                 comperr("bad float rmove: %d %d"sd);
890 #endif
891                 break;
892         default:
ragge
1.4
893                 printf("        movl %s,%s\n"rlong[s], rlong[d]);
mickey
1.1
894         }
895 }
896
897 /*
898  * For class c, find worst-case displacement of the number of
899  * registers in the array r[] indexed by class.
900  */
901 int
902 COLORMAP(int cint *r)
903 {
904
905         switch (c) {
906         case CLASSA:
ragge
1.4
907                 return r[CLASSA] < 14;
mickey
1.1
908         case CLASSB:
ragge
1.4
909                 return r[CLASSB] < 16;
mickey
1.1
910         }
911         return 0/* XXX gcc */
912 }
913
914 char *rnames[] = {
ragge
1.4
915         "%rax""%rdx""%rcx""%rbx""%rsi""%rdi""%rbp""%rsp",
916         "%r8""%r9""%r10""%r11""%r12""%r13""%r14""%r15",
917         "%xmm0""%xmm1""%xmm2""%xmm3""%xmm4""%xmm5""%xmm6""%xmm7",
918         "%xmm8""%xmm9""%xmm10""%xmm11""%xmm12""%xmm13""%xmm14",
919         "%xmm15",
920 };
921
922 /* register names for shorter sizes */
923 char *rbyte[] = {
924         "%al""%dl""%cl""%bl""%sil""%dil""%bpl""%spl",
925         "%r8b""%r9b""%r10b""%r11b""%r12b""%r13b""%r14b""%r15b"
926 };
927 char *rshort[] = {
928         "%ax""%dx""%cx""%bx""%si""%di""%bp""%sp",
929         "%r8w""%r9w""%r10w""%r11w""%r12w""%r13w""%r14w""%r15w"
930 };
931 char *rlong[] = {
mickey
1.1
932         "%eax""%edx""%ecx""%ebx""%esi""%edi""%ebp""%esp",
ragge
1.4
933         "%r8l""%r9l""%r10l""%r11l""%r12l""%r13l""%r14l""%r15l"
mickey
1.1
934 };
935
ragge
1.4
936
mickey
1.1
937 /*
938  * Return a class suitable for a specific type.
939  */
940 int
941 gclass(TWORD t)
942 {
ragge
1.4
943         if (t == FLOAT || t == DOUBLE || t == LDOUBLE)
mickey
1.1
944                 return CLASSB;
945         return CLASSA;
946 }
947
948 /*
949  * Calculate argument sizes.
950  */
951 void
952 lastcall(NODE *p)
953 {
954         NODE *op = p;
955         int size = 0;
956
957         p->n_qual = 0;
958         if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
959                 return;
960         for (p = p->n_rightp->n_op == CMp = p->n_left)
961                 size += argsiz(p->n_right);
962         size += argsiz(p);
963         if (kflag)
964                 size -= 4;
965         op->n_qual = size/* XXX */
966 }
967
968 /*
969  * Special shapes.
970  */
971 int
972 special(NODE *pint shape)
973 {
974         int o = p->n_op;
975
976         switch (shape) {
977         case SFUNCALL:
978                 if (o == STCALL || o == USTCALL)
979                         return SRREG;
980                 break;
981         case SPCON:
982                 if (o != ICON || p->n_name[0] ||
983                     p->n_lval < 0 || p->n_lval > 0x7fffffff)
984                         break;
985                 return SRDIR;
986         case SMIXOR:
987                 return tshape(pSZERO);
988         case SMILWXOR:
989                 if (o != ICON || p->n_name[0] ||
990                     p->n_lval == 0 || p->n_lval & 0xffffffff)
991                         break;
992                 return SRDIR;
993         case SMIHWXOR:
994                 if (o != ICON || p->n_name[0] ||
995                      p->n_lval == 0 || (p->n_lval >> 32) != 0)
996                         break;
997                 return SRDIR;
998         }
999         return SRNOPE;
1000 }
1001
1002 /*
1003  * Target-dependent command-line options.
1004  */
1005 void
1006 mflags(char *str)
1007 {
1008 }
1009
1010 /*
1011  * Do something target-dependent for xasm arguments.
1012  */
1013 int
1014 myxasm(struct interpass *ipNODE *p)
1015 {
ragge
1.4
1016 cerror("myxasm");
1017 #if 0
mickey
1.1
1018         struct interpass *ip2;
1019         NODE *in = 0, *ut = 0;
1020         TWORD t;
1021         char *w;
1022         int reg;
1023         int cw;
1024
1025         cw = xasmcode(p->n_name);
1026         if (cw & (XASMASG|XASMINOUT))
1027                 ut = p->n_left;
1028         if ((cw & XASMASG) == 0)
1029                 in = p->n_left;
1030
1031         switch (XASMVAL(cw)) {
1032         case 'D'reg = EDIbreak;
1033         case 'S'reg = ESIbreak;
1034         case 'a'reg = EAXbreak;
1035         case 'b'reg = EBXbreak;
1036         case 'c'reg = ECXbreak;
1037         case 'd'reg = EDXbreak;
1038         case 't'reg = 0break;
1039         case 'u'reg = 1break;
1040         case 'A'reg = EAXEDXbreak;
1041         case 'q'/* XXX let it be CLASSA as for now */
1042                 p->n_name = tmpstrdup(p->n_name);
1043                 w = strchr(p->n_name'q');
1044                 *w = 'r';
1045                 return 0;
1046         default:
1047                 return 0;
1048         }
1049         p->n_name = tmpstrdup(p->n_name);
1050         for (w = p->n_name; *ww++)
1051                 ;
1052         w[-1] = 'r'/* now reg */
1053         t = p->n_left->n_type;
1054         if (reg == EAXEDX) {
1055                 p->n_label = CLASSC;
1056         } else {
1057                 p->n_label = CLASSA;
1058                 if (t == CHAR || t == UCHAR) {
1059                         p->n_label = CLASSB;
1060                         reg = reg * 2 + 8;
1061                 }
1062         }
1063         if (t == FLOAT || t == DOUBLE || t == LDOUBLE) {
1064                 p->n_label = CLASSD;
1065                 reg += 037;
1066         }
1067
1068         if (in && ut)
1069                 in = tcopy(in);
1070         p->n_left = mklnode(REG0regt);
1071         if (ut) {
1072                 ip2 = ipnode(mkbinode(ASSIGNuttcopy(p->n_left), t));
1073                 DLIST_INSERT_AFTER(ipip2qelem);
1074         }
1075         if (in) {
1076                 ip2 = ipnode(mkbinode(ASSIGNtcopy(p->n_left), int));
1077                 DLIST_INSERT_BEFORE(ipip2qelem);
1078         }
ragge
1.4
1079 #endif
mickey
1.1
1080         return 1;
1081 }
1082
1083 void
1084 targarg(char *wvoid *arg)
1085 {
ragge
1.4
1086 cerror("targarg");
1087 #if 0
mickey
1.1
1088         NODE **ary = arg;
1089         NODE *p, *q;
1090
1091         p = ary[(int)w[1]-'0']->n_left;
1092         if (optype(p->n_op) != LTYPE)
1093                 comperr("bad xarg op %d"p->n_op);
1094         q = tcopy(p);
1095         if (q->n_op == REG) {
1096                 if (*w == 'k') {
1097                         q->n_type = INT;
1098                 } else if (*w != 'w') {
1099                         if (q->n_type > UCHAR) {
1100                                 regno(q) = regno(q)*2+8;
1101                                 if (*w == 'h')
1102                                         regno(q)++;
1103                         }
1104                         q->n_type = INT;
1105                 } else
1106                         q->n_type = SHORT;
1107         }
1108         adrput(stdoutq);
1109         tfree(q);
ragge
1.4
1110 #endif
mickey
1.1
1111 }
1112
1113 /*
1114  * target-specific conversion of numeric arguments.
1115  */
1116 int
1117 numconv(void *ipvoid *p1void *q1)
1118 {
1119         NODE *p = p1, *q = q1;
1120         int cw = xasmcode(q->n_name);
1121
1122         switch (XASMVAL(cw)) {
1123         case 'a':
1124         case 'b':
1125         case 'c':
1126         case 'd':
1127                 p->n_name = tmpcalloc(2);
1128                 p->n_name[0] = XASMVAL(cw);
1129                 return 1;
1130         default:
1131                 return 0;
1132         }
1133 }
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-23 08:22 +0200