Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090525191904

Diff

Diff from 1.10 to:

Annotations

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

Annotated File View

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