Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090524084331

Diff

Diff from 1.7 to:

Annotations

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

Annotated File View

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