Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20140603201950

Diff

Diff from 1.16 to:

Annotations

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

Annotated File View

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