Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110407185015

Diff

Diff from 1.18 to:

Annotations

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

Annotated File View

ragge
1.18
1 /*      $Id: code.c,v 1.18 2011/04/07 18:50:15 ragge Exp $      */
ragge
1.1
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29
30 /*
31  * MIPS port by Jan Enoksson (janeno-1@student.ltu.se) and
32  * Simon Olsson (simols-1@student.ltu.se) 2005.
33  */
34
gmcgarry
1.7
35 #include <assert.h>
36 #include "pass1.h"
ragge
1.1
37
38 /*
ragge
1.13
39  * Define everything needed to print out some data (or text).
40  * This means segment, alignment, visibility, etc.
41  */
42 void
43 defloc(struct symtab *sp)
44 {
45         static char *loctbl[] = { "text""data""section .rodata" };
46         static int lastloc = -1;
47         TWORD t;
ragge
1.16
48         char *n;
ragge
1.13
49         int s;
50
51         if (sp == NULL) {
52                 lastloc = -1;
53                 return;
54         }
55         t = sp->stype;
56         s = ISFTN(t) ? PROG : ISCON(cqual(tsp->squal)) ? RDATA : DATA;
57         lastloc = s;
58         if (s == PROG)
59                 return/* text is written in prologue() */
60         if (s != lastloc)
61                 printf("        .%s\n"loctbl[s]);
ragge
1.17
62         printf("        .p2align %d\n"ispow2(talign(tsp->sap)));
ragge
1.16
63         n = sp->soname ? sp->soname : sp->sname;
ragge
1.13
64         if (sp->sclass == EXTDEF)
ragge
1.16
65                 printf("        .globl %s\n"n);
ragge
1.13
66         if (sp->slevel == 0) {
67 #ifdef USE_GAS
ragge
1.16
68                 printf("\t.type %s,@object\n"n);
69                 printf("\t.size %s," CONFMT "\n"n,
ragge
1.17
70                     tsize(sp->stypesp->sdfsp->sap));
ragge
1.13
71 #endif
ragge
1.16
72                 printf("%s:\n"n);
ragge
1.13
73         } else
74                 printf(LABFMT ":\n"sp->soffset);
75 }
76
77
78 #ifdef notdef
79 /*
ragge
1.1
80  * cause the alignment to become a multiple of n
81  * never called for text segment.
82  */
83 void
84 defalign(int n)
85 {
gmcgarry
1.10
86         n = ispow2(n / SZCHAR);
87         if (n == -1)
88                 cerror("defalign: n != 2^i");
89         printf("\t.p2align %d\n"n);
ragge
1.1
90 }
91
92 /*
93  * define the current location as the name p->sname
94  * never called for text segment.
95  */
96 void
97 defnam(struct symtab *p)
98 {
ragge
1.12
99         char *c = p->soname;
ragge
1.1
100
101         if (p->sclass == EXTDEF)
gmcgarry
1.4
102                 printf("\t.globl %s\n"c);
103 #ifdef USE_GAS
104         printf("\t.type %s,@object\n"c);
ragge
1.17
105         printf("\t.size %s," CONFMT "\n"ctsize(p->stypep->sdfp->sap));
gmcgarry
1.4
106 #endif
ragge
1.1
107         printf("%s:\n"c);
108 }
ragge
1.13
109 #endif
ragge
1.1
110
gmcgarry
1.7
111 static int rvnr;
112
ragge
1.1
113 /*
114  * code for the end of a function
115  * deals with struct return here
116  */
117 void
118 efcode()
119 {
gmcgarry
1.7
120         NODE *p, *q;
121         int tempnr;
122         int ty;
123
ragge
1.1
124         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
125                 return;
gmcgarry
1.7
126
127         ty = cftnsp->stype - FTN;
128
ragge
1.17
129         q = block(REGNILNILINCREF(ty), 0cftnsp->sap);
gmcgarry
1.7
130         q->n_rval = V0;
ragge
1.17
131         p = tempnode(0INCREF(ty), 0cftnsp->sap);
ragge
1.11
132         tempnr = regno(p);
gmcgarry
1.7
133         p = buildtree(ASSIGNpq);
134         ecomp(p);
135
ragge
1.17
136         q = tempnode(tempnrINCREF(ty), 0cftnsp->sap);
gmcgarry
1.7
137         q = buildtree(UMULqNIL);
138
ragge
1.17
139         p = tempnode(rvnrINCREF(ty), 0cftnsp->sap);
gmcgarry
1.7
140         p = buildtree(UMULpNIL);
141
142         p = buildtree(ASSIGNpq);
143         ecomp(p);
144
ragge
1.17
145         q = tempnode(rvnrINCREF(ty), 0cftnsp->sap);
146         p = block(REGNILNILINCREF(ty), 0cftnsp->sap);
gmcgarry
1.7
147         p->n_rval = V0;
148         p = buildtree(ASSIGNpq);
149         ecomp(p);
ragge
1.1
150 }
151
gmcgarry
1.9
152 /* Put a symbol in a temporary
153  * used by bfcode() and its helpers */
154 static void
155 putintemp(struct symtab *sym)
156 {
157         NODE *p;
ragge
1.17
158         p = tempnode(0sym->stypesym->sdfsym->sap);
ragge
1.14
159         p = buildtree(ASSIGNpnametree(sym));
ragge
1.11
160         sym->soffset = regno(p->n_left);
gmcgarry
1.9
161         sym->sflags |= STNODE;
162         ecomp(p);
163 }
164
165 /* setup the hidden pointer to struct return parameter
166  * used by bfcode() */
167 static void
168 param_retptr(void)
169 {
170         NODE *p, *q;
171
ragge
1.17
172         p = tempnode(0PTR+STRTY0cftnsp->sap);
ragge
1.11
173         rvnr = regno(p);
ragge
1.17
174         q = block(REGNILNILPTR+STRTY0cftnsp->sap);
gmcgarry
1.9
175         q->n_rval = A0;
176         p = buildtree(ASSIGNpq);
177         ecomp(p);
178 }
179
180 /* setup struct parameter
181  * push the registers out to memory
182  * used by bfcode() */
183 static void
184 param_struct(struct symtab *symint *regp)
185 {
186         int reg = *regp;
187         NODE *p, *q;
188         int navail;
189         int sz;
190         int off;
191         int num;
192         int i;
193
194         navail = nargregs - (reg - A0);
ragge
1.17
195         sz = tsize(sym->stypesym->sdfsym->sap) / SZINT;
gmcgarry
1.9
196         off = ARGINIT/SZINT + (reg - A0);
197         num = sz > navail ? navail : sz;
198         for (i = 0i < numi++) {
ragge
1.18
199                 q = block(REGNILNILINT00);
gmcgarry
1.9
200                 q->n_rval = reg++;
ragge
1.18
201                 p = block(REGNILNILINT00);
gmcgarry
1.9
202                 p->n_rval = FP;
ragge
1.18
203                 p = block(PLUSpbcon(4*off++), INT00);
204                 p = block(UMULpNILINT00);
gmcgarry
1.9
205                 p = buildtree(ASSIGNpq);
206                 ecomp(p);
207         }
208
209         *regp = reg;
210 }
211
212 /* setup a 64-bit parameter (double/ldouble/longlong)
213  * used by bfcode() */
214 static void
215 param_64bit(struct symtab *symint *regpint dotemps)
216 {
217         int reg = *regp;
218         NODE *p, *q;
219         int navail;
220
221         /* alignment */
222         ++reg;
223         reg &= ~1;
224
225         navail = nargregs - (reg - A0);
226
gmcgarry
1.10
227         if (navail < 2) {
gmcgarry
1.9
228                 /* would have appeared half in registers/half
229                  * on the stack, but alignment ensures it
230                  * appears on the stack */
231                 if (dotemps)
232                         putintemp(sym);
gmcgarry
1.10
233                 *regp = reg;
234                 return;
235         }
236
ragge
1.17
237         q = block(REGNILNILsym->stypesym->sdfsym->sap);
gmcgarry
1.10
238         q->n_rval = A0A1 + (reg - A0);
239         if (dotemps) {
ragge
1.17
240                 p = tempnode(0sym->stypesym->sdfsym->sap);
ragge
1.11
241                 sym->soffset = regno(p);
gmcgarry
1.10
242                 sym->sflags |= STNODE;
gmcgarry
1.9
243         } else {
ragge
1.14
244                 p = nametree(sym);
gmcgarry
1.9
245         }
gmcgarry
1.10
246         p = buildtree(ASSIGNpq);
247         ecomp(p);
248         *regp = reg + 2;
gmcgarry
1.9
249 }
250
251 /* setup a 32-bit param on the stack
252  * used by bfcode() */
253 static void
254 param_32bit(struct symtab *symint *regpint dotemps)
255 {
256         NODE *p, *q;
257
ragge
1.17
258         q = block(REGNILNILsym->stypesym->sdfsym->sap);
gmcgarry
1.9
259         q->n_rval = (*regp)++;
260         if (dotemps) {
ragge
1.17
261                 p = tempnode(0sym->stypesym->sdfsym->sap);
ragge
1.11
262                 sym->soffset = regno(p);
gmcgarry
1.9
263                 sym->sflags |= STNODE;
264         } else {
ragge
1.14
265                 p = nametree(sym);
gmcgarry
1.9
266         }
267         p = buildtree(ASSIGNpq);
268         ecomp(p);
269 }
270
ragge
1.1
271 /*
gmcgarry
1.10
272  * XXX This is a hack.  We cannot have (l)doubles in more than one
273  * register class.  So we bounce them in and out of temps to
274  * move them in and out of the right registers.
275  */
276 static void
277 param_double(struct symtab *symint *regpint dotemps)
278 {
279         int reg = *regp;
280         NODE *p, *q, *t;
281         int navail;
282         int tmpnr;
283
284         /* alignment */
285         ++reg;
286         reg &= ~1;
287
288         navail = nargregs - (reg - A0);
289
290         if (navail < 2) {
291                 /* would have appeared half in registers/half
292                  * on the stack, but alignment ensures it
293                  * appears on the stack */
294                 if (dotemps)
295                         putintemp(sym);
296                 *regp = reg;
297                 return;
298         }
299
ragge
1.18
300         t = tempnode(0LONGLONG00);
ragge
1.11
301         tmpnr = regno(t);
ragge
1.18
302         q = block(REGNILNILLONGLONG00);
gmcgarry
1.10
303         q->n_rval = A0A1 + (reg - A0);
304         p = buildtree(ASSIGNtq);
305         ecomp(p);
306
307         if (dotemps) {
308                 sym->soffset = tmpnr;
309                 sym->sflags |= STNODE;
310         } else {
ragge
1.17
311                 q = tempnode(tmpnrsym->stypesym->sdfsym->sap);
ragge
1.15
312                 p = nametree(sym);
gmcgarry
1.10
313                 p = buildtree(ASSIGNpq);
314                 ecomp(p);
315         }
316         *regp = reg + 2;
317 }
318
319 /*
320  * XXX This is a hack.  We cannot have floats in more than one
321  * register class.  So we bounce them in and out of temps to
322  * move them in and out of the right registers.
323  */
324 static void
325 param_float(struct symtab *symint *regpint dotemps)
326 {
327         NODE *p, *q, *t;
328         int tmpnr;
329
ragge
1.18
330         t = tempnode(0INT00);
ragge
1.11
331         tmpnr = regno(t);
ragge
1.18
332         q = block(REGNILNILINT00);
gmcgarry
1.10
333         q->n_rval = (*regp)++;
334         p = buildtree(ASSIGNtq);
335         ecomp(p);
336
337         if (dotemps) {
338                 sym->soffset = tmpnr;
339                 sym->sflags |= STNODE;
340         } else {
ragge
1.17
341                 q = tempnode(tmpnrsym->stypesym->sdfsym->sap);
ragge
1.14
342                 p = nametree(sym);
gmcgarry
1.10
343                 p = buildtree(ASSIGNpq);
344                 ecomp(p);
345         }
346 }
347
348 /*
ragge
1.1
349  * code for the beginning of a function; a is an array of
350  * indices in symtab for the arguments; n is the number
351  */
352 void
gmcgarry
1.4
353 bfcode(struct symtab **spint cnt)
ragge
1.1
354 {
gmcgarry
1.9
355         union arglist *usym;
356         int lastreg = A0 + nargregs - 1;
357         int saveallargs = 0;
358         int ireg;
359
360         /*
361          * Detect if this function has ellipses and save all
362          * argument register onto stack.
363          */
364         usym = cftnsp->sdf->dfun;
365         while (usym && usym->type != TNULL) {
366                 if (usym->type == TELLIPSIS) {
367                         saveallargs = 1;
368                         break;
369                 }
370                 ++usym;
371         }
372
373         reg = A0;
ragge
1.1
374
gmcgarry
1.7
375         /* assign hidden return structure to temporary */
ragge
1.1
376         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
gmcgarry
1.9
377                 param_retptr();
378                 ++reg;
ragge
1.1
379         }
380
gmcgarry
1.4
381         /* recalculate the arg offset and create TEMP moves */
gmcgarry
1.9
382         for (i = 0i < cnti++) {
gmcgarry
1.7
383
gmcgarry
1.9
384                 if ((reg > lastreg) && !xtemps)
385                         break;
386                 else if (reg > lastreg
387                         putintemp(sp[i]);
388                 else if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY)
389                         param_struct(sp[i], &reg);
gmcgarry
1.10
390                 else if (DEUNSIGN(sp[i]->stype) == LONGLONG)
gmcgarry
1.9
391                         param_64bit(sp[i], &regxtemps && !saveallargs);
gmcgarry
1.10
392                 else if (sp[i]->stype == DOUBLE || sp[i]->stype == LDOUBLE)
393                         param_double(sp[i], &regxtemps && !saveallargs);
394                 else if (sp[i]->stype == FLOAT)
395                         param_float(sp[i], &regxtemps && !saveallargs);
gmcgarry
1.9
396                 else
397                         param_32bit(sp[i], &regxtemps && !saveallargs);
398         }
gmcgarry
1.7
399
gmcgarry
1.9
400         /* if saveallargs, save the rest of the args onto the stack */
401         if (!saveallargs)
402                 return;
403         while (reg <= lastreg) {
404                 NODE *p, *q;
405                 int off = ARGINIT/SZINT + (reg - A0);
ragge
1.18
406                 q = block(REGNILNILINT00);
gmcgarry
1.9
407                 q->n_rval = reg++;
ragge
1.18
408                 p = block(REGNILNILINT00);
gmcgarry
1.9
409                 p->n_rval = FP;
ragge
1.18
410                 p = block(PLUSpbcon(4*off), INT00);
411                 p = block(UMULpNILINT00);
gmcgarry
1.9
412                 p = buildtree(ASSIGNpq);
413                 ecomp(p);
414         }
ragge
1.1
415
416 }
417
418
419 /*
420  * by now, the automatics and register variables are allocated
421  */
422 void
423 bccode()
424 {
425         SETOFF(autooffSZINT);
426 }
427
428 /* called just before final exit */
429 /* flag is 1 if errors, 0 if none */
430 void
431 ejobcode(int flag )
432 {
433 }
434
435 void
436 bjobcode()
437 {
gmcgarry
1.7
438         printf("\t.section .mdebug.abi32\n");
439         printf("\t.previous\n");
440         printf("\t.abicalls\n");
ragge
1.1
441 }
442
ragge
1.13
443 #ifdef notdef
ragge
1.1
444 /*
445  * Print character t at position i in one string, until t == -1.
446  * Locctr & label is already defined.
447  */
448 void
449 bycode(int tint i)
450 {
gmcgarry
1.2
451         static int lastoctal = 0;
ragge
1.1
452
453         /* put byte i+1 in a string */
454
455         if (t < 0) {
456                 if (i != 0)
gmcgarry
1.10
457                         puts("\\000\"");
ragge
1.1
458         } else {
459                 if (i == 0)
gmcgarry
1.10
460                         printf("\t.ascii \"");
gmcgarry
1.2
461                 if (t == 0)
462                         return;
463                 else if (t == '\\' || t == '"') {
ragge
1.1
464                         lastoctal = 0;
465                         putchar('\\');
466                         putchar(t);
gmcgarry
1.10
467                 } else if (t == 011) {
468                         printf("\\t");
gmcgarry
1.2
469                 } else if (t == 012) {
470                         printf("\\n");
ragge
1.1
471                 } else if (t < 040 || t >= 0177) {
472                         lastoctal++;
473                         printf("\\%o",t);
474                 } else if (lastoctal && '0' <= t && t <= '9') {
475                         lastoctal = 0;
gmcgarry
1.10
476                         printf("\"\n\t.ascii \"%c"t);
ragge
1.1
477                 } else {        
478                         lastoctal = 0;
479                         putchar(t);
480                 }
481         }
482 }
ragge
1.13
483 #endif
ragge
1.1
484
485 /*
486  * return the alignment of field of type t
487  */
488 int
489 fldal(unsigned int t)
490 {
491         uerror("illegal field type");
492         return(ALINT);
493 }
494
495 /* fix up type of field p */
496 void
497 fldty(struct symtab *p)
498 {
499 }
500
stefan
1.5
501 /*
ragge
1.1
502  * XXX - fix genswitch.
503  */
stefan
1.5
504 int
505 mygenswitch(int numTWORD typestruct swents **pint n)
ragge
1.1
506 {
stefan
1.5
507         return 0;
ragge
1.1
508 }
gmcgarry
1.4
509
gmcgarry
1.9
510
511 /* setup call stack with a structure */
512 /* called from moveargs() */
513 static NODE *
514 movearg_struct(NODE *pNODE *parentint *regp)
515 {
516         int reg = *regp;
gmcgarry
1.10
517         NODE *l, *q, *t, *r;
518         int tmpnr;
gmcgarry
1.9
519         int navail;
520         int off;
521         int num;
522         int sz;
gmcgarry
1.10
523         int ty;
gmcgarry
1.9
524         int i;
525
526         navail = nargregs - (reg - A0);
ragge
1.17
527         sz = tsize(p->n_typep->n_dfp->n_ap) / SZINT;
gmcgarry
1.9
528         num = sz > navail ? navail : sz;
529
gmcgarry
1.10
530         l = p->n_left;
531         nfree(p);
532         ty = l->n_type;
ragge
1.17
533         t = tempnode(0l->n_typel->n_dfl->n_ap);
ragge
1.11
534         tmpnr = regno(t);
gmcgarry
1.10
535         l = buildtree(ASSIGNtl);
536
537         if (p != parent) {
gmcgarry
1.9
538                 q = parent->n_left;
gmcgarry
1.10
539         } else
gmcgarry
1.9
540                 q = NULL;
541
542         /* copy structure into registers */
543         for (i = 0i < numi++) {
ragge
1.18
544                 t = tempnode(tmpnrty00);
545                 t = block(SCONVtNILPTR+INT00);
546                 t = block(PLUStbcon(4*i), PTR+INT00);
gmcgarry
1.9
547                 t = buildtree(UMULtNIL);
548
ragge
1.18
549                 r = block(REGNILNILINT00);
gmcgarry
1.9
550                 r->n_rval = reg++;
551
552                 r = buildtree(ASSIGNrt);
553                 if (q == NULL)
554                         q = r;
gmcgarry
1.10
555                 else 
ragge
1.18
556                         q = block(CMqrINT00);
gmcgarry
1.9
557         }
558         off = ARGINIT/SZINT + nargregs;
559         for (i = numi < szi++) {
ragge
1.18
560                 t = tempnode(tmpnrty00);
561                 t = block(SCONVtNILPTR+INT00);
562                 t = block(PLUStbcon(4*i), PTR+INT00);
gmcgarry
1.9
563                 t = buildtree(UMULtNIL);
564
ragge
1.18
565                 r = block(REGNILNILINT00);
gmcgarry
1.9
566                 r->n_rval = FP;
ragge
1.18
567                 r = block(PLUSrbcon(4*off++), INT00);
568                 r = block(UMULrNILINT00);
gmcgarry
1.9
569
570                 r = buildtree(ASSIGNrt);
571                 if (q == NULL)
572                         q = r;
573                 else
ragge
1.18
574                         q = block(CMqrINT00);
gmcgarry
1.9
575         }
576
577         if (parent->n_op == CM) {
gmcgarry
1.10
578                 parent->n_left = q;
579                 q = l;
580         } else {
ragge
1.18
581                 q = block(CMqlINT00);
gmcgarry
1.9
582         }
583
584         *regp = reg;
585         return q;
586 }
587
588 /* setup call stack with 64-bit argument */
589 /* called from moveargs() */
590 static NODE *
591 movearg_64bit(NODE *pint *regp)
592 {
593         int reg = *regp;
594         NODE *q;
gmcgarry
1.10
595         int lastarg;
gmcgarry
1.9
596
597         /* alignment */
598         ++reg;
599         reg &= ~1;
600
gmcgarry
1.10
601         lastarg = A0 + nargregs - 1;
602         if (reg > lastarg) {
603                 *regp = reg;
ragge
1.17
604                 return block(FUNARGpNILp->n_typep->n_dfp->n_ap);
gmcgarry
1.10
605         }
606
ragge
1.17
607         q = block(REGNILNILp->n_typep->n_dfp->n_ap);
gmcgarry
1.10
608         q->n_rval = A0A1 + (reg - A0);
gmcgarry
1.9
609         q = buildtree(ASSIGNqp);
610
gmcgarry
1.10
611         *regp = reg + 2;
gmcgarry
1.9
612         return q;
613 }
614
615 /* setup call stack with 32-bit argument */
616 /* called from moveargs() */
617 static NODE *
618 movearg_32bit(NODE *pint *regp)
619 {
620         int reg = *regp;
621         NODE *q;
622
ragge
1.17
623         q = block(REGNILNILp->n_typep->n_dfp->n_ap);
gmcgarry
1.9
624         q->n_rval = reg++;
625         q = buildtree(ASSIGNqp);
626
627         *regp = reg;
628         return q;
629 }
630
631 static NODE *
632 moveargs(NODE *pint *regp)
gmcgarry
1.4
633 {
gmcgarry
1.9
634         NODE *r, **rp;
635         int lastreg;
636         int reg;
gmcgarry
1.7
637
gmcgarry
1.9
638         if (p->n_op == CM) {
639                 p->n_left = moveargs(p->n_leftregp);
640                 r = p->n_right;
641                 rp = &p->n_right;
gmcgarry
1.4
642         } else {
gmcgarry
1.9
643                 r = p;
644                 rp = &p;
gmcgarry
1.7
645         }
gmcgarry
1.4
646
gmcgarry
1.9
647         lastreg = A0 + nargregs - 1;
648         reg = *regp;
649
650         if (reg > lastreg && r->n_op != STARG)
ragge
1.17
651                 *rp = block(FUNARGrNILr->n_typer->n_dfr->n_ap);
gmcgarry
1.9
652         else if (r->n_op == STARG) {
653                 *rp = movearg_struct(rpregp);
gmcgarry
1.10
654         } else if (DEUNSIGN(r->n_type) == LONGLONG) {
gmcgarry
1.9
655                 *rp = movearg_64bit(rregp);
gmcgarry
1.10
656         } else if (r->n_type == DOUBLE || r->n_type == LDOUBLE) {
657                 /* XXX bounce in and out of temporary to change to longlong */
ragge
1.18
658                 NODE *t1 = tempnode(0LONGLONG00);
ragge
1.11
659                 int tmpnr = regno(t1);
ragge
1.17
660                 NODE *t2 = tempnode(tmpnrr->n_typer->n_dfr->n_ap);
gmcgarry
1.10
661                 t1 =  movearg_64bit(t1regp);
ragge
1.17
662                 r = block(ASSIGNt2rr->n_typer->n_dfr->n_ap);
gmcgarry
1.10
663                 if (p->n_op == CM) {
664                         p->n_left = buildtree(CMp->n_leftt1);
665                         p->n_right = r;
666                 } else {
667                         p = buildtree(CMt1r);
668                 }
669         } else if (r->n_type == FLOAT) {
670                 /* XXX bounce in and out of temporary to change to int */
ragge
1.18
671                 NODE *t1 = tempnode(0INT00);
ragge
1.11
672                 int tmpnr = regno(t1);
ragge
1.17
673                 NODE *t2 = tempnode(tmpnrr->n_typer->n_dfr->n_ap);
gmcgarry
1.10
674                 t1 =  movearg_32bit(t1regp);
ragge
1.17
675                 r = block(ASSIGNt2rr->n_typer->n_dfr->n_ap);
gmcgarry
1.10
676                 if (p->n_op == CM) {
677                         p->n_left = buildtree(CMp->n_leftt1);
678                         p->n_right = r;
679                 } else {
680                         p = buildtree(CMt1r);
681                 }
682         } else {
gmcgarry
1.9
683                 *rp = movearg_32bit(rregp);
gmcgarry
1.10
684         }
gmcgarry
1.9
685
686         return p;
gmcgarry
1.4
687 }
688
ragge
1.3
689 /*
690  * Called with a function call with arguments as argument.
691  * This is done early in buildtree() and only done once.
692  */
693 NODE *
694 funcode(NODE *p)
695 {
gmcgarry
1.4
696         int regnum = A0;
gmcgarry
1.7
697         NODE *l, *r, *t, *q;
698         int ty;
699
700         l = p->n_left;
701         r = p->n_right;
702
gmcgarry
1.9
703         /*
704          * if returning a structure, make the first argument
705          * a hidden pointer to return structure.
706          */
gmcgarry
1.7
707         ty = DECREF(l->n_type);
708         if (ty == STRTY+FTN || ty == UNIONTY+FTN) {
709                 ty = DECREF(l->n_type) - FTN;
ragge
1.17
710                 q = tempnode(0tyl->n_dfl->n_ap);
gmcgarry
1.7
711                 q = buildtree(ADDROFqNIL);
712                 if (r->n_op != CM) {
713                         p->n_right = block(CMqrINCREF(ty),
ragge
1.17
714                             l->n_dfl->n_ap);
gmcgarry
1.7
715                 } else {
716                         for (t = rt->n_left->n_op == CMt = t->n_left)
717                                 ;
718                         t->n_left = block(CMqt->n_leftINCREF(ty),
ragge
1.17
719                             l->n_dfl->n_ap);
gmcgarry
1.7
720                 }
721         }
722
gmcgarry
1.9
723         p->n_right = moveargs(p->n_right, &regnum);
724
ragge
1.3
725         return p;
726 }
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-02 23:27 +0200