Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080622152459

Diff

Diff from 1.38 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/arch/m16c/local2.c

Annotated File View

ragge
1.38
1 /*      $Id: local2.c,v 1.38 2008/06/22 15:24:59 ragge Exp $    */
pj
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 # include "pass2.h"
31 # include <ctype.h>
32
33 void acon(NODE *p);
34 int argsize(NODE *p);
35 void genargs(NODE *p);
36
37 static int ftlab1ftlab2;
38
39 void
40 deflab(int label)
41 {
42         printf(LABFMT ":\n"label);
43 }
44
45 static TWORD ftype;
ragge
1.4
46 static int addto;
pj
1.1
47
48 void
ragge
1.11
49 prologue(struct interpass_prolog *ipp)
pj
1.1
50 {
janeno-1
1.30
51     ftype = ipp->ipp_type;
pj
1.1
52
ragge
1.19
53 #if 0
janeno-1
1.30
54     if (ipp->ipp_regs > 0 && ipp->ipp_regs != MINRVAR)
55         comperr("fix prologue register savings"ipp->ipp_regs);
ragge
1.19
56 #endif
janeno-1
1.30
57     
58     printf("    RSEG CODE:CODE:REORDER:NOROOT(0)\n");
59     if (ipp->ipp_vis)   
60         printf("        PUBLIC %s\n"ipp->ipp_name);
61     printf("%s:\n"ipp->ipp_name);
62     
janeno-1
1.28
63 #if 0   
janeno-1
1.30
64     if (xsaveip) {
65         /* Optimizer running, save space on stack */
66         addto = (p2maxautooff - AUTOINIT)/SZCHAR;
67         printf("        enter #%d\n"addto);
68     } else {
69 #endif
70
janeno-1
1.28
71         /* non-optimized code, jump to epilogue for code generation */
janeno-1
1.30
72         ftlab1 = getlab();
73         ftlab2 = getlab();
74         printf("        jmp.w " LABFMT "\n"ftlab1);
janeno-1
1.28
75         deflab(ftlab2);
pj
1.1
76 }
77
78 /*
79  * End of block.
80  */
81 void
ragge
1.11
82 eoftn(struct interpass_prolog *ipp)
pj
1.1
83 {
ragge
1.18
84 #if 0
ragge
1.11
85         if (ipp->ipp_regs != MINRVAR)
86                 comperr("fix eoftn register savings %x"ipp->ipp_regs);
ragge
1.18
87 #endif
ragge
1.4
88
janeno-1
1.28
89         //      if (xsaveip == 0)
90         addto = (p2maxautooff - AUTOINIT)/SZCHAR;
pj
1.1
91
92         /* return from function code */
janeno-1
1.31
93         //deflab(ipp->ipp_ip.ip_lbl);   //XXX - is this necessary?
janeno-1
1.30
94         
ragge
1.25
95         /* If retval is a pointer and not a function pointer, put in A0 */
96         if (ISPTR(DECREF(ipp->ipp_type)) &&
97             !ISFTN(DECREF(DECREF(ipp->ipp_type))))
janeno-1
1.30
98             printf("    mov.w r0,a0\n");
99         
pj
1.1
100         /* struct return needs special treatment */
101         if (ftype == STRTY || ftype == UNIONTY) {
ragge
1.4
102                 comperr("fix struct return in eoftn");
ragge
1.6
103         } else
104                 printf("        exitd\n");
pj
1.1
105
106         /* Prolog code */
janeno-1
1.28
107         //      if (xsaveip == 0) {
pj
1.1
108                 deflab(ftlab1);
ragge
1.7
109                 printf("        enter #%d\n"addto);
pj
1.23
110                 printf("        jmp.w " LABFMT "\n"ftlab2);
janeno-1
1.28
111                 //}
pj
1.1
112 }
113
114 /*
115  * add/sub/...
116  *
117  * Param given:
118  */
119 void
120 hopcode(int fint o)
121 {
122         char *str;
123
124         switch (o) {
125         case PLUS:
126                 str = "add";
127                 break;
128         case MINUS:
129                 str = "sub";
130                 break;
131         case AND:
132                 str = "and";
133                 break;
134         case OR:
135                 str = "or";
136                 break;
137         case ER:
138                 str = "xor";
139                 break;
140         default:
141                 comperr("hopcode2: %d"o);
142                 str = 0/* XXX gcc */
143         }
ragge
1.10
144         printf("%s.%c"strf);
pj
1.1
145 }
146
147 char *
148 rnames[] = {  /* keyed to register number tokens */
janeno-1
1.30
149     "r0""r2""r1""r3""a0""a1""fb""sp""r0h""r0l",
janeno-1
1.28
150     "r1h""r1l",
pj
1.1
151 };
152
ragge
1.9
153 /*
154  * Return the size (in bytes) of some types.
155  */
pj
1.1
156 int
157 tlen(pNODE *p;
158 {
159         switch(p->n_type) {
160                 case CHAR:
161                 case UCHAR:
162                         return(1);
163
ragge
1.9
164                 case INT:
165                 case UNSIGNED:
166                 case FLOAT:
167                         return 2;
pj
1.1
168
169                 case DOUBLE:
170                 case LONG:
171                 case ULONG:
ragge
1.9
172                         return 4;
pj
1.1
173
174                 default:
175                         if (!ISPTR(p->n_type))
176                                 comperr("tlen type %d not pointer");
ragge
1.12
177                         return SZPOINT(p->n_type)/SZCHAR;
pj
1.1
178                 }
179 }
180
ragge
1.16
181 /*
182  * Emit code to compare two longlong numbers.
183  */
184 static void
185 twollcomp(NODE *p)
186 {
187         int o = p->n_op;
188         int s = getlab();
189         int e = p->n_label;
190         int cb1cb2;
191
192         if (o >= ULE)
193                 o -= (ULE-LE);
194         switch (o) {
195         case NE:
196                 cb1 = 0;
197                 cb2 = NE;
198                 break;
199         case EQ:
200                 cb1 = NE;
201                 cb2 = 0;
202                 break;
203         case LE:
204         case LT:
205                 cb1 = GT;
206                 cb2 = LT;
207                 break;
208         case GE:
209         case GT:
210                 cb1 = LT;
211                 cb2 = GT;
212                 break;
213         
214         default:
215                 cb1 = cb2 = 0/* XXX gcc */
216         }
217         if (p->n_op >= ULE)
218                 cb1 += 4cb2 += 4;
219         expand(p0"  cmp.w UR,UL\n");
220         if (cb1cbgen(cb1s);
221         if (cb2cbgen(cb2e);
222         expand(p0"  cmp.w AR,AL\n");
223         cbgen(p->n_ope);
224         deflab(s);
225 }
226
227
pj
1.1
228 void
229 zzzcode(NODE *pint c)
230 {
ragge
1.22
231         NODE *l;
232
ragge
1.4
233         switch (c) {
234         case 'A'/* print negative shift constant */
235                 p = getlr(p'R');
236                 if (p->n_op != ICON)
237                         comperr("ZA bad use");
238                 p->n_lval = -p->n_lval;
239                 adrput(stdoutp);
240                 p->n_lval = -p->n_lval;
241                 break;
242
ragge
1.9
243         case 'B':
244                 if (p->n_rval)
ragge
1.16
245                         printf("        add.b #%d,%s\n",
ragge
1.9
246                             p->n_rvalrnames[STKREG]);
247                 break;
248
ragge
1.11
249         case 'C'/* Print label address */
250                 p = p->n_left;
251                 if (p->n_lval)
252                         printf(LABFMT, (int)p->n_lval);
253                 else
254                         printf("%s"p->n_name);
255                 break;
256
ragge
1.13
257         case 'D'/* copy function pointers */
ragge
1.24
258                 l = p->n_left;
259                 printf("\tmov.w #HWRD(%s),%s\n\tmov.w #LWRD(%s),%s\n",
260                     p->n_right->n_namernames[l->n_rval+1],
261                     p->n_right->n_namernames[l->n_rval]);
ragge
1.13
262                 break;
263
ragge
1.16
264         case 'E'/* double-reg printout */
265                 /* XXX - always r0r2 here */
266                 printf("%s%s"rnames[R0], rnames[R2]);
267                 break;
268
269         case 'F'/* long comparisions */
270                 twollcomp(p);
271                 break;
272
ragge
1.17
273         case 'G':
274                 printf("R0R2");
275                 break;
276
ragge
1.22
277         case 'H'/* push 32-bit address (for functions) */
278                 printf("\tpush.w #HWRD(%s)\n\tpush.w #LWRD(%s)\n",
279                     p->n_left->n_namep->n_left->n_name);
280                 break;
281
282         case 'I'/* push 32-bit address (for functions) */
283                 l = p->n_left;
284                 printf("\tpush.w %d[%s]\n\tpush.w %d[%s]\n",
285                     (int)l->n_lvalrnames[l->n_rval],
286                     (int)l->n_lval+2rnames[l->n_rval]);
287                 break;
288
ragge
1.4
289         default:
290                 comperr("bad zzzcode %c"c);
291         }
pj
1.1
292 }
293
294 /*ARGSUSED*/
295 int
296 rewfld(NODE *p)
297 {
298         return(1);
299 }
300
301 int canaddr(NODE *);
302 int
303 canaddr(NODE *p)
304 {
305         int o = p->n_op;
306
307         if (o==NAME || o==REG || o==ICON || o==OREG ||
ragge
1.26
308             (o==UMUL && shumul(p->n_left) == SRDIR))
pj
1.1
309                 return(1);
310         return(0);
311 }
312
stefan
1.36
313 int
314 fldexpand(NODE *pint cookiechar **cp)
315 {
316         return 0;
317 }
318
pj
1.1
319 /*
320  * Does the bitfield shape match?
321  */
322 int
323 flshape(NODE *p)
324 {
325         int o = p->n_op;
326
327         if (o == OREG || o == REG || o == NAME)
328                 return SRDIR/* Direct match */
329         if (o == UMUL && shumul(p->n_left))
330                 return SROREG/* Convert into oreg */
331         return SRREG/* put it into a register */
332 }
333
334 /* INTEMP shapes must not contain any temporary registers */
335 /* XXX should this go away now? */
336 int
337 shtemp(NODE *p)
338 {
339         return 0;
340 }
341
342 void
343 adrcon(CONSZ val)
344 {
345         printf("$" CONFMTval);
346 }
347
348 void
349 conput(FILE *fpNODE *p)
350 {
351         int val = p->n_lval;
352
353         switch (p->n_op) {
354         case ICON:
355                 if (p->n_name[0] != '\0') {
356                         fprintf(fp"%s"p->n_name);
357                         if (val)
358                                 fprintf(fp"+%d"val);
359                 } else
360                         fprintf(fp"%d"val);
361                 return;
362
363         default:
364                 comperr("illegal conput");
365         }
366 }
367
368 /*ARGSUSED*/
369 void
370 insput(NODE *p)
371 {
372         comperr("insput");
373 }
374
375 /*
376  * Write out the upper address, like the upper register of a 2-register
377  * reference, or the next memory location.
378  */
379 void
380 upput(NODE *pint size)
381 {
382
ragge
1.13
383         size /= SZINT;
pj
1.1
384         switch (p->n_op) {
385         case REG:
386                 fputs(rnames[p->n_rval + 1], stdout);
387                 break;
388
389         case NAME:
390         case OREG:
391                 p->n_lval += size;
392                 adrput(stdoutp);
393                 p->n_lval -= size;
394                 break;
395         case ICON:
ragge
1.13
396                 fprintf(stdout"#" CONFMTp->n_lval >> 16);
pj
1.1
397                 break;
398         default:
399                 comperr("upput bad op %d size %d"p->n_opsize);
400         }
401 }
402
403 void
404 adrput(FILE *ioNODE *p)
405 {
406         /* output an address, with offsets, from p */
407
408         if (p->n_op == FLD)
409                 p = p->n_left;
410
411         switch (p->n_op) {
412
413         case NAME:
414                 if (p->n_name[0] != '\0')
415                         fputs(p->n_nameio);
416                 if (p->n_lval != 0)
417                         fprintf(io"+" CONFMTp->n_lval);
418                 return;
419
420         case OREG:
421                 if (p->n_lval)
422                         fprintf(io"%d", (int)p->n_lval);
ragge
1.3
423                 fprintf(io"[%s]"rnames[p->n_rval]);
pj
1.1
424                 return;
425         case ICON:
426                 /* addressable value of the constant */
427                 fputc('#'io);
428                 conput(iop);
429                 return;
430
431         case REG:
janeno-1
1.30
432             /*if (DEUNSIGN(p->n_type) == CHAR) {
ragge
1.8
433                         fprintf(io, "R%c%c", p->n_rval < 2 ? '0' : '1',
434                             (p->n_rval & 1) ? 'H' : 'L');
janeno-1
1.30
435                             } else*/
436             fprintf(io"%s"rnames[p->n_rval]);
437             return;
pj
1.1
438
439         default:
440                 comperr("illegal address, op %d, node %p"p->n_opp);
441                 return;
442
443         }
444 }
445
446 static char *
447 ccbranches[] = {
ragge
1.15
448         "jeq",          /* jumpe */
pj
1.1
449         "jne",          /* jumpn */
450         "jle",          /* jumple */
ragge
1.15
451         "jlt",          /* jumpl */
pj
1.1
452         "jge",          /* jumpge */
ragge
1.15
453         "jgt",          /* jumpg */
454         "jleu",         /* jumple (jlequ) */
455         "jltu",         /* jumpl (jlssu) */
456         "jgeu",         /* jumpge (jgequ) */
457         "jgtu",         /* jumpg (jgtru) */
pj
1.1
458 };
459
460
461 /*   printf conditional and unconditional branches */
462 void
463 cbgen(int oint lab)
464 {
465         if (o < EQ || o > UGT)
466                 comperr("bad conditional branch: %s"opst[o]);
467         printf("        %s " LABFMT "\n"ccbranches[o-EQ], lab);
468 }
469
gmcgarry
1.34
470 void
471 mycanon(NODE *p)
472 {
473 }
474
475 void
476 myoptim(struct interpass *ip)
477 {
478 }
479
janeno-1
1.32
480 #if 0
pj
1.1
481 void
482 mygenregs(NODE *p)
483 {
janeno-1
1.32
484
pj
1.1
485         if (p->n_op == MINUS && p->n_type == DOUBLE &&
486             (p->n_su & (LMASK|RMASK)) == (LREG|RREG)) {
487                 p->n_su |= DORIGHT;
488         }
489         /* Must walk down correct node first for logops to work */
490         if (p->n_op != CBRANCH)
491                 return;
492         p = p->n_left;
493         if ((p->n_su & (LMASK|RMASK)) != (LREG|RREG))
494                 return;
495         p->n_su &= ~DORIGHT;
janeno-1
1.32
496
497 }
pj
1.1
498 #endif
499
500 struct hardops hardops[] = {
ragge
1.6
501         { PLUSFLOAT"?F_ADD_L04" },
ragge
1.16
502         { MULLONG"?L_MUL_L03" },
503         { MULULONG"?L_MUL_L03" },
504         { DIVLONG"?SL_DIV_L03" },
505         { DIVULONG"?UL_DIV_L03" },
506         { MODLONG"?SL_MOD_L03" },
507         { MODULONG"?UL_MOD_L03" },
pj
1.1
508         { RSLONGLONG"__ashrdi3" },
509         { RSULONGLONG"__lshrdi3" },
510         { LSLONGLONG"__ashldi3" },
511         { LSULONGLONG"__ashldi3" },
512         { 0 },
513 };
514
ragge
1.13
515 int
516 special(NODE *pint shape)
517 {
518         switch (shape) {
519         case SFTN:
ragge
1.14
520                 if (ISPTR(p->n_type) && ISFTN(DECREF(p->n_type))) {
521                         if (p->n_op == NAME || p->n_op == OREG)
522                                 return SRDIR;
523                         else
524                                 return SRREG;
525                 }
ragge
1.13
526                 break;
527         }
528         return SRNOPE;
529 }
ragge
1.16
530
531 void    
532 myreader(NODE *p)
533 {
534         NODE *q, *r, *s, *right;
535
536         if (optype(p->n_op) == LTYPE)
537                 return;
538         if (optype(p->n_op) != UTYPE)
539                 myreader(p->n_right);
540         myreader(p->n_left);
541
542         switch (p->n_op) {
543         case PLUS:
544         case MINUS:
545                 if (p->n_type != LONG && p->n_type != ULONG)
546                         break;
547                 if (p->n_right->n_op == NAME || p->n_right->n_op == OREG)
548                         break;
549                 /* Must convert right into OREG */
550                 right = p->n_right;
551                 q = mklnode(OREGBITOOR(freetemp(szty(right->n_type))),
552                     FPREGright->n_type);
553                 s = mkbinode(ASSIGNqrightright->n_type);
554                 r = talloc(); 
555                 *r = *q;
556                 p->n_right = r;
557                 pass2_compile(ipnode(s));
558                 break;
559         }
560 }
janeno-1
1.28
561
562
563 void
564 rmove(int sint dTWORD t)
565 {
566         switch (t) {
567         case CHAR:
568         case UCHAR:
569             printf("    mov.b %s,%s\n"rnames[s], rnames[d]);
570             break;
571         default:
572             printf("    mov.w %s,%s\n"rnames[s], rnames[d]);
573         }
574 }
575
576 /*
577  * For class c, find worst-case displacement of the number of
578  * registers in the array r[] indexed by class.
579  */
580 int
581 COLORMAP(int cint *r)
582 {
583         int num;
584
585         switch (c) {
586         case CLASSA:
587                 num = r[CLASSA];
ragge
1.29
588                 num += r[CLASSC];
janeno-1
1.28
589                 return num < 4;
ragge
1.29
590         case CLASSB:
591                 num = r[CLASSB];
592                 return num < 2;
janeno-1
1.28
593         case CLASSC:
ragge
1.29
594                 num = 2*r[CLASSA];
595                 num += r[CLASSC];
596                 return num < 4;
janeno-1
1.28
597         }
598         return 0/* XXX gcc */
599 }
600
601 /*
602  * Return a class suitable for a specific type.
603  */
604 int
605 gclass(TWORD t)
606 {
607         if (t == CHAR || t == UCHAR)
janeno-1
1.31
608                 return CLASSC;
janeno-1
1.28
609         
610         if(ISPTR(t))
janeno-1
1.31
611                 return CLASSB;
janeno-1
1.28
612         
613         return CLASSA;
614 }
janeno-1
1.32
615
616 static int sizen;
617
618 /* XXX: Fix this. */
619 static int
620 argsiz(NODE *p)
621 {
622         TWORD t = p->n_type;
623
624         if (t < LONGLONG || t > MAXTYPES)
625                 return 4;
626         if (t == LONGLONG || t == ULONGLONG || t == DOUBLE)
627                 return 8;
628         if (t == LDOUBLE)
629                 return 12;
630         if (t == STRTY)
631                 return p->n_stsize;
632         comperr("argsiz");
633         return 0;
634 }
635
636 /*
637  * Calculate argument sizes.
638  * XXX: Fix this.
639  */
640 void
641 lastcall(NODE *p)
642 {
643         sizen = 0;
644         for (p = p->n_rightp->n_op == CMp = p->n_left)
645                 sizen += argsiz(p->n_right);
646         sizen += argsiz(p);
647 }
gmcgarry
1.35
648
649 /*
650  * Target-dependent command-line options.
651  */
652 void
653 mflags(char *str)
654 {
655 }
ragge
1.38
656 /*
657  * Do something target-dependent for xasm arguments.
658  * Supposed to find target-specific constraints and rewrite them.
659  */
660 int
661 myxasm(struct interpass *ipNODE *p)
662 {
663         return 0;
664 }
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-01 10:19 +0200