Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080729132558

Diff

Diff from 1.14 to:

Annotations

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

Annotated File View

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