Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.22 to:

Annotations

Annotate by Age | Author | Mixed | None

Annotated File View

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