Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20110705200419

Diff

Diff from 1.18 to:

Annotations

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

Annotated File View

ragge
1.18
1 /*      $Id: local2.c,v 1.18 2011/07/05 20:04:19 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 void
144 prtype(NODE *n)
ragge
1.1
145 {
ragge
1.17
146         static char pt[] = { 00'b''b''w''w''l''l'00,
147             'q''q''f''d' };
148         TWORD t = n->n_type;
149
150         if (ISPTR(t))
151                 t = UNSIGNED;
152
153         if (t > DOUBLE || pt[t] == 0)
154                 comperr("prtype: bad type");
155         putchar(pt[t]);
156 }
157
158 /*
159  * Emit conversions as given by the following table. Dest is always reg,
160  *   if it should be something else let peephole optimizer deal with it.
161  *   This code ensures type correctness in 32-bit registers.
162  *   XXX is that necessary?
163  *
164  * From                         To
165  *       char   uchar  short  ushort int    uint   ll    ull   float double
166  * char  movb   movb   cvtbw  cvtbw  cvtbl  cvtbl  A     A     cvtbf cvtbd
167  * uchar movb   movb   movzbw movzbw movzbl movzbl B     B     G     G
168  * short movb   movb   movw   movw   cvtwl  cvtwl  C(A)  C(A)  cvtwf cvtwd
169  * ushrt movb   movb   movw   movw   movzwl movzwl D(B)  D(B)  H     H
170  * int   movb   movb   movw   movw   movl   movl   E     E     cvtlf cvtld
171  * uint  movb   movb   movw   movw   movl   movl   F     F     I     I
172  * ll    movb   movb   movw   movw   movl   movl   movq  movq  J     K
173  * ull   movb   movb   movw   movw   movl   movl   movq  movq  L     M
174  * float cvtfb  cvtfb  cvtfw  cvtfw  cvtfl  cvtfl  N     O     movf  cvtfd
175  * doubl cvtdb  cvtdb  cvtdw  cvtdw  cvtdl  cvtdl  P     Q     cvtdf movd
176  *
177  *  A: cvtbl + sign extend
178  *  B: movzbl + zero extend
179  *  G: movzbw + cvtwX
180  *  H: movzwl + cvtwX
181  *  I: cvtld + addX
182  *  J: call __floatdisf
183  *  K: call __floatdidf
184  *  L: xxx + call __floatdisf
185  *  M: xxx + call __floatdidf
186  *  N: call __fixsfdi
187  *  O: call __fixunssfdi
188  *  P: call __fixdfdi
189  *  Q: call __fixunsdfdi
190  */
191
192 #define MVD     1 /* mov + dest type */
193 #define CVT     2 /* cvt + src type + dst type */
194 #define MVZ     3 /* movz + src type + dst type */
195 #define CSE     4 /* cvt + src type + l + sign extend upper */
196 #define MZE     5 /* movz + src type + l + zero extend upper */
197 #define MLE     6 /* movl + sign extend upper */
198 #define MLZ     7 /* movl + zero extend upper */
199 #define MZC     8 /* movz + cvt */
200
201 static char scary[][10] = {
202         { MVDMVDCVTCVTCVTCVTCSECSECVTCVT },
203         { MVDMVDMVZMVZMVZMVZMZEMZEMZCMZC },
204         { MVDMVDMVDMVDCVTCVTCSECSECVTCVT },
205         { MVDMVDMVDMVDMVZMVZMZEMZEMZCMZC },
206         { MVDMVDMVDMVDMVDMVDMLEMLECVTCVT },
207         { MVDMVDMVDMVDMVZMVZMLZMLZ'I''I' },
208         { MVDMVDMVDMVDMVDMVDMVDMVD'J''K' },
209         { MVDMVDMVDMVDMVDMVDMVDMVD'L''M' },
210         { CVTCVTCVTCVTCVTCVT'N''O'MVDCVT },
211         { CVTCVTCVTCVTCVTCVT'P''Q'CVTMVD },
212 };
213
214 static void
215 sconv(NODE *p)
216 {
217         NODE *l = p->n_left;
218         TWORD tstd;
219         int o;
220
221         /*
222          * Source node may be in register or memory.
223          * Result is always in register.
224          */
225         ts = l->n_type;
226         if (ISPTR(ts))
227                 ts = UNSIGNED;
228         td = p->n_type;
229         ts = ts < LONG ? ts-2 : ts-4;
230         td = td < LONG ? td-2 : td-4;
231
232         o = scary[ts][td];
233         switch (o) {
234         case MLE:
235         case MLZ:
236         case MVD:
237                 expand(pINAREG|INBREG"\tmovZL AL,A1\n");
238                 break;
239
240         case CSE:
241                 expand(pINAREG|INBREG"\tcvtZLl AL,A1\n");
242                 break;
ragge
1.1
243
ragge
1.17
244         case CVT:
245                 expand(pINAREG|INBREG"\tcvtZLZR AL,A1\n");
246                 break;
ragge
1.1
247
ragge
1.17
248         case MZE:
249                 expand(pINAREG|INBREG"\tmovzZLl AL,A1\n");
250                 break;
ragge
1.1
251
ragge
1.17
252         case MVZ:
253                 expand(pINAREG|INBREG"\tmovzZLZR AL,A1\n");
254                 break;
ragge
1.1
255
ragge
1.17
256         case MZC:
257                 expand(pINAREG|INBREG"\tmovzZLl AL,A1\n");
258                 expand(pINAREG|INBREG"\tcvtlZR A1,A1\n");
259                 break;
ragge
1.1
260
ragge
1.17
261         default:
262                 comperr("unsupported conversion %d"o);
263         }
264         switch (o) {
265         case MLE:
266         case CSE:
267                 expand(pINBREG"\tashl $-31,A1,U1\n");
268                 break;
269         case MLZ:
270         case MZE:
271                 expand(pINAREG|INBREG"\tclrl U1\n");
272                 break;
273         }
ragge
1.1
274 }
275
ragge
1.16
276 /*
ragge
1.18
277  * Assign a constant from p to q.  Both are expected to be leaves by now.
278  * This is for 64-bit integers.
279  */
280 static void
281 casg64(NODE *p)
282 {
283         NODE *l, *r;
284         char *str;
285         int mneg = 1;
286         
287         l = p->n_left;
288         r = p->n_right;
289
290 #ifdef PCC_DEBUG
291         if (r->n_op != ICON)
292                 comperr("casg");
293 #endif
294         if (r->n_name[0] != '\0') {
295                 /* named constant, nothing to do */
296                 str = "movq\tAR,AL";
297                 mneg = 0;
298         } else if (r->n_lval == 0) {
299                 str = "clrq\tAL";
300                 mneg = 0;
301         } else if (r->n_lval < 0) {
302                 if (r->n_lval >= -63) {
303                         r->n_lval = -r->n_lval;
304                         str = "mnegl\tAR,AL";
305                 } else if (r->n_lval >= -128) {
306                         str = "cvtbl\tAR,AL";
307                 } else if (r->n_lval >= -32768) {
308                         str = "cvtwl\tAR,AL";
309                 } else if (r->n_lval >= -4294967296LL) {
310                         str = "movl\tAR,AL";
311                 } else {
312                         str = "movq\tAR,AL";
313                         mneg = 0;
314                 }
315         } else {
316                 mneg = 0;
317                 if (r->n_lval <= 63 || r->n_lval > 4294967295) {
318                         str = "movq\tAR,AL";
319                 } else if (r->n_lval <= 255) {
320                         str = "movzbl\tAR,AL\n\tclrl\tUL";
321                 } else if (r->n_lval <= 65535) {
322                         str = "movzwl\tAR,AL\n\tclrl\tUL";
323                 } else /* if (r->n_lval <= 4294967295) */ {
324                         str = "movl\tAR,AL\n\tclrl\tUL";
325                 }
326         }
327         expand(pFOREFFstr);
328         if (mneg)
329                 expand(pFOREFF"\tmnegl $-1,UL\n");
330 }
331
332 /*
333  * Assign a constant from p to q.  Both are expected to be leaves by now.
334  * This is only for 32-bit integer types.
335  */
336 static void
337 casg(NODE *p)
338 {
339         NODE *l, *r;
340         char *str;
341         
342         l = p->n_left;
343         r = p->n_right;
344
345 #ifdef PCC_DEBUG
346         if (r->n_op != ICON)
347                 comperr("casg");
348 #endif
349         if (r->n_name[0] != '\0') {
350                 /* named constant, nothing to do */
351                 str = "movZL\tAR,AL";
352         } else if (r->n_lval == 0) {
353                 str = "clrZL\tAL";
354         } else if (r->n_lval < 0) {
355                 if (r->n_lval >= -63) {
356                         r->n_lval = -r->n_lval;
357                         str = "mnegZL\tAR,AL";
358                 } else if (r->n_lval >= -128) {
359                         str = "cvtbZL\tAR,AL";
360                 } else if (r->n_lval >= -32768) {
361                         str = "cvtwZL\tAR,AL";
362                 } else
363                         str = "movZL\tAR,AL";
364         } else {
365                 if (r->n_lval <= 63 || r->n_lval > 65535) {
366                         str = "movZL\tAR,AL";
367                 } else if (r->n_lval <= 255) {
368                         str = "movzbZL\tAR,AL";
369                 } else /* if (r->n_lval <= 65535) */ {
370                         str = "movzwZL\tAR,AL";
371                 }
372         }
373         expand(pFOREFFstr);
374 }
375
376 /*
ragge
1.16
377  * Emit code to compare two longlong numbers.
378  */
379 static void
380 twollcomp(NODE *p)
381 {
382         int u;
383         int s = getlab2();
384         int e = p->n_label;
385         int cb1cb2;
386
387         u = p->n_op;
388         switch (p->n_op) {
389         case NE:
390                 cb1 = 0;
391                 cb2 = NE;
392                 break;
393         case EQ:
394                 cb1 = NE;
395                 cb2 = 0;
396                 break;
397         case LE:
398         case LT:
399                 u += (ULE-LE);
400                 /* FALLTHROUGH */
401         case ULE:
402         case ULT:
403                 cb1 = GT;
404                 cb2 = LT;
405                 break;
406         case GE:
407         case GT:
408                 u += (ULE-LE);
409                 /* FALLTHROUGH */
410         case UGE:
411         case UGT:
412                 cb1 = LT;
413                 cb2 = GT;
414                 break;
415         
416         default:
417                 cb1 = cb2 = 0/* XXX gcc */
418         }
419         if (p->n_op >= ULE)
420                 cb1 += 4cb2 += 4;
421         expand(p0"  cmpl UR,UL\n");
422         if (cb1cbgen(cb1s);
423         if (cb2cbgen(cb2e);
424         expand(p0"  cmpl AL,AR\n");
425         cbgen(ue);
426         deflab(s);
427 }
428
429
ragge
1.2
430 void
ragge
1.18
431 zzzcode(NODE *pint c)
432 {
433         NODE *l, *r;
ragge
1.2
434         int m;
ragge
1.17
435         char *ch;
ragge
1.1
436
ragge
1.18
437         switch (c) {
ragge
1.1
438         case 'N':  /* logical ops, turned into 0-1 */
439                 /* use register given by register 1 */
ragge
1.11
440                 cbgen0m=getlab2());
ragge
1.2
441                 deflabp->n_label );
442                 printf"       clrl    %s\n"rnames[getlrp'1' )->n_rval] );
ragge
1.1
443                 deflabm );
444                 return;
445
ragge
1.18
446         case 'A'/* Assign a constant directly to a memory position */
447                 printf("\t");
448                 if (p->n_type < LONG || ISPTR(p->n_type))
449                         casg(p);
ragge
1.1
450                 else
ragge
1.18
451                         casg64(p);
452                 printf("\n");
453                 break;
ragge
1.1
454
ragge
1.16
455         case 'B'/* long long compare */
456                 twollcomp(p);
457                 break;
458
ragge
1.1
459         case 'C':       /* num words pushed on arg stack */
ragge
1.3
460                 printf("$%d"p->n_qual);
461                 break;
ragge
1.1
462
463         case 'D':       /* INCR and DECR */
ragge
1.2
464                 zzzcode(p->n_left'A');
ragge
1.1
465                 printf("\n      ");
466
ragge
1.2
467 #if 0
ragge
1.1
468         case 'E':       /* INCR and DECR, FOREFF */
ragge
1.2
469                 if (p->n_right->n_lval == 1)
ragge
1.1
470                         {
ragge
1.2
471                         printf("%s", (p->n_op == INCR ? "inc" : "dec") );
472                         prtype(p->n_left);
ragge
1.1
473                         printf("        ");
ragge
1.2
474                         adrput(stdoutp->n_left);
ragge
1.1
475                         return;
476                         }
ragge
1.2
477                 printf("%s", (p->n_op == INCR ? "add" : "sub") );
478                 prtype(p->n_left);
ragge
1.1
479                 printf("2       ");
ragge
1.2
480                 adrput(stdoutp->n_right);
ragge
1.1
481                 printf(",");
ragge
1.2
482                 adrput(p->n_left);
ragge
1.1
483                 return;
ragge
1.2
484 #endif
ragge
1.1
485
486         case 'F':       /* register type of right operand */
487                 {
488                 register NODE *n;
489                 extern int xdebug;
490                 register int ty;
491
492                 n = getlrp'R' );
ragge
1.2
493                 ty = n->n_type;
ragge
1.1
494
495                 if (xdebugprintf("->%d<-"ty);
496
497                 if ( ty==DOUBLEprintf("d");
498                 else if ( ty==FLOAT ) printf("f");
499                 else printf("l");
500                 return;
501                 }
502
ragge
1.17
503         case 'G'/* emit conversion instructions */
504                 sconv(p);
505                 break;
506
ragge
1.3
507         case 'J'/* jump or ret? */
508                 {
509                         struct interpass *ip =
ragge
1.12
510                             DLIST_PREV((struct interpass *)p2env.eppqelem);
ragge
1.3
511                         if (ip->type != IP_DEFLAB ||
512                             ip->ip_lbl != getlr(p'L')->n_lval)
513                                 expand(pFOREFF"jbr  LL");
514                         else
515                                 printf("ret");
516                 }
517                 break;
518
ragge
1.1
519         case 'L':       /* type of left operand */
520         case 'R':       /* type of right operand */
521                 {
522                 register NODE *n;
523                 extern int xdebug;
524
525                 n = getlr ( pc);
ragge
1.2
526                 if (xdebugprintf("->%d<-"n->n_type);
ragge
1.1
527
528                 prtype(n);
529                 return;
530                 }
531
ragge
1.17
532         case 'O'/* print out emulated ops */
533                 expand(pFOREFF"\tmovq       AR,-(%sp)\n");
534                 expand(pFOREFF"\tmovq       AL,-(%sp)\n");
535                 if (p->n_op == DIV && p->n_type == ULONGLONGch = "udiv";
536                 else if (p->n_op == DIVch = "div";
537                 else if (p->n_op == MOD && p->n_type == ULONGLONGch = "umod";
538                 else if (p->n_op == MODch = "mod";
539                 else ch = 0comperr("ZO");
540                 printf("\tcalls $4,__%sdi3\n"ch);
541                 break;
542
543
ragge
1.1
544         case 'Z':       /* complement mask for bit instr */
ragge
1.2
545                 printf("$%Ld", ~p->n_right->n_lval);
ragge
1.1
546                 return;
547
548         case 'U':       /* 32 - n, for unsigned right shifts */
ragge
1.2
549                 printf("$" CONFMT32 - p->n_right->n_lval );
ragge
1.1
550                 return;
551
552         case 'T':       /* rounded structure length for arguments */
553                 {
554                 int size;
555
ragge
1.2
556                 size = p->n_stsize;
ragge
1.1
557                 SETOFFsize4);
558                 printf("$%d"size);
559                 return;
560                 }
561
562         case 'S':  /* structure assignment */
563                 {
ragge
1.2
564                         register int size;
ragge
1.1
565
ragge
1.14
566                         size = p->n_stsize;
ragge
1.2
567                         l = r = NULL/* XXX gcc */
568                         ifp->n_op == STASG ){
569                                 l = p->n_left;
570                                 r = p->n_right;
ragge
1.1
571
572                                 }
ragge
1.14
573                         else ifp->n_op == STARG ){
574                                 /* store an arg into a temporary */
575                                 printf("\tsubl2 $%d,%%sp\n",
576                                     size < 4 ? 4 : size);
577                                 l = mklnode(OREG0SPINT);
ragge
1.2
578                                 r = p->n_left;
ragge
1.1
579                                 }
580                         else cerror"STASG bad" );
581
ragge
1.2
582                         ifr->n_op == ICON ) r->n_op = NAME;
583                         else ifr->n_op == REG ) r->n_op = OREG;
584                         else ifr->n_op != OREG ) cerror"STASG-r" );
ragge
1.1
585
586                         ifsize <= 0 || size > 65535 )
587                                 cerror("structure size <0=0 or >65535");
588
589                         switch(size) {
590                                 case 1:
591                                         printf("        movb    ");
592                                         break;
593                                 case 2:
594                                         printf("        movw    ");
595                                         break;
596                                 case 4:
597                                         printf("        movl    ");
598                                         break;
599                                 case 8:
600                                         printf("        movq    ");
601                                         break;
602                                 default:
603                                         printf("        movc3   $%d,"size);
604                                         break;
605                         }
ragge
1.2
606                         adrput(stdoutr);
ragge
1.1
607                         printf(",");
ragge
1.2
608                         adrput(stdoutl);
ragge
1.1
609                         printf("\n");
610
ragge
1.2
611                         ifr->n_op == NAME ) r->n_op = ICON;
612                         else ifr->n_op == OREG ) r->n_op = REG;
ragge
1.14
613                         if (p->n_op == STARG)
614                                 tfree(l);
ragge
1.1
615
616                         }
617                 break;
618
619         default:
ragge
1.2
620                 comperr("illegal zzzcode '%c'"c);
ragge
1.1
621         }
ragge
1.18
622 }
ragge
1.1
623
ragge
1.2
624 void
625 rmoveint rt,int  rsTWORD t ){
ragge
1.1
626         printf"       %s      %s,%s\n",
627                 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
628                 rnames[rs], rnames[rt] );
629         }
630
ragge
1.2
631 #if 0
ragge
1.1
632 setregs(){ /* set up temporary registers */
633         fregs = 6;      /* tbl- 6 free regs on VAX (0-5) */
634         ;
635         }
636
637 szty(t){ /* size, in registers, needed to hold thing of type t */
638         return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
639         }
ragge
1.2
640 #endif
ragge
1.1
641
ragge
1.2
642 int
ragge
1.1
643 rewfldp ) NODE *p; {
644         return(1);
645         }
646
ragge
1.2
647 #if 0
ragge
1.1
648 callreg(pNODE *p; {
649         returnR0 );
650         }
651
652 basep ) register NODE *p; {
653         register int o = p->op;
654
655         if( (o==ICON && p->name[0] != '\0')) return100 ); /* ie no base reg */
656         ifo==REG ) returnp->rval );
657     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
658                 returnp->left->rval );
659     ifo==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
660                 returnp->rval + 0200*1 );
661         ifo==INCR && p->left->op==REG ) returnp->left->rval + 0200*2 );
662         ifo==ASG MINUS && p->left->op==REGreturnp->left->rval + 0200*4 );
663         ifo==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
664           && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
665                 returnp->left->left->rval + 0200*(1+2) );
666         return( -1 );
667         }
668
669 offsetptyl ) register NODE *pint tyl; {
670
671         iftyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) returnp->rval );
672         if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
673               (p->right->op==ICON && p->right->name[0]=='\0')
674               && (1<<p->right->lval)==tyl))
675                 returnp->left->rval );
676         return( -1 );
677         }
ragge
1.2
678 #endif
ragge
1.1
679
ragge
1.2
680 #if 0
681 void
ragge
1.1
682 makeor2pqboregister NODE *p, *qregister int bo; {
683         register NODE *t;
684         NODE *f;
685
ragge
1.2
686         p->n_op = OREG;
687         f = p->n_left;  /* have to free this subtree later */
ragge
1.1
688
689         /* init base */
ragge
1.2
690         switch (q->n_op) {
ragge
1.1
691                 case ICON:
692                 case REG:
693                 case OREG:
694                         t = q;
695                         break;
696
697                 case MINUS:
ragge
1.2
698                         q->n_right->n_lval = -q->n_right->n_lval;
ragge
1.1
699                 case PLUS:
ragge
1.2
700                         t = q->n_right;
ragge
1.1
701                         break;
702
ragge
1.2
703                 case UMUL:
704                         t = q->n_left->n_left;
ragge
1.1
705                         break;
706
707                 default:
708                         cerror("illegal makeor2");
ragge
1.2
709                         t = NULL/* XXX gcc */
ragge
1.1
710         }
711
ragge
1.2
712         p->n_lval = t->n_lval;
713         p->n_name = t->n_name;
ragge
1.1
714
715         /* init offset */
ragge
1.2
716         p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
ragge
1.1
717
718         tfree(f);
719         return;
720         }
721
ragge
1.2
722 int
ragge
1.1
723 canaddrp ) NODE *p; {
ragge
1.2
724         register int o = p->n_op;
ragge
1.1
725
ragge
1.8
726         ifo==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_leftSTARNM|SOREG)) ) return(1);
ragge
1.1
727         return(0);
728         }
729
730 shltypeop ) register NODE *p; {
ragge
1.8
731         returno== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_leftSTARNM|SOREG)) );
ragge
1.1
732         }
ragge
1.2
733 #endif
ragge
1.1
734
ragge
1.2
735 int
stefan
1.6
736 fldexpand(NODE *pint cookiechar **cp)
737 {
738         return 0;
739 }
740
741 int
ragge
1.1
742 flshapep ) register NODE *p; {
ragge
1.2
743         returnp->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
744                 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
ragge
1.1
745         }
746
ragge
1.2
747 int
ragge
1.1
748 shtempp ) register NODE *p; {
ragge
1.2
749         ifp->n_op == STARG ) p = p->n_left;
ragge
1.8
750         returnp->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_leftSTARNM|SOREG)) );
ragge
1.1
751         }
752
ragge
1.16
753 /*
754  * Shape matches for UMUL.  Cooperates with offstar().
755  */
756 int
757 shumul(NODE *pint shape)
758 {
759
760         if (x2debug)
761                 printf("shumul(%p)\n"p);
762
763         /* Turns currently anything into OREG on vax */
764         if (shape & SOREG)
765                 return SROREG;
766         return SRNOPE;
767 }
768
769
770 #ifdef notdef
ragge
1.2
771 int
ragge
1.8
772 shumulpshape ) register NODE *pint shape; {
ragge
1.2
773         register int o;
ragge
1.1
774         extern int xdebug;
775
776         if (xdebug) {
ragge
1.2
777                  printf("\nshumul:op=%d,lop=%d,rop=%d"p->n_opp->n_left->n_opp->n_right->n_op);
778                 printf(" prname=%s,plty=%d, prlval=%lld\n"p->n_right->n_namep->n_left->n_typep->n_right->n_lval);
ragge
1.1
779                 }
780
781
ragge
1.2
782         o = p->n_op;
ragge
1.8
783         ifo == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
784                 if (shape & STARNM)
785                         return SRDIR;
ragge
1.1
786
787         if( ( o == INCR || o == ASG MINUS ) &&
ragge
1.2
788             ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
789             p->n_right->n_name[0] == '\0' )
ragge
1.1
790                 {
ragge
1.2
791                 switch (p->n_left->n_type)
ragge
1.1
792                         {
793                         case CHAR|PTR:
794                         case UCHAR|PTR:
795                                 o = 1;
796                                 break;
797
798                         case SHORT|PTR:
799                         case USHORT|PTR:
800                                 o = 2;
801                                 break;
802
803                         case INT|PTR:
804                         case UNSIGNED|PTR:
805                         case LONG|PTR:
806                         case ULONG|PTR:
807                         case FLOAT|PTR:
808                                 o = 4;
809                                 break;
810
811                         case DOUBLE|PTR:
812                                 o = 8;
813                                 break;
814
815                         default:
ragge
1.2
816                                 if ( ISPTR(p->n_left->n_type) ) {
ragge
1.1
817                                         o = 4;
818                                         break;
819                                         }
820                                 else return(0);
821                         }
ragge
1.2
822                 returnp->n_right->n_lval == o ? STARREG : 0);
ragge
1.1
823                 }
824
ragge
1.8
825         returnSRNOPE );
ragge
1.1
826         }
ragge
1.16
827 #endif
ragge
1.1
828
ragge
1.2
829 void
ragge
1.1
830 adrconval ) CONSZ val; {
831         printf"$" );
832         printfCONFMTval );
833         }
834
ragge
1.2
835 void
836 conput(FILE *fpNODE *p)
837 {
838         switchp->n_op ){
ragge
1.1
839
840         case ICON:
841                 aconp );
842                 return;
843
844         case REG:
ragge
1.2
845                 printf"%s"rnames[p->n_rval] );
ragge
1.1
846                 return;
847
848         default:
849                 cerror"illegal conput" );
850                 }
851         }
852
ragge
1.2
853 void
ragge
1.1
854 insputp ) register NODE *p; {
855         cerror"insput" );
856         }
857
ragge
1.16
858 /*
859  * Write out the upper address, like the upper register of a 2-register
860  * reference, or the next memory location.
861  */
ragge
1.2
862 void
ragge
1.16
863 upput(NODE *pint size)
864 {
865
866         size /= SZCHAR;
867         switch (p->n_op) {
868         case REG:
869                 fprintf(stdout"%s"rnames[regno(p)-16+1]);
870                 break;
871
872         case NAME:
873         case OREG:
874                 p->n_lval += size;
875                 adrput(stdoutp);
876                 p->n_lval -= size;
877                 break;
878         case ICON:
879                 fprintf(stdout"$" CONFMTp->n_lval >> 32);
880                 break;
881         default:
882                 comperr("upput bad op %d size %d"p->n_opsize);
ragge
1.1
883         }
ragge
1.16
884 }
ragge
1.1
885
ragge
1.2
886 void
887 adrput(FILE *fpNODE *p)
888 {
ragge
1.1
889         register int r;
890         /* output an address, with offsets, from p */
891
ragge
1.2
892         ifp->n_op == FLD ){
893                 p = p->n_left;
ragge
1.1
894                 }
ragge
1.2
895         switchp->n_op ){
ragge
1.1
896
897         case NAME:
898                 aconp );
899                 return;
900
901         case ICON:
902                 /* addressable value of the constant */
ragge
1.2
903                 if (p->n_name[0] == '\0'/* uses xxxab */
904                         printf("$");
905                 acon(p);
ragge
1.1
906                 return;
907
908         case REG:
ragge
1.2
909                 printf"%s"rnames[p->n_rval] );
ragge
1.1
910                 return;
911
912         case OREG:
ragge
1.2
913                 r = p->n_rval;
ragge
1.1
914                 ifR2TEST(r) ){ /* double indexing */
915                         register int flags;
916
917                         flags = R2UPK3(r);
918                         ifflags & 1 ) printf("*");
919                         ifflags & 4 ) printf("-");
ragge
1.2
920                         ifp->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
ragge
1.1
921                         ifR2UPK1(r) != 100printf"(%s)"rnames[R2UPK1(r)] );
922                         ifflags & 2 ) printf("+");
923                         printf"[%s]"rnames[R2UPK2(r)] );
924                         return;
925                         }
926                 ifr == AP ){  /* in the argument region */
ragge
1.2
927                         ifp->n_lval <= 0 || p->n_name[0] != '\0' ) werror"bad arg temp" );
928                         printfCONFMTp->n_lval );
ragge
1.17
929                         printf"(%%ap)" );
ragge
1.1
930                         return;
931                         }
ragge
1.2
932                 ifp->n_lval != 0 || p->n_name[0] != '\0'aconp );
933                 printf"(%s)"rnames[p->n_rval] );
ragge
1.1
934                 return;
935
ragge
1.2
936         case UMUL:
ragge
1.1
937                 /* STARNM or STARREG found */
938                 iftshape(pSTARNM) ) {
939                         printf"*" );
ragge
1.2
940                         adrput(0,  p->n_left);
ragge
1.1
941                         }
942                 else {  /* STARREG - really auto inc or dec */
943                         register NODE *q;
944
945 /* tbl
ragge
1.2
946                         p = p->n_left;
947                         p->n_left->n_op = OREG;
948                         if( p->n_op == INCR ) {
949                                 adrput( p->n_left );
ragge
1.1
950                                 printf( "+" );
951                                 }
952                         else {
953                                 printf( "-" );
ragge
1.2
954                                 adrput( p->n_left );
ragge
1.1
955                                 }
956    tbl */
ragge
1.2
957 #ifdef notyet
958                         printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
959                                 rnames[p->n_left->n_left->n_rval], 
960                                 (p->n_left->n_op==INCR ? '+' : '\0') );
961 #else
962                         printf("%c(%s)%c"'-',
963                                 rnames[p->n_left->n_left->n_rval], 
964                                 '\0' );
965 #endif
966                         p->n_op = OREG;
967                         p->n_rval = p->n_left->n_left->n_rval;
968                         q = p->n_left;
969 #ifdef notyet
970
971                         p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
972 #else
973                         p->n_lval = 0;
974 #endif
975                         p->n_name[0] = '\0';
ragge
1.1
976                         tfree(q);
977                 }
978                 return;
979
980         default:
981                 cerror"illegal address" );
982                 return;
983         }
984
ragge
1.2
985 }
ragge
1.1
986
987 /*
ragge
1.2
988  * print out a constant
989  */
990 void
991 acon(NODE *p)
992 {
ragge
1.1
993
ragge
1.2
994         if (p->n_name[0] == '\0') {
995                 printf(CONFMTp->n_lval);
996         } else ifp->n_lval == 0 ) {
997                 printf("%s"p->n_name);
998         } else {
999                 printf("%s+"p->n_name);
1000                 printf(CONFMTp->n_lval);
ragge
1.1
1001         }
ragge
1.2
1002 }
ragge
1.1
1003
ragge
1.2
1004 #if 0
ragge
1.1
1005 genscallpcookie ) register NODE *p; {
1006         /* structure valued call */
1007         returngencallpcookie ) );
1008         }
1009
1010 /* tbl */
1011 int gc_numbytes;
1012 /* tbl */
1013
1014 gencallpcookie ) register NODE *p; {
1015         /* generate the call given by p */
1016         register NODE *p1, *ptemp;
1017         register temptemp1;
1018         register m;
1019
1020         ifp->right ) temp = argsizep->right );
1021         else temp = 0;
1022
1023         ifp->op == STCALL || p->op == UNARY STCALL ){
1024                 /* set aside room for structure return */
1025
1026                 ifp->stsize > temp ) temp1 = p->stsize;
1027                 else temp1 = temp;
1028                 }
1029
1030         iftemp > maxargs ) maxargs = temp;
1031         SETOFF(temp1,4);
1032
1033         ifp->right ){ /* make temp node, put offset in, and generate args */
1034                 ptemp = talloc();
1035                 ptemp->op = OREG;
1036                 ptemp->lval = -1;
1037                 ptemp->rval = SP;
1038                 ptemp->name[0] = '\0';
1039                 ptemp->rall = NOPREF;
1040                 ptemp->su = 0;
1041                 genargsp->rightptemp );
ragge
1.2
1042                 nfree(ptemp);
ragge
1.1
1043                 }
1044
1045         p1 = p->left;
1046         ifp1->op != ICON ){
1047                 ifp1->op != REG ){
1048                         ifp1->op != OREG || R2TEST(p1->rval) ){
1049                                 ifp1->op != NAME ){