Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100407144549

Diff

Diff from 1.17 to:

Annotations

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

Annotated File View

ragge
1.17
1 /*      $Id: code.c,v 1.17 2010/04/07 14:45:49 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
31 # include "pass1.h"
32
ragge
1.11
33 static int nssengprnrsprsaoff;
ragge
1.14
34 static int thisssethisgprthisrsp;
ragge
1.8
35 enum { INTEGER = 1INTMEMSSESSEMEMX87STRREGSTRMEM };
ragge
1.10
36 static const int argregsi[] = { RDIRSIRDXRCXR08R09 };
ragge
1.11
37 /*
38  * The Register Save Area looks something like this.
39  * It is put first on stack with fixed offsets.
40  * struct {
41  *      long regs[6];
42  *      double xmm[8][2]; // 16 byte in width
43  * };
44  */
45 #define RSASZ           (6*SZLONG+8*2*SZDOUBLE)
46 #define RSALONGOFF(x)   (RSASZ-(x)*SZLONG)
47 #define RSADBLOFF(x)    ((8*2*SZDOUBLE)-(x)*SZDOUBLE*2)
48 /* va_list */
49 #define VAARGSZ         (SZINT*2+SZPOINT(CHAR)*2)
50 #define VAGPOFF(x)      (x)
51 #define VAFPOFF(x)      (x-SZINT)
52 #define VAOFA(x)        (x-SZINT-SZINT)
53 #define VARSA(x)        (x-SZINT-SZINT-SZPOINT(0))
mickey
1.1
54
55 int lastloc = -1;
56
ragge
1.8
57 static int argtyp(TWORD tunion dimfun *dfstruct suedef *sue);
ragge
1.14
58 static NODE *movtomem(NODE *pint offint reg);
ragge
1.8
59
mickey
1.1
60 /*
61  * Define everything needed to print out some data (or text).
62  * This means segment, alignment, visibility, etc.
63  */
64 void
65 defloc(struct symtab *sp)
66 {
67         extern char *nextsect;
68         static char *loctbl[] = { "text""data""section .rodata" };
ragge
1.6
69         int weak = 0;
70         char *name = NULL;
mickey
1.1
71         TWORD t;
72         int s;
73
74         if (sp == NULL) {
75                 lastloc = -1;
76                 return;
77         }
78         t = sp->stype;
79         s = ISFTN(t) ? PROG : ISCON(cqual(tsp->squal)) ? RDATA : DATA;
80 #ifdef TLS
81         if (sp->sflags & STLS) {
82                 if (s != DATA)
83                         cerror("non-data symbol in tls section");
84                 nextsect = ".tdata";
85         }
86 #endif
ragge
1.6
87 #ifdef GCC_COMPAT
88         {
89                 struct gcc_attrib *ga;
90
91                 if ((ga = gcc_get_attr(sp->ssueGCC_ATYP_SECTION)) != NULL)
92                         nextsect = ga->a1.sarg;
93                 if ((ga = gcc_get_attr(sp->ssueGCC_ATYP_WEAK)) != NULL)
94                         weak = 1;
95         }
96 #endif
97
mickey
1.1
98         if (nextsect) {
99                 printf("        .section %s\n"nextsect);
100                 nextsect = NULL;
101                 s = -1;
102         } else if (s != lastloc)
103                 printf("        .%s\n"loctbl[s]);
104         lastloc = s;
105         while (ISARY(t))
106                 t = DECREF(t);
ragge
1.3
107         s = ISFTN(t) ? ALINT : talign(tsp->ssue);
108         if (s > ALCHAR)
109                 printf("        .align %d\n"s/ALCHAR);
ragge
1.6
110         if (weak || sp->sclass == EXTDEF || sp->slevel == 0 || ISFTN(t))
111                 if ((name = sp->soname) == NULL)
112                         name = exname(sp->sname);
113         if (weak)
114                 printf("        .weak %s\n"name);
mickey
1.16
115         else if (sp->sclass == EXTDEF) {
116                 printf("\t.globl %s\n"name);
117                 printf("\t.type %s,@%s\n"name,
118                     ISFTN(t)? "function" : "object");
119         }
mickey
1.1
120         if (sp->slevel == 0)
ragge
1.6
121                 printf("%s:\n"name);
mickey
1.1
122         else
123                 printf(LABFMT ":\n"sp->soffset);
124 }
125
126 /*
127  * code for the end of a function
128  * deals with struct return here
129  */
130 void
131 efcode()
132 {
133         extern int gotnr;
134         NODE *p, *q;
135
136         gotnr = 0;      /* new number for next fun */
137         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
138                 return;
139         /* Create struct assignment */
140         q = block(OREGNILNILPTR+STRTY0cftnsp->ssue);
ragge
1.5
141         q->n_rval = RBP;
mickey
1.1
142         q->n_lval = 8/* return buffer offset */
143         q = buildtree(UMULqNIL);
144         p = block(REGNILNILPTR+STRTY0cftnsp->ssue);
145         p = buildtree(UMULpNIL);
146         p = buildtree(ASSIGNqp);
147         ecomp(p);
148 }
149
150 /*
151  * code for the beginning of a function; a is an array of
152  * indices in symtab for the arguments; n is the number
153  */
154 void
ragge
1.8
155 bfcode(struct symtab **sint cnt)
mickey
1.1
156 {
ragge
1.11
157         union arglist *al;
ragge
1.8
158         struct symtab *sp;
159         NODE *p, *r;
160         int irnotyp;
mickey
1.1
161
162         /* recalculate the arg offset and create TEMP moves */
ragge
1.8
163         /* Always do this for reg, even if not optimizing, to free arg regs */
ragge
1.9
164         nsse = ngpr = 0;
165         nrsp = ARGINIT;
ragge
1.17
166         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
167                 sp = cftnsp;
168                 if (tsize(sp->stypesp->sdfsp->ssue) > SZLONG*2)
169                         ngpr++; /* For hidden argument */
170         }
171
ragge
1.8
172         for (i = 0i < cnti++) {
173                 sp = s[i];
174
175                 if (sp == NULL)
176                         continue/* XXX when happens this? */
177
178                 switch (typ = argtyp(sp->stypesp->sdfsp->ssue)) {
179                 case INTEGER:
180                 case SSE:
181                         if (typ == SSE)
182                                 rno = XMM0 + nsse++;
183                         else
184                                 rno = argregsi[ngpr++];
185                         r = block(REGNILNILsp->stypesp->sdfsp->ssue);
186                         regno(r) = rno;
187                         p = tempnode(0sp->stypesp->sdfsp->ssue);
188                         sp->soffset = regno(p);
189                         sp->sflags |= STNODE;
190                         ecomp(buildtree(ASSIGNpr));
191                         break;
ragge
1.9
192
193                 case INTMEM:
194                         sp->soffset = nrsp;
195                         nrsp += SZLONG;
196                         if (xtemps) {
197                                 p = tempnode(0sp->stypesp->sdfsp->ssue);
198                                 p = buildtree(ASSIGNpnametree(sp));
199                                 sp->soffset = regno(p->n_left);
200                                 sp->sflags |= STNODE;
201                                 ecomp(p);
202                         }
203                         break;
204
ragge
1.17
205                 case STRMEM/* Struct in memory */
206                         sp->soffset = nrsp;
207                         nrsp += tsize(sp->stypesp->sdfsp->ssue);
208                         break;
209
210                 case STRREG/* Struct in register */
211                         /* Allocate space on stack for the struct */
212                         /* For simplicity always fetch two longwords */
213                         autooff += (2*SZLONG);
214
215                         r = block(REGNILNILLONG0MKSUE(LONG));
216                         regno(r) = argregsi[ngpr++];
217                         ecomp(movtomem(r, -autooffFPREG));
218
219                         if (tsize(sp->stypesp->sdfsp->ssue) > SZLONG) {
220                                 r = block(REGNILNILLONG0MKSUE(LONG));
221                                 regno(r) = argregsi[ngpr++];
222                                 ecomp(movtomem(r, -autooff+SZLONGFPREG));
223                         }
224
225                         sp->soffset = -autooff;
226                         break;
227
ragge
1.8
228                 default:
ragge
1.9
229                         cerror("bfcode: %d"typ);
mickey
1.1
230                 }
231         }
ragge
1.11
232
233         /* Check if there are varargs */
234         if (cftnsp->sdf == NULL || cftnsp->sdf->dfun == NULL)
235                 return/* no prototype */
236         al = cftnsp->sdf->dfun;
ragge
1.15
237
ragge
1.11
238         for (; al->type != TELLIPSISal++) {
239                 if (al->type == TNULL)
240                         return;
ragge
1.15
241                 if (BTYPE(al->type) == STRTY || BTYPE(al->type) == UNIONTY ||
242                     ISARY(al->type))
ragge
1.11
243                         al++;
244         }
245
246         /* fix stack offset */
247         SETOFF(autooffALMAX);
248
249         /* Save reg arguments in the reg save area */
250         p = NIL;
251         for (i = ngpri < 6i++) {
252                 r = block(REGNILNILLONG0MKSUE(LONG));
253                 regno(r) = argregsi[i];
ragge
1.14
254                 r = movtomem(r, -RSALONGOFF(i)-autooffFPREG);
ragge
1.11
255                 p = (p == NIL ? r : block(COMOPprINT0MKSUE(INT)));
256         }
257         for (i = nssei < 8i++) {
258                 r = block(REGNILNILDOUBLE0MKSUE(DOUBLE));
259                 regno(r) = i + XMM0;
ragge
1.14
260                 r = movtomem(r, -RSADBLOFF(i)-autooffFPREG);
ragge
1.11
261                 p = (p == NIL ? r : block(COMOPprINT0MKSUE(INT)));
262         }
263         autooff += RSASZ;
264         rsaoff = autooff;
ragge
1.14
265         thissse = nsse;
266         thisgpr = ngpr;
267         thisrsp = nrsp;
ragge
1.11
268
269         ecomp(p);
mickey
1.1
270 }
271
272
273 /*
274  * by now, the automatics and register variables are allocated
275  */
276 void
277 bccode()
278 {
279         SETOFF(autooffSZINT);
280 }
281
282 /* called just before final exit */
283 /* flag is 1 if errors, 0 if none */
284 void
285 ejobcode(int flag )
286 {
287 #define _MKSTR(x) #x
288 #define MKSTR(x) _MKSTR(x)
289 #define OS MKSTR(TARGOS)
290         printf("\t.ident \"PCC: %s (%s)\"\n\t.end\n"PACKAGE_STRINGOS);
291 }
292
ragge
1.11
293 /*
294  * Varargs stuff:
295  * The ABI says that va_list should be declared as this typedef.
296  * We handcraft it here and then just reference it.
297  *
298  * typedef struct {
299  *      unsigned int gp_offset;
300  *      unsigned int fp_offset;
301  *      void *overflow_arg_area;
302  *      void *reg_save_area;
303  * } __builtin_va_list[1];
304  */
ragge
1.13
305
ragge
1.11
306 static char *gp_offset, *fp_offset, *overflow_arg_area, *reg_save_area;
ragge
1.13
307
mickey
1.1
308 void
309 bjobcode()
310 {
ragge
1.11
311         struct rstack *rp;
312         NODE *p, *q;
313         char *c;
314
315         gp_offset = addname("gp_offset");
316         fp_offset = addname("fp_offset");
317         overflow_arg_area = addname("overflow_arg_area");
318         reg_save_area = addname("reg_save_area");
319
320         rp = bstruct(NULLSTNAMENULL);
321         p = block(NAMENILNILUNSIGNED0MKSUE(UNSIGNED));
322         soumemb(pgp_offset0);
323         soumemb(pfp_offset0);
324         p->n_type = VOID+PTR;
325         p->n_sue = MKSUE(VOID);
326         soumemb(poverflow_arg_area0);
327         soumemb(preg_save_area0);
328         nfree(p);
329         q = dclstruct(rp);
330         c = addname("__builtin_va_list");
331         p = block(LBbdty(NAMEc), bcon(1), INT0MKSUE(INT));
332         p = tymerge(qp);
333         p->n_sp = lookup(c0);
334         defid(pTYPEDEF);
335         nfree(q);
336         nfree(p);
337 }
338
339 static NODE *
340 mkstkref(int offTWORD typ)
341 {
342         NODE *p;
343
344         p = block(REGNILNILPTR|typ0MKSUE(LONG));
345         regno(p) = FPREG;
346         return buildtree(PLUSpbcon(off/SZCHAR));
347 }
348
349 NODE *
350 amd64_builtin_stdarg_start(NODE *fNODE *a)
351 {
352         NODE *p, *r;
353
354         /* check num args and type */
355         if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
356             !ISPTR(a->n_left->n_type))
357                 goto bad;
358
359         /* use the values from the function header */
360         p = a->n_left;
361         r = buildtree(ASSIGNstructref(ccopy(p), STREFreg_save_area),
362             mkstkref(-rsaoffVOID));
363         r = buildtree(COMOPr,
364             buildtree(ASSIGNstructref(ccopy(p), STREFoverflow_arg_area),
ragge
1.14
365             mkstkref(thisrspVOID)));
ragge
1.11
366         r = buildtree(COMOPr,
367             buildtree(ASSIGNstructref(ccopy(p), STREFgp_offset),
ragge
1.14
368             bcon(thisgpr*(SZLONG/SZCHAR))));
ragge
1.11
369         r = buildtree(COMOPr,
370             buildtree(ASSIGNstructref(ccopy(p), STREFfp_offset),
ragge
1.14
371             bcon(thissse*(SZDOUBLE*2/SZCHAR)+48)));
ragge
1.11
372
373         tfree(f);
374         tfree(a);
375         return r;
376 bad:
377         uerror("bad argument to __builtin_stdarg_start");
378         return bcon(0);
mickey
1.1
379 }
380
ragge
1.12
381 /*
382  * Create a tree that should be like the expression
383  *      ((long *)(l->gp_offset >= 48 ?
384  *          l->overflow_arg_area += 8, l->overflow_arg_area :
385  *          l->gp_offset += 8, l->reg_save_area + l->gp_offset))[-1]
ragge
1.13
386  * ...or similar for floats.
ragge
1.12
387  */
388 static NODE *
ragge
1.13
389 bva(NODE *apTWORD dtchar *otint addtoint max)
ragge
1.12
390 {
391         NODE *cm1, *cm2, *gpo, *ofa, *l1, *qc;
ragge
1.13
392         TWORD nt;
ragge
1.12
393
394         ofa = structref(ccopy(ap), STREFoverflow_arg_area);
ragge
1.13
395         l1 = buildtree(PLUSEQccopy(ofa), bcon(addto));
ragge
1.12
396         cm1 = buildtree(COMOPl1ofa);
397
ragge
1.13
398         gpo = structref(ccopy(ap), STREFot);
399         l1 = buildtree(PLUSEQccopy(gpo), bcon(addto));
ragge
1.12
400         cm2 = buildtree(COMOPl1buildtree(PLUSccopy(gpo),
401             structref(ccopy(ap), STREFreg_save_area)));
402         qc = buildtree(QUEST,
ragge
1.13
403             buildtree(GEgpobcon(max)),
ragge
1.12
404             buildtree(COLONcm1cm2));
ragge
1.13
405
406         nt = (dt == DOUBLE ? DOUBLE : LONG);
407         l1 = block(NAMENILNILnt|PTR0MKSUE(nt));
408         l1 = buildtree(CASTl1qc);
409         qc = l1->n_right;
410         nfree(l1->n_left);
411         nfree(l1);
412
ragge
1.14
413         /* qc has now a real type, for indexing */
414         addto = dt == DOUBLE ? 2 : 1;
ragge
1.13
415         qc = buildtree(UMULbuildtree(PLUSqcbcon(-addto)), NIL);
416
417         l1 = block(NAMENILNILdt0MKSUE(BTYPE(dt)));
ragge
1.12
418         l1 = buildtree(CASTl1qc);
ragge
1.13
419         qc = l1->n_right;
ragge
1.12
420         nfree(l1->n_left);
421         nfree(l1);
ragge
1.13
422
423         return qc;
ragge
1.12
424 }
425
ragge
1.11
426 NODE *
ragge
1.12
427 amd64_builtin_va_arg(NODE *fNODE *a)
428 {
429         NODE *ap, *r;
ragge
1.13
430         TWORD dt;
ragge
1.12
431
432         /* check num args and type */
433         if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
434             !ISPTR(a->n_left->n_type) || a->n_right->n_op != TYPE)
435                 goto bad;
436
437         ap = a->n_left;
ragge
1.13
438         dt = a->n_right->n_type;
439         if (dt <= ULONGLONG || ISPTR(dt)) {
ragge
1.12
440                 /* type might be in general register */
ragge
1.13
441                 r = bva(apdtgp_offset848);
442         } else if (dt == FLOAT || dt == DOUBLE) {
443                 /* Float are promoted to double here */
444                 if (dt == FLOAT)
445                         dt = DOUBLE;
446                 r = bva(apdtfp_offset16RSASZ/SZCHAR);
ragge
1.12
447         } else {
ragge
1.13
448                 uerror("amd64_builtin_va_arg not supported type");
449                 goto bad;
ragge
1.12
450         }
451         tfree(a);
452         tfree(f);
453         return r;
454 bad:
455         uerror("bad argument to __builtin_va_arg");
456         return bcon(0);
457 }
ragge
1.11
458
459 NODE *
ragge
1.13
460 amd64_builtin_va_end(NODE *fNODE *a)
461 {
462         tfree(f);
463         tfree(a);
464         return bcon(0); /* nothing */
465 }
ragge
1.11
466
467 NODE *
468 amd64_builtin_va_copy(NODE *fNODE *a) { cerror("amd64_builtin_va_copy"); return NULL; }
469
ragge
1.7
470 static NODE *
471 movtoreg(NODE *pint rno)
mickey
1.1
472 {
473         NODE *r;
474
ragge
1.9
475         r = block(REGNILNILp->n_typep->n_dfp->n_sue);
ragge
1.7
476         regno(r) = rno;
477         return clocal(buildtree(ASSIGNrp));
478 }  
479
ragge
1.9
480 static NODE *
ragge
1.14
481 movtomem(NODE *pint offint reg)
ragge
1.9
482 {
483         struct symtab s;
484         NODE *r, *l;
485
486         s.stype = p->n_type;
487         s.sdf = p->n_df;
488         s.ssue = p->n_sue;
489         s.soffset = off;
ragge
1.11
490         s.sclass = AUTO;
ragge
1.9
491
492         l = block(REGNILNILPTR+STRTY00);
493         l->n_lval = 0;
ragge
1.14
494         regno(l) = reg;
ragge
1.9
495
496         r = block(NAMENILNILp->n_typep->n_dfp->n_sue);
497         r->n_sp = &s;
498         r = stref(block(STREFlr000));
499
500         return clocal(buildtree(ASSIGNrp));
501 }  
502
ragge
1.7
503
504 /*
505  * AMD64 parameter classification.
506  */
507 static int
ragge
1.8
508 argtyp(TWORD tunion dimfun *dfstruct suedef *sue)
ragge
1.7
509 {
510         int cl = 0;
511
ragge
1.9
512         if (t <= ULONG || ISPTR(t)) {
ragge
1.7
513                 cl = ngpr < 6 ? INTEGER : INTMEM;
514         } else if (t == FLOAT || t == DOUBLE) {
ragge
1.8
515                 cl = nsse < 8 ? SSE : SSEMEM;
ragge
1.7
516         } else if (t == LDOUBLE) {
517                 cl = X87/* XXX */
518         } else if (t == STRTY) {
ragge
1.17
519                 /* XXX no SSEOP handling */
520                 if ((tsize(tdfsue) > 2*SZLONG) ||
521                     (gcc_get_attr(sueGCC_ATYP_PACKED) != NULL))
ragge
1.7
522                         cl = STRMEM;
523                 else
ragge
1.17
524                         cl = STRREG;
ragge
1.7
525         } else
526                 cerror("FIXME: classify");
527         return cl;
528 }
529
530 static void
531 argput(NODE *p)
532 {
533         NODE *q;
ragge
1.17
534         int typrssz;
mickey
1.1
535
ragge
1.7
536         /* first arg may be struct return pointer */
537         /* XXX - check if varargs; setup al */
ragge
1.8
538         switch (typ = argtyp(p->n_typep->n_dfp->n_sue)) {
ragge
1.7
539         case INTEGER:
540         case SSE:
541                 q = talloc();
542                 *q = *p;
543                 if (typ == SSE)
544                         r = XMM0 + nsse++;
545                 else
546                         r = argregsi[ngpr++];
547                 q = movtoreg(qr);
548                 *p = *q;
549                 nfree(q);
550                 break;
551         case X87:
552                 cerror("no long double yet");
553                 break;
ragge
1.9
554
555         case INTMEM:
556                 q = talloc();
557                 *q = *p;
558                 r = nrsp;
559                 nrsp += SZLONG;
ragge
1.14
560                 q = movtomem(qrSTKREG);
ragge
1.9
561                 *p = *q;
562                 nfree(q);
563                 break;
564
ragge
1.17
565         case STRREG/* Struct in registers */
566                 /* Cast to long pointer and move to the registers */
567                 ssz = tsize(p->n_typep->n_dfp->n_sue);
568
569                 if (ssz <= SZLONG) {
570                         q = cast(p->n_leftLONG+PTR0);
571                         q = buildtree(UMULqNIL);
572                         q = movtoreg(qargregsi[ngpr++]);
573                         *p = *q;
574                         nfree(q);
575                 } else if (ssz <= SZLONG*2) {
576                         NODE *qt, *q1, *q2, *ql, *qr;
577
578                         qt = tempnode(0LONG+PTR0MKSUE(LONG));
579                         q1 = ccopy(qt);
580                         q2 = ccopy(qt);
581                         ql = buildtree(ASSIGNqtcast(p->n_left,LONG+PTR0));
582                         qr = movtoreg(buildtree(UMULq1NIL),
583                             argregsi[ngpr++]);
584                         ql = buildtree(COMOPqlqr);
585                         qr = buildtree(UMULbuildtree(PLUSq2bcon(1)), NIL);
586                         qr = movtoreg(qrargregsi[ngpr++]);
587                         q = buildtree(COMOPqlqr);
588                         *p = *q;
589                         nfree(q);
590                 } else
591                         cerror("STRREG");
592                 break;
593
ragge
1.7
594         case STRMEM:
595                 /* Struct moved to memory */
596         default:
ragge
1.9
597                 cerror("argument %d"typ);
mickey
1.1
598         }
ragge
1.7
599 }
mickey
1.1
600
601
602 /*
603  * Called with a function call with arguments as argument.
604  * This is done early in buildtree() and only done once.
605  * Returns p.
606  */
607 NODE *
608 funcode(NODE *p)
609 {
ragge
1.8
610         NODE *l, *r;
mickey
1.1
611
ragge
1.9
612         nsse = ngpr = nrsp = 0;
ragge
1.17
613         /* Check if hidden arg needed */
614         /* If so, add it in pass2 */
615         if ((l = p->n_left)->n_type == INCREF(FTN)+STRTY ||
616             l->n_type == INCREF(FTN)+UNIONTY) {
617                 int ssz = tsize(BTYPE(l->n_type), l->n_dfl->n_sue);
618                 if (ssz > 2*SZLONG)
619                         ngpr++;
620         }
ragge
1.7
621         listf(p->n_rightargput);
ragge
1.8
622
623         /* Always emit number of SSE regs used */
624         l = movtoreg(bcon(nsse), RAX);
625         if (p->n_right->n_op != CM) {
626                 p->n_right = block(CMlp->n_rightINT0MKSUE(INT));
627         } else {
628                 for (r = p->n_rightr->n_left->n_op == CMr = r->n_left)
629                         ;
630                 r->n_left = block(CMlr->n_leftINT0MKSUE(INT));
631         }
mickey
1.1
632         return p;
633 }
634
635 /*
636  * return the alignment of field of type t
637  */
638 int
639 fldal(unsigned int t)
640 {
641         uerror("illegal field type");
642         return(ALINT);
643 }
644
645 /* fix up type of field p */
646 void
647 fldty(struct symtab *p)
648 {
649 }
650
651 /*
652  * XXX - fix genswitch.
653  */
654 int
655 mygenswitch(int numTWORD typestruct swents **pint n)
656 {
657         return 0;
658 }
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-30 12:12 +0200