Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100530153245

Diff

Diff from 1.18 to:

Annotations

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

Annotated File View

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