* add p cc
[mascara-docs.git] / compilers / pcc / pcc-1.0.0 / arch / vax / local2.c
blob1a9b7595ee95077d313d9f468b5ddda5da88fe96
1 /* $Id: local2.c,v 1.11 2008/11/22 16:12:25 ragge Exp $ */
2 /*
3 * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
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.
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.
36 # include "pass2.h"
37 # include "ctype.h"
38 /* a lot of the machine dependent parts of the second pass */
40 static void prtype(NODE *n);
41 static void acon(NODE *p);
44 * Print out the prolog assembler.
45 * addto and regoff are already calculated.
47 void
48 prologue(struct interpass_prolog *ipp)
50 if (ipp->ipp_vis)
51 printf(" .globl %s\n", ipp->ipp_name);
52 printf(" .align 4\n");
53 printf("%s:\n", ipp->ipp_name);
54 printf(" .word 0x%x\n", ipp->ipp_regs[0]);
55 if (p2maxautooff)
56 printf(" subl2 $%d,%%sp\n", p2maxautooff);
60 * Called after all instructions in a function are emitted.
61 * Generates code for epilog here.
63 void
64 eoftn(struct interpass_prolog *ipp)
66 if (ipp->ipp_ip.ip_lbl == 0)
67 return; /* no code needs to be generated */
68 printf(" ret\n");
71 struct hoptab { int opmask; char * opstring; } ioptab[] = {
73 { PLUS, "add", },
74 { MINUS, "sub", },
75 { MUL, "mul", },
76 { DIV, "div", },
77 { OR, "bis", },
78 { ER, "xor", },
79 { AND, "bic", },
80 { -1, "" },
83 void
84 hopcode( f, o ){
85 /* output the appropriate string from the above table */
87 register struct hoptab *q;
89 for( q = ioptab; q->opmask>=0; ++q ){
90 if( q->opmask == o ){
91 printf( "%s", q->opstring );
92 /* tbl
93 if( f == 'F' ) printf( "e" );
94 else if( f == 'D' ) printf( "d" );
95 tbl */
96 /* tbl */
97 switch( f ) {
98 case 'L':
99 case 'W':
100 case 'B':
101 case 'D':
102 case 'F':
103 printf("%c", tolower(f));
104 break;
107 /* tbl */
108 return;
111 cerror( "no hoptab for %s", opst[o] );
114 char *
115 rnames[] = { /* keyed to register number tokens */
117 "r0", "r1", "r2", "r3", "r4", "r5",
118 "r6", "r7", "r8", "r9", "r10", "r11",
119 "ap", "fp", "sp", "pc",
120 /* The concatenated regs has the name of the lowest */
121 "r0", "r1", "r2", "r3", "r4", "r5",
122 "r6", "r7", "r8", "r9", "r10"
126 tlen(p) NODE *p;
128 switch(p->n_type) {
129 case CHAR:
130 case UCHAR:
131 return(1);
133 case SHORT:
134 case USHORT:
135 return(2);
137 case DOUBLE:
138 case LDOUBLE:
139 case LONGLONG:
140 case ULONGLONG:
141 return(8);
143 default:
144 return(4);
148 static int
149 mixtypes(NODE *p, NODE *q)
151 TWORD tp, tq;
153 tp = p->n_type;
154 tq = q->n_type;
156 return( (tp==FLOAT || tp==DOUBLE) !=
157 (tq==FLOAT || tq==DOUBLE) );
160 void
161 prtype(NODE *n)
163 switch (n->n_type)
165 case DOUBLE:
166 printf("d");
167 return;
169 case FLOAT:
170 printf("f");
171 return;
173 case LONG:
174 case ULONG:
175 case INT:
176 case UNSIGNED:
177 printf("l");
178 return;
180 case SHORT:
181 case USHORT:
182 printf("w");
183 return;
185 case CHAR:
186 case UCHAR:
187 printf("b");
188 return;
190 default:
191 if ( !ISPTR( n->n_type ) ) cerror("zzzcode- bad type");
192 else {
193 printf("l");
194 return;
199 void
200 zzzcode( p, c ) register NODE *p; {
201 int m;
202 int val;
203 switch( c ){
205 case 'N': /* logical ops, turned into 0-1 */
206 /* use register given by register 1 */
207 cbgen( 0, m=getlab2());
208 deflab( p->n_label );
209 printf( " clrl %s\n", rnames[getlr( p, '1' )->n_rval] );
210 deflab( m );
211 return;
213 case 'A':
215 register NODE *l, *r;
217 if (xdebug) e2print(p, 0, &val, &val);
218 r = getlr(p, 'R');
219 if (optype(p->n_op) == LTYPE || p->n_op == UMUL) {
220 l = resc;
221 l->n_type = (r->n_type==FLOAT || r->n_type==DOUBLE ? DOUBLE : INT);
222 } else
223 l = getlr(p, 'L');
224 if (r->n_op == ICON && r->n_name[0] == '\0') {
225 if (r->n_lval == 0) {
226 printf("clr");
227 prtype(l);
228 printf(" ");
229 adrput(stdout, l);
230 return;
232 if (r->n_lval < 0 && r->n_lval >= -63) {
233 printf("mneg");
234 prtype(l);
235 r->n_lval = -r->n_lval;
236 goto ops;
238 r->n_type = (r->n_lval < 0 ?
239 (r->n_lval >= -128 ? CHAR
240 : (r->n_lval >= -32768 ? SHORT
241 : INT )) : r->n_type);
242 r->n_type = (r->n_lval >= 0 ?
243 (r->n_lval <= 63 ? INT
244 : ( r->n_lval <= 127 ? CHAR
245 : (r->n_lval <= 255 ? UCHAR
246 : (r->n_lval <= 32767 ? SHORT
247 : (r->n_lval <= 65535 ? USHORT
248 : INT ))))) : r->n_type );
250 if (l->n_op == REG && l->n_type != FLOAT && l->n_type != DOUBLE)
251 l->n_type = INT;
252 if (!mixtypes(l,r))
254 if (tlen(l) == tlen(r))
256 printf("mov");
257 prtype(l);
258 goto ops;
260 else if (tlen(l) > tlen(r) && ISUNSIGNED(r->n_type))
262 printf("movz");
264 else
266 printf("cvt");
269 else
271 printf("cvt");
273 prtype(r);
274 prtype(l);
275 ops:
276 printf(" ");
277 adrput(stdout, r);
278 printf(",");
279 adrput(stdout, l);
280 return;
283 case 'C': /* num words pushed on arg stack */
284 if (p->n_op == STCALL || p->n_op == USTCALL)
285 p->n_qual++;
286 printf("$%d", p->n_qual);
287 break;
289 case 'D': /* INCR and DECR */
290 zzzcode(p->n_left, 'A');
291 printf("\n ");
293 #if 0
294 case 'E': /* INCR and DECR, FOREFF */
295 if (p->n_right->n_lval == 1)
297 printf("%s", (p->n_op == INCR ? "inc" : "dec") );
298 prtype(p->n_left);
299 printf(" ");
300 adrput(stdout, p->n_left);
301 return;
303 printf("%s", (p->n_op == INCR ? "add" : "sub") );
304 prtype(p->n_left);
305 printf("2 ");
306 adrput(stdout, p->n_right);
307 printf(",");
308 adrput(p->n_left);
309 return;
310 #endif
312 case 'F': /* register type of right operand */
314 register NODE *n;
315 extern int xdebug;
316 register int ty;
318 n = getlr( p, 'R' );
319 ty = n->n_type;
321 if (xdebug) printf("->%d<-", ty);
323 if ( ty==DOUBLE) printf("d");
324 else if ( ty==FLOAT ) printf("f");
325 else printf("l");
326 return;
329 case 'J': /* jump or ret? */
331 extern struct interpass_prolog *epp;
332 struct interpass *ip =
333 DLIST_PREV((struct interpass *)epp, qelem);
334 if (ip->type != IP_DEFLAB ||
335 ip->ip_lbl != getlr(p, 'L')->n_lval)
336 expand(p, FOREFF, "jbr LL");
337 else
338 printf("ret");
340 break;
342 case 'L': /* type of left operand */
343 case 'R': /* type of right operand */
345 register NODE *n;
346 extern int xdebug;
348 n = getlr ( p, c);
349 if (xdebug) printf("->%d<-", n->n_type);
351 prtype(n);
352 return;
355 case 'Z': /* complement mask for bit instr */
356 printf("$%Ld", ~p->n_right->n_lval);
357 return;
359 case 'U': /* 32 - n, for unsigned right shifts */
360 printf("$" CONFMT, 32 - p->n_right->n_lval );
361 return;
363 case 'T': /* rounded structure length for arguments */
365 int size;
367 size = p->n_stsize;
368 SETOFF( size, 4);
369 printf("$%d", size);
370 return;
373 case 'S': /* structure assignment */
375 register NODE *l, *r;
376 register int size;
378 l = r = NULL; /* XXX gcc */
379 if( p->n_op == STASG ){
380 l = p->n_left;
381 r = p->n_right;
384 else if( p->n_op == STARG ){ /* store an arg into a temporary */
385 l = getlr( p, '3' );
386 r = p->n_left;
388 else cerror( "STASG bad" );
390 if( r->n_op == ICON ) r->n_op = NAME;
391 else if( r->n_op == REG ) r->n_op = OREG;
392 else if( r->n_op != OREG ) cerror( "STASG-r" );
394 size = p->n_stsize;
396 if( size <= 0 || size > 65535 )
397 cerror("structure size <0=0 or >65535");
399 switch(size) {
400 case 1:
401 printf(" movb ");
402 break;
403 case 2:
404 printf(" movw ");
405 break;
406 case 4:
407 printf(" movl ");
408 break;
409 case 8:
410 printf(" movq ");
411 break;
412 default:
413 printf(" movc3 $%d,", size);
414 break;
416 adrput(stdout, r);
417 printf(",");
418 adrput(stdout, l);
419 printf("\n");
421 if( r->n_op == NAME ) r->n_op = ICON;
422 else if( r->n_op == OREG ) r->n_op = REG;
425 break;
427 default:
428 comperr("illegal zzzcode '%c'", c);
432 void
433 rmove( int rt,int rs, TWORD t ){
434 printf( " %s %s,%s\n",
435 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
436 rnames[rs], rnames[rt] );
439 #if 0
440 setregs(){ /* set up temporary registers */
441 fregs = 6; /* tbl- 6 free regs on VAX (0-5) */
445 szty(t){ /* size, in registers, needed to hold thing of type t */
446 return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
448 #endif
451 rewfld( p ) NODE *p; {
452 return(1);
455 #if 0
456 callreg(p) NODE *p; {
457 return( R0 );
460 base( p ) register NODE *p; {
461 register int o = p->op;
463 if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
464 if( o==REG ) return( p->rval );
465 if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
466 return( p->left->rval );
467 if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
468 return( p->rval + 0200*1 );
469 if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
470 if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
471 if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
472 && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
473 return( p->left->left->rval + 0200*(1+2) );
474 return( -1 );
477 offset( p, tyl ) register NODE *p; int tyl; {
479 if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
480 if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
481 (p->right->op==ICON && p->right->name[0]=='\0')
482 && (1<<p->right->lval)==tyl))
483 return( p->left->rval );
484 return( -1 );
486 #endif
488 #if 0
489 void
490 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
491 register NODE *t;
492 NODE *f;
494 p->n_op = OREG;
495 f = p->n_left; /* have to free this subtree later */
497 /* init base */
498 switch (q->n_op) {
499 case ICON:
500 case REG:
501 case OREG:
502 t = q;
503 break;
505 case MINUS:
506 q->n_right->n_lval = -q->n_right->n_lval;
507 case PLUS:
508 t = q->n_right;
509 break;
511 case UMUL:
512 t = q->n_left->n_left;
513 break;
515 default:
516 cerror("illegal makeor2");
517 t = NULL; /* XXX gcc */
520 p->n_lval = t->n_lval;
521 p->n_name = t->n_name;
523 /* init offset */
524 p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
526 tfree(f);
527 return;
531 canaddr( p ) NODE *p; {
532 register int o = p->n_op;
534 if( o==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_left, STARNM|SOREG)) ) return(1);
535 return(0);
538 shltype( o, p ) register NODE *p; {
539 return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_left, STARNM|SOREG)) );
541 #endif
544 fldexpand(NODE *p, int cookie, char **cp)
546 return 0;
550 flshape( p ) register NODE *p; {
551 return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
552 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
556 shtemp( p ) register NODE *p; {
557 if( p->n_op == STARG ) p = p->n_left;
558 return( p->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_left, STARNM|SOREG)) );
562 shumul( p, shape ) register NODE *p; int shape; {
563 register int o;
564 extern int xdebug;
566 if (xdebug) {
567 printf("\nshumul:op=%d,lop=%d,rop=%d", p->n_op, p->n_left->n_op, p->n_right->n_op);
568 printf(" prname=%s,plty=%d, prlval=%lld\n", p->n_right->n_name, p->n_left->n_type, p->n_right->n_lval);
572 o = p->n_op;
573 if( o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
574 if (shape & STARNM)
575 return SRDIR;
577 #ifdef notyet
578 if( ( o == INCR || o == ASG MINUS ) &&
579 ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
580 p->n_right->n_name[0] == '\0' )
582 switch (p->n_left->n_type)
584 case CHAR|PTR:
585 case UCHAR|PTR:
586 o = 1;
587 break;
589 case SHORT|PTR:
590 case USHORT|PTR:
591 o = 2;
592 break;
594 case INT|PTR:
595 case UNSIGNED|PTR:
596 case LONG|PTR:
597 case ULONG|PTR:
598 case FLOAT|PTR:
599 o = 4;
600 break;
602 case DOUBLE|PTR:
603 o = 8;
604 break;
606 default:
607 if ( ISPTR(p->n_left->n_type) ) {
608 o = 4;
609 break;
611 else return(0);
613 return( p->n_right->n_lval == o ? STARREG : 0);
615 #endif
617 return( SRNOPE );
620 void
621 adrcon( val ) CONSZ val; {
622 printf( "$" );
623 printf( CONFMT, val );
626 void
627 conput(FILE *fp, NODE *p)
629 switch( p->n_op ){
631 case ICON:
632 acon( p );
633 return;
635 case REG:
636 printf( "%s", rnames[p->n_rval] );
637 return;
639 default:
640 cerror( "illegal conput" );
644 void
645 insput( p ) register NODE *p; {
646 cerror( "insput" );
649 void
650 upput( p , size) register NODE *p; {
651 cerror( "upput" );
654 void
655 adrput(FILE *fp, NODE *p)
657 register int r;
658 /* output an address, with offsets, from p */
660 if( p->n_op == FLD ){
661 p = p->n_left;
663 switch( p->n_op ){
665 case NAME:
666 acon( p );
667 return;
669 case ICON:
670 /* addressable value of the constant */
671 if (p->n_name[0] == '\0') /* uses xxxab */
672 printf("$");
673 acon(p);
674 return;
676 case REG:
677 printf( "%s", rnames[p->n_rval] );
678 return;
680 case OREG:
681 r = p->n_rval;
682 if( R2TEST(r) ){ /* double indexing */
683 register int flags;
685 flags = R2UPK3(r);
686 if( flags & 1 ) printf("*");
687 if( flags & 4 ) printf("-");
688 if( p->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
689 if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
690 if( flags & 2 ) printf("+");
691 printf( "[%s]", rnames[R2UPK2(r)] );
692 return;
694 if( r == AP ){ /* in the argument region */
695 if( p->n_lval <= 0 || p->n_name[0] != '\0' ) werror( "bad arg temp" );
696 printf( CONFMT, p->n_lval );
697 printf( "(ap)" );
698 return;
700 if( p->n_lval != 0 || p->n_name[0] != '\0') acon( p );
701 printf( "(%s)", rnames[p->n_rval] );
702 return;
704 case UMUL:
705 /* STARNM or STARREG found */
706 if( tshape(p, STARNM) ) {
707 printf( "*" );
708 adrput(0, p->n_left);
710 else { /* STARREG - really auto inc or dec */
711 register NODE *q;
713 /* tbl
714 p = p->n_left;
715 p->n_left->n_op = OREG;
716 if( p->n_op == INCR ) {
717 adrput( p->n_left );
718 printf( "+" );
720 else {
721 printf( "-" );
722 adrput( p->n_left );
724 tbl */
725 #ifdef notyet
726 printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
727 rnames[p->n_left->n_left->n_rval],
728 (p->n_left->n_op==INCR ? '+' : '\0') );
729 #else
730 printf("%c(%s)%c", '-',
731 rnames[p->n_left->n_left->n_rval],
732 '\0' );
733 #endif
734 p->n_op = OREG;
735 p->n_rval = p->n_left->n_left->n_rval;
736 q = p->n_left;
737 #ifdef notyet
739 p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
740 #else
741 p->n_lval = 0;
742 #endif
743 p->n_name[0] = '\0';
744 tfree(q);
746 return;
748 default:
749 cerror( "illegal address" );
750 return;
756 * print out a constant
758 void
759 acon(NODE *p)
762 if (p->n_name[0] == '\0') {
763 printf(CONFMT, p->n_lval);
764 } else if( p->n_lval == 0 ) {
765 printf("%s", p->n_name);
766 } else {
767 printf("%s+", p->n_name);
768 printf(CONFMT, p->n_lval);
772 #if 0
773 genscall( p, cookie ) register NODE *p; {
774 /* structure valued call */
775 return( gencall( p, cookie ) );
778 /* tbl */
779 int gc_numbytes;
780 /* tbl */
782 gencall( p, cookie ) register NODE *p; {
783 /* generate the call given by p */
784 register NODE *p1, *ptemp;
785 register temp, temp1;
786 register m;
788 if( p->right ) temp = argsize( p->right );
789 else temp = 0;
791 if( p->op == STCALL || p->op == UNARY STCALL ){
792 /* set aside room for structure return */
794 if( p->stsize > temp ) temp1 = p->stsize;
795 else temp1 = temp;
798 if( temp > maxargs ) maxargs = temp;
799 SETOFF(temp1,4);
801 if( p->right ){ /* make temp node, put offset in, and generate args */
802 ptemp = talloc();
803 ptemp->op = OREG;
804 ptemp->lval = -1;
805 ptemp->rval = SP;
806 ptemp->name[0] = '\0';
807 ptemp->rall = NOPREF;
808 ptemp->su = 0;
809 genargs( p->right, ptemp );
810 nfree(ptemp);
813 p1 = p->left;
814 if( p1->op != ICON ){
815 if( p1->op != REG ){
816 if( p1->op != OREG || R2TEST(p1->rval) ){
817 if( p1->op != NAME ){
818 order( p1, INAREG );
825 if( p1->op == REG && p->rval == R5 ){
826 cerror( "call register overwrite" );
829 /* tbl
830 setup gc_numbytes so reference to ZC works */
832 gc_numbytes = temp;
833 /* tbl */
835 p->op = UNARY CALL;
836 m = match( p, INTAREG|INTBREG );
837 /* tbl
838 switch( temp ) {
839 case 0:
840 break;
841 case 2:
842 printf( " tst (sp)+\n" );
843 break;
844 case 4:
845 printf( " cmp (sp)+,(sp)+\n" );
846 break;
847 default:
848 printf( " add $%d,sp\n", temp);
850 tbl */
851 return(m != MDONE);
853 #endif
855 static char *
856 ccbranches[] = {
857 "jeql",
858 "jneq",
859 "jleq",
860 "jlss",
861 "jgeq",
862 "jgtr",
863 "jlequ",
864 "jlssu",
865 "jgequ",
866 "jgtru",
870 * printf conditional and unconditional branches
872 void
873 cbgen(int o, int lab)
876 if (o == 0) {
877 printf(" jbr " LABFMT "\n", lab);
878 } else {
879 if (o > UGT)
880 comperr("bad conditional branch: %s", opst[o]);
881 printf("\t%s\t" LABFMT "\n", ccbranches[o-EQ], lab);
885 static void
886 optim2(NODE *p, void *arg)
888 /* do local tree transformations and optimizations */
890 register NODE *r;
892 switch( p->n_op ) {
894 case AND:
895 /* commute L and R to eliminate compliments and constants */
896 if( (p->n_left->n_op==ICON&&p->n_left->n_name[0]==0) || p->n_left->n_op==COMPL ) {
897 r = p->n_left;
898 p->n_left = p->n_right;
899 p->n_right = r;
901 #if 0
902 case ASG AND:
903 /* change meaning of AND to ~R&L - bic on pdp11 */
904 r = p->n_right;
905 if( r->op==ICON && r->name[0]==0 ) { /* compliment constant */
906 r->lval = ~r->lval;
908 else if( r->op==COMPL ) { /* ~~A => A */
909 r->op = FREE;
910 p->right = r->left;
912 else { /* insert complement node */
913 p->right = talloc();
914 p->right->op = COMPL;
915 p->right->rall = NOPREF;
916 p->right->type = r->type;
917 p->right->left = r;
918 p->right->right = NULL;
920 break;
921 #endif
925 void
926 myreader(struct interpass *ipole)
928 struct interpass *ip;
930 DLIST_FOREACH(ip, ipole, qelem) {
931 if (ip->type != IP_NODE)
932 continue;
933 walkf(ip->ip_node, optim2, 0);
937 void
938 mycanon(NODE *p)
942 void
943 myoptim(struct interpass *ip)
948 * Return argument size in regs.
950 static int
951 argsiz(NODE *p)
953 TWORD t = p->n_type;
955 if (t == STRTY || t == UNIONTY)
956 return p->n_stsize/(SZINT/SZCHAR);
957 return szty(t);
961 * Last chance to do something before calling a function.
963 void
964 lastcall(NODE *p)
966 NODE *op = p;
967 int size = 0;
969 /* Calculate argument sizes */
970 p->n_qual = 0;
971 if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
972 return;
973 for (p = p->n_right; p->n_op == CM; p = p->n_left)
974 size += argsiz(p->n_right);
975 size += argsiz(p);
976 op->n_qual = size; /* XXX */
980 * Return a class suitable for a specific type.
983 gclass(TWORD t)
985 return (szty(t) == 2 ? CLASSB : CLASSA);
989 * For class c, find worst-case displacement of the number of
990 * registers in the array r[] indexed by class.
993 COLORMAP(int c, int *r)
995 int num;
997 switch (c) {
998 case CLASSA:
999 /* there are 12 classa, so min 6 classb are needed to block */
1000 num = r[CLASSB] * 2;
1001 num += r[CLASSA];
1002 return num < 12;
1003 case CLASSB:
1004 /* 6 classa may block all classb */
1005 num = r[CLASSB] + r[CLASSA];
1006 return num < 6;
1008 comperr("COLORMAP");
1009 return 0; /* XXX gcc */
1013 * Special shapes.
1016 special(NODE *p, int shape)
1018 return SRNOPE;
1022 * Target-dependent command-line options.
1024 void
1025 mflags(char *str)
1029 * Do something target-dependent for xasm arguments.
1030 * Supposed to find target-specific constraints and rewrite them.
1033 myxasm(struct interpass *ip, NODE *p)
1035 return 0;