1 /*        Id: local2.c,v 1.42 2015/01/04 19:17:23 ragge Exp           */
2 /*        $NetBSD: local2.c,v 1.1.1.7 2016/02/09 20:28:36 plunky Exp $          */
3 /*
4  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * Redistributions of source code and documentation must retain the above
11  * copyright notice, this list of conditions and the following disclaimer.
12  * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditionsand the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * All advertising materials mentioning features or use of this software
16  * must display the following acknowledgement:
17  *        This product includes software developed or owned by Caldera
18  *        International, Inc.
19  * Neither the name of Caldera International, Inc. nor the names of other
20  * contributors may be used to endorse or promote products derived from
21  * this software without specific prior written permission.
22  *
23  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
24  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
25  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
28  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
32  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 # include "pass2.h"
38 # include "ctype.h"
39 /* a lot of the machine dependent parts of the second pass */
40 
41 static void prtype(NODE *n);
42 static void acon(NODE *p);
43 
44 /*
45  * Print out the prolog assembler.
46  * addto and regoff are already calculated.
47  */
48 void
prologue(struct interpass_prolog * ipp)49 prologue(struct interpass_prolog *ipp)
50 {
51           printf("  .word 0x%llx\n", (unsigned long long)ipp->ipp_regs[0]);
52           if (p2maxautooff)
53                     printf("  subl2 $%d,%%sp\n", p2maxautooff);
54           if (pflag) {
55                     int i = getlab2();
56                     printf("\tmovab\t" LABFMT ",%%r0\n", i);
57                     printf("\tjsb\t__mcount\n");
58                     printf("\t.data\n");
59                     printf("\t.align  2\n");
60                     printf(LABFMT ":\t.long\t0\n", i);
61                     printf("\t.text\n");
62           }
63 }
64 
65 /*
66  * Called after all instructions in a function are emitted.
67  * Generates code for epilog here.
68  */
69 void
eoftn(struct interpass_prolog * ipp)70 eoftn(struct interpass_prolog *ipp)
71 {
72           if (ipp->ipp_ip.ip_lbl == 0)
73                     return; /* no code needs to be generated */
74           printf("  ret\n");
75 }
76 
77 struct hoptab { int opmask; char * opstring; } ioptab[] = {
78 
79           { PLUS,   "add", },
80           { MINUS,  "sub", },
81           { MUL,    "mul", },
82           { DIV,    "div", },
83           { OR,     "bis", },
84           { ER,     "xor", },
85           { AND,    "bic", },
86           { -1, ""     },
87 };
88 
89 void
hopcode(f,o)90 hopcode( f, o ){
91           /* output the appropriate string from the above table */
92 
93           register struct hoptab *q;
94 
95           for( q = ioptab;  q->opmask>=0; ++q ){
96                     if( q->opmask == o ){
97                               printf( "%s", q->opstring );
98 /* tbl
99                               if( f == 'F' ) printf( "e" );
100                               else if( f == 'D' ) printf( "d" );
101    tbl */
102 /* tbl */
103                               switch( f ) {
104                                         case 'L':
105                                         case 'W':
106                                         case 'B':
107                                         case 'D':
108                                         case 'F':
109                                                   printf("%c", tolower(f));
110                                                   break;
111 
112                                         }
113 /* tbl */
114                               return;
115                               }
116                     }
117           cerror( "no hoptab for %s", opst[o] );
118           }
119 
120 char *
121 rnames[] = {  /* keyed to register number tokens */
122 
123           "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
124           "%r6", "%r7", "%r8", "%r9", "%r10", "%r11",
125           "%ap", "%fp", "%sp", "%pc",
126           /* The concatenated regs has the name of the lowest */
127           "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
128           "%r6", "%r7", "%r8", "%r9", "%r10"
129           };
130 
131 int
tlen(NODE * p)132 tlen(NODE *p)
133 {
134           switch(p->n_type) {
135           case CHAR:
136           case UCHAR:
137                     return(1);
138 
139           case SHORT:
140           case USHORT:
141                     return(2);
142 
143           case DOUBLE:
144           case LONGLONG:
145           case ULONGLONG:
146                     return(8);
147 
148           default:
149                     return(4);
150           }
151 }
152 
153 void
prtype(NODE * n)154 prtype(NODE *n)
155 {
156           static char pt[] = { 0, 0, 'b', 'b', 'w', 'w', 'l', 'l', 0, 0,
157               'q', 'q', 'f', 'd' };
158           TWORD t = n->n_type;
159 
160           if (ISPTR(t))
161                     t = UNSIGNED;
162 
163           if (t > DOUBLE || pt[t] == 0)
164                     comperr("prtype: bad type");
165           putchar(pt[t]);
166 }
167 
168 /*
169  * Emit conversions as given by the following table. Dest is always reg,
170  *   if it should be something else let peephole optimizer deal with it.
171  *   This code ensures type correctness in 32-bit registers.
172  *   XXX is that necessary?
173  *
174  * From                                 To
175  *         char   uchar  short  ushort int    uint   ll    ull   float double
176  * char  movb   movb   cvtbw  cvtbw  cvtbl  cvtbl  A     A     cvtbf cvtbd
177  * uchar movb   movb   movzbw movzbw movzbl movzbl B     B     G     G
178  * short movb   movb   movw   movw   cvtwl  cvtwl  C(A)  C(A)  cvtwf cvtwd
179  * ushrt movb   movb   movw   movw   movzwl movzwl D(B)  D(B)  H     H
180  * int   movb   movb   movw   movw   movl   movl   E     E     cvtlf cvtld
181  * uint  movb   movb   movw   movw   movl   movl   F     F     I     I
182  * ll    movb   movb   movw   movw   movl   movl   movq  movq  J     K
183  * ull   movb   movb   movw   movw   movl   movl   movq  movq  L     M
184  * float cvtfb  cvtfb  cvtfw  cvtfw  cvtfl  cvtfl  N     O     movf  cvtfd
185  * doubl cvtdb  cvtdb  cvtdw  cvtdw  cvtdl  cvtdl  P     Q     cvtdf movd
186  *
187  *  A: cvtbl + sign extend
188  *  B: movzbl + zero extend
189  *  G: movzbw + cvtwX
190  *  H: movzwl + cvtwX
191  *  I: cvtld + addX
192  *  J: call __floatdisf
193  *  K: call __floatdidf
194  *  L: xxx + call __floatdisf
195  *  M: xxx + call __floatdidf
196  *  N: call __fixsfdi
197  *  O: call __fixunssfdi
198  *  P: call __fixdfdi
199  *  Q: call __fixunsdfdi
200  */
201 
202 #define   MVD       1 /* mov + dest type */
203 #define   CVT       2 /* cvt + src type + dst type */
204 #define   MVZ       3 /* movz + src type + dst type */
205 #define   CSE       4 /* cvt + src type + l + sign extend upper */
206 #define   MZE       5 /* movz + src type + l + zero extend upper */
207 #define   MLE       6 /* movl + sign extend upper */
208 #define   MLZ       7 /* movl + zero extend upper */
209 #define   MZC       8 /* movz + cvt */
210 
211 static char scary[][10] = {
212           { MVD, MVD, CVT, CVT, CVT, CVT, CSE, CSE, CVT, CVT },
213           { MVD, MVD, MVZ, MVZ, MVZ, MVZ, MZE, MZE, MZC, MZC },
214           { MVD, MVD, MVD, MVD, CVT, CVT, CSE, CSE, CVT, CVT },
215           { MVD, MVD, MVD, MVD, MVZ, MVZ, MZE, MZE, MZC, MZC },
216           { MVD, MVD, MVD, MVD, MVD, MVD, MLE, MLE, CVT, CVT },
217           { MVD, MVD, MVD, MVD, MVD, MVD, MLZ, MLZ, 'I', 'I' },
218           { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'J', 'K' },
219           { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'L', 'M' },
220           { CVT, CVT, CVT, CVT, CVT, CVT, 'N', 'O', MVD, CVT },
221           { CVT, CVT, CVT, CVT, CVT, CVT, 'P', 'Q', CVT, MVD },
222 };
223 
224 static void
sconv(NODE * p)225 sconv(NODE *p)
226 {
227           NODE *l = p->n_left;
228           TWORD ts, td;
229           int o;
230 
231           /*
232            * Source node may be in register or memory.
233            * Result is always in register.
234            */
235           ts = l->n_type;
236           if (ISPTR(ts))
237                     ts = UNSIGNED;
238           td = p->n_type;
239           ts = ts < LONG ? ts-2 : ts-4;
240           td = td < LONG ? td-2 : td-4;
241 
242           o = scary[ts][td];
243           switch (o) {
244           case MLE:
245           case MLZ:
246                     expand(p, INAREG|INBREG, "\tmovl\tAL,A1\n");
247                     break;
248 
249           case MVD:
250                     if (l->n_op == REG && regno(l) == regno(getlr(p, '1')))
251                               break; /* unneccessary move */
252                     expand(p, INAREG|INBREG, "\tmovZR\tAL,A1\n");
253                     break;
254 
255           case CSE:
256                     expand(p, INAREG|INBREG, "\tcvtZLl\tAL,A1\n");
257                     break;
258 
259           case CVT:
260                     expand(p, INAREG|INBREG, "\tcvtZLZR\tAL,A1\n");
261                     break;
262 
263           case MZE:
264                     expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
265                     break;
266 
267           case MVZ:
268                     expand(p, INAREG|INBREG, "\tmovzZLZR\tAL,A1\n");
269                     break;
270 
271           case MZC:
272                     expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
273                     expand(p, INAREG|INBREG, "\tcvtlZR\tA1,A1\n");
274                     break;
275 
276           case 'I': /* unsigned to double */
277                     expand(p, INAREG|INBREG, "\tcvtld\tAL,A1\n");
278                     printf("\tjgeq\t1f\n");
279                     expand(p, INAREG|INBREG, "\taddd2\t$0d4.294967296e+9,A1\n");
280                     printf("1:\n");
281                     break;
282           default:
283                     comperr("unsupported conversion %d", o);
284           }
285           switch (o) {
286           case MLE:
287           case CSE:
288                     expand(p, INBREG, "\tashl\t$-31,A1,U1\n");
289                     break;
290           case MLZ:
291           case MZE:
292                     expand(p, INAREG|INBREG, "\tclrl\tU1\n");
293                     break;
294           }
295 }
296 
297 /*
298  * Assign a constant from p to q.  Both are expected to be leaves by now.
299  * This is for 64-bit integers.
300  */
301 static void
casg64(NODE * p)302 casg64(NODE *p)
303 {
304           NODE *l, *r;
305           char *str;
306           int mneg = 1;
307 
308           l = p->n_left;
309           r = p->n_right;
310 
311 #ifdef PCC_DEBUG
312           if (r->n_op != ICON)
313                     comperr("casg");
314 #endif
315           if (r->n_name[0] != '\0') {
316                     /* named constant, nothing to do */
317                     str = "movq\tAR,AL";
318                     mneg = 0;
319           } else if (r->n_lval == 0) {
320                     str = "clrq\tAL";
321                     mneg = 0;
322           } else if (r->n_lval < 0) {
323                     if (r->n_lval >= -63) {
324                               r->n_lval = -r->n_lval;
325                               str = "mnegl\tAR,AL";
326                     } else if (r->n_lval >= -128) {
327                               str = "cvtbl\tAR,AL";
328                     } else if (r->n_lval >= -32768) {
329                               str = "cvtwl\tAR,AL";
330                     } else if (r->n_lval >= -4294967296LL) {
331                               str = "movl\tAR,AL";
332                     } else {
333                               str = "movq\tAR,AL";
334                               mneg = 0;
335                     }
336           } else {
337                     mneg = 0;
338                     if (r->n_lval <= 63 || r->n_lval > 4294967295LL) {
339                               str = "movq\tAR,AL";
340                     } else if (r->n_lval <= 255) {
341                               str = "movzbl\tAR,AL\n\tclrl\tUL";
342                     } else if (r->n_lval <= 65535) {
343                               str = "movzwl\tAR,AL\n\tclrl\tUL";
344                     } else /* if (r->n_lval <= 4294967295) */ {
345                               str = "movl\tAR,AL\n\tclrl\tUL";
346                     }
347           }
348           expand(p, FOREFF, str);
349           if (mneg)
350                     expand(p, FOREFF, "\n\tmnegl $1,UL");
351 }
352 
353 /*
354  * Assign a constant from p to q.  Both are expected to be leaves by now.
355  * This is only for 32-bit integer types.
356  */
357 static void
casg(NODE * p)358 casg(NODE *p)
359 {
360           NODE *l, *r;
361           char *str;
362 
363           l = p->n_left;
364           r = p->n_right;
365 
366 #ifdef PCC_DEBUG
367           if (r->n_op != ICON)
368                     comperr("casg");
369 #endif
370           if (r->n_name[0] != '\0') {
371                     /* named constant, nothing to do */
372                     str = "movZL\tAR,AL";
373           } else if (r->n_lval == 0) {
374                     str = "clrZL\tAL";
375           } else if (r->n_lval < 0) {
376                     if (r->n_lval >= -63) {
377                               r->n_lval = -r->n_lval;
378                               str = "mnegZL\tAR,AL";
379                     } else if (r->n_lval >= -128) {
380                               if (l->n_type == CHAR)
381                                         str = "movb\tAR,AL";
382                               else
383                                         str = "cvtbZL\tAR,AL";
384                     } else if (r->n_lval >= -32768) {
385                               if (l->n_type == SHORT)
386                                         str = "movw\tAR,AL";
387                               else
388                                         str = "cvtwZL\tAR,AL";
389                     } else
390                               str = "movZL\tAR,AL";
391           } else {
392                     if (r->n_lval <= 63 || r->n_lval > 65535) {
393                               str = "movZL\tAR,AL";
394                     } else if (r->n_lval <= 255) {
395                               str = l->n_type < SHORT ?
396                                   "movb\tAR,AL" : "movzbZL\tAR,AL";
397                     } else /* if (r->n_lval <= 65535) */ {
398                               str = l->n_type < INT ?
399                                   "movw\tAR,AL" : "movzwZL\tAR,AL";
400                     }
401           }
402           expand(p, FOREFF, str);
403 }
404 
405 /*
406  * Emit code to compare two longlong numbers.
407  */
408 static void
twollcomp(NODE * p)409 twollcomp(NODE *p)
410 {
411           int u;
412           int s = getlab2();
413           int e = p->n_label;
414           int cb1, cb2;
415 
416           u = p->n_op;
417           switch (p->n_op) {
418           case NE:
419                     cb1 = 0;
420                     cb2 = NE;
421                     break;
422           case EQ:
423                     cb1 = NE;
424                     cb2 = 0;
425                     break;
426           case LE:
427           case LT:
428                     u += (ULE-LE);
429                     /* FALLTHROUGH */
430           case ULE:
431           case ULT:
432                     cb1 = GT;
433                     cb2 = LT;
434                     break;
435           case GE:
436           case GT:
437                     u += (ULE-LE);
438                     /* FALLTHROUGH */
439           case UGE:
440           case UGT:
441                     cb1 = LT;
442                     cb2 = GT;
443                     break;
444 
445           default:
446                     cb1 = cb2 = 0; /* XXX gcc */
447           }
448           if (p->n_op >= ULE)
449                     cb1 += 4, cb2 += 4;
450           expand(p, 0, "      cmpl UL,UR\n");
451           if (cb1) cbgen(cb1, s);
452           if (cb2) cbgen(cb2, e);
453           expand(p, 0, "      cmpl AL,AR\n");
454           cbgen(u, e);
455           deflab(s);
456 }
457 
458 
459 void
zzzcode(NODE * p,int c)460 zzzcode(NODE *p, int c)
461 {
462           NODE *l, *r;
463           TWORD t;
464           int m;
465           char *ch;
466 
467           switch (c) {
468           case 'N':  /* logical ops, turned into 0-1 */
469                     /* use register given by register 1 */
470                     cbgen( 0, m=getlab2());
471                     deflab( p->n_label );
472                     printf( " clrl      %s\n", rnames[getlr( p, '1' )->n_rval] );
473                     deflab( m );
474                     return;
475 
476           case 'A': /* Assign a constant directly to a memory position */
477                     printf("\t");
478                     if (p->n_type < LONG || ISPTR(p->n_type))
479                               casg(p);
480                     else
481                               casg64(p);
482                     printf("\n");
483                     break;
484 
485           case 'B': /* long long compare */
486                     twollcomp(p);
487                     break;
488 
489           case 'C': /* num words pushed on arg stack */
490                     printf("$%d", p->n_qual);
491                     break;
492 
493           case 'D': /* INCR and DECR */
494                     zzzcode(p->n_left, 'A');
495                     printf("\n          ");
496 
497 #if 0
498           case 'E': /* INCR and DECR, FOREFF */
499                     if (p->n_right->n_lval == 1)
500                               {
501                               printf("%s", (p->n_op == INCR ? "inc" : "dec") );
502                               prtype(p->n_left);
503                               printf("  ");
504                               adrput(stdout, p->n_left);
505                               return;
506                               }
507                     printf("%s", (p->n_op == INCR ? "add" : "sub") );
508                     prtype(p->n_left);
509                     printf("2 ");
510                     adrput(stdout, p->n_right);
511                     printf(",");
512                     adrput(p->n_left);
513                     return;
514 #endif
515 
516           case 'F': /* register type of right operand */
517                     {
518                     register NODE *n;
519                     register int ty;
520 
521                     n = getlr( p, 'R' );
522                     ty = n->n_type;
523 
524                     if (x2debug) printf("->%d<-", ty);
525 
526                     if ( ty==DOUBLE) printf("d");
527                     else if ( ty==FLOAT ) printf("f");
528                     else printf("l");
529                     return;
530                     }
531 
532           case 'G': /* emit conversion instructions */
533                     sconv(p);
534                     break;
535 
536           case 'J': /* jump or ret? */
537                     {
538                               struct interpass *ip =
539                                   DLIST_PREV((struct interpass *)p2env.epp, qelem);
540                               if (ip->type != IP_DEFLAB ||
541                                   ip->ip_lbl != getlr(p, 'L')->n_lval)
542                                         expand(p, FOREFF, "jbr        LL");
543                               else
544                                         printf("ret");
545                     }
546                     break;
547 
548           case 'L': /* type of left operand */
549           case 'R': /* type of right operand */
550                     {
551                     register NODE *n;
552 
553                     n = getlr ( p, c);
554                     if (x2debug) printf("->%d<-", n->n_type);
555 
556                     prtype(n);
557                     return;
558                     }
559 
560           case 'l': /* print out long long constant as hex */
561           case 'r': /* works around a bug in gas */
562                     l = getlr(p, c == 'l' ? 'L' : 'R');
563                     if (l->n_op == ICON && ISLONGLONG(l->n_type)) {
564                               printf("$0x%llx", l->n_lval);
565                     } else
566                               adrput(stdout, l);
567                     break;
568 
569           case 'O': /* print out emulated ops */
570                     expand(p, FOREFF, "\tmovq     AR,-(%sp)\n");
571                     expand(p, FOREFF, "\tmovq     AL,-(%sp)\n");
572                     if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
573                     else if (p->n_op == DIV) ch = "div";
574                     else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
575                     else if (p->n_op == MOD) ch = "mod";
576                     else if (p->n_op == MUL) ch = "mul";
577                     else ch = 0, comperr("ZO %d", p->n_op);
578                     printf("\tcalls     $4,__%sdi3\n", ch);
579                     break;
580 
581 
582           case 'Z': /* complement mask for bit instr */
583                     printf("$%lld", ~p->n_right->n_lval);
584                     return;
585 
586           case 'U': /* 32 - n, for unsigned right shifts */
587                     t = DEUNSIGN(p->n_left->n_type);
588                     m = t == CHAR ? 8 : t == SHORT ? 16 : 32;
589                     printf("$" CONFMT, m - p->n_right->n_lval);
590                     return;
591 
592           case 'T': /* rounded structure length for arguments */
593                     {
594                     int size;
595 
596                     size = attr_find(p->n_ap, ATTR_P2STRUCT)->iarg(0);
597                     SETOFF( size, 4);
598                     printf("$%d", size);
599                     return;
600                     }
601 
602           case 'S':  /* structure assignment */
603                     {
604                               register int size;
605 
606                               size = attr_find(p->n_ap, ATTR_P2STRUCT)->iarg(0);
607                               SETOFF(size, 4);
608                               l = r = NULL; /* XXX gcc */
609                               if( p->n_op == STASG ){
610                                         l = p->n_left;
611                                         r = p->n_right;
612 
613                                         }
614                               else if( p->n_op == STARG ){
615                                         /* store an arg into a temporary */
616                                         printf("\tsubl2 $%d,%%sp\n",
617                                             size < 4 ? 4 : size);
618                                         l = mklnode(OREG, 0, SP, INT);
619                                         r = p->n_left;
620                                         }
621                               else cerror( "STASG bad" );
622 
623                               if( r->n_op == ICON ) r->n_op = NAME;
624                               else if( r->n_op == REG ) r->n_op = OREG;
625                               else if( r->n_op != OREG ) cerror( "STASG-r" );
626 
627                     if (size != 0) {
628                               if( size <= 0 || size > 65535 )
629                                         cerror("structure size <0=0 or >65535");
630 
631                               switch(size) {
632                                         case 1:
633                                                   printf("  movb      ");
634                                                   break;
635                                         case 2:
636                                                   printf("  movw      ");
637                                                   break;
638                                         case 4:
639                                                   printf("  movl      ");
640                                                   break;
641                                         case 8:
642                                                   printf("  movq      ");
643                                                   break;
644                                         default:
645                                                   printf("  movc3     $%d,", size);
646                                                   break;
647                               }
648                               adrput(stdout, r);
649                               printf(",");
650                               adrput(stdout, l);
651                               printf("\n");
652                     }
653 
654                               if( r->n_op == NAME ) r->n_op = ICON;
655                               else if( r->n_op == OREG ) r->n_op = REG;
656                               if (p->n_op == STARG)
657                                         tfree(l);
658 
659                               }
660                     break;
661 
662           default:
663                     comperr("illegal zzzcode '%c'", c);
664           }
665 }
666 
667 void
rmove(int rt,int rs,TWORD t)668 rmove(int rt, int rs, TWORD t)
669 {
670           char c = (t == FLOAT ? 'f' : t == DOUBLE ? 'd' :
671               t == LONGLONG || t == ULONGLONG ? 'q' : 'l');
672           printf("  mov%c     %s,%s\n", c, rnames[rt], rnames[rs]);
673 }
674 
675 int
rewfld(NODE * p)676 rewfld(NODE *p)
677 {
678           return(1);
679 }
680 
681 #if 0
682 int
683 callreg(NODE *p)
684 {
685           return( R0 );
686 }
687 
688 int
689 base(register NODE *p)
690 {
691           register int o = p->op;
692 
693           if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
694           if( o==REG ) return( p->rval );
695     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
696                     return( p->left->rval );
697     if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
698                     return( p->rval + 0200*1 );
699           if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
700           if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
701           if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
702             && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
703                     return( p->left->left->rval + 0200*(1+2) );
704           return( -1 );
705 }
706 
707 int
708 offset(register NODE *p, int tyl)
709 {
710 
711           if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
712           if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
713                 (p->right->op==ICON && p->right->name[0]=='\0')
714                 && (1<<p->right->lval)==tyl))
715                     return( p->left->rval );
716           return( -1 );
717 }
718 #endif
719 
720 #if 0
721 void
722 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
723           register NODE *t;
724           NODE *f;
725 
726           p->n_op = OREG;
727           f = p->n_left;      /* have to free this subtree later */
728 
729           /* init base */
730           switch (q->n_op) {
731                     case ICON:
732                     case REG:
733                     case OREG:
734                               t = q;
735                               break;
736 
737                     case MINUS:
738                               q->n_right->n_lval = -q->n_right->n_lval;
739                     case PLUS:
740                               t = q->n_right;
741                               break;
742 
743                     case UMUL:
744                               t = q->n_left->n_left;
745                               break;
746 
747                     default:
748                               cerror("illegal makeor2");
749                               t = NULL; /* XXX gcc */
750           }
751 
752           p->n_lval = t->n_lval;
753           p->n_name = t->n_name;
754 
755           /* init offset */
756           p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
757 
758           tfree(f);
759           return;
760           }
761 
762 int
763 canaddr( p ) NODE *p; {
764           register int o = p->n_op;
765 
766           if( o==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_left, STARNM|SOREG)) ) return(1);
767           return(0);
768           }
769 
770 shltype( o, p ) register NODE *p; {
771           return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_left, STARNM|SOREG)) );
772           }
773 #endif
774 
775 int
fldexpand(NODE * p,int cookie,char ** cp)776 fldexpand(NODE *p, int cookie, char **cp)
777 {
778           return 0;
779 }
780 
781 int
flshape(register NODE * p)782 flshape(register NODE *p)
783 {
784           return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
785                     (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
786 }
787 
788 int
shtemp(register NODE * p)789 shtemp(register NODE *p)
790 {
791           if( p->n_op == STARG ) p = p->n_left;
792           return( p->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_left, STARNM|SOREG)) );
793 }
794 
795 /*
796  * Shape matches for UMUL.  Cooperates with offstar().
797  */
798 int
shumul(NODE * p,int shape)799 shumul(NODE *p, int shape)
800 {
801 
802           if (x2debug)
803                     printf("shumul(%p)\n", p);
804 
805           /* Turns currently anything into OREG on vax */
806           if (shape & SOREG)
807                     return SROREG;
808           return SRNOPE;
809 }
810 
811 
812 #ifdef notdef
813 int
shumul(p,shape)814 shumul( p, shape ) register NODE *p; int shape; {
815           register int o;
816 
817           if (x2debug) {
818                      printf("\nshumul:op=%d,lop=%d,rop=%d", p->n_op, p->n_left->n_op, p->n_right->n_op);
819                     printf(" prname=%s,plty=%d, prlval=%lld\n", p->n_right->n_name, p->n_left->n_type, p->n_right->n_lval);
820                     }
821 
822 
823           o = p->n_op;
824           if( o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
825                     if (shape & STARNM)
826                               return SRDIR;
827 
828           if( ( o == INCR || o == ASG MINUS ) &&
829               ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
830               p->n_right->n_name[0] == '\0' )
831                     {
832                     switch (p->n_left->n_type)
833                               {
834                               case CHAR|PTR:
835                               case UCHAR|PTR:
836                                         o = 1;
837                                         break;
838 
839                               case SHORT|PTR:
840                               case USHORT|PTR:
841                                         o = 2;
842                                         break;
843 
844                               case INT|PTR:
845                               case UNSIGNED|PTR:
846                               case LONG|PTR:
847                               case ULONG|PTR:
848                               case FLOAT|PTR:
849                                         o = 4;
850                                         break;
851 
852                               case DOUBLE|PTR:
853                                         o = 8;
854                                         break;
855 
856                               default:
857                                         if ( ISPTR(p->n_left->n_type) ) {
858                                                   o = 4;
859                                                   break;
860                                                   }
861                                         else return(0);
862                               }
863                     return( p->n_right->n_lval == o ? STARREG : 0);
864                     }
865 
866           return( SRNOPE );
867           }
868 #endif
869 
870 void
adrcon(CONSZ val)871 adrcon(CONSZ val)
872 {
873           comperr("adrcon");
874           printf( "$" );
875           printf( CONFMT, val );
876 }
877 
878 void
conput(FILE * fp,NODE * p)879 conput(FILE *fp, NODE *p)
880 {
881           switch( p->n_op ){
882 
883           case ICON:
884                     acon( p );
885                     return;
886 
887           case REG:
888                     printf( "%s", rnames[p->n_rval] );
889                     return;
890 
891           default:
892                     cerror( "illegal conput" );
893                     }
894           }
895 
896 void
insput(register NODE * p)897 insput(register NODE *p)
898 {
899           cerror( "insput" );
900 }
901 
902 /*
903  * Write out the upper address, like the upper register of a 2-register
904  * reference, or the next memory location.
905  */
906 void
upput(NODE * p,int size)907 upput(NODE *p, int size)
908 {
909 
910           size /= SZCHAR;
911           switch (p->n_op) {
912           case REG:
913                     printf("%s", rnames[regno(p)-16+1]);
914                     break;
915 
916           case NAME:
917                     if (kflag)
918                               comperr("upput NAME");
919           case OREG:
920                     p->n_lval += size;
921                     adrput(stdout, p);
922                     p->n_lval -= size;
923                     break;
924           case ICON:
925                     printf("$" CONFMT, (p->n_lval >> 32) & 0xffffffff);
926                     break;
927           default:
928                     comperr("upput bad op %d size %d", p->n_op, size);
929           }
930 }
931 
932 void
adrput(FILE * fp,NODE * p)933 adrput(FILE *fp, NODE *p)
934 {
935           register int r;
936           /* output an address, with offsets, from p */
937 
938           if( p->n_op == FLD ){
939                     p = p->n_left;
940                     }
941           switch( p->n_op ){
942 
943           case NAME:
944                     acon( p );
945                     return;
946 
947           case ICON:
948                     /* addressable value of the constant */
949                     if (p->n_name[0] == '\0') /* uses xxxab */
950                               printf("$");
951                     if (ISLONGLONG(p->n_type))
952                               printf("0x%llx", p->n_lval);
953                     else
954                               acon(p);
955                     return;
956 
957           case REG:
958                     printf( "%s", rnames[p->n_rval] );
959                     return;
960 
961           case OREG:
962                     r = p->n_rval;
963                     if( R2TEST(r) ){ /* double indexing */
964                               register int flags;
965 
966                               flags = R2UPK3(r);
967                               if( flags & 1 ) printf("*");
968                               if( flags & 4 ) printf("-");
969                               if( p->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
970                               if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
971                               if( flags & 2 ) printf("+");
972                               printf( "[%s]", rnames[R2UPK2(r)] );
973                               return;
974                               }
975                     if( r == AP ){  /* in the argument region */
976                               if( p->n_lval <= 0 || p->n_name[0] != '\0' )
977                                         werror( "bad arg temp" );
978                               printf( CONFMT, p->n_lval );
979                               printf( "(%%ap)" );
980                               return;
981                               }
982                     if( p->n_lval != 0 || p->n_name[0] != '\0') acon( p );
983                     printf( "(%s)", rnames[p->n_rval] );
984                     return;
985 
986           case UMUL:
987                     /* STARNM or STARREG found */
988                     if( tshape(p, STARNM) ) {
989                               printf( "*" );
990                               adrput(0,  p->n_left);
991                               }
992                     else {    /* STARREG - really auto inc or dec */
993                               register NODE *q;
994 
995 /* tbl
996                               p = p->n_left;
997                               p->n_left->n_op = OREG;
998                               if( p->n_op == INCR ) {
999                                         adrput( p->n_left );
1000                                         printf( "+" );
1001                                         }
1002                               else {
1003                                         printf( "-" );
1004                                         adrput( p->n_left );
1005                                         }
1006    tbl */
1007 #ifdef notyet
1008                               printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
1009                                         rnames[p->n_left->n_left->n_rval],
1010                                         (p->n_left->n_op==INCR ? '+' : '\0') );
1011 #else
1012                               printf("%c(%s)%c", '-',
1013                                         rnames[p->n_left->n_left->n_rval],
1014                                         '\0' );
1015 #endif
1016                               p->n_op = OREG;
1017                               p->n_rval = p->n_left->n_left->n_rval;
1018                               q = p->n_left;
1019 #ifdef notyet
1020 
1021                               p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
1022 #else
1023                               p->n_lval = 0;
1024 #endif
1025                               p->n_name[0] = '\0';
1026                               tfree(q);
1027                     }
1028                     return;
1029 
1030           default:
1031                     cerror( "illegal address" );
1032                     return;
1033           }
1034 
1035 }
1036 
1037 /*
1038  * print out a constant
1039  */
1040 void
acon(NODE * p)1041 acon(NODE *p)
1042 {
1043           int u = (int)p->n_lval;;
1044           CONSZ v = u;
1045 
1046           if (p->n_name[0] == '\0') {
1047                     printf(CONFMT, v);
1048           } else if( p->n_lval == 0 ) {
1049                     printf("%s", p->n_name);
1050           } else {
1051                     printf("%s+", p->n_name);
1052                     printf(CONFMT, v);
1053           }
1054 }
1055 
1056 #if 0
1057 genscall( p, cookie ) register NODE *p; {
1058           /* structure valued call */
1059           return( gencall( p, cookie ) );
1060           }
1061 
1062 /* tbl */
1063 int gc_numbytes;
1064 /* tbl */
1065 
1066 gencall( p, cookie ) register NODE *p; {
1067           /* generate the call given by p */
1068           register NODE *p1, *ptemp;
1069           register temp, temp1;
1070           register m;
1071 
1072           if( p->right ) temp = argsize( p->right );
1073           else temp = 0;
1074 
1075           if( p->op == STCALL || p->op == UNARY STCALL ){
1076                     /* set aside room for structure return */
1077 
1078                     if( p->stsize > temp ) temp1 = p->stsize;
1079                     else temp1 = temp;
1080                     }
1081 
1082           if( temp > maxargs ) maxargs = temp;
1083           SETOFF(temp1,4);
1084 
1085           if( p->right ){ /* make temp node, put offset in, and generate args */
1086                     ptemp = talloc();
1087                     ptemp->op = OREG;
1088                     ptemp->lval = -1;
1089                     ptemp->rval = SP;
1090                     ptemp->name[0] = '\0';
1091                     ptemp->rall = NOPREF;
1092                     ptemp->su = 0;
1093                     genargs( p->right, ptemp );
1094                     nfree(ptemp);
1095                     }
1096 
1097           p1 = p->left;
1098           if( p1->op != ICON ){
1099                     if( p1->op != REG ){
1100                               if( p1->op != OREG || R2TEST(p1->rval) ){
1101                                         if( p1->op != NAME ){
1102                                                   order( p1, INAREG );
1103                                                   }
1104                                         }
1105                               }
1106                     }
1107 
1108 /*
1109           if( p1->op == REG && p->rval == R5 ){
1110                     cerror( "call register overwrite" );
1111                     }
1112  */
1113 /* tbl
1114           setup gc_numbytes so reference to ZC works */
1115 
1116           gc_numbytes = temp;
1117 /* tbl */
1118 
1119           p->op = UNARY CALL;
1120           m = match( p, INTAREG|INTBREG );
1121 /* tbl
1122           switch( temp ) {
1123           case 0:
1124                     break;
1125           case 2:
1126                     printf( " tst       (%sp)+\n" );
1127                     break;
1128           case 4:
1129                     printf( " cmp       (%sp)+,(%sp)+\n" );
1130                     break;
1131           default:
1132                     printf( " add       $%d,%sp\n", temp);
1133                     }
1134    tbl */
1135           return(m != MDONE);
1136           }
1137 #endif
1138 
1139 static char *
1140 ccbranches[] = {
1141           "jeql",
1142           "jneq",
1143           "jleq",
1144           "jlss",
1145           "jgeq",
1146           "jgtr",
1147           "jlequ",
1148           "jlssu",
1149           "jgequ",
1150           "jgtru",
1151 };
1152 
1153 /*
1154  * printf conditional and unconditional branches
1155  */
1156 void
cbgen(int o,int lab)1157 cbgen(int o, int lab)
1158 {
1159 
1160           if (o == 0) {
1161                     printf("  jbr     " LABFMT "\n", lab);
1162           } else {
1163                     if (o > UGT)
1164                               comperr("bad conditional branch: %s", opst[o]);
1165                     printf("\t%s\t" LABFMT "\n", ccbranches[o-EQ], lab);
1166           }
1167 }
1168 
1169 static void
mkcall(NODE * p,char * name)1170 mkcall(NODE *p, char *name)
1171 {
1172           p->n_op = CALL;
1173           p->n_right = mkunode(FUNARG, p->n_left, 0, p->n_left->n_type);
1174           p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
1175           p->n_left->n_name = name;
1176 }
1177 
1178 /* do local tree transformations and optimizations */
1179 static void
optim2(NODE * p,void * arg)1180 optim2(NODE *p, void *arg)
1181 {
1182           NODE *r, *s;
1183           TWORD lt;
1184 
1185           switch (p->n_op) {
1186           case DIV:
1187           case MOD:
1188                     if (p->n_type == USHORT || p->n_type == UCHAR) {
1189                               r = mkunode(SCONV, p->n_left, 0, UNSIGNED);
1190                               r = mkunode(FUNARG, r, 0, UNSIGNED);
1191                               s = mkunode(SCONV, p->n_right, 0, UNSIGNED);
1192                               s = mkunode(FUNARG, s, 0, UNSIGNED);
1193                               r = mkbinode(CM, r, s, INT);
1194                               s = mklnode(ICON, 0, 0, FTN|UNSIGNED);
1195                               s->n_name = p->n_op == MOD ? "__urem" : "__udiv";
1196                               p->n_left = mkbinode(CALL, s, r, UNSIGNED);
1197                               p->n_op = SCONV;
1198                     } else if (p->n_type == UNSIGNED) {
1199                               p->n_left = mkunode(FUNARG, p->n_left, 0, UNSIGNED);
1200                               p->n_right = mkunode(FUNARG, p->n_right, 0, UNSIGNED);
1201                               p->n_right = mkbinode(CM, p->n_left, p->n_right, INT);
1202                               p->n_left = mklnode(ICON, 0, 0, FTN|UNSIGNED);
1203                               p->n_left->n_name = p->n_op == MOD ? "__urem" : "__udiv";
1204                               p->n_op = CALL;
1205                     }
1206                     break;
1207 
1208           case RS:
1209                     if (p->n_type == ULONGLONG) {
1210                               p->n_right = mkbinode(CM,
1211                                   mkunode(FUNARG, p->n_left, 0, p->n_left->n_type),
1212                                   mkunode(FUNARG, p->n_right, 0, p->n_right->n_type),
1213                                   INT);
1214                               p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
1215                               p->n_left->n_name = "__lshrdi3";
1216                               p->n_op = CALL;
1217                     } else if (p->n_type == INT || p->n_type == LONGLONG) {
1218                               /* convert >> to << with negative shift count */
1219                               /* RS of char & short must use extv */
1220                               if (p->n_right->n_op == ICON) {
1221                                         p->n_right->n_lval = -p->n_right->n_lval;
1222                               } else if (p->n_right->n_op == UMINUS) {
1223                                         r = p->n_right->n_left;
1224                                         nfree(p->n_right);
1225                                         p->n_right = r;
1226                               } else {
1227                                         p->n_right = mkunode(UMINUS, p->n_right,
1228                                             0, p->n_right->n_type);
1229                               }
1230                               p->n_op = LS;
1231                     }
1232                     break;
1233 
1234           case AND:
1235                     /* commute L and R to eliminate compliments and constants */
1236                     if ((p->n_left->n_op == ICON && p->n_left->n_name[0] == 0) ||
1237                         p->n_left->n_op==COMPL) {
1238                               r = p->n_left;
1239                               p->n_left = p->n_right;
1240                               p->n_right = r;
1241                     }
1242                     /* change meaning of AND to ~R&L - bic on pdp11 */
1243                     r = p->n_right;
1244                     if (r->n_op == ICON && r->n_name[0] == 0) {
1245                               /* compliment constant */
1246                               r->n_lval = ~r->n_lval;
1247                     } else if (r->n_op == COMPL) { /* ~~A => A */
1248                               s = r->n_left;
1249                               nfree(r);
1250                               p->n_right = s;
1251                     } else { /* insert complement node */
1252                               p->n_right = mkunode(COMPL, r, 0, r->n_type);
1253                     }
1254                     break;
1255           case SCONV:
1256                     lt = p->n_left->n_type;
1257                     switch (p->n_type) {
1258                     case LONGLONG:
1259                               if (lt == FLOAT)
1260                                         mkcall(p, "__fixsfdi");
1261                               else if (lt == DOUBLE)
1262                                         mkcall(p, "__fixdfdi");
1263                               break;
1264                     case ULONGLONG:
1265                               if (lt == FLOAT)
1266                                         mkcall(p, "__fixunssfdi");
1267                               else if (lt == DOUBLE)
1268                                         mkcall(p, "__fixunsdfdi");
1269                               break;
1270                     case FLOAT:
1271                               if (lt == LONGLONG)
1272                                         mkcall(p, "__floatdisf");
1273                               else if (lt == ULONGLONG) {
1274                                         p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
1275                                         p->n_type = FLOAT;
1276                                         mkcall(p->n_left, "__floatundidf");
1277                               } else if (lt == UNSIGNED) {
1278                                         /* insert an extra double-to-float sconv */
1279                                         p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
1280                               }
1281                               break;
1282                     case DOUBLE:
1283                               if (lt == LONGLONG)
1284                                         mkcall(p, "__floatdidf");
1285                               else if (lt == ULONGLONG)
1286                                         mkcall(p, "__floatundidf");
1287                               break;
1288 
1289                     }
1290                     break;
1291           }
1292 }
1293 
1294 static void
aofname(NODE * p,void * arg)1295 aofname(NODE *p, void *arg)
1296 {
1297           int o = optype(p->n_op);
1298           TWORD t;
1299 
1300           if (o == LTYPE || p->n_op == ADDROF)
1301                     return;
1302           t = p->n_left->n_type;
1303           if (p->n_left->n_op == NAME && ISLONGLONG(t))
1304                     p->n_left = mkunode(UMUL,
1305                         mkunode(ADDROF, p->n_left, 0, INCREF(t)), 0, t);
1306           if (o == BITYPE && p->n_right->n_op == NAME &&
1307               ISLONGLONG(p->n_right->n_type)) {
1308                     t = p->n_right->n_type;
1309                     p->n_right = mkunode(UMUL,
1310                         mkunode(ADDROF, p->n_right, 0, INCREF(t)), 0, t);
1311           }
1312 }
1313 
1314 void
myreader(struct interpass * ipole)1315 myreader(struct interpass *ipole)
1316 {
1317           struct interpass *ip;
1318 
1319           DLIST_FOREACH(ip, ipole, qelem) {
1320                     if (ip->type != IP_NODE)
1321                               continue;
1322                     if (kflag)
1323                               walkf(ip->ip_node, aofname, 0);
1324                     walkf(ip->ip_node, optim2, 0);
1325           }
1326 }
1327 
1328 void
mycanon(NODE * p)1329 mycanon(NODE *p)
1330 {
1331 }
1332 
1333 void
myoptim(struct interpass * ip)1334 myoptim(struct interpass *ip)
1335 {
1336 }
1337 
1338 /*
1339  * Return argument size in regs.
1340  */
1341 static int
argsiz(NODE * p)1342 argsiz(NODE *p)
1343 {
1344           TWORD t = p->n_type;
1345 
1346           if (t == STRTY || t == UNIONTY)
1347                     return (attr_find(p->n_ap, ATTR_P2STRUCT)->iarg(0)+3)/4;
1348           return szty(t);
1349 }
1350 
1351 /*
1352  * Last chance to do something before calling a function.
1353  */
1354 void
lastcall(NODE * p)1355 lastcall(NODE *p)
1356 {
1357           NODE *op = p;
1358           int size = 0;
1359 
1360           /* Calculate argument sizes */
1361           p->n_qual = 0;
1362           if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
1363                     return;
1364           for (p = p->n_right; p->n_op == CM; p = p->n_left)
1365                     size += argsiz(p->n_right);
1366           if (p->n_op != ASSIGN)
1367                     size += argsiz(p);
1368           op->n_qual = size; /* XXX */
1369 }
1370 
1371 /*
1372  * Return a class suitable for a specific type.
1373  */
1374 int
gclass(TWORD t)1375 gclass(TWORD t)
1376 {
1377           return (szty(t) == 2 ? CLASSB : CLASSA);
1378 }
1379 
1380 /*
1381  * For class c, find worst-case displacement of the number of
1382  * registers in the array r[] indexed by class.
1383  */
1384 int
COLORMAP(int c,int * r)1385 COLORMAP(int c, int *r)
1386 {
1387           int num;
1388           int a,b;
1389 
1390           a = r[CLASSA];
1391           b = r[CLASSB];
1392           switch (c) {
1393           case CLASSA:
1394                     /* there are 12 classa, so min 6 classb are needed to block */
1395                     num = b * 2;
1396                     num += a;
1397                     return num < 12;
1398           case CLASSB:
1399                     if (b > 3) return 0;
1400                     if (b > 2 && a) return 0;
1401                     if (b > 1 && a > 2) return 0;
1402                     if (b && a > 3) return 0;
1403                     if (a > 5) return 0;
1404                     return 1;
1405           }
1406           comperr("COLORMAP");
1407           return 0; /* XXX gcc */
1408 }
1409 
1410 /*
1411  * Special shapes.
1412  */
1413 int
special(NODE * p,int shape)1414 special(NODE *p, int shape)
1415 {
1416           return SRNOPE;
1417 }
1418 
1419 /*
1420  * Target-dependent command-line options.
1421  */
1422 void
mflags(char * str)1423 mflags(char *str)
1424 {
1425 }
1426 /*
1427  * Do something target-dependent for xasm arguments.
1428  * Supposed to find target-specific constraints and rewrite them.
1429  */
1430 int
myxasm(struct interpass * ip,NODE * p)1431 myxasm(struct interpass *ip, NODE *p)
1432 {
1433           char *c;
1434           int i;
1435 
1436           /* Discard o<> constraints since they will not be generated */
1437           for (c = p->n_name; *c; c++) {
1438                     if (*c == 'o' || *c == '<' || *c == '>') {
1439                               for (i = 0; c[i]; i++)
1440                                         c[i] = c[i+1];
1441                               c--;
1442                     }
1443           }
1444           return 0;
1445 }
1446 
1447 int
xasmconstregs(char * s)1448 xasmconstregs(char *s)
1449 {
1450           int i;
1451 
1452           for (i = 0; i < 16; i++)
1453                     if (strcmp(&rnames[i][1], s) == 0)
1454                               return i;
1455           return -1;
1456 }
1457