Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20140309093258

Diff

Diff from 1.15 to:

Annotations

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

Annotated File View

ragge
1.15
1 /*      $Id: local.c,v 1.15 2014/03/09 09:32:58 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  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27
28 # include "pass1.h"
29
30 /*      this file contains code which is dependent on the target machine */
31
32 NODE *
33 clocal(NODE *p)
34 {
35         struct symtab *q;
36         NODE *r, *l;
37         int o;
38
39         switcho = p->n_op ){
40         case NAME:
41                 /* handle variables */
42                 if ((q = p->n_sp) == NULL)
43                         return p/* Nothing to care about */
44                 switch (q->sclass) {
45                 case AUTO:
46                         /* fake up a structure reference */
47                         r = block(REGNILNILPTR+STRTY00);
48                         r->n_lval = 0;
49                         r->n_rval = FPREG;
50                         p = stref(block(STREFrp000));
51                         break;
52                 default:
53                         break;
54                 }
55                 break;
56
57         case PMCONV:
58         case PVCONV:
59                 ifp->n_right->n_op != ICON ) cerror"bad conversion"0);
60                 nfree(p);
61                 return(buildtree(o==PMCONV?MUL:DIVp->n_leftp->n_right));
62
63         case PCONV:
64                 l = p->n_left;
65                 /* if conversion to another pointer type, just remove */
66                 if (p->n_type > BTMASK && l->n_type > BTMASK)
67                         goto delp;
68                 break;
69
70         delp:   l->n_type = p->n_type;
71                 l->n_qual = p->n_qual;
72                 l->n_df = p->n_df;
ragge
1.15
73                 l->n_ap = p->n_ap;
ragge
1.1
74                 nfree(p);
75                 p = l;
76                 break;
77         }
78
79 #if 0
80         register struct symtab *q;
81         register NODE *r, *l;
82         register int o;
83         register int m;
84         TWORD t;
85
86 //printf("in:\n");
87 //fwalk(p, eprint, 0);
88         switcho = p->n_op ){
89
90         case NAME:
91                 if ((q = p->n_sp) == NULL)
92                         return p/* Nothing to care about */
93
94                 switch (q->sclass) {
95
96                 case PARAM:
97                 case AUTO:
98                         /* fake up a structure reference */
99                         r = block(REGNILNILPTR+STRTY00);
100                         r->n_lval = 0;
101                         r->n_rval = FPREG;
102                         p = stref(block(STREFrp000));
103                         break;
104
105                 case STATIC:
106                         if (q->slevel == 0)
107                                 break;
108                         p->n_lval = 0;
109                         p->n_sp = q;
110                         break;
111
112                 case REGISTER:
113                         p->n_op = REG;
114                         p->n_lval = 0;
115                         p->n_rval = q->soffset;
116                         break;
117
118                         }
119                 break;
120
121         case STCALL:
122         case CALL:
123                 /* Fix function call arguments. On x86, just add funarg */
124                 for (r = p->n_rightr->n_op == CMr = r->n_left) {
125                         if (r->n_right->n_op != STARG &&
126                             r->n_right->n_op != FUNARG)
127                                 r->n_right = block(FUNARGr->n_rightNIL
128                                     r->n_right->n_typer->n_right->n_df,
129                                     r->n_right->n_sue);
130                 }
131                 if (r->n_op != STARG && r->n_op != FUNARG) {
132                         l = talloc();
133                         *l = *r;
134                         r->n_op = FUNARGr->n_left = lr->n_type = l->n_type;
135                 }
136                 break;
137                 
138         case CBRANCH:
139                 l = p->n_left;
140
141                 /*
ragge
1.5
142                  * Remove unnecessary conversion ops.
ragge
1.1
143                  */
144                 if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
145                         if (coptype(l->n_op) != BITYPE)
146                                 break;
147                         if (l->n_right->n_op == ICON) {
148                                 r = l->n_left->n_left;
149                                 if (r->n_type >= FLOAT && r->n_type <= LDOUBLE)
150                                         break;
151                                 /* Type must be correct */
152                                 t = r->n_type;
153                                 nfree(l->n_left);
154                                 l->n_left = r;
155                                 l->n_type = t;
156                                 l->n_right->n_type = t;
157                         }
158                 }
159                 break;
160
161         case PCONV:
162                 /* Remove redundant PCONV's. Be careful */
163                 l = p->n_left;
164                 if (l->n_op == ICON) {
165                         l->n_lval = (unsigned)l->n_lval;
166                         goto delp;
167                 }
168                 if (l->n_type < INT || l->n_type == LONGLONG || 
169                     l->n_type == ULONGLONG) {
170                         /* float etc? */
171                         p->n_left = block(SCONVlNIL,
ragge
1.9
172                             UNSIGNED00);
ragge
1.1
173                         break;
174                 }
175                 /* if left is SCONV, cannot remove */
176                 if (l->n_op == SCONV)
177                         break;
178                 /* if conversion to another pointer type, just remove */
179                 if (p->n_type > BTMASK && l->n_type > BTMASK)
180                         goto delp;
181                 break;
182
183         delp:   l->n_type = p->n_type;
184                 l->n_qual = p->n_qual;
185                 l->n_df = p->n_df;
186                 l->n_sue = p->n_sue;
187                 nfree(p);
188                 p = l;
189                 break;
190
191         case SCONV:
192                 l = p->n_left;
193
194                 if (p->n_type == l->n_type) {
195                         nfree(p);
196                         return l;
197                 }
198
199                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
200                     btdims[p->n_type].suesize == btdims[l->n_type].suesize) {
201                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
202                             l->n_type != FLOAT && l->n_type != DOUBLE &&
203                             l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
204                                 if (l->n_op == NAME || l->n_op == UMUL ||
205                                     l->n_op == TEMP) {
206                                         l->n_type = p->n_type;
207                                         nfree(p);
208                                         return l;
209                                 }
210                         }
211                 }
212
213                 if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
214                     coptype(l->n_op) == BITYPE) {
215                         l->n_type = p->n_type;
216                         nfree(p);
217                         return l;
218                 }
219
220                 o = l->n_op;
221                 m = p->n_type;
222
223                 if (o == ICON) {
224                         CONSZ val = l->n_lval;
225
226                         if (!ISPTR(m)) /* Pointers don't need to be conv'd */
227                             switch (m) {
228                         case CHAR:
229                                 l->n_lval = (char)val;
230                                 break;
231                         case UCHAR:
232                                 l->n_lval = val & 0377;
233                                 break;
234                         case SHORT:
235                                 l->n_lval = (short)val;
236                                 break;
237                         case USHORT:
238                                 l->n_lval = val & 0177777;
239                                 break;
240                         case ULONG:
241                         case UNSIGNED:
242                                 l->n_lval = val & 0xffffffff;
243                                 break;
244                         case LONG:
245                         case INT:
246                                 l->n_lval = (int)val;
247                                 break;
248                         case LONGLONG:
249                                 l->n_lval = (long long)val;
250                                 break;
251                         case ULONGLONG:
252                                 l->n_lval = val;
253                                 break;
254                         case VOID:
255                                 break;
256                         case LDOUBLE:
257                         case DOUBLE:
258                         case FLOAT:
259                                 l->n_op = FCON;
260                                 l->n_dcon = val;
261                                 break;
262                         default:
263                                 cerror("unknown type %d"m);
264                         }
265                         l->n_type = m;
ragge
1.9
266                         l->n_sue = 0;
ragge
1.1
267                         nfree(p);
268                         return l;
269                 }
270                 if (DEUNSIGN(p->n_type) == SHORT &&
271                     DEUNSIGN(l->n_type) == SHORT) {
272                         nfree(p);
273                         p = l;
274                 }
275                 if ((p->n_type == CHAR || p->n_type == UCHAR ||
276                     p->n_type == SHORT || p->n_type == USHORT) &&
277                     (l->n_type == FLOAT || l->n_type == DOUBLE ||
278                     l->n_type == LDOUBLE)) {
279                         p = block(SCONVpNILp->n_typep->n_dfp->n_sue);
280                         p->n_left->n_type = INT;
281                         return p;
282                 }
283                 break;
284
285         case MOD:
286         case DIV:
287                 if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
288                         break;
289                 if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
290                         break;
291                 /* make it an int division by inserting conversions */
ragge
1.9
292                 p->n_left = block(SCONVp->n_leftNILINT00);
293                 p->n_right = block(SCONVp->n_rightNILINT00);
294                 p = block(SCONVpNILp->n_type00);
ragge
1.1
295                 p->n_left->n_type = INT;
296                 break;
297
298         case PMCONV:
299         case PVCONV:
300                 ifp->n_right->n_op != ICON ) cerror"bad conversion"0);
301                 nfree(p);
302                 return(buildtree(o==PMCONV?MUL:DIVp->n_leftp->n_right));
303
304         case FORCE:
305                 /* put return value in return reg */
306                 p->n_op = ASSIGN;
307                 p->n_right = p->n_left;
ragge
1.9
308                 p->n_left = block(REGNILNILp->n_type00);
ragge
1.1
309                 p->n_left->n_rval = RETREG(p->n_type);
310                 break;
311
312         case LS:
313         case RS:
314                 /* shift count must be in a char
315                  * unless longlong, where it must be int */
316                 if (p->n_right->n_op == ICON)
317                         break/* do not do anything */
318                 if (p->n_type == LONGLONG || p->n_type == ULONGLONG) {
319                         if (p->n_right->n_type != INT)
320                                 p->n_right = block(SCONVp->n_rightNIL,
ragge
1.9
321                                     INT00);
ragge
1.1
322                         break;
323                 }
324                 if (p->n_right->n_type == CHAR || p->n_right->n_type == UCHAR)
325                         break;
326                 p->n_right = block(SCONVp->n_rightNIL,
ragge
1.9
327                     CHAR00);
ragge
1.1
328                 break;
329         }
330 //printf("ut:\n");
331 //fwalk(p, eprint, 0);
332
333 #endif
334
335         return(p);
336 }
337
338 void
339 myp2tree(NODE *p)
340 {
ragge
1.7
341         struct symtab *sp;
ragge
1.14
342         int o = p->n_op;
ragge
1.3
343
344         if (o != FCON
345                 return;
346
ragge
1.7
347         sp = inlalloc(sizeof(struct symtab));
348         sp->sclass = STATIC;
ragge
1.15
349         sp->sap = 0;
ragge
1.7
350         sp->slevel = 1/* fake numeric label */
351         sp->soffset = getlab();
352         sp->sflags = 0;
353         sp->stype = p->n_type;
354         sp->squal = (CON >> TSHIFT);
355
356         defloc(sp);
ragge
1.15
357         ninval(0tsize(sp->stypesp->sdfsp->sap), p);
ragge
1.7
358
ragge
1.3
359         p->n_op = NAME;
ragge
1.7
360         p->n_lval = 0;
361         p->n_sp = sp;
ragge
1.3
362
ragge
1.1
363 }
364
365 /*ARGSUSED*/
366 int
367 andable(NODE *p)
368 {
369         return(1);  /* all names can have & taken on them */
370 }
371
372 /*
373  * Return 1 if a variable of type type is OK to put in register.
374  */
375 int
376 cisreg(TWORD t)
377 {
378         return 1/* try to put anything in a register */
379 }
380
381 /*
382  * return a node, for structure references, which is suitable for
383  * being added to a pointer of type t, in order to be off bits offset
384  * into a structure
385  * t, d, and s are the type, dimension offset, and sizeoffset
386  * For nova, return the type-specific index number which calculation
387  * is based on its size. For example, char a[3] would return 3.
388  * Be careful about only handling first-level pointers, the following
389  * indirections must be fullword.
390  */
391 NODE *
ragge
1.15
392 offcon(OFFSZ offTWORD tunion dimfun *dstruct attr *ap)
ragge
1.1
393 {
394         register NODE *p;
395
396         if (xdebug)
ragge
1.15
397                 printf("offcon: OFFSZ %ld type %x dim %p siz %ld\n",
398                     offtdtsize(tdap));
ragge
1.1
399
400         p = bcon(0);
401         p->n_lval = off/SZINT;  /* Default */
402         if (ISPTR(DECREF(t)))
403                 return p;
404         if (t == VOID || t == CHAR || t == UCHAR)
405                 p->n_lval = off/SZCHAR/* pointer to char */
406         return(p);
407 }
408
409 /*
410  * Allocate off bits on the stack.  p is a tree that when evaluated
411  * is the multiply count for off, t is a NAME node where to write
412  * the allocated address.
413  */
414 void
415 spalloc(NODE *tNODE *pOFFSZ off)
416 {
417         NODE *sp;
418
419 cerror("spalloc");
420         if ((off % SZINT) == 0)
421                 p =  buildtree(MULpbcon(off/SZINT));
422         else if ((off % SZSHORT) == 0) {
423                 p = buildtree(MULpbcon(off/SZSHORT));
424                 p = buildtree(PLUSpbcon(1));
425                 p = buildtree(RSpbcon(1));
426         } else if ((off % SZCHAR) == 0) {
427                 p = buildtree(MULpbcon(off/SZCHAR));
428                 p = buildtree(PLUSpbcon(3));
429                 p = buildtree(RSpbcon(2));
430         } else
431                 cerror("roundsp");
432
433         /* save the address of sp */
ragge
1.15
434         sp = block(REGNILNILPTR+INTt->n_dft->n_ap);
ragge
1.1
435         sp->n_lval = 0;
436         sp->n_rval = STKREG;
437         t->n_type = sp->n_type;
438         ecomp(buildtree(ASSIGNtsp)); /* Emit! */
439
440         /* add the size to sp */
441         sp = block(REGNILNILp->n_type00);
442         sp->n_lval = 0;
443         sp->n_rval = STKREG;
444         ecomp(buildtree(PLUSEQspp));
445 }
446
447 /*
448  * print out a constant node
449  * mat be associated with a label
450  */
ragge
1.12
451 int
ragge
1.15
452 ninval(CONSZ offint fszNODE *p)
ragge
1.1
453 {
ragge
1.15
454         switch (p->n_type) {
455         case FLOAT:
456         case DOUBLE:
457         case LDOUBLE:
458                 cerror("ninval");
ragge
1.1
459         }
ragge
1.12
460         return 1;
ragge
1.1
461 }
462
463 /* make a name look like an external name in the local machine */
464 char *
465 exname(char *p)
466 {
467         if (p == NULL)
468                 return "";
469         return p;
470 }
471
472 /*
473  * map types which are not defined on the local machine
474  */
475 TWORD
476 ctype(TWORD type)
477 {
478         switch (BTYPE(type)) {
479         case LONGLONG:
480                 MODTYPE(type,LONG);
481                 break;
482
483         case ULONGLONG:
484                 MODTYPE(type,ULONG);
485                 break;
486         case SHORT:
487                 MODTYPE(type,INT);
488                 break;
489         case USHORT:
490                 MODTYPE(type,UNSIGNED);
491                 break;
492         }
493         return (type);
494 }
495
ragge
1.15
496 #if 0
ragge
1.1
497 /* curid is a variable which is defined but
498  * is not initialized (and not a function );
499  * This routine returns the storage class for an uninitialized declaration
500  */
501 int
502 noinit()
503 {
504         return(EXTERN);
505 }
ragge
1.15
506 #endif
ragge
1.1
507
508 void
509 calldec(NODE *pNODE *q
510 {
511 }
512
513 void
514 extdec(struct symtab *q)
515 {
516 }
517
ragge
1.15
518 #if 0
ragge
1.1
519 /* make a common declaration for id, if reasonable */
520 void
521 commdec(struct symtab *q)
522 {
523         int off;
524
525         off = tsize(q->stypeq->sdfq->ssue);
526         off = (off+(SZCHAR-1))/SZCHAR;
ragge
1.4
527         printf("        .comm %s,0%o\n"exname(q->soname), off);
ragge
1.1
528 }
529
530 /* make a local common declaration for id, if reasonable */
531 void
532 lcommdec(struct symtab *q)
533 {
534         int off;
535
536         off = tsize(q->stypeq->sdfq->ssue);
537         off = (off+(SZCHAR-1))/SZCHAR;
538         if (q->slevel == 0)
ragge
1.4
539                 printf("        .lcomm %s,0%o\n"exname(q->soname), off);
ragge
1.1
540         else
541                 printf("        .lcomm " LABFMT ",0%o\n"q->soffsetoff);
542 }
543
544 /*
545  * print a (non-prog) label.
546  */
547 void
548 deflab1(int label)
549 {
550         printf(LABFMT ":\n"label);
551 }
552
553 static char *loctbl[] = { "text""data""section .rodata""section .rodata" };
554
555 void
556 setloc1(int locc)
557 {
558         if (locc == lastloc)
559                 return;
560         lastloc = locc;
561         printf("        .%s\n"loctbl[locc]);
562 }
ragge
1.15
563 #endif
564
ragge
1.4
565 /*
566  * Give target the opportunity of handling pragmas.
567  */
568 int
ragge
1.8
569 mypragma(char *str)
ragge
1.4
570 {
ragge
1.8
571         return 0;
572 }
ragge
1.4
573
574 /*
575  * Called when a identifier has been declared, to give target last word.
576  */
577 void
578 fixdef(struct symtab *sp)
579 {
580 }
581
gmcgarry
1.6
582 void
583 pass1_lastchance(struct interpass *ip)
584 {
585 }
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-09-03 06:44 +0200