Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080101173100

Diff

Diff from 1.12 to:

Annotations

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

Annotated File View

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