Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20140419074750

Diff

Diff from 1.24 to:

Annotations

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

Annotated File View

ragge
1.24
1 /*      $Id: code.c,v 1.24 2014/04/19 07:47:51 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.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
ragge
1.24
59                 printf("\t.section %s,\"a%c\",@progbits\n"name,
60                     cftnsp ? 'x' : 'w');
ragge
1.21
61                 return;
62         }
63         printf("\t%s\n"name);
64 }
65
66 /*
ragge
1.13
67  * Define everything needed to print out some data (or text).
68  * This means segment, alignment, visibility, etc.
69  */
70 void
71 defloc(struct symtab *sp)
72 {
ragge
1.16
73         char *n;
ragge
1.13
74
ragge
1.21
75         if (ISFTN(sp->stype))
76                 return/* XXX until fixed */
77
78         if ((n = sp->soname) == NULL)
79                 n = exname(sp->sname);
80
ragge
1.13
81         if (sp->sclass == EXTDEF)
ragge
1.16
82                 printf("        .globl %s\n"n);
ragge
1.13
83         if (sp->slevel == 0) {
84 #ifdef USE_GAS
ragge
1.21
85                 printf("\t.type %s,@%s\n"n,
86                     ISFTN(sp->stype) ? "function" : "object");
87                 if (!ISFTN(sp->stype))
88                         printf("\t.size %s," CONFMT "\n"n,
89                             tsize(sp->stypesp->sdfsp->sap));
ragge
1.13
90 #endif
ragge
1.16
91                 printf("%s:\n"n);
ragge
1.13
92         } else
93                 printf(LABFMT ":\n"sp->soffset);
94 }
95
96
97 /*
ragge
1.1
98  * cause the alignment to become a multiple of n
99  */
100 void
101 defalign(int n)
102 {
gmcgarry
1.10
103         n = ispow2(n / SZCHAR);
104         if (n == -1)
105                 cerror("defalign: n != 2^i");
106         printf("\t.p2align %d\n"n);
ragge
1.1
107 }
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
plunky
1.22
116 efcode(void)
ragge
1.1
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
ragge
1.17
127         q = block(REGNILNILINCREF(ty), 0cftnsp->sap);
gmcgarry
1.7
128         q->n_rval = V0;
ragge
1.17
129         p = tempnode(0INCREF(ty), 0cftnsp->sap);
ragge
1.11
130         tempnr = regno(p);
gmcgarry
1.7
131         p = buildtree(ASSIGNpq);
132         ecomp(p);
133
ragge
1.17
134         q = tempnode(tempnrINCREF(ty), 0cftnsp->sap);
gmcgarry
1.7
135         q = buildtree(UMULqNIL);
136
ragge
1.17
137         p = tempnode(rvnrINCREF(ty), 0cftnsp->sap);
gmcgarry
1.7
138         p = buildtree(UMULpNIL);
139
140         p = buildtree(ASSIGNpq);
141         ecomp(p);
142
ragge
1.17
143         q = tempnode(rvnrINCREF(ty), 0cftnsp->sap);
144         p = block(REGNILNILINCREF(ty), 0cftnsp->sap);
gmcgarry
1.7
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;
ragge
1.17
156         p = tempnode(0sym->stypesym->sdfsym->sap);
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
ragge
1.17
170         p = tempnode(0PTR+STRTY0cftnsp->sap);
ragge
1.11
171         rvnr = regno(p);
ragge
1.17
172         q = block(REGNILNILPTR+STRTY0cftnsp->sap);
gmcgarry
1.9
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);
ragge
1.17
193         sz = tsize(sym->stypesym->sdfsym->sap) / SZINT;
gmcgarry
1.9
194         off = ARGINIT/SZINT + (reg - A0);
195         num = sz > navail ? navail : sz;
196         for (i = 0i < numi++) {
ragge
1.18
197                 q = block(REGNILNILINT00);
gmcgarry
1.9
198                 q->n_rval = reg++;
ragge
1.18
199                 p = block(REGNILNILINT00);
gmcgarry
1.9
200                 p->n_rval = FP;
ragge
1.18
201                 p = block(PLUSpbcon(4*off++), INT00);
202                 p = block(UMULpNILINT00);
gmcgarry
1.9
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
ragge
1.17
235         q = block(REGNILNILsym->stypesym->sdfsym->sap);
gmcgarry
1.10
236         q->n_rval = A0A1 + (reg - A0);
237         if (dotemps) {
ragge
1.17
238                 p = tempnode(0sym->stypesym->sdfsym->sap);
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
ragge
1.17
256         q = block(REGNILNILsym->stypesym->sdfsym->sap);
gmcgarry
1.9
257         q->n_rval = (*regp)++;
258         if (dotemps) {
ragge
1.17
259                 p = tempnode(0sym->stypesym->sdfsym->sap);
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
ragge
1.18
298         t = tempnode(0LONGLONG00);
ragge
1.11
299         tmpnr = regno(t);
ragge
1.18
300         q = block(REGNILNILLONGLONG00);
gmcgarry
1.10
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 {
ragge
1.17
309                 q = tempnode(tmpnrsym->stypesym->sdfsym->sap);
ragge
1.15
310                 p = nametree(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
ragge
1.18
328         t = tempnode(0INT00);
ragge
1.11
329         tmpnr = regno(t);
ragge
1.18
330         q = block(REGNILNILINT00);
gmcgarry
1.10
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 {
ragge
1.17
339                 q = tempnode(tmpnrsym->stypesym->sdfsym->sap);
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);
ragge
1.18
404                 q = block(REGNILNILINT00);
gmcgarry
1.9
405                 q->n_rval = reg++;
ragge
1.18
406                 p = block(REGNILNILINT00);
gmcgarry
1.9
407                 p->n_rval = FP;
ragge
1.18
408                 p = block(PLUSpbcon(4*off), INT00);
409                 p = block(UMULpNILINT00);
gmcgarry
1.9
410                 p = buildtree(ASSIGNpq);
411                 ecomp(p);
412         }
ragge
1.1
413
414 }
415
416
417 /* called just before final exit */
418 /* flag is 1 if errors, 0 if none */
419 void
plunky
1.22
420 ejobcode(int flag)
ragge
1.1
421 {
422 }
423
424 void
plunky
1.22
425 bjobcode(void)
ragge
1.1
426 {
gmcgarry
1.7
427         printf("\t.section .mdebug.abi32\n");
428         printf("\t.previous\n");
429         printf("\t.abicalls\n");
ragge
1.1
430 }
431
ragge
1.13
432 #ifdef notdef
ragge
1.1
433 /*
434  * Print character t at position i in one string, until t == -1.
435  * Locctr & label is already defined.
436  */
437 void
438 bycode(int tint i)
439 {
gmcgarry
1.2
440         static int lastoctal = 0;
ragge
1.1
441
442         /* put byte i+1 in a string */
443
444         if (t < 0) {
445                 if (i != 0)
gmcgarry
1.10
446                         puts("\\000\"");
ragge
1.1
447         } else {
448                 if (i == 0)
gmcgarry
1.10
449                         printf("\t.ascii \"");
gmcgarry
1.2
450                 if (t == 0)
451                         return;
452                 else if (t == '\\' || t == '"') {
ragge
1.1
453                         lastoctal = 0;
454                         putchar('\\');
455                         putchar(t);
gmcgarry
1.10
456                 } else if (t == 011) {
457                         printf("\\t");
gmcgarry
1.2
458                 } else if (t == 012) {
459                         printf("\\n");
ragge
1.1
460                 } else if (t < 040 || t >= 0177) {
461                         lastoctal++;
462                         printf("\\%o",t);
463                 } else if (lastoctal && '0' <= t && t <= '9') {
464                         lastoctal = 0;
gmcgarry
1.10
465                         printf("\"\n\t.ascii \"%c"t);
ragge
1.1
466                 } else {        
467                         lastoctal = 0;
468                         putchar(t);
469                 }
470         }
471 }
ragge
1.13
472 #endif
ragge
1.1
473
474 /* fix up type of field p */
475 void
476 fldty(struct symtab *p)
477 {
478 }
479
stefan
1.5
480 /*
ragge
1.1
481  * XXX - fix genswitch.
482  */
stefan
1.5
483 int
484 mygenswitch(int numTWORD typestruct swents **pint n)
ragge
1.1
485 {
stefan
1.5
486         return 0;
ragge
1.1
487 }
gmcgarry
1.4
488
gmcgarry
1.9
489
490 /* setup call stack with a structure */
491 /* called from moveargs() */
492 static NODE *
493 movearg_struct(NODE *pNODE *parentint *regp)
494 {
495         int reg = *regp;
gmcgarry
1.10
496         NODE *l, *q, *t, *r;
497         int tmpnr;
gmcgarry
1.9
498         int navail;
499         int off;
500         int num;
501         int sz;
gmcgarry
1.10
502         int ty;
gmcgarry
1.9
503         int i;
504
505         navail = nargregs - (reg - A0);
ragge
1.17
506         sz = tsize(p->n_typep->n_dfp->n_ap) / SZINT;
gmcgarry
1.9
507         num = sz > navail ? navail : sz;
508
gmcgarry
1.10
509         l = p->n_left;
510         nfree(p);
511         ty = l->n_type;
ragge
1.17
512         t = tempnode(0l->n_typel->n_dfl->n_ap);
ragge
1.11
513         tmpnr = regno(t);
gmcgarry
1.10
514         l = buildtree(ASSIGNtl);
515
516         if (p != parent) {
gmcgarry
1.9
517                 q = parent->n_left;
gmcgarry
1.10
518         } else
gmcgarry
1.9
519                 q = NULL;
520
521         /* copy structure into registers */
522         for (i = 0i < numi++) {
ragge
1.18
523                 t = tempnode(tmpnrty00);
524                 t = block(SCONVtNILPTR+INT00);
525                 t = block(PLUStbcon(4*i), PTR+INT00);
gmcgarry
1.9
526                 t = buildtree(UMULtNIL);
527
ragge
1.18
528                 r = block(REGNILNILINT00);
gmcgarry
1.9
529                 r->n_rval = reg++;
530
531                 r = buildtree(ASSIGNrt);
532                 if (q == NULL)
533                         q = r;
gmcgarry
1.10
534                 else 
ragge
1.18
535                         q = block(CMqrINT00);
gmcgarry
1.9
536         }
537         off = ARGINIT/SZINT + nargregs;
538         for (i = numi < szi++) {
ragge
1.18
539                 t = tempnode(tmpnrty00);
540                 t = block(SCONVtNILPTR+INT00);
541                 t = block(PLUStbcon(4*i), PTR+INT00);
gmcgarry
1.9
542                 t = buildtree(UMULtNIL);
543
ragge
1.18
544                 r = block(REGNILNILINT00);
gmcgarry
1.9
545                 r->n_rval = FP;
ragge
1.18
546                 r = block(PLUSrbcon(4*off++), INT00);
547                 r = block(UMULrNILINT00);
gmcgarry
1.9
548
549                 r = buildtree(ASSIGNrt);
550                 if (q == NULL)
551                         q = r;
552                 else
ragge
1.18
553                         q = block(CMqrINT00);
gmcgarry
1.9
554         }
555
556         if (parent->n_op == CM) {
gmcgarry
1.10
557                 parent->n_left = q;
558                 q = l;
559         } else {
ragge
1.18
560                 q = block(CMqlINT00);
gmcgarry
1.9
561         }
562
563         *regp = reg;
564         return q;
565 }
566
567 /* setup call stack with 64-bit argument */
568 /* called from moveargs() */
569 static NODE *
570 movearg_64bit(NODE *pint *regp)
571 {
572         int reg = *regp;
573         NODE *q;
gmcgarry
1.10
574         int lastarg;
gmcgarry
1.9
575
576         /* alignment */
577         ++reg;
578         reg &= ~1;
579
gmcgarry
1.10
580         lastarg = A0 + nargregs - 1;
581         if (reg > lastarg) {
582                 *regp = reg;
ragge
1.17
583                 return block(FUNARGpNILp->n_typep->n_dfp->n_ap);
gmcgarry
1.10
584         }
585
ragge
1.17
586         q = block(REGNILNILp->n_typep->n_dfp->n_ap);
gmcgarry
1.10
587         q->n_rval = A0A1 + (reg - A0);
gmcgarry
1.9
588         q = buildtree(ASSIGNqp);
589
gmcgarry
1.10
590         *regp = reg + 2;
gmcgarry
1.9
591         return q;
592 }
593
594 /* setup call stack with 32-bit argument */
595 /* called from moveargs() */
596 static NODE *
597 movearg_32bit(NODE *pint *regp)
598 {
599         int reg = *regp;
600         NODE *q;
601
ragge
1.17
602         q = block(REGNILNILp->n_typep->n_dfp->n_ap);
gmcgarry
1.9
603         q->n_rval = reg++;
604         q = buildtree(ASSIGNqp);
605
606         *regp = reg;
607         return q;
608 }
609
610 static NODE *
611 moveargs(NODE *pint *regp)
gmcgarry
1.4
612 {
gmcgarry
1.9
613         NODE *r, **rp;
614         int lastreg;
615         int reg;
gmcgarry
1.7
616
gmcgarry
1.9
617         if (p->n_op == CM) {
618                 p->n_left = moveargs(p->n_leftregp);
619                 r = p->n_right;
620                 rp = &p->n_right;
gmcgarry
1.4
621         } else {
gmcgarry
1.9
622                 r = p;
623                 rp = &p;
gmcgarry
1.7
624         }
gmcgarry
1.4
625
gmcgarry
1.9
626         lastreg = A0 + nargregs - 1;
627         reg = *regp;
628
629         if (reg > lastreg && r->n_op != STARG)
ragge
1.17
630                 *rp = block(FUNARGrNILr->n_typer->n_dfr->n_ap);
gmcgarry
1.9
631         else if (r->n_op == STARG) {
632                 *rp = movearg_struct(rpregp);
gmcgarry
1.10
633         } else if (DEUNSIGN(r->n_type) == LONGLONG) {
gmcgarry
1.9
634                 *rp = movearg_64bit(rregp);
gmcgarry
1.10
635         } else if (r->n_type == DOUBLE || r->n_type == LDOUBLE) {
636                 /* XXX bounce in and out of temporary to change to longlong */
ragge
1.18
637                 NODE *t1 = tempnode(0LONGLONG00);
ragge
1.11
638                 int tmpnr = regno(t1);
ragge
1.17
639                 NODE *t2 = tempnode(tmpnrr->n_typer->n_dfr->n_ap);
gmcgarry
1.10
640                 t1 =  movearg_64bit(t1regp);
ragge
1.17
641                 r = block(ASSIGNt2rr->n_typer->n_dfr->n_ap);
gmcgarry
1.10
642                 if (p->n_op == CM) {
643                         p->n_left = buildtree(CMp->n_leftt1);
644                         p->n_right = r;
645                 } else {
646                         p = buildtree(CMt1r);
647                 }
648         } else if (r->n_type == FLOAT) {
649                 /* XXX bounce in and out of temporary to change to int */
ragge
1.18
650                 NODE *t1 = tempnode(0INT00);
ragge
1.11
651                 int tmpnr = regno(t1);
ragge
1.17
652                 NODE *t2 = tempnode(tmpnrr->n_typer->n_dfr->n_ap);
gmcgarry
1.10
653                 t1 =  movearg_32bit(t1regp);
ragge
1.17
654                 r = block(ASSIGNt2rr->n_typer->n_dfr->n_ap);
gmcgarry
1.10
655                 if (p->n_op == CM) {
656                         p->n_left = buildtree(CMp->n_leftt1);
657                         p->n_right = r;
658                 } else {
659                         p = buildtree(CMt1r);
660                 }
661         } else {
gmcgarry
1.9
662                 *rp = movearg_32bit(rregp);
gmcgarry
1.10
663         }
gmcgarry
1.9
664
665         return p;
gmcgarry
1.4
666 }
667
ragge
1.3
668 /*
669  * Called with a function call with arguments as argument.
670  * This is done early in buildtree() and only done once.
671  */
672 NODE *
673 funcode(NODE *p)
674 {
gmcgarry
1.4
675         int regnum = A0;
gmcgarry
1.7
676         NODE *l, *r, *t, *q;
677         int ty;
678
679         l = p->n_left;
680         r = p->n_right;
681
gmcgarry
1.9
682         /*
683          * if returning a structure, make the first argument
684          * a hidden pointer to return structure.
685          */
gmcgarry
1.7
686         ty = DECREF(l->n_type);
687         if (ty == STRTY+FTN || ty == UNIONTY+FTN) {
688                 ty = DECREF(l->n_type) - FTN;
ragge
1.17
689                 q = tempnode(0tyl->n_dfl->n_ap);
gmcgarry
1.7
690                 q = buildtree(ADDROFqNIL);
691                 if (r->n_op != CM) {
692                         p->n_right = block(CMqrINCREF(ty),
ragge
1.17
693                             l->n_dfl->n_ap);
gmcgarry
1.7
694                 } else {
695                         for (t = rt->n_left->n_op == CMt = t->n_left)
696                                 ;
697                         t->n_left = block(CMqt->n_leftINCREF(ty),
ragge
1.17
698                             l->n_dfl->n_ap);
gmcgarry
1.7
699                 }
700         }
701
gmcgarry
1.9
702         p->n_right = moveargs(p->n_right, &regnum);
703
ragge
1.3
704         return p;
705 }
ragge
1.23
706
707 NODE *
708 builtin_cfa(const struct bitable *btNODE *a)
709 {
710         uerror("missing builtin_cfa");
711         return bcon(0);
712 }
713
714 NODE *
715 builtin_frame_address(const struct bitable *btNODE *a)
716 {
717         uerror("missing builtin_frame_address");
718         return bcon(0);
719 }
720
721 NODE *
722 builtin_return_address(const struct bitable *btNODE *a)
723 {       
724         uerror("missing builtin_return_address");
725         return bcon(0);
726 }
727
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-22 13:44 +0100