Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120901091746

Diff

Diff from 1.34 to:

Annotations

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

Annotated File View

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