Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20160106161124

Diff

Diff from 1.27 to:

Annotations

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

Annotated File View

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