Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080106160559

Diff

Diff from 1.13 to:

Annotations

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

Annotated File View

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