Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:gmcgarry:20071128022353

Diff

Diff from 1.6 to:

Annotations

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

Annotated File View

gmcgarry
1.6
1 /*      $Id: local.c,v 1.6 2007/11/28 02:23:53 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  * MIPS port by Jan Enoksson (janeno-1@student.ltu.se) and
31  * Simon Olsson (simols-1@student.ltu.se) 2005.
32  */
33
gmcgarry
1.3
34 #include "pass1.h"
ragge
1.1
35
gmcgarry
1.2
36 static int inbitsinval;
37
gmcgarry
1.3
38 /* this is called to do local transformations on
39  * an expression tree preparitory to its being
40  * written out in intermediate code.
41  */
ragge
1.1
42 NODE *
43 clocal(NODE *p)
44 {
gmcgarry
1.3
45         struct symtab *q;
46         NODE *r, *l;
47         int o;
48         int mml;
gmcgarry
1.6
49         TWORD ty;
ragge
1.1
50
51 //printf("in:\n");
52 //fwalk(p, eprint, 0);
gmcgarry
1.3
53
gmcgarry
1.6
54         switch (o = p->n_op) {
ragge
1.1
55
56         case NAME:
57                 if ((q = p->n_sp) == NULL)
58                         return p/* Nothing to care about */
59
60                 switch (q->sclass) {
61
62                 case PARAM:
63                 case AUTO:
64                         /* fake up a structure reference */
65                         r = block(REGNILNILPTR+STRTY00);
66                         r->n_lval = 0;
gmcgarry
1.3
67                         r->n_rval = FP;
ragge
1.1
68                         p = stref(block(STREFrp000));
69                         break;
70
71                 case STATIC:
72                         if (q->slevel == 0)
73                                 break;
74                         p->n_lval = 0;
75                         p->n_sp = q;
76                         break;
77
78                 case REGISTER:
79                         p->n_op = REG;
80                         p->n_lval = 0;
81                         p->n_rval = q->soffset;
82                         break;
83
84                         }
85                 break;
86
87         case FUNARG:
88                 /* Args smaller than int are given as int */
89                 if (p->n_type != CHAR && p->n_type != UCHAR && 
90                     p->n_type != SHORT && p->n_type != USHORT)
91                         break;
92                 p->n_left = block(SCONVp->n_leftNILINT0MKSUE(INT));
93                 p->n_type = INT;
94                 p->n_sue = MKSUE(INT);
95                 p->n_rval = SZINT;
96                 break;
97
98         case CBRANCH:
99                 l = p->n_left;
100
101                 /*
102                  * Remove unneccessary conversion ops.
103                  */
104                 if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
105                         if (coptype(l->n_op) != BITYPE)
106                                 break;
107                         if (l->n_right->n_op == ICON) {
108                                 r = l->n_left->n_left;
109                                 if (r->n_type >= FLOAT && r->n_type <= LDOUBLE)
110                                         break;
111                                 /* Type must be correct */
gmcgarry
1.6
112                                 ty = r->n_type;
ragge
1.1
113                                 nfree(l->n_left);
114                                 l->n_left = r;
gmcgarry
1.6
115                                 l->n_type = ty;
116                                 l->n_right->n_type = ty;
ragge
1.1
117                         }
118 #if 0
119                           else if (l->n_right->n_op == SCONV &&
120                             l->n_left->n_type == l->n_right->n_type) {
121                                 r = l->n_left->n_left;
122                                 nfree(l->n_left);
123                                 l->n_left = r;
124                                 r = l->n_right->n_left;
125                                 nfree(l->n_right);
126                                 l->n_right = r;
127                         }
128 #endif
129                 }
130                 break;
131
132         case PCONV:
133                 ml = p->n_left->n_type;
134                 l = p->n_left;
135                 if ((ml == CHAR || ml == UCHAR || ml == SHORT || ml == USHORT)
136                     && l->n_op != ICON)
137                         break;
138                 l->n_type = p->n_type;
139                 l->n_qual = p->n_qual;
140                 l->n_df = p->n_df;
141                 l->n_sue = p->n_sue;
142                 nfree(p);
143                 p = l;
144                 break;
145
146         case SCONV:
147                 l = p->n_left;
148
149                 if (p->n_type == l->n_type) {
150                         nfree(p);
151                         return l;
152                 }
153
154                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
155                     btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
156                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
157                             l->n_type != FLOAT && l->n_type != DOUBLE &&
158                             l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
159                                 if (l->n_op == NAME || l->n_op == UMUL) {
160                                         l->n_type = p->n_type;
161                                         nfree(p);
162                                         return l;
163                                 }
164                         }
165                 }
166
167                 if ((p->n_type == INT || p->n_type == UNSIGNED) &&
168                     ISPTR(l->n_type)) {
169                         nfree(p);
170                         return l;
171                 }
172
173                 o = l->n_op;
174                 m = p->n_type;
175
176                 if (o == ICON) {
177                         CONSZ val = l->n_lval;
178
179                         if (!ISPTR(m)) /* Pointers don't need to be conv'd */
180                             switch (m) {
181                         case CHAR:
182                                 l->n_lval = (char)val;
183                                 break;
184                         case UCHAR:
185                                 l->n_lval = val & 0377;
186                                 break;
187                         case SHORT:
188                                 l->n_lval = (short)val;
189                                 break;
190                         case USHORT:
191                                 l->n_lval = val & 0177777;
192                                 break;
193                         case ULONG:
194                         case UNSIGNED:
195                                 l->n_lval = val & 0xffffffff;
196                                 break;
197                         case LONG:
198                         case INT:
199                                 l->n_lval = (int)val;
200                                 break;
201                         case LONGLONG:
202                                 l->n_lval = (long long)val;
203                                 break;
204                         case ULONGLONG:
205                                 l->n_lval = val;
206                                 break;
207                         case VOID:
208                                 break;
209                         case LDOUBLE:
210                         case DOUBLE:
211                         case FLOAT:
212                                 l->n_op = FCON;
213                                 l->n_dcon = val;
214                                 break;
215                         default:
216                                 cerror("unknown type %d"m);
217                         }
218                         l->n_type = m;
219                         nfree(p);
220                         return l;
221                 }
222                 if (DEUNSIGN(p->n_type) == SHORT &&
223                     DEUNSIGN(l->n_type) == SHORT) {
224                         nfree(p);
225                         p = l;
226                 }
227                 break;
228
229         case MOD:
230         case DIV:
231                 if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
232                         break;
233                 if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
234                         break;
235                 /* make it an int division by inserting conversions */
236                 p->n_left = block(SCONVp->n_leftNILINT0MKSUE(INT));
237                 p->n_right = block(SCONVp->n_rightNILINT0MKSUE(INT));
238                 p = block(SCONVpNILp->n_type0MKSUE(p->n_type));
239                 p->n_left->n_type = INT;
240                 break;
241
242         case PMCONV:
243         case PVCONV:
244                 ifp->n_right->n_op != ICON ) cerror"bad conversion"0);
245                 nfree(p);
246                 return(buildtree(o==PMCONV?MUL:DIVp->n_leftp->n_right));
247
248         case FORCE:
249                 /* put return value in return reg */
250                 p->n_op = ASSIGN;
251                 p->n_right = p->n_left;
gmcgarry
1.2
252                 p->n_left = block(REGNILNILp->n_type0MKSUE(INT));
gmcgarry
1.3
253                 p->n_left->n_rval = RETREG(p->n_type);
ragge
1.1
254                 break;
255         }
gmcgarry
1.3
256
ragge
1.1
257 //printf("ut:\n");
258 //fwalk(p, eprint, 0);
259
260         return(p);
261 }
262
263 void
264 myp2tree(NODE *p)
265 {
266 }
267
268 /*ARGSUSED*/
269 int
270 andable(NODE *p)
271 {
272         return(1);  /* all names can have & taken on them */
273 }
274
275 /*
276  * at the end of the arguments of a ftn, set the automatic offset
277  */
278 void
279 cendarg()
280 {
281         autooff = AUTOINIT;
282 }
283
284 /*
285  * is an automatic variable of type t OK for a register variable
286  */
287 int
288 cisreg(TWORD t)
289 {
290         if (t == INT || t == UNSIGNED || t == LONG || t == ULONG)
291                 return(1);
292         return 0/* XXX - fix reg assignment in pftn.c */
293 }
294
295 /*
296  * return a node, for structure references, which is suitable for
297  * being added to a pointer of type t, in order to be off bits offset
298  * into a structure
299  * t, d, and s are the type, dimension offset, and sizeoffset
300  * Be careful about only handling first-level pointers, the following
301  * indirections must be fullword.
302  */
303 NODE *
304 offcon(OFFSZ offTWORD tunion dimfun *dstruct suedef *sue)
305 {
gmcgarry
1.3
306         NODE *p;
ragge
1.1
307
308         if (xdebug)
309                 printf("offcon: OFFSZ %lld type %x dim %p siz %d\n",
310                     offtdsue->suesize);
311
gmcgarry
1.3
312         p = bcon(off/SZCHAR);
313         return p;
ragge
1.1
314 }
315
316 /*
317  * Allocate off bits on the stack.  p is a tree that when evaluated
318  * is the multiply count for off, t is a NAME node where to write
319  * the allocated address.
320  */
321 void
322 spalloc(NODE *tNODE *pOFFSZ off)
323 {
324         NODE *sp;
325
326         if ((off % SZINT) == 0)
327                 p =  buildtree(MULpbcon(off/SZINT));
328         else if ((off % SZSHORT) == 0) {
329                 p = buildtree(MULpbcon(off/SZSHORT));
330                 p = buildtree(PLUSpbcon(1));
331                 p = buildtree(RSpbcon(1));
332         } else if ((off % SZCHAR) == 0) {
333                 p = buildtree(MULpbcon(off/SZCHAR));
334                 p = buildtree(PLUSpbcon(3));
335                 p = buildtree(RSpbcon(2));
336         } else
337                 cerror("roundsp");
338
339         /* save the address of sp */
340         sp = block(REGNILNILPTR+INTt->n_dft->n_sue);
341         sp->n_lval = 0;
gmcgarry
1.6
342         sp->n_rval = SP;
ragge
1.1
343         t->n_type = sp->n_type;
344         ecomp(buildtree(ASSIGNtsp)); /* Emit! */
345
346         /* add the size to sp */
347         sp = block(REGNILNILp->n_type00);
348         sp->n_lval = 0;
gmcgarry
1.6
349         sp->n_rval = SP;
ragge
1.1
350         ecomp(buildtree(PLUSEQspp));
351 }
352
353 /*
354  * print out a constant node
355  * mat be associated with a label
356  */
357 void
gmcgarry
1.2
358 ninval(CONSZ offint fszNODE *p)
ragge
1.1
359 {
gmcgarry
1.3
360         union { float fdouble dlong double lint i[3]; } u;
361         struct symtab *q;
362         TWORD t;
363 #ifndef USE_GAS
gmcgarry
1.5
364         int ij;
gmcgarry
1.3
365 #endif
ragge
1.1
366
gmcgarry
1.3
367         t = p->n_type;
368         if (t > BTMASK)
369                 t = INT/* pointer */
370
371         if (p->n_op != ICON && p->n_op != FCON)
372                 cerror("ninval: init node not constant");
373
374         if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(t) != INT)
375                 uerror("element not constant");
376
377         switch (t) {
378         case LONGLONG:
379         case ULONGLONG:
380 #ifdef USE_GAS
381                 printf("\t.dword 0x%llx\n", (long long)p->n_lval);
382 #else
gmcgarry
1.5
383                 i = p->n_lval >> 32;
384                 j = p->n_lval & 0xffffffff;
gmcgarry
1.3
385                 p->n_type = INT;
gmcgarry
1.5
386                 if (bigendian) {
387                         p->n_lval = j;
388                         ninval(off32p);
389                         p->n_lval = i;
390                         ninval(off+3232p);
391                 } else {
392                         p->n_lval = i;
393                         ninval(off32p);
394                         p->n_lval = j;
395                         ninval(off+3232p);
396                 }
gmcgarry
1.3
397 #endif
398                 break;
399         case BOOL:
400                 if (p->n_lval > 1)
401                         p->n_lval = p->n_lval != 0;
402                 /* FALLTHROUGH */
403         case INT:
404         case UNSIGNED:
405                 printf("\t.word 0x%x", (int)p->n_lval);
406                 if ((q = p->n_sp) != NULL) {
407                         if ((q->sclass == STATIC && q->slevel > 0) ||
408                             q->sclass == ILABEL) {
409                                 printf("+" LABFMTq->soffset);
410                         } else
411                                 printf("+%s"exname(q->sname));
412                 }
413                 printf("\n");
414                 break;
415         case SHORT:
416         case USHORT:
417                 printf("\t.half 0x%x\n", (int)p->n_lval & 0xffff);
418                 break;
419         case CHAR:
420         case UCHAR:
421                 printf("\t.byte %d\n", (int)p->n_lval & 0xff);
422                 break;
423         case LDOUBLE:
424                 u.i[2] = 0;
425                 u.l = (long double)p->n_dcon;
426                 printf("\t.word\t0x%x,0x%x,0x%x\n"u.i[0], u.i[1], u.i[2]);
427                 break;
428         case DOUBLE:
429                 u.d = (double)p->n_dcon;
430                 printf("\t.word\t0x%x\n"u.i[0]);
431                 printf("\t.word\t0x%x\n"u.i[1]);
432                 break;
433         case FLOAT:
434                 u.f = (float)p->n_dcon;
435                 printf("\t.word\t0x%x\n"u.i[0]);
436                 break;
437         default:
438                 cerror("ninval");
439         }
ragge
1.1
440 }
441
442 /* make a name look like an external name in the local machine */
443 char *
444 exname(char *p)
445 {
446         if (p == NULL)
447                 return "";
448         return p;
449 }
450
451 /*
452  * map types which are not defined on the local machine
453  */
454 TWORD
455 ctype(TWORD type)
456 {
457         switch (BTYPE(type)) {
458         case LONG:
459                 MODTYPE(type,INT);
460                 break;
461
462         case ULONG:
463                 MODTYPE(type,UNSIGNED);
464
465         }
466         return (type);
467 }
468
469 /* curid is a variable which is defined but
470  * is not initialized (and not a function );
471  * This routine returns the storage class for an uninitialized declaration
472  */
473 int
474 noinit()
475 {
476         return(EXTERN);
477 }
478
479 void
480 calldec(NODE *pNODE *q
481 {
482 }
483
484 void
485 extdec(struct symtab *q)
486 {
487 }
488
489 /* make a common declaration for id, if reasonable */
490 void
491 commdec(struct symtab *q)
492 {
493         int off;
494
495         off = tsize(q->stypeq->sdfq->ssue);
496         off = (off+(SZCHAR-1))/SZCHAR;
497
498 #ifdef GCC_COMPAT
499         printf("        .comm %s,0%o\n"gcc_findname(q), off);
500 #else
501         printf("        .comm %s,0%o\n"exname(q->sname), off);
502 #endif
503 }
504
505 /* make a local common declaration for id, if reasonable */
506 void
507 lcommdec(struct symtab *q)
508 {
509         int off;
510
511         off = tsize(q->stypeq->sdfq->ssue);
512         off = (off+(SZCHAR-1))/SZCHAR;
513         if (q->slevel == 0)
514 #ifdef GCC_COMPAT
gmcgarry
1.3
515                 printf("\t.lcomm %s,0%o\n"gcc_findname(q), off);
ragge
1.1
516 #else
gmcgarry
1.3
517                 printf("\t.lcomm %s,0%o\n"exname(q->sname), off);
ragge
1.1
518 #endif
519         else
gmcgarry
1.3
520                 printf("\t.lcomm " LABFMT ",0%o\n"q->soffsetoff);
ragge
1.1
521 }
522
523 /*
524  * print a (non-prog) label.
525  */
526 void
527 deflab1(int label)
528 {
529         printf(LABFMT ":\n"label);
530 }
531
gmcgarry
1.6
532 /* ro-text, ro-data, rw-data, ro-strings */
533 static char *loctbl[] = { "text""rdata""data""rdata" };
ragge
1.1
534
535 void
536 setloc1(int locc)
537 {
gmcgarry
1.6
538         if ((locc == lastloc) || (lastloc == DATA && locc == STRNG) ||
539             (locc == STRNG && lastloc == DATA))
ragge
1.1
540                 return;
541         lastloc = locc;
gmcgarry
1.3
542         printf("\t.%s\n"loctbl[locc]);
ragge
1.1
543 }
gmcgarry
1.2
544
545 /*
546  * Initialize a bitfield.
547  */
548 void
549 infld(CONSZ offint fszCONSZ val)
550 {
551         if (idebug)
552                 printf("infld off %lld, fsz %d, val %lld inbits %d\n",
553                     offfszvalinbits);
554         val &= (1 << fsz)-1;
555         while (fsz + inbits >= SZCHAR) {
556                 inval |= (val << inbits);
557                 printf("\t.byte %d\n"inval & 255);
558                 fsz -= (SZCHAR - inbits);
559                 val >>= (SZCHAR - inbits);
560                 inval = inbits = 0;
561         }
562         if (fsz) {
563                 inval |= (val << inbits);
564                 inbits += fsz;
565         }
566 }
567
568 /*
569  * set fsz bits in sequence to zero.
570  */
571 void
572 zbits(OFFSZ offint fsz)
573 {
574         int m;
575
576         if (idebug)
577                 printf("zbits off %lld, fsz %d inbits %d\n"offfszinbits);
578         if ((m = (inbits % SZCHAR))) {
579                 m = SZCHAR - m;
580                 if (fsz < m) {
581                         inbits += fsz;
582                         return;
583                 } else {
584                         fsz -= m;
585                         printf("\t.byte %d\n"inval);
586                         inval = inbits = 0;
587                 }
588         }
589         if (fsz >= SZCHAR) {
590                 printf("\t.zero %d\n"fsz/SZCHAR);
591                 fsz -= (fsz/SZCHAR) * SZCHAR;
592         }
593         if (fsz) {
594                 inval = 0;
595                 inbits = fsz;
596         }
597 }
gmcgarry
1.6
598
599 /*
600  * va_start(ap, last) implementation.
601  *
602  * f is the NAME node for this builtin function.
603  * a is the argument list containing:
604  *         CM
605  *      ap   last
606  */
607 NODE *
608 mips_builtin_stdarg_start(NODE *fNODE *a)
609 {
610         NODE *p;
611         int sz = 1;
612
613         /* check num args and type */
614         if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
615             !ISPTR(a->n_left->n_type))
616                 goto bad;
617
618         /* must first deal with argument size; use int size */
619         p = a->n_right;
620         if (p->n_type < INT)
621                 sz = SZINT / tsize(p->n_typep->n_dfp->n_sue);
622
623 bad:
624         return f;
625 }
626
627 NODE *
628 mips_builtin_va_arg(NODE *fNODE *a)
629 {
630         return f;
631 }
632
633 NODE *
634 mips_builtin_va_end(NODE *fNODE *a)
635 {
636         return f;
637 }
638
639 NODE *
640 mips_builtin_va_copy(NODE *fNODE *a)
641 {
642         return f;
643 }
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-10-31 13:53 +0100