Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20090530085034

Diff

Diff from 1.11 to:

Annotations

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

Annotated File View

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