Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20100411122652

Diff

Diff from 1.20 to:

Annotations

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

Annotated File View

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