Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120322185617

Diff

Diff from 1.28 to:

Annotations

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

Annotated File View

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