Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.27
 
1.28
 
MAIN:plunky:20120322185617
 
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
 122122 tlen(NODE *p)
 123123 {
 124124         switch(p->n_type) {
 125125         case CHAR:
 126126         case UCHAR:
 127127                 return(1);
 128128 
 129129         case SHORT:
 130130         case USHORT:
 131131                 return(2);
 132132 
 133133         case DOUBLE:
 134134         case LONGLONG:
 135135         case ULONGLONG:
 136136                 return(8);
 137137 
 138138         default:
 139139                 return(4);
 140140         }
 141141 }
 142142 
 143143 void
 144144 prtype(NODE *n)
 145145 {
 146146         static char pt[] = { 0, 0, 'b', 'b', 'w', 'w', 'l', 'l', 0, 0,
 147147             'q', 'q', 'f', 'd' };
 148148         TWORD t = n->n_type;
 149149 
 150150         if (ISPTR(t))
 151151                 t = UNSIGNED;
 152152 
 153153         if (t > DOUBLE || pt[t] == 0)
 154154                 comperr("prtype: bad type");
 155155         putchar(pt[t]);
 156156 }
 157157 
 158158 /*
 159159  * Emit conversions as given by the following table. Dest is always reg,
 160160  *   if it should be something else let peephole optimizer deal with it.
 161161  *   This code ensures type correctness in 32-bit registers.
 162162  *   XXX is that necessary?
 163163  *
 164164  * From                         To
 165165  *       char   uchar  short  ushort int    uint   ll    ull   float double
 166166  * char  movb   movb   cvtbw  cvtbw  cvtbl  cvtbl  A     A     cvtbf cvtbd
 167167  * uchar movb   movb   movzbw movzbw movzbl movzbl B     B     G     G
 168168  * short movb   movb   movw   movw   cvtwl  cvtwl  C(A)  C(A)  cvtwf cvtwd
 169169  * ushrt movb   movb   movw   movw   movzwl movzwl D(B)  D(B)  H     H
 170170  * int   movb   movb   movw   movw   movl   movl   E     E     cvtlf cvtld
 171171  * uint  movb   movb   movw   movw   movl   movl   F     F     I     I
 172172  * ll    movb   movb   movw   movw   movl   movl   movq  movq  J     K
 173173  * ull   movb   movb   movw   movw   movl   movl   movq  movq  L     M
 174174  * float cvtfb  cvtfb  cvtfw  cvtfw  cvtfl  cvtfl  N     O     movf  cvtfd
 175175  * doubl cvtdb  cvtdb  cvtdw  cvtdw  cvtdl  cvtdl  P     Q     cvtdf movd
 176176  *
 177177  *  A: cvtbl + sign extend
 178178  *  B: movzbl + zero extend
 179179  *  G: movzbw + cvtwX
 180180  *  H: movzwl + cvtwX
 181181  *  I: cvtld + addX
 182182  *  J: call __floatdisf
 183183  *  K: call __floatdidf
 184184  *  L: xxx + call __floatdisf
 185185  *  M: xxx + call __floatdidf
 186186  *  N: call __fixsfdi
 187187  *  O: call __fixunssfdi
 188188  *  P: call __fixdfdi
 189189  *  Q: call __fixunsdfdi
 190190  */
 191191 
 192192 #define MVD     1 /* mov + dest type */
 193193 #define CVT     2 /* cvt + src type + dst type */
 194194 #define MVZ     3 /* movz + src type + dst type */
 195195 #define CSE     4 /* cvt + src type + l + sign extend upper */
 196196 #define MZE     5 /* movz + src type + l + zero extend upper */
 197197 #define MLE     6 /* movl + sign extend upper */
 198198 #define MLZ     7 /* movl + zero extend upper */
 199199 #define MZC     8 /* movz + cvt */
 200200 
 201201 static char scary[][10] = {
 202202         { MVD, MVD, CVT, CVT, CVT, CVT, CSE, CSE, CVT, CVT },
 203203         { MVD, MVD, MVZ, MVZ, MVZ, MVZ, MZE, MZE, MZC, MZC },
 204204         { MVD, MVD, MVD, MVD, CVT, CVT, CSE, CSE, CVT, CVT },
 205205         { MVD, MVD, MVD, MVD, MVZ, MVZ, MZE, MZE, MZC, MZC },
 206206         { MVD, MVD, MVD, MVD, MVD, MVD, MLE, MLE, CVT, CVT },
 207207         { MVD, MVD, MVD, MVD, MVD, MVD, MLZ, MLZ, 'I', 'I' },
 208208         { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'J', 'K' },
 209209         { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'L', 'M' },
 210210         { CVT, CVT, CVT, CVT, CVT, CVT, 'N', 'O', MVD, CVT },
 211211         { CVT, CVT, CVT, CVT, CVT, CVT, 'P', 'Q', CVT, MVD },
 212212 };
 213213 
 214214 static void
 215215 sconv(NODE *p)
 216216 {
 217217         NODE *l = p->n_left;
 218218         TWORD ts, td;
 219219         int o;
 220220 
 221221         /*
 222222          * Source node may be in register or memory.
 223223          * Result is always in register.
 224224          */
 225225         ts = l->n_type;
 226226         if (ISPTR(ts))
 227227                 ts = UNSIGNED;
 228228         td = p->n_type;
 229229         ts = ts < LONG ? ts-2 : ts-4;
 230230         td = td < LONG ? td-2 : td-4;
 231231 
 232232         o = scary[ts][td];
 233233         switch (o) {
 234234         case MLE:
 235235         case MLZ:
 236236                 expand(p, INAREG|INBREG, "\tmovl\tAL,A1\n");
 237237                 break;
 238238 
 239239         case MVD:
 240240                 if (l->n_op == REG && regno(l) == regno(getlr(p, '1')))
 241241                         break; /* unneccessary move */
 242242                 expand(p, INAREG|INBREG, "\tmovZR\tAL,A1\n");
 243243                 break;
 244244 
 245245         case CSE:
 246246                 expand(p, INAREG|INBREG, "\tcvtZLl\tAL,A1\n");
 247247                 break;
 248248 
 249249         case CVT:
 250250                 expand(p, INAREG|INBREG, "\tcvtZLZR\tAL,A1\n");
 251251                 break;
 252252 
 253253         case MZE:
 254254                 expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
 255255                 break;
 256256 
 257257         case MVZ:
 258258                 expand(p, INAREG|INBREG, "\tmovzZLZR\tAL,A1\n");
 259259                 break;
 260260 
 261261         case MZC:
 262262                 expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
 263263                 expand(p, INAREG|INBREG, "\tcvtlZR\tA1,A1\n");
 264264                 break;
 265265 
 266266         case 'I': /* unsigned to double */
 267267                 expand(p, INAREG|INBREG, "\tcvtld\tAL,A1\n");
 268268                 printf("\tjgeq\t1f\n");
 269269                 expand(p, INAREG|INBREG, "\taddd2\t$0d4.294967296e+9,A1\n");
 270270                 printf("1:\n");
 271271                 break;
 272272         default:
 273273                 comperr("unsupported conversion %d", o);
 274274         }
 275275         switch (o) {
 276276         case MLE:
 277277         case CSE:
 278278                 expand(p, INBREG, "\tashl\t$-31,A1,U1\n");
 279279                 break;
 280280         case MLZ:
 281281         case MZE:
 282282                 expand(p, INAREG|INBREG, "\tclrl\tU1\n");
 283283                 break;
 284284         }
 285285 }
 286286 
 287287 /*
 288288  * Assign a constant from p to q.  Both are expected to be leaves by now.
 289289  * This is for 64-bit integers.
 290290  */
 291291 static void
 292292 casg64(NODE *p)
 293293 {
 294294         NODE *l, *r;
 295295         char *str;
 296296         int mneg = 1;
 297297         
 298298         l = p->n_left;
 299299         r = p->n_right;
 300300 
 301301 #ifdef PCC_DEBUG
 302302         if (r->n_op != ICON)
 303303                 comperr("casg");
 304304 #endif
 305305         if (r->n_name[0] != '\0') {
 306306                 /* named constant, nothing to do */
 307307                 str = "movq\tAR,AL";
 308308                 mneg = 0;
 309309         } else if (r->n_lval == 0) {
 310310                 str = "clrq\tAL";
 311311                 mneg = 0;
 312312         } else if (r->n_lval < 0) {
 313313                 if (r->n_lval >= -63) {
 314314                         r->n_lval = -r->n_lval;
 315315                         str = "mnegl\tAR,AL";
 316316                 } else if (r->n_lval >= -128) {
 317317                         str = "cvtbl\tAR,AL";
 318318                 } else if (r->n_lval >= -32768) {
 319319                         str = "cvtwl\tAR,AL";
 320320                 } else if (r->n_lval >= -4294967296LL) {
 321321                         str = "movl\tAR,AL";
 322322                 } else {
 323323                         str = "movq\tAR,AL";
 324324                         mneg = 0;
 325325                 }
 326326         } else {
 327327                 mneg = 0;
 328328                 if (r->n_lval <= 63 || r->n_lval > 4294967295LL) {
 329329                         str = "movq\tAR,AL";
 330330                 } else if (r->n_lval <= 255) {
 331331                         str = "movzbl\tAR,AL\n\tclrl\tUL";
 332332                 } else if (r->n_lval <= 65535) {
 333333                         str = "movzwl\tAR,AL\n\tclrl\tUL";
 334334                 } else /* if (r->n_lval <= 4294967295) */ {
 335335                         str = "movl\tAR,AL\n\tclrl\tUL";
 336336                 }
 337337         }
 338338         expand(p, FOREFF, str);
 339339         if (mneg)
 340340                 expand(p, FOREFF, "\n\tmnegl $-1,UL");
 341341 }
 342342 
 343343 /*
 344344  * Assign a constant from p to q.  Both are expected to be leaves by now.
 345345  * This is only for 32-bit integer types.
 346346  */
 347347 static void
 348348 casg(NODE *p)
 349349 {
 350350         NODE *l, *r;
 351351         char *str;
 352352         
 353353         l = p->n_left;
 354354         r = p->n_right;
 355355 
 356356 #ifdef PCC_DEBUG
 357357         if (r->n_op != ICON)
 358358                 comperr("casg");
 359359 #endif
 360360         if (r->n_name[0] != '\0') {
 361361                 /* named constant, nothing to do */
 362362                 str = "movZL\tAR,AL";
 363363         } else if (r->n_lval == 0) {
 364364                 str = "clrZL\tAL";
 365365         } else if (r->n_lval < 0) {
 366366                 if (r->n_lval >= -63) {
 367367                         r->n_lval = -r->n_lval;
 368368                         str = "mnegZL\tAR,AL";
 369369                 } else if (r->n_lval >= -128) {
 370370                         if (l->n_type == CHAR)
 371371                                 str = "movb\tAR,AL";
 372372                         else
 373373                                 str = "cvtbZL\tAR,AL";
 374374                 } else if (r->n_lval >= -32768) {
 375375                         if (l->n_type == SHORT)
 376376                                 str = "movw\tAR,AL";
 377377                         else
 378378                                 str = "cvtwZL\tAR,AL";
 379379                 } else
 380380                         str = "movZL\tAR,AL";
 381381         } else {
 382382                 if (r->n_lval <= 63 || r->n_lval > 65535) {
 383383                         str = "movZL\tAR,AL";
 384384                 } else if (r->n_lval <= 255) {
 385385                         str = l->n_type < SHORT ?
 386386                             "movb\tAR,AL" : "movzbZL\tAR,AL";
 387387                 } else /* if (r->n_lval <= 65535) */ {
 388388                         str = l->n_type < INT ?
 389389                             "movw\tAR,AL" : "movzwZL\tAR,AL";
 390390                 }
 391391         }
 392392         expand(p, FOREFF, str);
 393393 }
 394394 
 395395 /*
 396396  * Emit code to compare two longlong numbers.
 397397  */
 398398 static void
 399399 twollcomp(NODE *p)
 400400 {
 401401         int u;
 402402         int s = getlab2();
 403403         int e = p->n_label;
 404404         int cb1, cb2;
 405405 
 406406         u = p->n_op;
 407407         switch (p->n_op) {
 408408         case NE:
 409409                 cb1 = 0;
 410410                 cb2 = NE;
 411411                 break;
 412412         case EQ:
 413413                 cb1 = NE;
 414414                 cb2 = 0;
 415415                 break;
 416416         case LE:
 417417         case LT:
 418418                 u += (ULE-LE);
 419419                 /* FALLTHROUGH */
 420420         case ULE:
 421421         case ULT:
 422422                 cb1 = GT;
 423423                 cb2 = LT;
 424424                 break;
 425425         case GE:
 426426         case GT:
 427427                 u += (ULE-LE);
 428428                 /* FALLTHROUGH */
 429429         case UGE:
 430430         case UGT:
 431431                 cb1 = LT;
 432432                 cb2 = GT;
 433433                 break;
 434434         
 435435         default:
 436436                 cb1 = cb2 = 0; /* XXX gcc */
 437437         }
 438438         if (p->n_op >= ULE)
 439439                 cb1 += 4, cb2 += 4;
 440440         expand(p, 0, "  cmpl UL,UR\n");
 441441         if (cb1) cbgen(cb1, s);
 442442         if (cb2) cbgen(cb2, e);
 443443         expand(p, 0, "  cmpl AL,AR\n");
 444444         cbgen(u, e);
 445445         deflab(s);
 446446 }
 447447 
 448448 
 449449 void
 450450 zzzcode(NODE *p, int c)
 451451 {
 452452         NODE *l, *r;
 453453         int m;
 454454         char *ch;
 455455 
 456456         switch (c) {
 457457         case 'N'/* logical ops, turned into 0-1 */
 458458                 /* use register given by register 1 */
 459459                 cbgen( 0, m=getlab2());
 460460                 deflab( p->n_label );
 461461                 printf( "       clrl    %s\n", rnames[getlr( p, '1' )->n_rval] );
 462462                 deflab( m );
 463463                 return;
 464464 
 465465         case 'A': /* Assign a constant directly to a memory position */
 466466                 printf("\t");
 467467                 if (p->n_type < LONG || ISPTR(p->n_type))
 468468                         casg(p);
 469469                 else
 470470                         casg64(p);
 471471                 printf("\n");
 472472                 break;
 473473 
 474474         case 'B': /* long long compare */
 475475                 twollcomp(p);
 476476                 break;
 477477 
 478478         case 'C':       /* num words pushed on arg stack */
 479479                 printf("$%d", p->n_qual);
 480480                 break;
 481481 
 482482         case 'D':       /* INCR and DECR */
 483483                 zzzcode(p->n_left, 'A');
 484484                 printf("\n      ");
 485485 
 486486 #if 0
 487487         case 'E':       /* INCR and DECR, FOREFF */
 488488                 if (p->n_right->n_lval == 1)
 489489                         {
 490490                         printf("%s", (p->n_op == INCR ? "inc" : "dec") );
 491491                         prtype(p->n_left);
 492492                         printf("        ");
 493493                         adrput(stdout, p->n_left);
 494494                         return;
 495495                         }
 496496                 printf("%s", (p->n_op == INCR ? "add" : "sub") );
 497497                 prtype(p->n_left);
 498498                 printf("2       ");
 499499                 adrput(stdout, p->n_right);
 500500                 printf(",");
 501501                 adrput(p->n_left);
 502502                 return;
 503503 #endif
 504504 
 505505         case 'F':       /* register type of right operand */
 506506                 {
 507507                 register NODE *n;
<>508 -                extern int xdebug;
509508                 register int ty;
 510509 
 511510                 n = getlr( p, 'R' );
 512511                 ty = n->n_type;
 513512 
<>514 -                if (xdebug) printf("->%d<-", ty);
  513+                if (x2debug) printf("->%d<-", ty);
515514 
 516515                 if ( ty==DOUBLE) printf("d");
 517516                 else if ( ty==FLOAT ) printf("f");
 518517                 else printf("l");
 519518                 return;
 520519                 }
 521520 
 522521         case 'G': /* emit conversion instructions */
 523522                 sconv(p);
 524523                 break;
 525524 
 526525         case 'J': /* jump or ret? */
 527526                 {
 528527                         struct interpass *ip =
 529528                             DLIST_PREV((struct interpass *)p2env.epp, qelem);
 530529                         if (ip->type != IP_DEFLAB ||
 531530                             ip->ip_lbl != getlr(p, 'L')->n_lval)
 532531                                 expand(p, FOREFF, "jbr  LL");
 533532                         else
 534533                                 printf("ret");
 535534                 }
 536535                 break;
 537536 
 538537         case 'L':       /* type of left operand */
 539538         case 'R':       /* type of right operand */
 540539                 {
 541540                 register NODE *n;
<>542 -                extern int xdebug;
543541 
 544542                 n = getlr ( p, c);
<>545 -                if (xdebug) printf("->%d<-", n->n_type);
  543+                if (x2debug) printf("->%d<-", n->n_type);
546544 
 547545                 prtype(n);
 548546                 return;
 549547                 }
 550548 
 551549         case 'O': /* print out emulated ops */
 552550                 expand(p, FOREFF, "\tmovq       AR,-(%sp)\n");
 553551                 expand(p, FOREFF, "\tmovq       AL,-(%sp)\n");
 554552                 if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
 555553                 else if (p->n_op == DIV) ch = "div";
 556554                 else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
 557555                 else if (p->n_op == MOD) ch = "mod";
 558556                 else if (p->n_op == MUL) ch = "mul";
 559557                 else ch = 0, comperr("ZO %d", p->n_op);
 560558                 printf("\tcalls $4,__%sdi3\n", ch);
 561559                 break;
 562560 
 563561 
 564562         case 'Z':       /* complement mask for bit instr */
 565563                 printf("$%Ld", ~p->n_right->n_lval);
 566564                 return;
 567565 
 568566         case 'U':       /* 32 - n, for unsigned right shifts */
 569567                 m = p->n_left->n_type == UCHAR ? 8 :
 570568                     p->n_left->n_type == USHORT ? 16 : 32;
 571569                 printf("$" CONFMT, m - p->n_right->n_lval);
 572570                 return;
 573571 
 574572         case 'T':       /* rounded structure length for arguments */
 575573                 {
 576574                 int size;
 577575 
 578576                 size = p->n_stsize;
 579577                 SETOFF( size, 4);
 580578                 printf("$%d", size);
 581579                 return;
 582580                 }
 583581 
 584582         case 'S'/* structure assignment */
 585583                 {
 586584                         register int size;
 587585 
 588586                         size = p->n_stsize;
 589587                         l = r = NULL; /* XXX gcc */
 590588                         if( p->n_op == STASG ){
 591589                                 l = p->n_left;
 592590                                 r = p->n_right;
 593591 
 594592                                 }
 595593                         else if( p->n_op == STARG ){
 596594                                 /* store an arg into a temporary */
 597595                                 printf("\tsubl2 $%d,%%sp\n",
 598596                                     size < 4 ? 4 : size);
 599597                                 l = mklnode(OREG, 0, SP, INT);
 600598                                 r = p->n_left;
 601599                                 }
 602600                         else cerror( "STASG bad" );
 603601 
 604602                         if( r->n_op == ICON ) r->n_op = NAME;
 605603                         else if( r->n_op == REG ) r->n_op = OREG;
 606604                         else if( r->n_op != OREG ) cerror( "STASG-r" );
 607605 
 608606                         if( size <= 0 || size > 65535 )
 609607                                 cerror("structure size <0=0 or >65535");
 610608 
 611609                         switch(size) {
 612610                                 case 1:
 613611                                         printf("        movb    ");
 614612                                         break;
 615613                                 case 2:
 616614                                         printf("        movw    ");
 617615                                         break;
 618616                                 case 4:
 619617                                         printf("        movl    ");
 620618                                         break;
 621619                                 case 8:
 622620                                         printf("        movq    ");
 623621                                         break;
 624622                                 default:
 625623                                         printf("        movc3   $%d,", size);
 626624                                         break;
 627625                         }
 628626                         adrput(stdout, r);
 629627                         printf(",");
 630628                         adrput(stdout, l);
 631629                         printf("\n");
 632630 
 633631                         if( r->n_op == NAME ) r->n_op = ICON;
 634632                         else if( r->n_op == OREG ) r->n_op = REG;
 635633                         if (p->n_op == STARG)
 636634                                 tfree(l);
 637635 
 638636                         }
 639637                 break;
 640638 
 641639         default:
 642640                 comperr("illegal zzzcode '%c'", c);
 643641         }
 644642 }
 645643 
 646644 void
 647645 rmove( int rt,int  rs, TWORD t ){
 648646         printf( "       %s      %s,%s\n",
 649647                 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
 650648                 rnames[rt], rnames[rs] );
 651649         }
 652650 
 653651 #if 0
 654652 setregs(){ /* set up temporary registers */
 655653         fregs = 6;      /* tbl- 6 free regs on VAX (0-5) */
 656654         ;
 657655         }
 658656 
 659657 szty(t){ /* size, in registers, needed to hold thing of type t */
 660658         return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
 661659         }
 662660 #endif
 663661 
 664662 int
 665663 rewfld( p ) NODE *p; {
 666664         return(1);
 667665         }
 668666 
 669667 #if 0
 670668 callreg(p) NODE *p; {
 671669         return( R0 );
 672670         }
 673671 
 674672 base( p ) register NODE *p; {
 675673         register int o = p->op;
 676674 
 677675         if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
 678676         if( o==REG ) return( p->rval );
 679677     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
 680678                 return( p->left->rval );
 681679     if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 682680                 return( p->rval + 0200*1 );
 683681         if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
 684682         if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
 685683         if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
 686684           && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 687685                 return( p->left->left->rval + 0200*(1+2) );
 688686         return( -1 );
 689687         }
 690688 
 691689 offset( p, tyl ) register NODE *p; int tyl; {
 692690 
 693691         if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
 694692         if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
 695693               (p->right->op==ICON && p->right->name[0]=='\0')
 696694               && (1<<p->right->lval)==tyl))
 697695                 return( p->left->rval );
 698696         return( -1 );
 699697         }
 700698 #endif
 701699 
 702700 #if 0
 703701 void
 704702 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
 705703         register NODE *t;
 706704         NODE *f;
 707705 
 708706         p->n_op = OREG;
 709707         f = p->n_left;  /* have to free this subtree later */
 710708 
 711709         /* init base */
 712710         switch (q->n_op) {
 713711                 case ICON:
 714712                 case REG:
 715713                 case OREG:
 716714                         t = q;
 717715                         break;
 718716 
 719717                 case MINUS:
 720718                         q->n_right->n_lval = -q->n_right->n_lval;
 721719                 case PLUS:
 722720                         t = q->n_right;
 723721                         break;
 724722 
 725723                 case UMUL:
 726724                         t = q->n_left->n_left;
 727725                         break;
 728726 
 729727                 default:
 730728                         cerror("illegal makeor2");
 731729                         t = NULL; /* XXX gcc */
 732730         }
 733731 
 734732         p->n_lval = t->n_lval;
 735733         p->n_name = t->n_name;
 736734 
 737735         /* init offset */
 738736         p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
 739737 
 740738         tfree(f);
 741739         return;
 742740         }
 743741 
 744742 int
 745743 canaddr( p ) NODE *p; {
 746744         register int o = p->n_op;
 747745 
 748746         if( o==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_left, STARNM|SOREG)) ) return(1);
 749747         return(0);
 750748         }
 751749 
 752750 shltype( o, p ) register NODE *p; {
 753751         return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 754752         }
 755753 #endif
 756754 
 757755 int
 758756 fldexpand(NODE *p, int cookie, char **cp)
 759757 {
 760758         return 0;
 761759 }
 762760 
 763761 int
 764762 flshape( p ) register NODE *p; {
 765763         return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
 766764                 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
 767765         }
 768766 
 769767 int
 770768 shtemp( p ) register NODE *p; {
 771769         if( p->n_op == STARG ) p = p->n_left;
 772770         return( p->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 773771         }
 774772 
 775773 /*
 776774  * Shape matches for UMUL.  Cooperates with offstar().
 777775  */
 778776 int
 779777 shumul(NODE *p, int shape)
 780778 {
 781779 
 782780         if (x2debug)
 783781                 printf("shumul(%p)\n", p);
 784782 
 785783         /* Turns currently anything into OREG on vax */
 786784         if (shape & SOREG)
 787785                 return SROREG;
 788786         return SRNOPE;
 789787 }
 790788 
 791789 
 792790 #ifdef notdef
 793791 int
 794792 shumul( p, shape ) register NODE *p; int shape; {
 795793         register int o;
<>796 -        extern int xdebug;
797794 
<>798 -        if (xdebug) {
  795+        if (x2debug) {
<_799796                  printf("\nshumul:op=%d,lop=%d,rop=%d", p->n_op, p->n_left->n_op, p->n_right->n_op);
 800797                 printf(" prname=%s,plty=%d, prlval=%lld\n", p->n_right->n_name, p->n_left->n_type, p->n_right->n_lval);
 801798                 }
 802799 
 803800 
 804801         o = p->n_op;
 805802         if( o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
 806803                 if (shape & STARNM)
 807804                         return SRDIR;
 808805 
 809806         if( ( o == INCR || o == ASG MINUS ) &&
 810807             ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
 811808             p->n_right->n_name[0] == '\0' )
 812809                 {
 813810                 switch (p->n_left->n_type)
 814811                         {
 815812                         case CHAR|PTR:
 816813                         case UCHAR|PTR:
 817814                                 o = 1;
 818815                                 break;
 819816 
 820817                         case SHORT|PTR:
 821818                         case USHORT|PTR:
 822819                                 o = 2;
 823820                                 break;
 824821 
 825822                         case INT|PTR:
 826823                         case UNSIGNED|PTR:
 827824                         case LONG|PTR:
 828825                         case ULONG|PTR:
 829826                         case FLOAT|PTR:
 830827                                 o = 4;
 831828                                 break;
 832829 
 833830                         case DOUBLE|PTR:
 834831                                 o = 8;
 835832                                 break;
 836833 
 837834                         default:
 838835                                 if ( ISPTR(p->n_left->n_type) ) {
 839836                                         o = 4;
 840837                                         break;
 841838                                         }
 842839                                 else return(0);
 843840                         }
 844841                 return( p->n_right->n_lval == o ? STARREG : 0);
 845842                 }
 846843 
 847844         return( SRNOPE );
 848845         }
 849846 #endif
 850847 
 851848 void
 852849 adrcon( val ) CONSZ val; {
 853850         printf( "$" );
 854851         printf( CONFMT, val );
 855852         }
 856853 
 857854 void
 858855 conput(FILE *fp, NODE *p)
 859856 {
 860857         switch( p->n_op ){
 861858 
 862859         case ICON:
 863860                 acon( p );
 864861                 return;
 865862 
 866863         case REG:
 867864                 printf( "%s", rnames[p->n_rval] );
 868865                 return;
 869866 
 870867         default:
 871868                 cerror( "illegal conput" );
 872869                 }
 873870         }
 874871 
 875872 void
 876873 insput( p ) register NODE *p; {
 877874         cerror( "insput" );
 878875         }
 879876 
 880877 /*
 881878  * Write out the upper address, like the upper register of a 2-register
 882879  * reference, or the next memory location.
 883880  */
 884881 void
 885882 upput(NODE *p, int size)
 886883 {
 887884 
 888885         size /= SZCHAR;
 889886         switch (p->n_op) {
 890887         case REG:
 891888                 fprintf(stdout, "%s", rnames[regno(p)-16+1]);
 892889                 break;
 893890 
 894891         case NAME:
 895892         case OREG:
 896893                 p->n_lval += size;
 897894                 adrput(stdout, p);
 898895                 p->n_lval -= size;
 899896                 break;
 900897         case ICON:
 901898                 fprintf(stdout, "$" CONFMT, p->n_lval >> 32);
 902899                 break;
 903900         default:
 904901                 comperr("upput bad op %d size %d", p->n_op, size);
 905902         }
 906903 }
 907904 
 908905 void
 909906 adrput(FILE *fp, NODE *p)
 910907 {
 911908         register int r;
 912909         /* output an address, with offsets, from p */
 913910 
 914911         if( p->n_op == FLD ){
 915912                 p = p->n_left;
 916913                 }
 917914         switch( p->n_op ){
 918915 
 919916         case NAME:
 920917                 acon( p );
 921918                 return;
 922919 
 923920         case ICON:
 924921                 /* addressable value of the constant */
 925922                 if (p->n_name[0] == '\0') /* uses xxxab */
 926923                         printf("$");
 927924                 acon(p);
 928925                 return;
 929926 
 930927         case REG:
 931928                 printf( "%s", rnames[p->n_rval] );
 932929                 return;
 933930 
 934931         case OREG:
 935932                 r = p->n_rval;
 936933                 if( R2TEST(r) ){ /* double indexing */
 937934                         register int flags;
 938935 
 939936                         flags = R2UPK3(r);
 940937                         if( flags & 1 ) printf("*");
 941938                         if( flags & 4 ) printf("-");
 942939                         if( p->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
 943940                         if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
 944941                         if( flags & 2 ) printf("+");
 945942                         printf( "[%s]", rnames[R2UPK2(r)] );
 946943                         return;
 947944                         }
 948945                 if( r == AP ){  /* in the argument region */
 949946                         if( p->n_lval <= 0 || p->n_name[0] != '\0' )
 950947                                 werror( "bad arg temp" );
 951948                         printf( CONFMT, p->n_lval );
 952949                         printf( "(%%ap)" );
 953950                         return;
 954951                         }
 955952                 if( p->n_lval != 0 || p->n_name[0] != '\0') acon( p );
 956953                 printf( "(%s)", rnames[p->n_rval] );
 957954                 return;
 958955 
 959956         case UMUL:
 960957                 /* STARNM or STARREG found */
 961958                 if( tshape(p, STARNM) ) {
 962959                         printf( "*" );
 963960                         adrput(0p->n_left);
 964961                         }
 965962                 else {  /* STARREG - really auto inc or dec */
 966963                         register NODE *q;
 967964 
 968965 /* tbl
 969966                         p = p->n_left;
 970967                         p->n_left->n_op = OREG;
 971968                         if( p->n_op == INCR ) {
 972969                                 adrput( p->n_left );
 973970                                 printf( "+" );
 974971                                 }
 975972                         else {
 976973                                 printf( "-" );
 977974                                 adrput( p->n_left );
 978975                                 }
 979976    tbl */
 980977 #ifdef notyet
 981978                         printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
 982979                                 rnames[p->n_left->n_left->n_rval],
 983980                                 (p->n_left->n_op==INCR ? '+' : '\0') );
 984981 #else
 985982                         printf("%c(%s)%c", '-',
 986983                                 rnames[p->n_left->n_left->n_rval],
 987984                                 '\0' );
 988985 #endif
 989986                         p->n_op = OREG;
 990987                         p->n_rval = p->n_left->n_left->n_rval;
 991988                         q = p->n_left;
 992989 #ifdef notyet
 993990 
 994991                         p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
 995992 #else
 996993                         p->n_lval = 0;
 997994 #endif
 998995                         p->n_name[0] = '\0';
 999996                         tfree(q);
 1000997                 }
 1001998                 return;
 1002999 
 10031000         default:
 10041001                 cerror( "illegal address" );
 10051002                 return;
 10061003         }
 10071004 
 10081005 }
 10091006 
 10101007 /*
 10111008  * print out a constant
 10121009  */
 10131010 void
 10141011 acon(NODE *p)
 10151012 {
 10161013 
 10171014         if (p->n_name[0] == '\0') {
 10181015                 printf(CONFMT, p->n_lval);
 10191016         } else if( p->n_lval == 0 ) {
 10201017                 printf("%s", p->n_name);
 10211018         } else {
 10221019                 printf("%s+", p->n_name);
 10231020                 printf(CONFMT, p->n_lval);
 10241021         }
 10251022 }
 10261023 
 10271024 #if 0
 10281025 genscall( p, cookie ) register NODE *p; {
 10291026         /* structure valued call */
 10301027         return( gencall( p, cookie ) );
 10311028         }
 10321029 
 10331030 /* tbl */
 10341031 int gc_numbytes;
 10351032 /* tbl */
 10361033 
 10371034 gencall( p, cookie ) register NODE *p; {
 10381035         /* generate the call given by p */
 10391036         register NODE *p1, *ptemp;
 10401037         register temp, temp1;
 10411038         register m;
 10421039 
 10431040         if( p->right ) temp = argsize( p->right );
 10441041         else temp = 0;
 10451042 
 10461043         if( p->op == STCALL || p->op == UNARY STCALL ){
 10471044                 /* set aside room for structure return */
 10481045 
 10491046                 if( p->stsize > temp ) temp1 = p->stsize;
 10501047                 else temp1 = temp;
 10511048                 }
 10521049 
 10531050         if( temp > maxargs ) maxargs = temp;
 10541051         SETOFF(temp1,4);
 10551052 
 10561053         if( p->right ){ /* make temp node, put offset in, and generate args */
 10571054                 ptemp = talloc();
 10581055                 ptemp->op = OREG;
 10591056                 ptemp->lval = -1;
 10601057                 ptemp->rval = SP;
 10611058                 ptemp->name[0] = '\0';
 10621059                 ptemp->rall = NOPREF;
 10631060                 ptemp->su = 0;
 10641061                 genargs( p->right, ptemp );
 10651062                 nfree(ptemp);
 10661063                 }
 10671064 
 10681065         p1 = p->left;
 10691066         if( p1->op != ICON ){
 10701067                 if( p1->op != REG ){
 10711068                         if( p1->op != OREG || R2TEST(p1->rval) ){
 10721069                                 if( p1->op != NAME ){
 10731070                                         order( p1, INAREG );
 10741071                                         }
 10751072                                 }
 10761073                         }
 10771074                 }
 10781075 
 10791076 /*
 10801077         if( p1->op == REG && p->rval == R5 ){
 10811078                 cerror( "call register overwrite" );
 10821079                 }
 10831080  */
 10841081 /* tbl
 10851082         setup gc_numbytes so reference to ZC works */
 10861083 
 10871084         gc_numbytes = temp;
 10881085 /* tbl */
 10891086 
 10901087         p->op = UNARY CALL;
 10911088         m = match( p, INTAREG|INTBREG );
 10921089 /* tbl
 10931090         switch( temp ) {
 10941091         case 0:
 10951092                 break;
 10961093         case 2:
 10971094                 printf( "       tst     (%sp)+\n" );
 10981095                 break;
 10991096         case 4:
 11001097                 printf( "       cmp     (%sp)+,(%sp)+\n" );
 11011098                 break;
 11021099         default:
 11031100                 printf( "       add     $%d,%sp\n", temp);
 11041101                 }
 11051102    tbl */
 11061103         return(m != MDONE);
 11071104         }
 11081105 #endif
 11091106 
 11101107 static char *
 11111108 ccbranches[] = {
 11121109         "jeql",
 11131110         "jneq",
 11141111         "jleq",
 11151112         "jlss",
 11161113         "jgeq",
 11171114         "jgtr",
 11181115         "jlequ",
 11191116         "jlssu",
 11201117         "jgequ",
 11211118         "jgtru",
 11221119 };
 11231120 
 11241121 /*
 11251122  * printf conditional and unconditional branches
 11261123  */
 11271124 void
 11281125 cbgen(int o, int lab)
 11291126 {
 11301127 
 11311128         if (o == 0) {
 11321129                 printf("        jbr     " LABFMT "\n", lab);
 11331130         } else {
 11341131                 if (o > UGT)
 11351132                         comperr("bad conditional branch: %s", opst[o]);
 11361133                 printf("\t%s\t" LABFMT "\n", ccbranches[o-EQ], lab);
 11371134         }
 11381135 }
 11391136 
 11401137 static void
 11411138 mkcall(NODE *p, char *name)
 11421139 {
 11431140         p->n_op = CALL;
 11441141         p->n_right = mkunode(FUNARG, p->n_left, 0, p->n_left->n_type);
 11451142         p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
 11461143         p->n_left->n_name = "__fixunsdfdi";
 11471144 }
 11481145 
 11491146 /* do local tree transformations and optimizations */
 11501147 static void
 11511148 optim2(NODE *p, void *arg)
 11521149 {
 11531150         NODE *r, *s;
 11541151         TWORD lt;
 11551152 
 11561153         switch (p->n_op) {
 11571154         case MOD:
 11581155                 if (p->n_type == USHORT || p->n_type == UCHAR) {
 11591156                         r = mkunode(SCONV, p->n_left, 0, UNSIGNED);
 11601157                         r = mkunode(FUNARG, r, 0, UNSIGNED);
 11611158                         s = mkunode(SCONV, p->n_right, 0, UNSIGNED);
 11621159                         s = mkunode(FUNARG, s, 0, UNSIGNED);
 11631160                         r = mkbinode(CM, r, s, INT);
 11641161                         s = mklnode(ICON, 0, 0, FTN|UNSIGNED);
 11651162                         s->n_name = "__urem";
 11661163                         p->n_left = mkbinode(CALL, s, r, UNSIGNED);
 11671164                         p->n_op = SCONV;
 11681165                 } else if (p->n_type == UNSIGNED) {
 11691166                         p->n_left = mkunode(FUNARG, p->n_left, 0, UNSIGNED);
 11701167                         p->n_right = mkunode(FUNARG, p->n_right, 0, UNSIGNED);
 11711168                         p->n_right = mkbinode(CM, p->n_left, p->n_right, INT);
 11721169                         p->n_left = mklnode(ICON, 0, 0, FTN|UNSIGNED);
 11731170                         p->n_left->n_name = "__urem";
 11741171                         p->n_op = CALL;
 11751172                 }
 11761173                 break;
 11771174 
 11781175         case RS:
 11791176                 if (p->n_type == ULONGLONG) {
 11801177                         p->n_right = mkbinode(CM,
 11811178                             mkunode(FUNARG, p->n_left, 0, p->n_left->n_type),
 11821179                             mkunode(FUNARG, p->n_right, 0, p->n_right->n_type),
 11831180                             INT);
 11841181                         p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
 11851182                         p->n_left->n_name = "__lshrdi3";
 11861183                         p->n_op = CALL;
 11871184                 } else if (p->n_type == INT) {
 11881185                         /* convert >> to << with negative shift count */
 11891186                         /* RS of char & short must use extv */
 11901187                         if (p->n_right->n_op == ICON) {
 11911188                                 p->n_right->n_lval = -p->n_right->n_lval;
 11921189                         } else if (p->n_right->n_op == UMINUS) {
 11931190                                 r = p->n_right->n_left;
 11941191                                 nfree(p->n_right);
 11951192                                 p->n_right = r;
 11961193                         } else {
 11971194                                 p->n_right = mkunode(UMINUS, p->n_right,
 11981195                                     0, p->n_right->n_type);
 11991196                         }
 12001197                         p->n_op = LS;
 12011198                 }
 12021199                 break;
 12031200 
 12041201         case AND:
 12051202                 /* commute L and R to eliminate compliments and constants */
 12061203                 if ((p->n_left->n_op == ICON && p->n_left->n_name[0] == 0) ||
 12071204                     p->n_left->n_op==COMPL) {
 12081205                         r = p->n_left;
 12091206                         p->n_left = p->n_right;
 12101207                         p->n_right = r;
 12111208                 }
 12121209                 /* change meaning of AND to ~R&L - bic on pdp11 */
 12131210                 r = p->n_right;
 12141211                 if (r->n_op == ICON && r->n_name[0] == 0) {
 12151212                         /* compliment constant */
 12161213                         r->n_lval = ~r->n_lval;
 12171214                 } else if (r->n_op == COMPL) { /* ~~A => A */
 12181215                         s = r->n_left;
 12191216                         nfree(r);
 12201217                         p->n_right = s;
 12211218                 } else { /* insert complement node */
 12221219                         p->n_right = mkunode(COMPL, r, 0, r->n_type);
 12231220                 }
 12241221                 break;
 12251222         case SCONV:
 12261223                 lt = p->n_left->n_type;
 12271224                 switch (p->n_type) {
 12281225                 case LONGLONG:
 12291226                         if (lt == FLOAT)
 12301227                                 mkcall(p, "__fixsfdi");
 12311228                         else if (lt == DOUBLE)
 12321229                                 mkcall(p, "__fixdfdi");
 12331230                         break;
 12341231                 case ULONGLONG:
 12351232                         if (lt == FLOAT)
 12361233                                 mkcall(p, "__fixunssfdi");
 12371234                         else if (lt == DOUBLE)
 12381235                                 mkcall(p, "__fixunsdfdi");
 12391236                         break;
 12401237                 case FLOAT:
 12411238                         if (lt == LONGLONG)
 12421239                                 mkcall(p, "__floatdisf");
 12431240                         else if (lt == ULONGLONG) {
 12441241                                 p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
 12451242                                 p->n_type = FLOAT;
 12461243                                 mkcall(p->n_left, "__floatunsdidf");
 12471244                         } else if (lt == UNSIGNED) {
 12481245                                 /* insert an extra double-to-float sconv */
 12491246                                 p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
 12501247                         }
 12511248                         break;
 12521249                 case DOUBLE:
 12531250                         if (lt == LONGLONG)
 12541251                                 mkcall(p, "__floatdidf");
 12551252                         else if (lt == ULONGLONG)
 12561253                                 mkcall(p->n_left, "__floatunsdidf");
 12571254                         break;
 12581255                         
 12591256                 }
 12601257                 break;
 12611258         }
 12621259 }
 12631260 
 12641261 void
 12651262 myreader(struct interpass *ipole)
 12661263 {
 12671264         struct interpass *ip;
 12681265 
 12691266         DLIST_FOREACH(ip, ipole, qelem) {
 12701267                 if (ip->type != IP_NODE)
 12711268                         continue;
 12721269                 walkf(ip->ip_node, optim2, 0);
 12731270         }
 12741271 }
 12751272 
 12761273 void
 12771274 mycanon(NODE *p)
 12781275 {
 12791276 }
 12801277 
 12811278 void
 12821279 myoptim(struct interpass *ip)
 12831280 {
 12841281 }
 12851282 
 12861283 /*
 12871284  * Return argument size in regs.
 12881285  */
 12891286 static int
 12901287 argsiz(NODE *p)
 12911288 {
 12921289         TWORD t = p->n_type;
 12931290 
 12941291         if (t == STRTY || t == UNIONTY)
 12951292                 return p->n_stsize/(SZINT/SZCHAR);
 12961293         return szty(t);
 12971294 }
 12981295 
 12991296 /*
 13001297  * Last chance to do something before calling a function.
 13011298  */
 13021299 void
 13031300 lastcall(NODE *p)
 13041301 {
 13051302         NODE *op = p;
 13061303         int size = 0;
 13071304 
 13081305         /* Calculate argument sizes */
 13091306         p->n_qual = 0;
 13101307         if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
 13111308                 return;
 13121309         for (p = p->n_right; p->n_op == CM; p = p->n_left)
 13131310                 size += argsiz(p->n_right);
 13141311         if (p->n_op != ASSIGN)
 13151312                 size += argsiz(p);
 13161313         op->n_qual = size; /* XXX */
 13171314 }
 13181315 
 13191316 /*
 13201317  * Return a class suitable for a specific type.
 13211318  */
 13221319 int
 13231320 gclass(TWORD t)
 13241321 {
 13251322         return (szty(t) == 2 ? CLASSB : CLASSA);
 13261323 }
 13271324 
 13281325 /*
 13291326  * For class c, find worst-case displacement of the number of
 13301327  * registers in the array r[] indexed by class.
 13311328  */
 13321329 int
 13331330 COLORMAP(int c, int *r)
 13341331 {
 13351332         int num;
 13361333         int a,b;
 13371334 
 13381335         a = r[CLASSA];
 13391336         b = r[CLASSB];
 13401337         switch (c) {
 13411338         case CLASSA:
 13421339                 /* there are 12 classa, so min 6 classb are needed to block */
 13431340                 num = b * 2;
 13441341                 num += a;
 13451342                 return num < 12;
 13461343         case CLASSB:
 13471344                 if (b > 3) return 0;
 13481345                 if (b > 2 && a) return 0;
 13491346                 if (b > 1 && a > 2) return 0;
 13501347                 if (b && a > 3) return 0;
 13511348                 if (a > 5) return 0;
 13521349                 return 1;
 13531350         }
 13541351         comperr("COLORMAP");
 13551352         return 0; /* XXX gcc */
 13561353 }
 13571354 
 13581355 /*
 13591356  * Special shapes.
 13601357  */
 13611358 int
 13621359 special(NODE *p, int shape)
 13631360 {
 13641361         return SRNOPE;
 13651362 }
 13661363 
 13671364 /*
 13681365  * Target-dependent command-line options.
 13691366  */
 13701367 void
 13711368 mflags(char *str)
 13721369 {
 13731370 }
 13741371 /*
 13751372  * Do something target-dependent for xasm arguments.
 13761373  * Supposed to find target-specific constraints and rewrite them.
 13771374  */
 13781375 int
 13791376 myxasm(struct interpass *ip, NODE *p)
 13801377 {
 13811378         return 0;
 13821379 }
 13831380 
 13841381 int
 13851382 xasmconstregs(char *s)
 13861383 {
 13871384         int i;
 13881385 
 13891386         for (i = 0; i < 16; i++)
 13901387                 if (strcmp(&rnames[i][1], s) == 0)
 13911388                         return i;
 13921389         return -1;
 13931390 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-23 04:03 +0100