Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110702151159

Diff

Diff from 1.17 to:

Annotations

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

Annotated File View

ragge
1.17
1 /*      $Id: local2.c,v 1.17 2011/07/02 15:11:59 ragge Exp $    */
ragge
1.1
2 /*
3  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * Redistributions of source code and documentation must retain the above
10  * copyright notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditionsand the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * All advertising materials mentioning features or use of this software
15  * must display the following acknowledgement:
16  *      This product includes software developed or owned by Caldera
17  *      International, Inc.
18  * Neither the name of Caldera International, Inc. nor the names of other
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35
ragge
1.2
36 # include "pass2.h"
ragge
1.1
37 # include "ctype.h"
38 /* a lot of the machine dependent parts of the second pass */
39
ragge
1.2
40 static void prtype(NODE *n);
41 static void acon(NODE *p);
42
43 /*
44  * Print out the prolog assembler.
45  * addto and regoff are already calculated.
46  */
47 void
48 prologue(struct interpass_prolog *ipp)
49 {
ragge
1.16
50         printf("        .word 0x%llx\n", (unsigned long long)ipp->ipp_regs[0]);
ragge
1.2
51         if (p2maxautooff)
52                 printf("        subl2 $%d,%%sp\n"p2maxautooff);
53 }
ragge
1.1
54
ragge
1.2
55 /*
56  * Called after all instructions in a function are emitted.
57  * Generates code for epilog here.
58  */
59 void
60 eoftn(struct interpass_prolog *ipp)
61 {
62         if (ipp->ipp_ip.ip_lbl == 0)
63                 return/* no code needs to be generated */
64         printf("        ret\n");
65 }
ragge
1.1
66
67 struct hoptab { int opmaskchar * opstring; } ioptab[] = {
68
ragge
1.2
69         { PLUS"add", },
70         { MINUS,        "sub", },
71         { MUL,  "mul", },
72         { DIV,  "div", },
73         { OR,   "bis", },
74         { ER,   "xor", },
75         { AND,  "bic", },
76         { -1""     },
77 };
ragge
1.1
78
ragge
1.2
79 void
ragge
1.1
80 hopcodefo ){
81         /* output the appropriate string from the above table */
82
83         register struct hoptab *q;
84
85         forq = ioptab;  q->opmask>=0; ++q ){
86                 ifq->opmask == o ){
87                         printf"%s"q->opstring );
88 /* tbl
89                         if( f == 'F' ) printf( "e" );
90                         else if( f == 'D' ) printf( "d" );
91    tbl */
92 /* tbl */
93                         switchf ) {
94                                 case 'L':
95                                 case 'W':
96                                 case 'B':
97                                 case 'D':
98                                 case 'F':
99                                         printf("%c"tolower(f));
100                                         break;
101
102                                 }
103 /* tbl */
104                         return;
105                         }
106                 }
107         cerror"no hoptab for %s"opst[o] );
108         }
109
110 char *
111 rnames[] = {  /* keyed to register number tokens */
112
ragge
1.15
113         "%r0""%r1""%r2""%r3""%r4""%r5",
114         "%r6""%r7""%r8""%r9""%r10""%r11",
115         "%ap""%fp""%sp""%pc",
ragge
1.2
116         /* The concatenated regs has the name of the lowest */
ragge
1.15
117         "%r0""%r1""%r2""%r3""%r4""%r5",
118         "%r6""%r7""%r8""%r9""%r10"
ragge
1.1
119         };
120
ragge
1.2
121 int
ragge
1.17
122 tlen(NODE *p)
ragge
1.1
123 {
ragge
1.2
124         switch(p->n_type) {
ragge
1.17
125         case CHAR:
126         case UCHAR:
127                 return(1);
128
129         case SHORT:
130         case USHORT:
131                 return(2);
132
133         case DOUBLE:
134         case LONGLONG:
135         case ULONGLONG:
136                 return(8);
ragge
1.1
137
ragge
1.17
138         default:
139                 return(4);
140         }
ragge
1.1
141 }
142
ragge
1.2
143 static int
144 mixtypes(NODE *pNODE *q)
ragge
1.1
145 {
ragge
1.2
146         TWORD tptq;
ragge
1.1
147
ragge
1.2
148         tp = p->n_type;
149         tq = q->n_type;
ragge
1.1
150
151         return( (tp==FLOAT || tp==DOUBLE) !=
152                 (tq==FLOAT || tq==DOUBLE) );
153 }
154
ragge
1.2
155 void
156 prtype(NODE *n)
ragge
1.1
157 {
ragge
1.17
158         static char pt[] = { 00'b''b''w''w''l''l'00,
159             'q''q''f''d' };
160         TWORD t = n->n_type;
161
162         if (ISPTR(t))
163                 t = UNSIGNED;
164
165         if (t > DOUBLE || pt[t] == 0)
166                 comperr("prtype: bad type");
167         putchar(pt[t]);
168 }
169
170 /*
171  * Emit conversions as given by the following table. Dest is always reg,
172  *   if it should be something else let peephole optimizer deal with it.
173  *   This code ensures type correctness in 32-bit registers.
174  *   XXX is that necessary?
175  *
176  * From                         To
177  *       char   uchar  short  ushort int    uint   ll    ull   float double
178  * char  movb   movb   cvtbw  cvtbw  cvtbl  cvtbl  A     A     cvtbf cvtbd
179  * uchar movb   movb   movzbw movzbw movzbl movzbl B     B     G     G
180  * short movb   movb   movw   movw   cvtwl  cvtwl  C(A)  C(A)  cvtwf cvtwd
181  * ushrt movb   movb   movw   movw   movzwl movzwl D(B)  D(B)  H     H
182  * int   movb   movb   movw   movw   movl   movl   E     E     cvtlf cvtld
183  * uint  movb   movb   movw   movw   movl   movl   F     F     I     I
184  * ll    movb   movb   movw   movw   movl   movl   movq  movq  J     K
185  * ull   movb   movb   movw   movw   movl   movl   movq  movq  L     M
186  * float cvtfb  cvtfb  cvtfw  cvtfw  cvtfl  cvtfl  N     O     movf  cvtfd
187  * doubl cvtdb  cvtdb  cvtdw  cvtdw  cvtdl  cvtdl  P     Q     cvtdf movd
188  *
189  *  A: cvtbl + sign extend
190  *  B: movzbl + zero extend
191  *  G: movzbw + cvtwX
192  *  H: movzwl + cvtwX
193  *  I: cvtld + addX
194  *  J: call __floatdisf
195  *  K: call __floatdidf
196  *  L: xxx + call __floatdisf
197  *  M: xxx + call __floatdidf
198  *  N: call __fixsfdi
199  *  O: call __fixunssfdi
200  *  P: call __fixdfdi
201  *  Q: call __fixunsdfdi
202  */
203
204 #define MVD     1 /* mov + dest type */
205 #define CVT     2 /* cvt + src type + dst type */
206 #define MVZ     3 /* movz + src type + dst type */
207 #define CSE     4 /* cvt + src type + l + sign extend upper */
208 #define MZE     5 /* movz + src type + l + zero extend upper */
209 #define MLE     6 /* movl + sign extend upper */
210 #define MLZ     7 /* movl + zero extend upper */
211 #define MZC     8 /* movz + cvt */
212
213 static char scary[][10] = {
214         { MVDMVDCVTCVTCVTCVTCSECSECVTCVT },
215         { MVDMVDMVZMVZMVZMVZMZEMZEMZCMZC },
216         { MVDMVDMVDMVDCVTCVTCSECSECVTCVT },
217         { MVDMVDMVDMVDMVZMVZMZEMZEMZCMZC },
218         { MVDMVDMVDMVDMVDMVDMLEMLECVTCVT },
219         { MVDMVDMVDMVDMVZMVZMLZMLZ'I''I' },
220         { MVDMVDMVDMVDMVDMVDMVDMVD'J''K' },
221         { MVDMVDMVDMVDMVDMVDMVDMVD'L''M' },
222         { CVTCVTCVTCVTCVTCVT'N''O'MVDCVT },
223         { CVTCVTCVTCVTCVTCVT'P''Q'CVTMVD },
224 };
225
226 static void
227 sconv(NODE *p)
228 {
229         NODE *l = p->n_left;
230         TWORD tstd;
231         int o;
232
233         /*
234          * Source node may be in register or memory.
235          * Result is always in register.
236          */
237         ts = l->n_type;
238         if (ISPTR(ts))
239                 ts = UNSIGNED;
240         td = p->n_type;
241         ts = ts < LONG ? ts-2 : ts-4;
242         td = td < LONG ? td-2 : td-4;
243
244         o = scary[ts][td];
245         switch (o) {
246         case MLE:
247         case MLZ:
248         case MVD:
249                 expand(pINAREG|INBREG"\tmovZL AL,A1\n");
250                 break;
251
252         case CSE:
253                 expand(pINAREG|INBREG"\tcvtZLl AL,A1\n");
254                 break;
ragge
1.1
255
ragge
1.17
256         case CVT:
257                 expand(pINAREG|INBREG"\tcvtZLZR AL,A1\n");
258                 break;
ragge
1.1
259
ragge
1.17
260         case MZE:
261                 expand(pINAREG|INBREG"\tmovzZLl AL,A1\n");
262                 break;
ragge
1.1
263
ragge
1.17
264         case MVZ:
265                 expand(pINAREG|INBREG"\tmovzZLZR AL,A1\n");
266                 break;
ragge
1.1
267
ragge
1.17
268         case MZC:
269                 expand(pINAREG|INBREG"\tmovzZLl AL,A1\n");
270                 expand(pINAREG|INBREG"\tcvtlZR A1,A1\n");
271                 break;
ragge
1.1
272
ragge
1.17
273         default:
274                 comperr("unsupported conversion %d"o);
275         }
276         switch (o) {
277         case MLE:
278         case CSE:
279                 expand(pINBREG"\tashl $-31,A1,U1\n");
280                 break;
281         case MLZ:
282         case MZE:
283                 expand(pINAREG|INBREG"\tclrl U1\n");
284                 break;
285         }
ragge
1.1
286 }
287
ragge
1.16
288 /*
289  * Emit code to compare two longlong numbers.
290  */
291 static void
292 twollcomp(NODE *p)
293 {
294         int u;
295         int s = getlab2();
296         int e = p->n_label;
297         int cb1cb2;
298
299         u = p->n_op;
300         switch (p->n_op) {
301         case NE:
302                 cb1 = 0;
303                 cb2 = NE;
304                 break;
305         case EQ:
306                 cb1 = NE;
307                 cb2 = 0;
308                 break;
309         case LE:
310         case LT:
311                 u += (ULE-LE);
312                 /* FALLTHROUGH */
313         case ULE:
314         case ULT:
315                 cb1 = GT;
316                 cb2 = LT;
317                 break;
318         case GE:
319         case GT:
320                 u += (ULE-LE);
321                 /* FALLTHROUGH */
322         case UGE:
323         case UGT:
324                 cb1 = LT;
325                 cb2 = GT;
326                 break;
327         
328         default:
329                 cb1 = cb2 = 0/* XXX gcc */
330         }
331         if (p->n_op >= ULE)
332                 cb1 += 4cb2 += 4;
333         expand(p0"  cmpl UR,UL\n");
334         if (cb1cbgen(cb1s);
335         if (cb2cbgen(cb2e);
336         expand(p0"  cmpl AL,AR\n");
337         cbgen(ue);
338         deflab(s);
339 }
340
341
ragge
1.2
342 void
ragge
1.1
343 zzzcodepc ) register NODE *p; {
ragge
1.2
344         int m;
345         int val;
ragge
1.17
346         char *ch;
ragge
1.1
347         switchc ){
348
349         case 'N':  /* logical ops, turned into 0-1 */
350                 /* use register given by register 1 */
ragge
1.11
351                 cbgen0m=getlab2());
ragge
1.2
352                 deflabp->n_label );
353                 printf"       clrl    %s\n"rnames[getlrp'1' )->n_rval] );
ragge
1.1
354                 deflabm );
355                 return;
356
357         case 'A':
358                 {
359                 register NODE *l, *r;
360
ragge
1.2
361                 if (xdebuge2print(p0, &val, &val);
ragge
1.1
362                 r = getlr(p'R');
ragge
1.2
363                 if (optype(p->n_op) == LTYPE || p->n_op == UMUL) {
ragge
1.1
364                         l = resc;
ragge
1.2
365                         l->n_type = (r->n_type==FLOAT || r->n_type==DOUBLE ? DOUBLE : INT);
366                 } else
ragge
1.1
367                         l = getlr(p'L');
ragge
1.2
368                 if (r->n_op == ICON  && r->n_name[0] == '\0') {
369                         if (r->n_lval == 0) {
ragge
1.1
370                                 printf("clr");
371                                 prtype(l);
372                                 printf("        ");
ragge
1.2
373                                 adrput(stdoutl);
ragge
1.1
374                                 return;
ragge
1.2
375                         }
376                         if (r->n_lval < 0 && r->n_lval >= -63) {
ragge
1.1
377                                 printf("mneg");
378                                 prtype(l);
ragge
1.2
379                                 r->n_lval = -r->n_lval;
ragge
1.1
380                                 goto ops;
381                         }
ragge
1.2
382                         r->n_type = (r->n_lval < 0 ?
383                                         (r->n_lval >= -128 ? CHAR
384                                         : (r->n_lval >= -32768 ? SHORT
385                                         : INT )) : r->n_type);
386                         r->n_type = (r->n_lval >= 0 ?
387                                         (r->n_lval <= 63 ? INT
388                                         : ( r->n_lval <= 127 ? CHAR
389                                         : (r->n_lval <= 255 ? UCHAR
390                                         : (r->n_lval <= 32767 ? SHORT
391                                         : (r->n_lval <= 65535 ? USHORT
392                                         : INT ))))) : r->n_type );
393                         }
394                 if (l->n_op == REG && l->n_type != FLOAT && l->n_type != DOUBLE)
395                         l->n_type = INT;
ragge
1.1
396                 if (!mixtypes(l,r))
397                         {
398                         if (tlen(l) == tlen(r))
399                                 {
400                                 printf("mov");
401                                 prtype(l);
402                                 goto ops;
403                                 }
ragge
1.2
404                         else if (tlen(l) > tlen(r) && ISUNSIGNED(r->n_type))
ragge
1.1
405                                 {
406                                 printf("movz");
407                                 }
408                         else
409                                 {
410                                 printf("cvt");
411                                 }
412                         }
413                 else
414                         {
415                         printf("cvt");
416                         }
417                 prtype(r);
418                 prtype(l);
419         ops:
420                 printf("        ");
ragge
1.2
421                 adrput(stdoutr);
ragge
1.1
422                 printf(",");
ragge
1.2
423                 adrput(stdoutl);
ragge
1.1
424                 return;
425                 }
426
ragge
1.16
427         case 'B'/* long long compare */
428                 twollcomp(p);
429                 break;
430
ragge
1.1
431         case 'C':       /* num words pushed on arg stack */
ragge
1.3
432                 printf("$%d"p->n_qual);
433                 break;
ragge
1.1
434
435         case 'D':       /* INCR and DECR */
ragge
1.2
436                 zzzcode(p->n_left'A');
ragge
1.1
437                 printf("\n      ");
438
ragge
1.2
439 #if 0
ragge
1.1
440         case 'E':       /* INCR and DECR, FOREFF */
ragge
1.2
441                 if (p->n_right->n_lval == 1)
ragge
1.1
442                         {
ragge
1.2
443                         printf("%s", (p->n_op == INCR ? "inc" : "dec") );
444                         prtype(p->n_left);
ragge
1.1
445                         printf("        ");
ragge
1.2
446                         adrput(stdoutp->n_left);
ragge
1.1
447                         return;
448                         }
ragge
1.2
449                 printf("%s", (p->n_op == INCR ? "add" : "sub") );
450                 prtype(p->n_left);
ragge
1.1
451                 printf("2       ");
ragge
1.2
452                 adrput(stdoutp->n_right);
ragge
1.1
453                 printf(",");
ragge
1.2
454                 adrput(p->n_left);
ragge
1.1
455                 return;
ragge
1.2
456 #endif
ragge
1.1
457
458         case 'F':       /* register type of right operand */
459                 {
460                 register NODE *n;
461                 extern int xdebug;
462                 register int ty;
463
464                 n = getlrp'R' );
ragge
1.2
465                 ty = n->n_type;
ragge
1.1
466
467                 if (xdebugprintf("->%d<-"ty);
468
469                 if ( ty==DOUBLEprintf("d");
470                 else if ( ty==FLOAT ) printf("f");
471                 else printf("l");
472                 return;
473                 }
474
ragge
1.17
475         case 'G'/* emit conversion instructions */
476                 sconv(p);
477                 break;
478
ragge
1.3
479         case 'J'/* jump or ret? */
480                 {
481                         struct interpass *ip =
ragge
1.12
482                             DLIST_PREV((struct interpass *)p2env.eppqelem);
ragge
1.3
483                         if (ip->type != IP_DEFLAB ||
484                             ip->ip_lbl != getlr(p'L')->n_lval)
485                                 expand(pFOREFF"jbr  LL");
486                         else
487                                 printf("ret");
488                 }
489                 break;
490
ragge
1.1
491         case 'L':       /* type of left operand */
492         case 'R':       /* type of right operand */
493                 {
494                 register NODE *n;
495                 extern int xdebug;
496
497                 n = getlr ( pc);
ragge
1.2
498                 if (xdebugprintf("->%d<-"n->n_type);
ragge
1.1
499
500                 prtype(n);
501                 return;
502                 }
503
ragge
1.17
504         case 'O'/* print out emulated ops */
505                 expand(pFOREFF"\tmovq       AR,-(%sp)\n");
506                 expand(pFOREFF"\tmovq       AL,-(%sp)\n");
507                 if (p->n_op == DIV && p->n_type == ULONGLONGch = "udiv";
508                 else if (p->n_op == DIVch = "div";
509                 else if (p->n_op == MOD && p->n_type == ULONGLONGch = "umod";
510                 else if (p->n_op == MODch = "mod";
511                 else ch = 0comperr("ZO");
512                 printf("\tcalls $4,__%sdi3\n"ch);
513                 break;
514
515
ragge
1.1
516         case 'Z':       /* complement mask for bit instr */
ragge
1.2
517                 printf("$%Ld", ~p->n_right->n_lval);
ragge
1.1
518                 return;
519
520         case 'U':       /* 32 - n, for unsigned right shifts */
ragge
1.2
521                 printf("$" CONFMT32 - p->n_right->n_lval );
ragge
1.1
522                 return;
523
524         case 'T':       /* rounded structure length for arguments */
525                 {
526                 int size;
527
ragge
1.2
528                 size = p->n_stsize;
ragge
1.1
529                 SETOFFsize4);
530                 printf("$%d"size);
531                 return;
532                 }
533
534         case 'S':  /* structure assignment */
535                 {
536                         register NODE *l, *r;
ragge
1.2
537                         register int size;
ragge
1.1
538
ragge
1.14
539                         size = p->n_stsize;
ragge
1.2
540                         l = r = NULL/* XXX gcc */
541                         ifp->n_op == STASG ){
542                                 l = p->n_left;
543                                 r = p->n_right;
ragge
1.1
544
545                                 }
ragge
1.14
546                         else ifp->n_op == STARG ){
547                                 /* store an arg into a temporary */
548                                 printf("\tsubl2 $%d,%%sp\n",
549                                     size < 4 ? 4 : size);
550                                 l = mklnode(OREG0SPINT);
ragge
1.2
551                                 r = p->n_left;
ragge
1.1
552                                 }
553                         else cerror"STASG bad" );
554
ragge
1.2
555                         ifr->n_op == ICON ) r->n_op = NAME;
556                         else ifr->n_op == REG ) r->n_op = OREG;
557                         else ifr->n_op != OREG ) cerror"STASG-r" );
ragge
1.1
558
559                         ifsize <= 0 || size > 65535 )
560                                 cerror("structure size <0=0 or >65535");
561
562                         switch(size) {
563                                 case 1:
564                                         printf("        movb    ");
565                                         break;
566                                 case 2:
567                                         printf("        movw    ");
568                                         break;
569                                 case 4:
570                                         printf("        movl    ");
571                                         break;
572                                 case 8:
573                                         printf("        movq    ");
574                                         break;
575                                 default:
576                                         printf("        movc3   $%d,"size);
577                                         break;
578                         }
ragge
1.2
579                         adrput(stdoutr);
ragge
1.1
580                         printf(",");
ragge
1.2
581                         adrput(stdoutl);
ragge
1.1
582                         printf("\n");
583
ragge
1.2
584                         ifr->n_op == NAME ) r->n_op = ICON;
585                         else ifr->n_op == OREG ) r->n_op = REG;
ragge
1.14
586                         if (p->n_op == STARG)
587                                 tfree(l);
ragge
1.1
588
589                         }
590                 break;
591
592         default:
ragge
1.2
593                 comperr("illegal zzzcode '%c'"c);
ragge
1.1
594                 }
595         }
596
ragge
1.2
597 void
598 rmoveint rt,int  rsTWORD t ){
ragge
1.1
599         printf"       %s      %s,%s\n",
600                 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
601                 rnames[rs], rnames[rt] );
602         }
603
ragge
1.2
604 #if 0
ragge
1.1
605 setregs(){ /* set up temporary registers */
606         fregs = 6;      /* tbl- 6 free regs on VAX (0-5) */
607         ;
608         }
609
610 szty(t){ /* size, in registers, needed to hold thing of type t */
611         return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
612         }
ragge
1.2
613 #endif
ragge
1.1
614
ragge
1.2
615 int
ragge
1.1
616 rewfldp ) NODE *p; {
617         return(1);
618         }
619
ragge
1.2
620 #if 0
ragge
1.1
621 callreg(pNODE *p; {
622         returnR0 );
623         }
624
625 basep ) register NODE *p; {
626         register int o = p->op;
627
628         if( (o==ICON && p->name[0] != '\0')) return100 ); /* ie no base reg */
629         ifo==REG ) returnp->rval );
630     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
631                 returnp->left->rval );
632     ifo==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
633                 returnp->rval + 0200*1 );
634         ifo==INCR && p->left->op==REG ) returnp->left->rval + 0200*2 );
635         ifo==ASG MINUS && p->left->op==REGreturnp->left->rval + 0200*4 );
636         ifo==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
637           && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
638                 returnp->left->left->rval + 0200*(1+2) );
639         return( -1 );
640         }
641
642 offsetptyl ) register NODE *pint tyl; {
643
644         iftyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) returnp->rval );
645         if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
646               (p->right->op==ICON && p->right->name[0]=='\0')
647               && (1<<p->right->lval)==tyl))
648                 returnp->left->rval );
649         return( -1 );
650         }
ragge
1.2
651 #endif
ragge
1.1
652
ragge
1.2
653 #if 0
654 void
ragge
1.1
655 makeor2pqboregister NODE *p, *qregister int bo; {
656         register NODE *t;
657         NODE *f;
658
ragge
1.2
659         p->n_op = OREG;
660         f = p->n_left;  /* have to free this subtree later */
ragge
1.1
661
662         /* init base */
ragge
1.2
663         switch (q->n_op) {
ragge
1.1
664                 case ICON:
665                 case REG:
666                 case OREG:
667                         t = q;
668                         break;
669
670                 case MINUS:
ragge
1.2
671                         q->n_right->n_lval = -q->n_right->n_lval;
ragge
1.1
672                 case PLUS:
ragge
1.2
673                         t = q->n_right;
ragge
1.1
674                         break;
675
ragge
1.2
676                 case UMUL:
677                         t = q->n_left->n_left;
ragge
1.1
678                         break;
679
680                 default:
681                         cerror("illegal makeor2");
ragge
1.2
682                         t = NULL/* XXX gcc */
ragge
1.1
683         }
684
ragge
1.2
685         p->n_lval = t->n_lval;
686         p->n_name = t->n_name;
ragge
1.1
687
688         /* init offset */
ragge
1.2
689         p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
ragge
1.1
690
691         tfree(f);
692         return;
693         }
694
ragge
1.2
695 int
ragge
1.1
696 canaddrp ) NODE *p; {
ragge
1.2
697         register int o = p->n_op;
ragge
1.1
698
ragge
1.8
699         ifo==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_leftSTARNM|SOREG)) ) return(1);
ragge
1.1
700         return(0);
701         }
702
703 shltypeop ) register NODE *p; {
ragge
1.8
704         returno== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_leftSTARNM|SOREG)) );
ragge
1.1
705         }
ragge
1.2
706 #endif
ragge
1.1
707
ragge
1.2
708 int
stefan
1.6
709 fldexpand(NODE *pint cookiechar **cp)
710 {
711         return 0;
712 }
713
714 int
ragge
1.1
715 flshapep ) register NODE *p; {
ragge
1.2
716         returnp->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
717                 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
ragge
1.1
718         }
719
ragge
1.2
720 int
ragge
1.1
721 shtempp ) register NODE *p; {
ragge
1.2
722         ifp->n_op == STARG ) p = p->n_left;
ragge
1.8
723         returnp->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_leftSTARNM|SOREG)) );
ragge
1.1
724         }
725
ragge
1.16
726 /*
727  * Shape matches for UMUL.  Cooperates with offstar().
728  */
729 int
730 shumul(NODE *pint shape)
731 {
732
733         if (x2debug)
734                 printf("shumul(%p)\n"p);
735
736         /* Turns currently anything into OREG on vax */
737         if (shape & SOREG)
738                 return SROREG;
739         return SRNOPE;
740 }
741
742
743 #ifdef notdef
ragge
1.2
744 int
ragge
1.8
745 shumulpshape ) register NODE *pint shape; {
ragge
1.2
746         register int o;
ragge
1.1
747         extern int xdebug;
748
749         if (xdebug) {
ragge
1.2
750                  printf("\nshumul:op=%d,lop=%d,rop=%d"p->n_opp->n_left->n_opp->n_right->n_op);
751                 printf(" prname=%s,plty=%d, prlval=%lld\n"p->n_right->n_namep->n_left->n_typep->n_right->n_lval);
ragge
1.1
752                 }
753
754
ragge
1.2
755         o = p->n_op;
ragge
1.8
756         ifo == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
757                 if (shape & STARNM)
758                         return SRDIR;
ragge
1.1
759
760         if( ( o == INCR || o == ASG MINUS ) &&
ragge
1.2
761             ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
762             p->n_right->n_name[0] == '\0' )
ragge
1.1
763                 {
ragge
1.2
764                 switch (p->n_left->n_type)
ragge
1.1
765                         {
766                         case CHAR|PTR:
767                         case UCHAR|PTR:
768                                 o = 1;
769                                 break;
770
771                         case SHORT|PTR:
772                         case USHORT|PTR:
773                                 o = 2;
774                                 break;
775
776                         case INT|PTR:
777                         case UNSIGNED|PTR:
778                         case LONG|PTR:
779                         case ULONG|PTR:
780                         case FLOAT|PTR:
781                                 o = 4;
782                                 break;
783
784                         case DOUBLE|PTR:
785                                 o = 8;
786                                 break;
787
788                         default:
ragge
1.2
789                                 if ( ISPTR(p->n_left->n_type) ) {
ragge
1.1
790                                         o = 4;
791                                         break;
792                                         }
793                                 else return(0);
794                         }
ragge
1.2
795                 returnp->n_right->n_lval == o ? STARREG : 0);
ragge
1.1
796                 }
797
ragge
1.8
798         returnSRNOPE );
ragge
1.1
799         }
ragge
1.16
800 #endif
ragge
1.1
801
ragge
1.2
802 void
ragge
1.1
803 adrconval ) CONSZ val; {
804         printf"$" );
805         printfCONFMTval );
806         }
807
ragge
1.2
808 void
809 conput(FILE *fpNODE *p)
810 {
811         switchp->n_op ){
ragge
1.1
812
813         case ICON:
814                 aconp );
815                 return;
816
817         case REG:
ragge
1.2
818                 printf"%s"rnames[p->n_rval] );
ragge
1.1
819                 return;
820
821         default:
822                 cerror"illegal conput" );
823                 }
824         }
825
ragge
1.2
826 void
ragge
1.1
827 insputp ) register NODE *p; {
828         cerror"insput" );
829         }
830
ragge
1.16
831 /*
832  * Write out the upper address, like the upper register of a 2-register
833  * reference, or the next memory location.
834  */
ragge
1.2
835 void
ragge
1.16
836 upput(NODE *pint size)
837 {
838
839         size /= SZCHAR;
840         switch (p->n_op) {
841         case REG:
842                 fprintf(stdout"%s"rnames[regno(p)-16+1]);
843                 break;
844
845         case NAME:
846         case OREG:
847                 p->n_lval += size;
848                 adrput(stdoutp);
849                 p->n_lval -= size;
850                 break;
851         case ICON:
852                 fprintf(stdout"$" CONFMTp->n_lval >> 32);
853                 break;
854         default:
855                 comperr("upput bad op %d size %d"p->n_opsize);
ragge
1.1
856         }
ragge
1.16
857 }
ragge
1.1
858
ragge
1.2
859 void
860 adrput(FILE *fpNODE *p)
861 {
ragge
1.1
862         register int r;
863         /* output an address, with offsets, from p */
864
ragge
1.2
865         ifp->n_op == FLD ){
866                 p = p->n_left;
ragge
1.1
867                 }
ragge
1.2
868         switchp->n_op ){
ragge
1.1
869
870         case NAME:
871                 aconp );
872                 return;
873
874         case ICON:
875                 /* addressable value of the constant */
ragge
1.2
876                 if (p->n_name[0] == '\0'/* uses xxxab */
877                         printf("$");
878                 acon(p);
ragge
1.1
879                 return;
880
881         case REG:
ragge
1.2
882                 printf"%s"rnames[p->n_rval] );
ragge
1.1
883                 return;
884
885         case OREG:
ragge
1.2
886                 r = p->n_rval;
ragge
1.1
887                 ifR2TEST(r) ){ /* double indexing */
888                         register int flags;
889
890                         flags = R2UPK3(r);
891                         ifflags & 1 ) printf("*");
892                         ifflags & 4 ) printf("-");
ragge
1.2
893                         ifp->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
ragge
1.1
894                         ifR2UPK1(r) != 100printf"(%s)"rnames[R2UPK1(r)] );
895                         ifflags & 2 ) printf("+");
896                         printf"[%s]"rnames[R2UPK2(r)] );
897                         return;
898                         }
899                 ifr == AP ){  /* in the argument region */
ragge
1.2
900                         ifp->n_lval <= 0 || p->n_name[0] != '\0' ) werror"bad arg temp" );
901                         printfCONFMTp->n_lval );
ragge
1.17
902                         printf"(%%ap)" );
ragge
1.1
903                         return;
904                         }
ragge
1.2
905                 ifp->n_lval != 0 || p->n_name[0] != '\0'aconp );
906                 printf"(%s)"rnames[p->n_rval] );
ragge
1.1
907                 return;
908
ragge
1.2
909         case UMUL:
ragge
1.1
910                 /* STARNM or STARREG found */
911                 iftshape(pSTARNM) ) {
912                         printf"*" );
ragge
1.2
913                         adrput(0,  p->n_left);
ragge
1.1
914                         }
915                 else {  /* STARREG - really auto inc or dec */
916                         register NODE *q;
917
918 /* tbl
ragge
1.2
919                         p = p->n_left;
920                         p->n_left->n_op = OREG;
921                         if( p->n_op == INCR ) {
922                                 adrput( p->n_left );
ragge
1.1
923                                 printf( "+" );
924                                 }
925                         else {
926                                 printf( "-" );
ragge
1.2
927                                 adrput( p->n_left );
ragge
1.1
928                                 }
929    tbl */
ragge
1.2
930 #ifdef notyet
931                         printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
932                                 rnames[p->n_left->n_left->n_rval], 
933                                 (p->n_left->n_op==INCR ? '+' : '\0') );
934 #else
935                         printf("%c(%s)%c"'-',
936                                 rnames[p->n_left->n_left->n_rval], 
937                                 '\0' );
938 #endif
939                         p->n_op = OREG;
940                         p->n_rval = p->n_left->n_left->n_rval;
941                         q = p->n_left;
942 #ifdef notyet
943
944                         p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
945 #else
946                         p->n_lval = 0;
947 #endif
948                         p->n_name[0] = '\0';
ragge
1.1
949                         tfree(q);
950                 }
951                 return;
952
953         default:
954                 cerror"illegal address" );
955                 return;
956         }
957
ragge
1.2
958 }
ragge
1.1
959
960 /*
ragge
1.2
961  * print out a constant
962  */
963 void
964 acon(NODE *p)
965 {
ragge
1.1
966
ragge
1.2
967         if (p->n_name[0] == '\0') {
968                 printf(CONFMTp->n_lval);
969         } else ifp->n_lval == 0 ) {
970                 printf("%s"p->n_name);
971         } else {
972                 printf("%s+"p->n_name);
973                 printf(CONFMTp->n_lval);
ragge
1.1
974         }
ragge
1.2
975 }
ragge
1.1
976
ragge
1.2
977 #if 0
ragge
1.1
978 genscallpcookie ) register NODE *p; {
979         /* structure valued call */
980         returngencallpcookie ) );
981         }
982
983 /* tbl */
984 int gc_numbytes;
985 /* tbl */
986
987 gencallpcookie ) register NODE *p; {
988         /* generate the call given by p */
989         register NODE *p1, *ptemp;
990         register temptemp1;
991         register m;
992
993         ifp->right ) temp = argsizep->right );
994         else temp = 0;
995
996         ifp->op == STCALL || p->op == UNARY STCALL ){
997                 /* set aside room for structure return */
998
999                 ifp->stsize > temp ) temp1 = p->stsize;
1000                 else temp1 = temp;
1001                 }
1002
1003         iftemp > maxargs ) maxargs = temp;
1004         SETOFF(temp1,4);
1005
1006         ifp->right ){ /* make temp node, put offset in, and generate args */
1007                 ptemp = talloc();
1008                 ptemp->op = OREG;
1009                 ptemp->lval = -1;
1010                 ptemp->rval = SP;
1011                 ptemp->name[0] = '\0';
1012                 ptemp->rall = NOPREF;
1013                 ptemp->su = 0;
1014                 genargsp->rightptemp );
ragge
1.2
1015                 nfree(ptemp);
ragge
1.1
1016                 }
1017
1018         p1 = p->left;
1019         ifp1->op != ICON ){
1020                 ifp1->op != REG ){
1021                         ifp1->op != OREG || R2TEST(p1->rval) ){
1022                                 ifp1->op != NAME ){
1023                                         orderp1INAREG );
1024                                         }
1025                                 }
1026                         }
1027                 }
1028
1029 /*
1030         if( p1->op == REG && p->rval == R5 ){
1031                 cerror( "call register overwrite" );
1032                 }
1033  */
1034