Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20071213042014

Diff

Diff from 1.9 to:

Annotations

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

Annotated File View

gmcgarry
1.9
1 /*      $Id: code.c,v 1.9 2007/12/13 04:20:14 gmcgarry 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 {
45         n /= SZCHAR;
46         if (n == 1)
47                 return;
gmcgarry
1.4
48         printf("\t.align %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 {
58         char *c = p->sname;
59
60 #ifdef GCC_COMPAT
61         c = gcc_findname(p);
62 #endif
63         if (p->sclass == EXTDEF)
gmcgarry
1.4
64                 printf("\t.globl %s\n"c);
65 #ifdef USE_GAS
66         printf("\t.type %s,@object\n"c);
67         printf("\t.size %s," CONFMT "\n"ctsize(p->stypep->sdfp->ssue));
68 #endif
ragge
1.1
69         printf("%s:\n"c);
70 }
71
gmcgarry
1.7
72 static int rvnr;
73
ragge
1.1
74 /*
75  * code for the end of a function
76  * deals with struct return here
77  */
78 void
79 efcode()
80 {
gmcgarry
1.7
81         NODE *p, *q;
82         int tempnr;
83         int ty;
84
ragge
1.1
85         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
86                 return;
gmcgarry
1.7
87
88         ty = cftnsp->stype - FTN;
89
90         q = block(REGNILNILINCREF(ty), 0cftnsp->ssue);
91         q->n_rval = V0;
92         p = tempnode(0INCREF(ty), 0cftnsp->ssue);
93         tempnr = p->n_lval;
94         p = buildtree(ASSIGNpq);
95         ecomp(p);
96
97         q = tempnode(tempnrINCREF(ty), 0cftnsp->ssue);
98         q = buildtree(UMULqNIL);
99
100         p = tempnode(rvnrINCREF(ty), 0cftnsp->ssue);
101         p = buildtree(UMULpNIL);
102
103         p = buildtree(ASSIGNpq);
104         ecomp(p);
105
106         q = tempnode(rvnrINCREF(ty), 0cftnsp->ssue);
107         p = block(REGNILNILINCREF(ty), 0cftnsp->ssue);
108         p->n_rval = V0;
109         p = buildtree(ASSIGNpq);
110         ecomp(p);
ragge
1.1
111 }
112
gmcgarry
1.9
113 /* Put a symbol in a temporary
114  * used by bfcode() and its helpers */
115 static void
116 putintemp(struct symtab *sym)
117 {
118         NODE *p;
119         spname = sym;
120         p = tempnode(0sym->stypesym->sdfsym->ssue);
121         p = buildtree(ASSIGNpbuildtree(NAME00));
122         sym->soffset = p->n_left->n_lval;
123         sym->sflags |= STNODE;
124         ecomp(p);
125 }
126
127 /* setup the hidden pointer to struct return parameter
128  * used by bfcode() */
129 static void
130 param_retptr(void)
131 {
132         NODE *p, *q;
133
134         p = tempnode(0PTR+STRTY0cftnsp->ssue);
135         rvnr = p->n_lval;
136         q = block(REGNILNILPTR+STRTY0cftnsp->ssue);
137         q->n_rval = A0;
138         p = buildtree(ASSIGNpq);
139         ecomp(p);
140 }
141
142 /* setup struct parameter
143  * push the registers out to memory
144  * used by bfcode() */
145 static void
146 param_struct(struct symtab *symint *regp)
147 {
148         int reg = *regp;
149         NODE *p, *q;
150         int navail;
151         int sz;
152         int off;
153         int num;
154         int i;
155
156         navail = nargregs - (reg - A0);
157         sz = tsize(sym->stypesym->sdfsym->ssue) / SZINT;
158         off = ARGINIT/SZINT + (reg - A0);
159         num = sz > navail ? navail : sz;
160         for (i = 0i < numi++) {
161                 q = block(REGNILNILINT0MKSUE(INT));
162                 q->n_rval = reg++;
163                 p = block(REGNILNILINT0MKSUE(INT));
164                 p->n_rval = FP;
165                 p = block(PLUSpbcon(4*off++), INT0MKSUE(INT));
166                 p = block(UMULpNILINT0MKSUE(INT));
167                 p = buildtree(ASSIGNpq);
168                 ecomp(p);
169         }
170
171         *regp = reg;
172 }
173
174 /* setup a 64-bit parameter (double/ldouble/longlong)
175  * used by bfcode() */
176 static void
177 param_64bit(struct symtab *symint *regpint dotemps)
178 {
179         int reg = *regp;
180         NODE *p, *q;
181         int navail;
182         int sz;
183
184         /* alignment */
185         ++reg;
186         reg &= ~1;
187
188         navail = nargregs - (reg - A0);
189         sz = szty(sym->stype);
190
191         if (sz > navail) {
192                 /* would have appeared half in registers/half
193                  * on the stack, but alignment ensures it
194                  * appears on the stack */
195                 if (dotemps)
196                         putintemp(sym);
197         } else {
198                 q = block(REGNILNIL,
199                     sym->stypesym->sdfsym->ssue);
200                 q->n_rval = A0A1 + (reg - A0);
201                 if (dotemps) {
202                         p = tempnode(0sym->stypesym->sdfsym->ssue);
203                         sym->soffset = p->n_lval;
204                         sym->sflags |= STNODE;
205                 } else {
206                         spname = sym;
207                         p = buildtree(NAME00);
208                 }
209                 p = buildtree(ASSIGNpq);
210                 ecomp(p);
211                 reg += 2;
212         }
213
214         *regp = reg;
215 }
216
217 /* setup a 32-bit param on the stack
218  * used by bfcode() */
219 static void
220 param_32bit(struct symtab *symint *regpint dotemps)
221 {
222         NODE *p, *q;
223
224         q = block(REGNILNILsym->stypesym->sdfsym->ssue);
225         q->n_rval = (*regp)++;
226         if (dotemps) {
227                 p = tempnode(0sym->stypesym->sdfsym->ssue);
228                 sym->soffset = p->n_lval;
229                 sym->sflags |= STNODE;
230         } else {
231                 spname = sym;
232                 p = buildtree(NAME00);
233         }
234         p = buildtree(ASSIGNpq);
235         ecomp(p);
236 }
237
ragge
1.1
238 /*
239  * code for the beginning of a function; a is an array of
240  * indices in symtab for the arguments; n is the number
241  */
242 void
gmcgarry
1.4
243 bfcode(struct symtab **spint cnt)
ragge
1.1
244 {
gmcgarry
1.9
245         union arglist *usym;
246         int lastreg = A0 + nargregs - 1;
247         int saveallargs = 0;
248         int ireg;
249
250         /*
251          * Detect if this function has ellipses and save all
252          * argument register onto stack.
253          */
254         usym = cftnsp->sdf->dfun;
255         while (usym && usym->type != TNULL) {
256                 if (usym->type == TELLIPSIS) {
257                         saveallargs = 1;
258                         break;
259                 }
260                 ++usym;
261         }
262
263         reg = A0;
ragge
1.1
264
gmcgarry
1.7
265         /* assign hidden return structure to temporary */
ragge
1.1
266         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
gmcgarry
1.9
267                 param_retptr();
268                 ++reg;
ragge
1.1
269         }
270
gmcgarry
1.4
271         /* recalculate the arg offset and create TEMP moves */
gmcgarry
1.9
272         for (i = 0i < cnti++) {
gmcgarry
1.7
273
gmcgarry
1.9
274                 if ((reg > lastreg) && !xtemps)
275                         break;
276                 else if (reg > lastreg
277                         putintemp(sp[i]);
278                 else if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY)
279                         param_struct(sp[i], &reg);
280                 else if (sp[i]->stype == DOUBLE || sp[i]->stype == LDOUBLE ||
281                      DEUNSIGN(sp[i]->stype) == LONGLONG)
282                         param_64bit(sp[i], &regxtemps && !saveallargs);
283                 else
284                         param_32bit(sp[i], &regxtemps && !saveallargs);
285         }
gmcgarry
1.7
286
gmcgarry
1.9
287         /* if saveallargs, save the rest of the args onto the stack */
288         if (!saveallargs)
289                 return;
290         while (reg <= lastreg) {
291                 NODE *p, *q;
292                 int off = ARGINIT/SZINT + (reg - A0);
293                 q = block(REGNILNILINT0MKSUE(INT));
294                 q->n_rval = reg++;
295                 p = block(REGNILNILINT0MKSUE(INT));
296                 p->n_rval = FP;
297                 p = block(PLUSpbcon(4*off), INT0MKSUE(INT));
298                 p = block(UMULpNILINT0MKSUE(INT));
299                 p = buildtree(ASSIGNpq);
300                 ecomp(p);
301         }
ragge
1.1
302
303 }
304
305
306 /*
307  * by now, the automatics and register variables are allocated
308  */
309 void
310 bccode()
311 {
312         SETOFF(autooffSZINT);
313 }
314
315 /* called just before final exit */
316 /* flag is 1 if errors, 0 if none */
317 void
318 ejobcode(int flag )
319 {
320 }
321
322 void
323 bjobcode()
324 {
gmcgarry
1.7
325         printf("\t.section .mdebug.abi32\n");
326         printf("\t.previous\n");
327         printf("\t.abicalls\n");
ragge
1.1
328 }
329
330 /*
331  * Print character t at position i in one string, until t == -1.
332  * Locctr & label is already defined.
333  */
334 void
335 bycode(int tint i)
336 {
gmcgarry
1.2
337         static int lastoctal = 0;
ragge
1.1
338
339         /* put byte i+1 in a string */
340
341         if (t < 0) {
342                 if (i != 0)
343                         puts("\"");
344         } else {
345                 if (i == 0)
gmcgarry
1.2
346                         printf("\t.asciiz \"");
347                 if (t == 0)
348                         return;
349                 else if (t == '\\' || t == '"') {
ragge
1.1
350                         lastoctal = 0;
351                         putchar('\\');
352                         putchar(t);
gmcgarry
1.2
353                 } else if (t == 012) {
354                         printf("\\n");
ragge
1.1
355                 } else if (t < 040 || t >= 0177) {
356                         lastoctal++;
357                         printf("\\%o",t);
358                 } else if (lastoctal && '0' <= t && t <= '9') {
359                         lastoctal = 0;
gmcgarry
1.2
360                         printf("\"\n\t.asciiz \"%c"t);
ragge
1.1
361                 } else {        
362                         lastoctal = 0;
363                         putchar(t);
364                 }
365         }
366 }
367
368 /*
369  * return the alignment of field of type t
370  */
371 int
372 fldal(unsigned int t)
373 {
374         uerror("illegal field type");
375         return(ALINT);
376 }
377
378 /* fix up type of field p */
379 void
380 fldty(struct symtab *p)
381 {
382 }
383
stefan
1.5
384 /*
ragge
1.1
385  * XXX - fix genswitch.
386  */
stefan
1.5
387 int
388 mygenswitch(int numTWORD typestruct swents **pint n)
ragge
1.1
389 {
stefan
1.5
390         return 0;
ragge
1.1
391 }
gmcgarry
1.4
392
gmcgarry
1.9
393
394 /* setup call stack with a structure */
395 /* called from moveargs() */
396 static NODE *
397 movearg_struct(NODE *pNODE *parentint *regp)
398 {
399         int reg = *regp;
400         NODE *q, *t, *r;
401         int navail;
402         int off;
403         int num;
404         int sz;
405         int i;
406
407         navail = nargregs - (reg - A0);
408         sz = tsize(p->n_typep->n_dfp->n_sue) / SZINT;
409         num = sz > navail ? navail : sz;
410
411         if (p != parent)
412                 q = parent->n_left;
413         else
414                 q = NULL;
415
416         /* copy structure into registers */
417         for (i = 0i < numi++) {
418                 t = tcopy(p->n_left);
419                 t = block(SCONVtNILPTR+INT0MKSUE(PTR+INT));
420                 t = block(PLUStbcon(4*i), PTR+INT0MKSUE(PTR+INT));
421                 t = buildtree(UMULtNIL);
422
423                 r = block(REGNILNILINT0MKSUE(INT));
424                 r->n_rval = reg++;
425
426                 r = buildtree(ASSIGNrt);
427                 if (q == NULL)
428                         q = r;
429                 else
430                         q = block(CMqrINT0MKSUE(INT));
431         }
432         off = ARGINIT/SZINT + nargregs;
433         for (i = numi < szi++) {
434                 t = tcopy(p->n_left);
435                 t = block(SCONVtNILPTR+INT0MKSUE(PTR+INT));
436                 t = block(PLUStbcon(4*i), PTR+INT0MKSUE(PTR+INT));
437                 t = buildtree(UMULtNIL);
438
439                 r = block(REGNILNILINT0MKSUE(INT));
440                 r->n_rval = FP;
441                 r = block(PLUSrbcon(4*off++), INT0MKSUE(INT));
442                 r = block(UMULrNILINT0MKSUE(INT));
443
444                 r = buildtree(ASSIGNrt);
445                 if (q == NULL)
446                         q = r;
447                 else
448                         q = block(CMqrINT0MKSUE(INT));
449         }
450         tfree(p);
451
452         if (parent->n_op == CM) {
453                 parent->n_left = q->n_left;
454                 t = q;
455                 q = q->n_right;
456                 nfree(t);
457         }
458
459         *regp = reg;
460         return q;
461 }
462
463 /* setup call stack with 64-bit argument */
464 /* called from moveargs() */
465 static NODE *
466 movearg_64bit(NODE *pint *regp)
467 {
468         int reg = *regp;
469         NODE *q;
470
471         /* alignment */
472         ++reg;
473         reg &= ~1;
474
475         q = block(REGNILNILp->n_typep->n_dfp->n_sue);
476         q->n_rval = A0A1 + (reg++ - A0);
477         q = buildtree(ASSIGNqp);
478
479         *regp = reg;
480         return q;
481 }
482
483 /* setup call stack with 32-bit argument */
484 /* called from moveargs() */
485 static NODE *
486 movearg_32bit(NODE *pint *regp)
487 {
488         int reg = *regp;
489         NODE *q;
490
491         q = block(REGNILNILp->n_typep->n_dfp->n_sue);
492         q->n_rval = reg++;
493         q = buildtree(ASSIGNqp);
494
495         *regp = reg;
496         return q;
497 }
498
499 static NODE *
500 moveargs(NODE *pint *regp)
gmcgarry
1.4
501 {
gmcgarry
1.9
502         NODE *r, **rp;
503         int lastreg;
504         int reg;
gmcgarry
1.7
505
gmcgarry
1.9
506         if (p->n_op == CM) {
507                 p->n_left = moveargs(p->n_leftregp);
508                 r = p->n_right;
509                 rp = &p->n_right;
gmcgarry
1.4
510         } else {
gmcgarry
1.9
511                 r = p;
512                 rp = &p;
gmcgarry
1.7
513         }
gmcgarry
1.4
514
gmcgarry
1.9
515         lastreg = A0 + nargregs - 1;
516         reg = *regp;
517
518         if (reg > lastreg && r->n_op != STARG)
519                 *rp = block(FUNARGrNILr->n_typer->n_dfr->n_sue);
520         else if (r->n_op == STARG) {
521                 *rp = movearg_struct(rpregp);
522         } else if (DEUNSIGN(r->n_type) == LONGLONG || r->n_type == DOUBLE ||
523             r->n_type == LDOUBLE)
524                 *rp = movearg_64bit(rregp);
525         else
526                 *rp = movearg_32bit(rregp);
527
528         return p;
gmcgarry
1.4
529 }
530
ragge
1.3
531 /*
532  * Called with a function call with arguments as argument.
533  * This is done early in buildtree() and only done once.
534  */
535 NODE *
536 funcode(NODE *p)
537 {
gmcgarry
1.4
538         int regnum = A0;
gmcgarry
1.7
539         NODE *l, *r, *t, *q;
540         int ty;
541
542         l = p->n_left;
543         r = p->n_right;
544
gmcgarry
1.9
545         /*
546          * if returning a structure, make the first argument
547          * a hidden pointer to return structure.
548          */
gmcgarry
1.7
549         ty = DECREF(l->n_type);
550         if (ty == STRTY+FTN || ty == UNIONTY+FTN) {
551                 ty = DECREF(l->n_type) - FTN;
552                 q = tempnode(0tyl->n_dfl->n_sue);
553                 q = buildtree(ADDROFqNIL);
554                 if (r->n_op != CM) {
555                         p->n_right = block(CMqrINCREF(ty),
556                             l->n_dfl->n_sue);
557                 } else {
558                         for (t = rt->n_left->n_op == CMt = t->n_left)
559                                 ;
560                         t->n_left = block(CMqt->n_leftINCREF(ty),
561                             l->n_dfl->n_sue);
562                 }
563         }
564
gmcgarry
1.9
565         p->n_right = moveargs(p->n_right, &regnum);
566
ragge
1.3
567         return p;
568 }
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-28 21:47 +0100