Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.16
 
1.17
 
MAIN:ragge:20110702151159
 
local2.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 44  *
 55  * Redistribution and use in source and binary forms, with or without
 66  * modification, are permitted provided that the following conditions
 77  * are met:
 88  *
 99  * Redistributions of source code and documentation must retain the above
 1010  * copyright notice, this list of conditions and the following disclaimer.
 1111  * Redistributions in binary form must reproduce the above copyright
 1212  * notice, this list of conditionsand the following disclaimer in the
 1313  * documentation and/or other materials provided with the distribution.
 1414  * All advertising materials mentioning features or use of this software
 1515  * must display the following acknowledgement:
 1616  *      This product includes software developed or owned by Caldera
 1717  *      International, Inc.
 1818  * Neither the name of Caldera International, Inc. nor the names of other
 1919  * contributors may be used to endorse or promote products derived from
 2020  * this software without specific prior written permission.
 2121  *
 2222  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 2323  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 2424  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 2525  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 2626  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 2727  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 2828  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 2929  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 3030  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 3131  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 3232  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 3333  * POSSIBILITY OF SUCH DAMAGE.
 3434  */
 3535 
 3636 # include "pass2.h"
 3737 # include "ctype.h"
 3838 /* a lot of the machine dependent parts of the second pass */
 3939 
 4040 static void prtype(NODE *n);
 4141 static void acon(NODE *p);
 4242 
 4343 /*
 4444  * Print out the prolog assembler.
 4545  * addto and regoff are already calculated.
 4646  */
 4747 void
 4848 prologue(struct interpass_prolog *ipp)
 4949 {
 5050         printf("        .word 0x%llx\n", (unsigned long long)ipp->ipp_regs[0]);
 5151         if (p2maxautooff)
 5252                 printf("        subl2 $%d,%%sp\n", p2maxautooff);
 5353 }
 5454 
 5555 /*
 5656  * Called after all instructions in a function are emitted.
 5757  * Generates code for epilog here.
 5858  */
 5959 void
 6060 eoftn(struct interpass_prolog *ipp)
 6161 {
 6262         if (ipp->ipp_ip.ip_lbl == 0)
 6363                 return; /* no code needs to be generated */
 6464         printf("        ret\n");
 6565 }
 6666 
 6767 struct hoptab { int opmask; char * opstring; } ioptab[] = {
 6868 
 6969         { PLUS"add", },
 7070         { MINUS,        "sub", },
 7171         { MUL,  "mul", },
 7272         { DIV,  "div", },
 7373         { OR,   "bis", },
 7474         { ER,   "xor", },
 7575         { AND,  "bic", },
 7676         { -1, ""     },
 7777 };
 7878 
 7979 void
 8080 hopcode( f, o ){
 8181         /* output the appropriate string from the above table */
 8282 
 8383         register struct hoptab *q;
 8484 
 8585         for( q = ioptabq->opmask>=0; ++q ){
 8686                 if( q->opmask == o ){
 8787                         printf( "%s", q->opstring );
 8888 /* tbl
 8989                         if( f == 'F' ) printf( "e" );
 9090                         else if( f == 'D' ) printf( "d" );
 9191    tbl */
 9292 /* tbl */
 9393                         switch( f ) {
 9494                                 case 'L':
 9595                                 case 'W':
 9696                                 case 'B':
 9797                                 case 'D':
 9898                                 case 'F':
 9999                                         printf("%c", tolower(f));
 100100                                         break;
 101101 
 102102                                 }
 103103 /* tbl */
 104104                         return;
 105105                         }
 106106                 }
 107107         cerror( "no hoptab for %s", opst[o] );
 108108         }
 109109 
 110110 char *
 111111 rnames[] = {  /* keyed to register number tokens */
 112112 
 113113         "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
 114114         "%r6", "%r7", "%r8", "%r9", "%r10", "%r11",
 115115         "%ap", "%fp", "%sp", "%pc",
 116116         /* The concatenated regs has the name of the lowest */
 117117         "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
 118118         "%r6", "%r7", "%r8", "%r9", "%r10"
 119119         };
 120120 
 121121 int
<>122 -tlen(p) NODE *p;
  122+tlen(NODE *p)
123123 {
 124124         switch(p->n_type) {
<>125 -                case CHAR:
 126 -                case UCHAR:
 127 -                        return(1);
  125+        case CHAR:
  126+        case UCHAR:
  127+                return(1);
128128 
<>129 -                case SHORT:
 130 -                case USHORT:
 131 -                        return(2);
  129+        case SHORT:
  130+        case USHORT:
  131+                return(2);
132132 
<>133 -                case DOUBLE:
 134 -                case LDOUBLE:
 135 -                case LONGLONG:
 136 -                case ULONGLONG:
 137 -                        return(8);
  133+        case DOUBLE:
  134+        case LONGLONG:
  135+        case ULONGLONG:
  136+                return(8);
138137 
<>139 -                default:
 140 -                        return(4);
 141 -                }
  138+        default:
  139+                return(4);
  140+        }
142141 }
 143142 
 144143 static int
 145144 mixtypes(NODE *p, NODE *q)
 146145 {
 147146         TWORD tp, tq;
 148147 
 149148         tp = p->n_type;
 150149         tq = q->n_type;
 151150 
 152151         return( (tp==FLOAT || tp==DOUBLE) !=
 153152                 (tq==FLOAT || tq==DOUBLE) );
 154153 }
 155154 
 156155 void
 157156 prtype(NODE *n)
 158157 {
<>159 -        switch (n->n_type)
 160 -                {
 161 -                case DOUBLE:
 162 -                        printf("d");
 163 -                        return;
  158+        static char pt[] = { 0, 0, 'b', 'b', 'w', 'w', 'l', 'l', 0, 0,
  159+            'q', 'q', 'f', 'd' };
  160+        TWORD t = n->n_type;
164161 
<>165 -                case FLOAT:
 166 -                        printf("f");
 167 -                        return;
  162+        if (ISPTR(t))
  163+                t = UNSIGNED;
168164 
<>169 -                case LONG:
 170 -                case ULONG:
 171 -                case INT:
 172 -                case UNSIGNED:
 173 -                        printf("l");
 174 -                        return;
  165+        if (t > DOUBLE || pt[t] == 0)
  166+                comperr("prtype: bad type");
  167+        putchar(pt[t]);
  168+}
175169 
<>176 -                case SHORT:
 177 -                case USHORT:
 178 -                        printf("w");
 179 -                        return;
  170+/*
  171+ * Emit conversions as given by the following table. Dest is always reg,
  172+ *   if it should be something else let peephole optimizer deal with it.
  173+ *   This code ensures type correctness in 32-bit registers.
  174+ *   XXX is that necessary?
  175+ *
  176+ * From                         To
  177+ *       char   uchar  short  ushort int    uint   ll    ull   float double
  178+ * char  movb   movb   cvtbw  cvtbw  cvtbl  cvtbl  A     A     cvtbf cvtbd
  179+ * uchar movb   movb   movzbw movzbw movzbl movzbl B     B     G     G
  180+ * short movb   movb   movw   movw   cvtwl  cvtwl  C(A)  C(A)  cvtwf cvtwd
  181+ * ushrt movb   movb   movw   movw   movzwl movzwl D(B)  D(B)  H     H
  182+ * int   movb   movb   movw   movw   movl   movl   E     E     cvtlf cvtld
  183+ * uint  movb   movb   movw   movw   movl   movl   F     F     I     I
  184+ * ll    movb   movb   movw   movw   movl   movl   movq  movq  J     K
  185+ * ull   movb   movb   movw   movw   movl   movl   movq  movq  L     M
  186+ * float cvtfb  cvtfb  cvtfw  cvtfw  cvtfl  cvtfl  N     O     movf  cvtfd
  187+ * doubl cvtdb  cvtdb  cvtdw  cvtdw  cvtdl  cvtdl  P     Q     cvtdf movd
  188+ *
  189+ *  A: cvtbl + sign extend
  190+ *  B: movzbl + zero extend
  191+ *  G: movzbw + cvtwX
  192+ *  H: movzwl + cvtwX
  193+ *  I: cvtld + addX
  194+ *  J: call __floatdisf
  195+ *  K: call __floatdidf
  196+ *  L: xxx + call __floatdisf
  197+ *  M: xxx + call __floatdidf
  198+ *  N: call __fixsfdi
  199+ *  O: call __fixunssfdi
  200+ *  P: call __fixdfdi
  201+ *  Q: call __fixunsdfdi
  202+ */
180203 
<>181 -                case CHAR:
 182 -                case UCHAR:
 183 -                        printf("b");
 184 -                        return;
  204+#define MVD     1 /* mov + dest type */
  205+#define CVT     2 /* cvt + src type + dst type */
  206+#define MVZ     3 /* movz + src type + dst type */
  207+#define CSE     4 /* cvt + src type + l + sign extend upper */
  208+#define MZE     5 /* movz + src type + l + zero extend upper */
  209+#define MLE     6 /* movl + sign extend upper */
  210+#define MLZ     7 /* movl + zero extend upper */
  211+#define MZC     8 /* movz + cvt */
185212 
<>186 -                default:
 187 -                        if ( !ISPTR( n->n_type ) ) cerror("zzzcode- bad type");
 188 -                        else {
 189 -                                printf("l");
 190 -                                return;
 191 -                                }
 192 -                }
  213+static char scary[][10] = {
  214+        { MVD, MVD, CVT, CVT, CVT, CVT, CSE, CSE, CVT, CVT },
  215+        { MVD, MVD, MVZ, MVZ, MVZ, MVZ, MZE, MZE, MZC, MZC },
  216+        { MVD, MVD, MVD, MVD, CVT, CVT, CSE, CSE, CVT, CVT },
  217+        { MVD, MVD, MVD, MVD, MVZ, MVZ, MZE, MZE, MZC, MZC },
  218+        { MVD, MVD, MVD, MVD, MVD, MVD, MLE, MLE, CVT, CVT },
  219+        { MVD, MVD, MVD, MVD, MVZ, MVZ, MLZ, MLZ, 'I', 'I' },
  220+        { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'J', 'K' },
  221+        { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'L', 'M' },
  222+        { CVT, CVT, CVT, CVT, CVT, CVT, 'N', 'O', MVD, CVT },
  223+        { CVT, CVT, CVT, CVT, CVT, CVT, 'P', 'Q', CVT, MVD },
  224+};
  225+
  226+static void
  227+sconv(NODE *p)
  228+{
  229+        NODE *l = p->n_left;
  230+        TWORD ts, td;
  231+        int o;
  232+
  233+        /*
  234+         * Source node may be in register or memory.
  235+         * Result is always in register.
  236+         */
  237+        ts = l->n_type;
  238+        if (ISPTR(ts))
  239+                ts = UNSIGNED;
  240+        td = p->n_type;
  241+        ts = ts < LONG ? ts-2 : ts-4;
  242+        td = td < LONG ? td-2 : td-4;
  243+
  244+        o = scary[ts][td];
  245+        switch (o) {
  246+        case MLE:
  247+        case MLZ:
  248+        case MVD:
  249+                expand(p, INAREG|INBREG, "\tmovZL AL,A1\n");
  250+                break;
  251+
  252+        case CSE:
  253+                expand(p, INAREG|INBREG, "\tcvtZLl AL,A1\n");
  254+                break;
  255+
  256+        case CVT:
  257+                expand(p, INAREG|INBREG, "\tcvtZLZR AL,A1\n");
  258+                break;
  259+
  260+        case MZE:
  261+                expand(p, INAREG|INBREG, "\tmovzZLl AL,A1\n");
  262+                break;
  263+
  264+        case MVZ:
  265+                expand(p, INAREG|INBREG, "\tmovzZLZR AL,A1\n");
  266+                break;
  267+
  268+        case MZC:
  269+                expand(p, INAREG|INBREG, "\tmovzZLl AL,A1\n");
  270+                expand(p, INAREG|INBREG, "\tcvtlZR A1,A1\n");
  271+                break;
  272+
  273+        default:
  274+                comperr("unsupported conversion %d", o);
  275+        }
  276+        switch (o) {
  277+        case MLE:
  278+        case CSE:
  279+                expand(p, INBREG, "\tashl $-31,A1,U1\n");
  280+                break;
  281+        case MLZ:
  282+        case MZE:
  283+                expand(p, INAREG|INBREG, "\tclrl U1\n");
  284+                break;
  285+        }
193286 }
 194287 
 195288 /*
 196289  * Emit code to compare two longlong numbers.
 197290  */
 198291 static void
 199292 twollcomp(NODE *p)
 200293 {
 201294         int u;
 202295         int s = getlab2();
 203296         int e = p->n_label;
 204297         int cb1, cb2;
 205298 
 206299         u = p->n_op;
 207300         switch (p->n_op) {
 208301         case NE:
 209302                 cb1 = 0;
 210303                 cb2 = NE;
 211304                 break;
 212305         case EQ:
 213306                 cb1 = NE;
 214307                 cb2 = 0;
 215308                 break;
 216309         case LE:
 217310         case LT:
 218311                 u += (ULE-LE);
 219312                 /* FALLTHROUGH */
 220313         case ULE:
 221314         case ULT:
 222315                 cb1 = GT;
 223316                 cb2 = LT;
 224317                 break;
 225318         case GE:
 226319         case GT:
 227320                 u += (ULE-LE);
 228321                 /* FALLTHROUGH */
 229322         case UGE:
 230323         case UGT:
 231324                 cb1 = LT;
 232325                 cb2 = GT;
 233326                 break;
 234327         
 235328         default:
 236329                 cb1 = cb2 = 0; /* XXX gcc */
 237330         }
 238331         if (p->n_op >= ULE)
 239332                 cb1 += 4, cb2 += 4;
 240333         expand(p, 0, "  cmpl UR,UL\n");
 241334         if (cb1) cbgen(cb1, s);
 242335         if (cb2) cbgen(cb2, e);
 243336         expand(p, 0, "  cmpl AL,AR\n");
 244337         cbgen(u, e);
 245338         deflab(s);
 246339 }
 247340 
 248341 
 249342 void
 250343 zzzcode( p, c ) register NODE *p; {
 251344         int m;
 252345         int val;
<> 346+        char *ch;
253347         switch( c ){
 254348 
 255349         case 'N'/* logical ops, turned into 0-1 */
 256350                 /* use register given by register 1 */
 257351                 cbgen( 0, m=getlab2());
 258352                 deflab( p->n_label );
 259353                 printf( "       clrl    %s\n", rnames[getlr( p, '1' )->n_rval] );
 260354                 deflab( m );
 261355                 return;
 262356 
 263357         case 'A':
 264358                 {
 265359                 register NODE *l, *r;
 266360 
 267361                 if (xdebug) e2print(p, 0, &val, &val);
 268362                 r = getlr(p, 'R');
 269363                 if (optype(p->n_op) == LTYPE || p->n_op == UMUL) {
 270364                         l = resc;
 271365                         l->n_type = (r->n_type==FLOAT || r->n_type==DOUBLE ? DOUBLE : INT);
 272366                 } else
 273367                         l = getlr(p, 'L');
 274368                 if (r->n_op == ICON  && r->n_name[0] == '\0') {
 275369                         if (r->n_lval == 0) {
 276370                                 printf("clr");
 277371                                 prtype(l);
 278372                                 printf("        ");
 279373                                 adrput(stdout, l);
 280374                                 return;
 281375                         }
 282376                         if (r->n_lval < 0 && r->n_lval >= -63) {
 283377                                 printf("mneg");
 284378                                 prtype(l);
 285379                                 r->n_lval = -r->n_lval;
 286380                                 goto ops;
 287381                         }
 288382                         r->n_type = (r->n_lval < 0 ?
 289383                                         (r->n_lval >= -128 ? CHAR
 290384                                         : (r->n_lval >= -32768 ? SHORT
 291385                                         : INT )) : r->n_type);
 292386                         r->n_type = (r->n_lval >= 0 ?
 293387                                         (r->n_lval <= 63 ? INT
 294388                                         : ( r->n_lval <= 127 ? CHAR
 295389                                         : (r->n_lval <= 255 ? UCHAR
 296390                                         : (r->n_lval <= 32767 ? SHORT
 297391                                         : (r->n_lval <= 65535 ? USHORT
 298392                                         : INT ))))) : r->n_type );
 299393                         }
 300394                 if (l->n_op == REG && l->n_type != FLOAT && l->n_type != DOUBLE)
 301395                         l->n_type = INT;
 302396                 if (!mixtypes(l,r))
 303397                         {
 304398                         if (tlen(l) == tlen(r))
 305399                                 {
 306400                                 printf("mov");
 307401                                 prtype(l);
 308402                                 goto ops;
 309403                                 }
 310404                         else if (tlen(l) > tlen(r) && ISUNSIGNED(r->n_type))
 311405                                 {
 312406                                 printf("movz");
 313407                                 }
 314408                         else
 315409                                 {
 316410                                 printf("cvt");
 317411                                 }
 318412                         }
 319413                 else
 320414                         {
 321415                         printf("cvt");
 322416                         }
 323417                 prtype(r);
 324418                 prtype(l);
 325419         ops:
 326420                 printf("        ");
 327421                 adrput(stdout, r);
 328422                 printf(",");
 329423                 adrput(stdout, l);
 330424                 return;
 331425                 }
 332426 
 333427         case 'B': /* long long compare */
 334428                 twollcomp(p);
 335429                 break;
 336430 
 337431         case 'C':       /* num words pushed on arg stack */
 338432                 printf("$%d", p->n_qual);
 339433                 break;
 340434 
 341435         case 'D':       /* INCR and DECR */
 342436                 zzzcode(p->n_left, 'A');
 343437                 printf("\n      ");
 344438 
 345439 #if 0
 346440         case 'E':       /* INCR and DECR, FOREFF */
 347441                 if (p->n_right->n_lval == 1)
 348442                         {
 349443                         printf("%s", (p->n_op == INCR ? "inc" : "dec") );
 350444                         prtype(p->n_left);
 351445                         printf("        ");
 352446                         adrput(stdout, p->n_left);
 353447                         return;
 354448                         }
 355449                 printf("%s", (p->n_op == INCR ? "add" : "sub") );
 356450                 prtype(p->n_left);
 357451                 printf("2       ");
 358452                 adrput(stdout, p->n_right);
 359453                 printf(",");
 360454                 adrput(p->n_left);
 361455                 return;
 362456 #endif
 363457 
 364458         case 'F':       /* register type of right operand */
 365459                 {
 366460                 register NODE *n;
 367461                 extern int xdebug;
 368462                 register int ty;
 369463 
 370464                 n = getlr( p, 'R' );
 371465                 ty = n->n_type;
 372466 
 373467                 if (xdebug) printf("->%d<-", ty);
 374468 
 375469                 if ( ty==DOUBLE) printf("d");
 376470                 else if ( ty==FLOAT ) printf("f");
 377471                 else printf("l");
 378472                 return;
 379473                 }
 380474 
<> 475+        case 'G': /* emit conversion instructions */
  476+                sconv(p);
  477+                break;
  478+
381479         case 'J': /* jump or ret? */
 382480                 {
 383481                         struct interpass *ip =
 384482                             DLIST_PREV((struct interpass *)p2env.epp, qelem);
 385483                         if (ip->type != IP_DEFLAB ||
 386484                             ip->ip_lbl != getlr(p, 'L')->n_lval)
 387485                                 expand(p, FOREFF, "jbr  LL");
 388486                         else
 389487                                 printf("ret");
 390488                 }
 391489                 break;
 392490 
 393491         case 'L':       /* type of left operand */
 394492         case 'R':       /* type of right operand */
 395493                 {
 396494                 register NODE *n;
 397495                 extern int xdebug;
 398496 
 399497                 n = getlr ( p, c);
 400498                 if (xdebug) printf("->%d<-", n->n_type);
 401499 
 402500                 prtype(n);
 403501                 return;
 404502                 }
 405503 
<> 504+        case 'O': /* print out emulated ops */
  505+                expand(p, FOREFF, "\tmovq       AR,-(%sp)\n");
  506+                expand(p, FOREFF, "\tmovq       AL,-(%sp)\n");
  507+                if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
  508+                else if (p->n_op == DIV) ch = "div";
  509+                else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
  510+                else if (p->n_op == MOD) ch = "mod";
  511+                else ch = 0, comperr("ZO");
  512+                printf("\tcalls $4,__%sdi3\n", ch);
  513+                break;
  514+
  515+
406516         case 'Z':       /* complement mask for bit instr */
 407517                 printf("$%Ld", ~p->n_right->n_lval);
 408518                 return;
 409519 
 410520         case 'U':       /* 32 - n, for unsigned right shifts */
 411521                 printf("$" CONFMT, 32 - p->n_right->n_lval );
 412522                 return;
 413523 
 414524         case 'T':       /* rounded structure length for arguments */
 415525                 {
 416526                 int size;
 417527 
 418528                 size = p->n_stsize;
 419529                 SETOFF( size, 4);
 420530                 printf("$%d", size);
 421531                 return;
 422532                 }
 423533 
 424534         case 'S'/* structure assignment */
 425535                 {
 426536                         register NODE *l, *r;
 427537                         register int size;
 428538 
 429539                         size = p->n_stsize;
 430540                         l = r = NULL; /* XXX gcc */
 431541                         if( p->n_op == STASG ){
 432542                                 l = p->n_left;
 433543                                 r = p->n_right;
 434544 
 435545                                 }
 436546                         else if( p->n_op == STARG ){
 437547                                 /* store an arg into a temporary */
 438548                                 printf("\tsubl2 $%d,%%sp\n",
 439549                                     size < 4 ? 4 : size);
 440550                                 l = mklnode(OREG, 0, SP, INT);
 441551                                 r = p->n_left;
 442552                                 }
 443553                         else cerror( "STASG bad" );
 444554 
 445555                         if( r->n_op == ICON ) r->n_op = NAME;
 446556                         else if( r->n_op == REG ) r->n_op = OREG;
 447557                         else if( r->n_op != OREG ) cerror( "STASG-r" );
 448558 
 449559                         if( size <= 0 || size > 65535 )
 450560                                 cerror("structure size <0=0 or >65535");
 451561 
 452562                         switch(size) {
 453563                                 case 1:
 454564                                         printf("        movb    ");
 455565                                         break;
 456566                                 case 2:
 457567                                         printf("        movw    ");
 458568                                         break;
 459569                                 case 4:
 460570                                         printf("        movl    ");
 461571                                         break;
 462572                                 case 8:
 463573                                         printf("        movq    ");
 464574                                         break;
 465575                                 default:
 466576                                         printf("        movc3   $%d,", size);
 467577                                         break;
 468578                         }
 469579                         adrput(stdout, r);
 470580                         printf(",");
 471581                         adrput(stdout, l);
 472582                         printf("\n");
 473583 
 474584                         if( r->n_op == NAME ) r->n_op = ICON;
 475585                         else if( r->n_op == OREG ) r->n_op = REG;
 476586                         if (p->n_op == STARG)
 477587                                 tfree(l);
 478588 
 479589                         }
 480590                 break;
 481591 
 482592         default:
 483593                 comperr("illegal zzzcode '%c'", c);
 484594                 }
 485595         }
 486596 
 487597 void
 488598 rmove( int rt,int  rs, TWORD t ){
 489599         printf( "       %s      %s,%s\n",
 490600                 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
 491601                 rnames[rs], rnames[rt] );
 492602         }
 493603 
 494604 #if 0
 495605 setregs(){ /* set up temporary registers */
 496606         fregs = 6;      /* tbl- 6 free regs on VAX (0-5) */
 497607         ;
 498608         }
 499609 
 500610 szty(t){ /* size, in registers, needed to hold thing of type t */
 501611         return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
 502612         }
 503613 #endif
 504614 
 505615 int
 506616 rewfld( p ) NODE *p; {
 507617         return(1);
 508618         }
 509619 
 510620 #if 0
 511621 callreg(p) NODE *p; {
 512622         return( R0 );
 513623         }
 514624 
 515625 base( p ) register NODE *p; {
 516626         register int o = p->op;
 517627 
 518628         if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
 519629         if( o==REG ) return( p->rval );
 520630     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
 521631                 return( p->left->rval );
 522632     if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 523633                 return( p->rval + 0200*1 );
 524634         if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
 525635         if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
 526636         if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
 527637           && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 528638                 return( p->left->left->rval + 0200*(1+2) );
 529639         return( -1 );
 530640         }
 531641 
 532642 offset( p, tyl ) register NODE *p; int tyl; {
 533643 
 534644         if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
 535645         if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
 536646               (p->right->op==ICON && p->right->name[0]=='\0')
 537647               && (1<<p->right->lval)==tyl))
 538648                 return( p->left->rval );
 539649         return( -1 );
 540650         }
 541651 #endif
 542652 
 543653 #if 0
 544654 void
 545655 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
 546656         register NODE *t;
 547657         NODE *f;
 548658 
 549659         p->n_op = OREG;
 550660         f = p->n_left;  /* have to free this subtree later */
 551661 
 552662         /* init base */
 553663         switch (q->n_op) {
 554664                 case ICON:
 555665                 case REG:
 556666                 case OREG:
 557667                         t = q;
 558668                         break;
 559669 
 560670                 case MINUS:
 561671                         q->n_right->n_lval = -q->n_right->n_lval;
 562672                 case PLUS:
 563673                         t = q->n_right;
 564674                         break;
 565675 
 566676                 case UMUL:
 567677                         t = q->n_left->n_left;
 568678                         break;
 569679 
 570680                 default:
 571681                         cerror("illegal makeor2");
 572682                         t = NULL; /* XXX gcc */
 573683         }
 574684 
 575685         p->n_lval = t->n_lval;
 576686         p->n_name = t->n_name;
 577687 
 578688         /* init offset */
 579689         p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
 580690 
 581691         tfree(f);
 582692         return;
 583693         }
 584694 
 585695 int
 586696 canaddr( p ) NODE *p; {
 587697         register int o = p->n_op;
 588698 
 589699         if( o==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_left, STARNM|SOREG)) ) return(1);
 590700         return(0);
 591701         }
 592702 
 593703 shltype( o, p ) register NODE *p; {
 594704         return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 595705         }
 596706 #endif
 597707 
 598708 int
 599709 fldexpand(NODE *p, int cookie, char **cp)
 600710 {
 601711         return 0;
 602712 }
 603713 
 604714 int
 605715 flshape( p ) register NODE *p; {
 606716         return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
 607717                 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
 608718         }
 609719 
 610720 int
 611721 shtemp( p ) register NODE *p; {
 612722         if( p->n_op == STARG ) p = p->n_left;
 613723         return( p->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 614724         }
 615725 
 616726 /*
 617727  * Shape matches for UMUL.  Cooperates with offstar().
 618728  */
 619729 int
 620730 shumul(NODE *p, int shape)
 621731 {
 622732 
 623733         if (x2debug)
 624734                 printf("shumul(%p)\n", p);
 625735 
 626736         /* Turns currently anything into OREG on vax */
 627737         if (shape & SOREG)
 628738                 return SROREG;
 629739         return SRNOPE;
 630740 }
 631741 
 632742 
 633743 #ifdef notdef
 634744 int
 635745 shumul( p, shape ) register NODE *p; int shape; {
 636746         register int o;
 637747         extern int xdebug;
 638748 
 639749         if (xdebug) {
 640750                  printf("\nshumul:op=%d,lop=%d,rop=%d", p->n_op, p->n_left->n_op, p->n_right->n_op);
 641751                 printf(" prname=%s,plty=%d, prlval=%lld\n", p->n_right->n_name, p->n_left->n_type, p->n_right->n_lval);
 642752                 }
 643753 
 644754 
 645755         o = p->n_op;
 646756         if( o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
 647757                 if (shape & STARNM)
 648758                         return SRDIR;
 649759 
 650760         if( ( o == INCR || o == ASG MINUS ) &&
 651761             ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
 652762             p->n_right->n_name[0] == '\0' )
 653763                 {
 654764                 switch (p->n_left->n_type)
 655765                         {
 656766                         case CHAR|PTR:
 657767                         case UCHAR|PTR:
 658768                                 o = 1;
 659769                                 break;
 660770 
 661771                         case SHORT|PTR:
 662772                         case USHORT|PTR:
 663773                                 o = 2;
 664774                                 break;
 665775 
 666776                         case INT|PTR:
 667777                         case UNSIGNED|PTR:
 668778                         case LONG|PTR:
 669779                         case ULONG|PTR:
 670780                         case FLOAT|PTR:
 671781                                 o = 4;
 672782                                 break;
 673783 
 674784                         case DOUBLE|PTR:
 675785                                 o = 8;
 676786                                 break;
 677787 
 678788                         default:
 679789                                 if ( ISPTR(p->n_left->n_type) ) {
 680790                                         o = 4;
 681791                                         break;
 682792                                         }
 683793                                 else return(0);
 684794                         }
 685795                 return( p->n_right->n_lval == o ? STARREG : 0);
 686796                 }
 687797 
 688798         return( SRNOPE );
 689799         }
 690800 #endif
 691801 
 692802 void
 693803 adrcon( val ) CONSZ val; {
 694804         printf( "$" );
 695805         printf( CONFMT, val );
 696806         }
 697807 
 698808 void
 699809 conput(FILE *fp, NODE *p)
 700810 {
 701811         switch( p->n_op ){
 702812 
 703813         case ICON:
 704814                 acon( p );
 705815                 return;
 706816 
 707817         case REG:
 708818                 printf( "%s", rnames[p->n_rval] );
 709819                 return;
 710820 
 711821         default:
 712822                 cerror( "illegal conput" );
 713823                 }
 714824         }
 715825 
 716826 void
 717827 insput( p ) register NODE *p; {
 718828         cerror( "insput" );
 719829         }
 720830 
 721831 /*
 722832  * Write out the upper address, like the upper register of a 2-register
 723833  * reference, or the next memory location.
 724834  */
 725835 void
 726836 upput(NODE *p, int size)
 727837 {
 728838 
 729839         size /= SZCHAR;
 730840         switch (p->n_op) {
 731841         case REG:
 732842                 fprintf(stdout, "%s", rnames[regno(p)-16+1]);
 733843                 break;
 734844 
 735845         case NAME:
 736846         case OREG:
 737847                 p->n_lval += size;
 738848                 adrput(stdout, p);
 739849                 p->n_lval -= size;
 740850                 break;
 741851         case ICON:
 742852                 fprintf(stdout, "$" CONFMT, p->n_lval >> 32);
 743853                 break;
 744854         default:
 745855                 comperr("upput bad op %d size %d", p->n_op, size);
 746856         }
 747857 }
 748858 
 749859 void
 750860 adrput(FILE *fp, NODE *p)
 751861 {
 752862         register int r;
 753863         /* output an address, with offsets, from p */
 754864 
 755865         if( p->n_op == FLD ){
 756866                 p = p->n_left;
 757867                 }
 758868         switch( p->n_op ){
 759869 
 760870         case NAME:
 761871                 acon( p );
 762872                 return;
 763873 
 764874         case ICON:
 765875                 /* addressable value of the constant */
 766876                 if (p->n_name[0] == '\0') /* uses xxxab */
 767877                         printf("$");
 768878                 acon(p);
 769879                 return;
 770880 
 771881         case REG:
 772882                 printf( "%s", rnames[p->n_rval] );
 773883                 return;
 774884 
 775885         case OREG:
 776886                 r = p->n_rval;
 777887                 if( R2TEST(r) ){ /* double indexing */
 778888                         register int flags;
 779889 
 780890                         flags = R2UPK3(r);
 781891                         if( flags & 1 ) printf("*");
 782892                         if( flags & 4 ) printf("-");
 783893                         if( p->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
 784894                         if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
 785895                         if( flags & 2 ) printf("+");
 786896                         printf( "[%s]", rnames[R2UPK2(r)] );
 787897                         return;
 788898                         }
 789899                 if( r == AP ){  /* in the argument region */
 790900                         if( p->n_lval <= 0 || p->n_name[0] != '\0' ) werror( "bad arg temp" );
 791901                         printf( CONFMT, p->n_lval );
<>792 -                        printf( "(ap)" );
  902+                        printf( "(%%ap)" );
<_793903                         return;
 794904                         }
 795905                 if( p->n_lval != 0 || p->n_name[0] != '\0') acon( p );
 796906                 printf( "(%s)", rnames[p->n_rval] );
 797907                 return;
 798908 
 799909         case UMUL:
 800910                 /* STARNM or STARREG found */
 801911                 if( tshape(p, STARNM) ) {
 802912                         printf( "*" );
 803913                         adrput(0p->n_left);
 804914                         }
 805915                 else {  /* STARREG - really auto inc or dec */
 806916                         register NODE *q;
 807917 
 808918 /* tbl
 809919                         p = p->n_left;
 810920                         p->n_left->n_op = OREG;
 811921                         if( p->n_op == INCR ) {
 812922                                 adrput( p->n_left );
 813923                                 printf( "+" );
 814924                                 }
 815925                         else {
 816926                                 printf( "-" );
 817927                                 adrput( p->n_left );
 818928                                 }
 819929    tbl */
 820930 #ifdef notyet
 821931                         printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
 822932                                 rnames[p->n_left->n_left->n_rval],
 823933                                 (p->n_left->n_op==INCR ? '+' : '\0') );
 824934 #else
 825935                         printf("%c(%s)%c", '-',
 826936                                 rnames[p->n_left->n_left->n_rval],
 827937                                 '\0' );
 828938 #endif
 829939                         p->n_op = OREG;
 830940                         p->n_rval = p->n_left->n_left->n_rval;
 831941                         q = p->n_left;
 832942 #ifdef notyet
 833943 
 834944                         p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
 835945 #else
 836946                         p->n_lval = 0;
 837947 #endif
 838948                         p->n_name[0] = '\0';
 839949                         tfree(q);
 840950                 }
 841951                 return;
 842952 
 843953         default:
 844954                 cerror( "illegal address" );
 845955                 return;
 846956         }
 847957 
 848958 }
 849959 
 850960 /*
 851961  * print out a constant
 852962  */
 853963 void
 854964 acon(NODE *p)
 855965 {
 856966 
 857967         if (p->n_name[0] == '\0') {
 858968                 printf(CONFMT, p->n_lval);
 859969         } else if( p->n_lval == 0 ) {
 860970                 printf("%s", p->n_name);
 861971         } else {
 862972                 printf("%s+", p->n_name);
 863973                 printf(CONFMT, p->n_lval);
 864974         }
 865975 }
 866976 
 867977 #if 0
 868978 genscall( p, cookie ) register NODE *p; {
 869979         /* structure valued call */
 870980         return( gencall( p, cookie ) );
 871981         }
 872982 
 873983 /* tbl */
 874984 int gc_numbytes;
 875985 /* tbl */
 876986 
 877987 gencall( p, cookie ) register NODE *p; {
 878988         /* generate the call given by p */
 879989         register NODE *p1, *ptemp;
 880990         register temp, temp1;
 881991         register m;
 882992 
 883993         if( p->right ) temp = argsize( p->right );
 884994         else temp = 0;
 885995 
 886996         if( p->op == STCALL || p->op == UNARY STCALL ){
 887997                 /* set aside room for structure return */
 888998 
 889999                 if( p->stsize > temp ) temp1 = p->stsize;
 8901000                 else temp1 = temp;
 8911001                 }
 8921002 
 8931003         if( temp > maxargs ) maxargs = temp;
 8941004         SETOFF(temp1,4);
 8951005 
 8961006         if( p->right ){ /* make temp node, put offset in, and generate args */
 8971007                 ptemp = talloc();
 8981008                 ptemp->op = OREG;
 8991009                 ptemp->lval = -1;
 9001010                 ptemp->rval = SP;
 9011011                 ptemp->name[0] = '\0';
 9021012                 ptemp->rall = NOPREF;
 9031013                 ptemp->su = 0;
 9041014                 genargs( p->right, ptemp );
 9051015                 nfree(ptemp);
 9061016                 }
 9071017 
 9081018         p1 = p->left;
 9091019         if( p1->op != ICON ){
 9101020                 if( p1->op != REG ){
 9111021                         if( p1->op != OREG || R2TEST(p1->rval) ){
 9121022                                 if( p1->op != NAME ){
 9131023                                         order( p1, INAREG );
 9141024                                         }
 9151025                                 }
 9161026                         }
 9171027                 }
 9181028 
 9191029 /*
 9201030         if( p1->op == REG && p->rval == R5 ){
 9211031                 cerror( "call register overwrite" );
 9221032                 }
 9231033  */
 9241034 /* tbl
 9251035         setup gc_numbytes so reference to ZC works */
 9261036 
 9271037         gc_numbytes = temp;
 9281038 /* tbl */
 9291039 
 9301040         p->op = UNARY CALL;
 9311041         m = match( p, INTAREG|INTBREG );
 9321042 /* tbl
 9331043         switch( temp ) {
 9341044         case 0:
 9351045                 break;
 9361046         case 2:
 9371047                 printf( "       tst     (sp)+\n" );
 9381048                 break;
 9391049         case 4:
 9401050                 printf( "       cmp     (sp)+,(sp)+\n" );
 9411051                 break;
 9421052         default:
 9431053                 printf( "       add     $%d,sp\n", temp);
 9441054                 }
 9451055    tbl */
 9461056         return(m != MDONE);
 9471057         }
 9481058 #endif
 9491059 
 9501060 static char *
 9511061 ccbranches[] = {
 9521062         "jeql",
 9531063         "jneq",
 9541064         "jleq",
 9551065         "jlss",
 9561066         "jgeq",
 9571067         "jgtr",
 9581068         "jlequ",
 9591069         "jlssu",
 9601070         "jgequ",
 9611071         "jgtru",
 9621072 };
 9631073 
 9641074 /*
 9651075  * printf conditional and unconditional branches
 9661076  */
 9671077 void
 9681078 cbgen(int o, int lab)
 9691079 {
 9701080 
 9711081         if (o == 0) {
 9721082                 printf("        jbr     " LABFMT "\n", lab);
 9731083         } else {
 9741084                 if (o > UGT)
 9751085                         comperr("bad conditional branch: %s", opst[o]);
 9761086                 printf("\t%s\t" LABFMT "\n", ccbranches[o-EQ], lab);
 9771087         }
 9781088 }
 9791089 
 9801090 static void
 9811091 optim2(NODE *p, void *arg)
 9821092 {
 9831093         /* do local tree transformations and optimizations */
 9841094 
 9851095         register NODE *r;
 9861096 
 9871097         switch( p->n_op ) {
 9881098 
 9891099         case AND:
 9901100                 /* commute L and R to eliminate compliments and constants */
 9911101                 if( (p->n_left->n_op==ICON&&p->n_left->n_name[0]==0) || p->n_left->n_op==COMPL ) {
 9921102                         r = p->n_left;
 9931103                         p->n_left = p->n_right;
 9941104                         p->n_right = r;
 9951105                         }
 9961106 #if 0
 9971107         case ASG AND:
 9981108                 /* change meaning of AND to ~R&L - bic on pdp11 */
 9991109                 r = p->n_right;
 10001110                 if( r->op==ICON && r->name[0]==0 ) { /* compliment constant */
 10011111                         r->lval = ~r->lval;
 10021112                         }
 10031113                 else if( r->op==COMPL ) { /* ~~A => A */
 10041114                         r->op = FREE;
 10051115                         p->right = r->left;
 10061116                         }
 10071117                 else { /* insert complement node */
 10081118                         p->right = talloc();
 10091119                         p->right->op = COMPL;
 10101120                         p->right->rall = NOPREF;
 10111121                         p->right->type = r->type;
 10121122                         p->right->left = r;
 10131123                         p->right->right = NULL;
 10141124                         }
 10151125                 break;
 10161126 #endif
 10171127                 }
 10181128         }
 10191129 
 10201130 void
 10211131 myreader(struct interpass *ipole)
 10221132 {
 10231133         struct interpass *ip;
 10241134 
 10251135         DLIST_FOREACH(ip, ipole, qelem) {
 10261136                 if (ip->type != IP_NODE)
 10271137                         continue;
 10281138                 walkf(ip->ip_node, optim2, 0);
 10291139         }
 10301140 }
 10311141 
 10321142 void
 10331143 mycanon(NODE *p)
 10341144 {
 10351145 }
 10361146 
 10371147 void
 10381148 myoptim(struct interpass *ip)
 10391149 {
 10401150 }
 10411151 
 10421152 /*
 10431153  * Return argument size in regs.
 10441154  */
 10451155 static int
 10461156 argsiz(NODE *p)
 10471157 {
 10481158         TWORD t = p->n_type;
 10491159 
 10501160         if (t == STRTY || t == UNIONTY)
 10511161                 return p->n_stsize/(SZINT/SZCHAR);
 10521162         return szty(t);
 10531163 }
 10541164 
 10551165 /*
 10561166  * Last chance to do something before calling a function.
 10571167  */
 10581168 void
 10591169 lastcall(NODE *p)
 10601170 {
 10611171         NODE *op = p;
 10621172         int size = 0;
 10631173 
 10641174         /* Calculate argument sizes */
 10651175         p->n_qual = 0;
 10661176         if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
 10671177                 return;
 10681178         for (p = p->n_right; p->n_op == CM; p = p->n_left)
 10691179                 size += argsiz(p->n_right);
 10701180         if (p->n_op != ASSIGN)
 10711181                 size += argsiz(p);
 10721182         op->n_qual = size; /* XXX */
 10731183 }
 10741184 
 10751185 /*
 10761186  * Return a class suitable for a specific type.
 10771187  */
 10781188 int
 10791189 gclass(TWORD t)
 10801190 {
 10811191         return (szty(t) == 2 ? CLASSB : CLASSA);
 10821192 }
 10831193 
 10841194 /*
 10851195  * For class c, find worst-case displacement of the number of
 10861196  * registers in the array r[] indexed by class.
 10871197  */
 10881198 int
 10891199 COLORMAP(int c, int *r)
 10901200 {
 10911201         int num;
 10921202 
 10931203         switch (c) {
 10941204         case CLASSA:
 10951205                 /* there are 12 classa, so min 6 classb are needed to block */
 10961206                 num = r[CLASSB] * 2;
 10971207                 num += r[CLASSA];
 10981208                 return num < 12;
 10991209         case CLASSB:
 11001210                 /* 6 classa may block all classb */
 11011211                 num = r[CLASSB] + r[CLASSA];
 11021212                 return num < 6;
 11031213         }
 11041214         comperr("COLORMAP");
 11051215         return 0; /* XXX gcc */
 11061216 }
 11071217 
 11081218 /*
 11091219  * Special shapes.
 11101220  */
 11111221 int
 11121222 special(NODE *p, int shape)
 11131223 {
 11141224         return SRNOPE;
 11151225 }
 11161226 
 11171227 /*
 11181228  * Target-dependent command-line options.
 11191229  */
 11201230 void
 11211231 mflags(char *str)
 11221232 {
 11231233 }
 11241234 /*
 11251235  * Do something target-dependent for xasm arguments.
 11261236  * Supposed to find target-specific constraints and rewrite them.
 11271237  */
 11281238 int
 11291239 myxasm(struct interpass *ip, NODE *p)
 11301240 {
 11311241         return 0;
 11321242 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-09-02 18:55 +0200