Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.24
 
1.25
 
MAIN:ragge:20110728071346
 
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:
<> 236+                expand(p, INAREG|INBREG, "\tmovl\tAL,A1\n");
  237+                break;
  238+
236239         case MVD:
<>237 -                expand(p, INAREG|INBREG, "\tmovZL\tAL,A1\n");
  240+                if (l->n_op == REG && regno(l) == regno(getlr(p, '1')))
  241+                        break; /* unneccessary move */
  242+                expand(p, INAREG|INBREG, "\tmovZR\tAL,A1\n");
<_238243                 break;
 239244 
 240245         case CSE:
 241246                 expand(p, INAREG|INBREG, "\tcvtZLl\tAL,A1\n");
 242247                 break;
 243248 
 244249         case CVT:
 245250                 expand(p, INAREG|INBREG, "\tcvtZLZR\tAL,A1\n");
 246251                 break;
 247252 
 248253         case MZE:
 249254                 expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
 250255                 break;
 251256 
 252257         case MVZ:
 253258                 expand(p, INAREG|INBREG, "\tmovzZLZR\tAL,A1\n");
 254259                 break;
 255260 
 256261         case MZC:
 257262                 expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
 258263                 expand(p, INAREG|INBREG, "\tcvtlZR\tA1,A1\n");
 259264                 break;
 260265 
 261266         case 'I': /* unsigned to double */
 262267                 expand(p, INAREG|INBREG, "\tcvtld\tAL,A1\n");
 263268                 printf("\tjgeq\t1f\n");
 264269                 expand(p, INAREG|INBREG, "\taddd2\t$0d4.294967296e+9,A1\n");
 265270                 printf("1:\n");
 266271                 break;
 267272         default:
 268273                 comperr("unsupported conversion %d", o);
 269274         }
 270275         switch (o) {
 271276         case MLE:
 272277         case CSE:
 273278                 expand(p, INBREG, "\tashl\t$-31,A1,U1\n");
 274279                 break;
 275280         case MLZ:
 276281         case MZE:
 277282                 expand(p, INAREG|INBREG, "\tclrl\tU1\n");
 278283                 break;
 279284         }
 280285 }
 281286 
 282287 /*
 283288  * Assign a constant from p to q.  Both are expected to be leaves by now.
 284289  * This is for 64-bit integers.
 285290  */
 286291 static void
 287292 casg64(NODE *p)
 288293 {
 289294         NODE *l, *r;
 290295         char *str;
 291296         int mneg = 1;
 292297         
 293298         l = p->n_left;
 294299         r = p->n_right;
 295300 
 296301 #ifdef PCC_DEBUG
 297302         if (r->n_op != ICON)
 298303                 comperr("casg");
 299304 #endif
 300305         if (r->n_name[0] != '\0') {
 301306                 /* named constant, nothing to do */
 302307                 str = "movq\tAR,AL";
 303308                 mneg = 0;
 304309         } else if (r->n_lval == 0) {
 305310                 str = "clrq\tAL";
 306311                 mneg = 0;
 307312         } else if (r->n_lval < 0) {
 308313                 if (r->n_lval >= -63) {
 309314                         r->n_lval = -r->n_lval;
 310315                         str = "mnegl\tAR,AL";
 311316                 } else if (r->n_lval >= -128) {
 312317                         str = "cvtbl\tAR,AL";
 313318                 } else if (r->n_lval >= -32768) {
 314319                         str = "cvtwl\tAR,AL";
 315320                 } else if (r->n_lval >= -4294967296LL) {
 316321                         str = "movl\tAR,AL";
 317322                 } else {
 318323                         str = "movq\tAR,AL";
 319324                         mneg = 0;
 320325                 }
 321326         } else {
 322327                 mneg = 0;
 323328                 if (r->n_lval <= 63 || r->n_lval > 4294967295LL) {
 324329                         str = "movq\tAR,AL";
 325330                 } else if (r->n_lval <= 255) {
 326331                         str = "movzbl\tAR,AL\n\tclrl\tUL";
 327332                 } else if (r->n_lval <= 65535) {
 328333                         str = "movzwl\tAR,AL\n\tclrl\tUL";
 329334                 } else /* if (r->n_lval <= 4294967295) */ {
 330335                         str = "movl\tAR,AL\n\tclrl\tUL";
 331336                 }
 332337         }
 333338         expand(p, FOREFF, str);
 334339         if (mneg)
 335340                 expand(p, FOREFF, "\n\tmnegl $-1,UL");
 336341 }
 337342 
 338343 /*
 339344  * Assign a constant from p to q.  Both are expected to be leaves by now.
 340345  * This is only for 32-bit integer types.
 341346  */
 342347 static void
 343348 casg(NODE *p)
 344349 {
 345350         NODE *l, *r;
 346351         char *str;
 347352         
 348353         l = p->n_left;
 349354         r = p->n_right;
 350355 
 351356 #ifdef PCC_DEBUG
 352357         if (r->n_op != ICON)
 353358                 comperr("casg");
 354359 #endif
 355360         if (r->n_name[0] != '\0') {
 356361                 /* named constant, nothing to do */
 357362                 str = "movZL\tAR,AL";
 358363         } else if (r->n_lval == 0) {
 359364                 str = "clrZL\tAL";
 360365         } else if (r->n_lval < 0) {
 361366                 if (r->n_lval >= -63) {
 362367                         r->n_lval = -r->n_lval;
 363368                         str = "mnegZL\tAR,AL";
 364369                 } else if (r->n_lval >= -128) {
 365370                         if (l->n_type == CHAR)
 366371                                 str = "movb\tAR,AL";
 367372                         else
 368373                                 str = "cvtbZL\tAR,AL";
 369374                 } else if (r->n_lval >= -32768) {
 370375                         if (l->n_type == SHORT)
 371376                                 str = "movw\tAR,AL";
 372377                         else
 373378                                 str = "cvtwZL\tAR,AL";
 374379                 } else
 375380                         str = "movZL\tAR,AL";
 376381         } else {
 377382                 if (r->n_lval <= 63 || r->n_lval > 65535) {
 378383                         str = "movZL\tAR,AL";
 379384                 } else if (r->n_lval <= 255) {
 380385                         str = l->n_type < SHORT ?
 381386                             "movb\tAR,AL" : "movzbZL\tAR,AL";
 382387                 } else /* if (r->n_lval <= 65535) */ {
 383388                         str = l->n_type < INT ?
 384389                             "movw\tAR,AL" : "movzwZL\tAR,AL";
 385390                 }
 386391         }
 387392         expand(p, FOREFF, str);
 388393 }
 389394 
 390395 /*
 391396  * Emit code to compare two longlong numbers.
 392397  */
 393398 static void
 394399 twollcomp(NODE *p)
 395400 {
 396401         int u;
 397402         int s = getlab2();
 398403         int e = p->n_label;
 399404         int cb1, cb2;
 400405 
 401406         u = p->n_op;
 402407         switch (p->n_op) {
 403408         case NE:
 404409                 cb1 = 0;
 405410                 cb2 = NE;
 406411                 break;
 407412         case EQ:
 408413                 cb1 = NE;
 409414                 cb2 = 0;
 410415                 break;
 411416         case LE:
 412417         case LT:
 413418                 u += (ULE-LE);
 414419                 /* FALLTHROUGH */
 415420         case ULE:
 416421         case ULT:
 417422                 cb1 = GT;
 418423                 cb2 = LT;
 419424                 break;
 420425         case GE:
 421426         case GT:
 422427                 u += (ULE-LE);
 423428                 /* FALLTHROUGH */
 424429         case UGE:
 425430         case UGT:
 426431                 cb1 = LT;
 427432                 cb2 = GT;
 428433                 break;
 429434         
 430435         default:
 431436                 cb1 = cb2 = 0; /* XXX gcc */
 432437         }
 433438         if (p->n_op >= ULE)
 434439                 cb1 += 4, cb2 += 4;
 435440         expand(p, 0, "  cmpl UR,UL\n");
 436441         if (cb1) cbgen(cb1, s);
 437442         if (cb2) cbgen(cb2, e);
 438443         expand(p, 0, "  cmpl AL,AR\n");
 439444         cbgen(u, e);
 440445         deflab(s);
 441446 }
 442447 
 443448 
 444449 void
 445450 zzzcode(NODE *p, int c)
 446451 {
 447452         NODE *l, *r;
 448453         int m;
 449454         char *ch;
 450455 
 451456         switch (c) {
 452457         case 'N'/* logical ops, turned into 0-1 */
 453458                 /* use register given by register 1 */
 454459                 cbgen( 0, m=getlab2());
 455460                 deflab( p->n_label );
 456461                 printf( "       clrl    %s\n", rnames[getlr( p, '1' )->n_rval] );
 457462                 deflab( m );
 458463                 return;
 459464 
 460465         case 'A': /* Assign a constant directly to a memory position */
 461466                 printf("\t");
 462467                 if (p->n_type < LONG || ISPTR(p->n_type))
 463468                         casg(p);
 464469                 else
 465470                         casg64(p);
 466471                 printf("\n");
 467472                 break;
 468473 
 469474         case 'B': /* long long compare */
 470475                 twollcomp(p);
 471476                 break;
 472477 
 473478         case 'C':       /* num words pushed on arg stack */
 474479                 printf("$%d", p->n_qual);
 475480                 break;
 476481 
 477482         case 'D':       /* INCR and DECR */
 478483                 zzzcode(p->n_left, 'A');
 479484                 printf("\n      ");
 480485 
 481486 #if 0
 482487         case 'E':       /* INCR and DECR, FOREFF */
 483488                 if (p->n_right->n_lval == 1)
 484489                         {
 485490                         printf("%s", (p->n_op == INCR ? "inc" : "dec") );
 486491                         prtype(p->n_left);
 487492                         printf("        ");
 488493                         adrput(stdout, p->n_left);
 489494                         return;
 490495                         }
 491496                 printf("%s", (p->n_op == INCR ? "add" : "sub") );
 492497                 prtype(p->n_left);
 493498                 printf("2       ");
 494499                 adrput(stdout, p->n_right);
 495500                 printf(",");
 496501                 adrput(p->n_left);
 497502                 return;
 498503 #endif
 499504 
 500505         case 'F':       /* register type of right operand */
 501506                 {
 502507                 register NODE *n;
 503508                 extern int xdebug;
 504509                 register int ty;
 505510 
 506511                 n = getlr( p, 'R' );
 507512                 ty = n->n_type;
 508513 
 509514                 if (xdebug) printf("->%d<-", ty);
 510515 
 511516                 if ( ty==DOUBLE) printf("d");
 512517                 else if ( ty==FLOAT ) printf("f");
 513518                 else printf("l");
 514519                 return;
 515520                 }
 516521 
 517522         case 'G': /* emit conversion instructions */
 518523                 sconv(p);
 519524                 break;
 520525 
 521526         case 'J': /* jump or ret? */
 522527                 {
 523528                         struct interpass *ip =
 524529                             DLIST_PREV((struct interpass *)p2env.epp, qelem);
 525530                         if (ip->type != IP_DEFLAB ||
 526531                             ip->ip_lbl != getlr(p, 'L')->n_lval)
 527532                                 expand(p, FOREFF, "jbr  LL");
 528533                         else
 529534                                 printf("ret");
 530535                 }
 531536                 break;
 532537 
 533538         case 'L':       /* type of left operand */
 534539         case 'R':       /* type of right operand */
 535540                 {
 536541                 register NODE *n;
 537542                 extern int xdebug;
 538543 
 539544                 n = getlr ( p, c);
 540545                 if (xdebug) printf("->%d<-", n->n_type);
 541546 
 542547                 prtype(n);
 543548                 return;
 544549                 }
 545550 
 546551         case 'O': /* print out emulated ops */
 547552                 expand(p, FOREFF, "\tmovq       AR,-(%sp)\n");
 548553                 expand(p, FOREFF, "\tmovq       AL,-(%sp)\n");
 549554                 if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
 550555                 else if (p->n_op == DIV) ch = "div";
 551556                 else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
 552557                 else if (p->n_op == MOD) ch = "mod";
 553558                 else if (p->n_op == MUL) ch = "mul";
 554559                 else ch = 0, comperr("ZO %d", p->n_op);
 555560                 printf("\tcalls $4,__%sdi3\n", ch);
 556561                 break;
 557562 
 558563 
 559564         case 'Z':       /* complement mask for bit instr */
 560565                 printf("$%Ld", ~p->n_right->n_lval);
 561566                 return;
 562567 
 563568         case 'U':       /* 32 - n, for unsigned right shifts */
 564569                 m = p->n_left->n_type == UCHAR ? 8 :
 565570                     p->n_left->n_type == USHORT ? 16 : 32;
 566571                 printf("$" CONFMT, m - p->n_right->n_lval);
 567572                 return;
 568573 
 569574         case 'T':       /* rounded structure length for arguments */
 570575                 {
 571576                 int size;
 572577 
 573578                 size = p->n_stsize;
 574579                 SETOFF( size, 4);
 575580                 printf("$%d", size);
 576581                 return;
 577582                 }
 578583 
 579584         case 'S'/* structure assignment */
 580585                 {
 581586                         register int size;
 582587 
 583588                         size = p->n_stsize;
 584589                         l = r = NULL; /* XXX gcc */
 585590                         if( p->n_op == STASG ){
 586591                                 l = p->n_left;
 587592                                 r = p->n_right;
 588593 
 589594                                 }
 590595                         else if( p->n_op == STARG ){
 591596                                 /* store an arg into a temporary */
 592597                                 printf("\tsubl2 $%d,%%sp\n",
 593598                                     size < 4 ? 4 : size);
 594599                                 l = mklnode(OREG, 0, SP, INT);
 595600                                 r = p->n_left;
 596601                                 }
 597602                         else cerror( "STASG bad" );
 598603 
 599604                         if( r->n_op == ICON ) r->n_op = NAME;
 600605                         else if( r->n_op == REG ) r->n_op = OREG;
 601606                         else if( r->n_op != OREG ) cerror( "STASG-r" );
 602607 
 603608                         if( size <= 0 || size > 65535 )
 604609                                 cerror("structure size <0=0 or >65535");
 605610 
 606611                         switch(size) {
 607612                                 case 1:
 608613                                         printf("        movb    ");
 609614                                         break;
 610615                                 case 2:
 611616                                         printf("        movw    ");
 612617                                         break;
 613618                                 case 4:
 614619                                         printf("        movl    ");
 615620                                         break;
 616621                                 case 8:
 617622                                         printf("        movq    ");
 618623                                         break;
 619624                                 default:
 620625                                         printf("        movc3   $%d,", size);
 621626                                         break;
 622627                         }
 623628                         adrput(stdout, r);
 624629                         printf(",");
 625630                         adrput(stdout, l);
 626631                         printf("\n");
 627632 
 628633                         if( r->n_op == NAME ) r->n_op = ICON;
 629634                         else if( r->n_op == OREG ) r->n_op = REG;
 630635                         if (p->n_op == STARG)
 631636                                 tfree(l);
 632637 
 633638                         }
 634639                 break;
 635640 
 636641         default:
 637642                 comperr("illegal zzzcode '%c'", c);
 638643         }
 639644 }
 640645 
 641646 void
 642647 rmove( int rt,int  rs, TWORD t ){
 643648         printf( "       %s      %s,%s\n",
 644649                 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
 645650                 rnames[rs], rnames[rt] );
 646651         }
 647652 
 648653 #if 0
 649654 setregs(){ /* set up temporary registers */
 650655         fregs = 6;      /* tbl- 6 free regs on VAX (0-5) */
 651656         ;
 652657         }
 653658 
 654659 szty(t){ /* size, in registers, needed to hold thing of type t */
 655660         return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
 656661         }
 657662 #endif
 658663 
 659664 int
 660665 rewfld( p ) NODE *p; {
 661666         return(1);
 662667         }
 663668 
 664669 #if 0
 665670 callreg(p) NODE *p; {
 666671         return( R0 );
 667672         }
 668673 
 669674 base( p ) register NODE *p; {
 670675         register int o = p->op;
 671676 
 672677         if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
 673678         if( o==REG ) return( p->rval );
 674679     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
 675680                 return( p->left->rval );
 676681     if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 677682                 return( p->rval + 0200*1 );
 678683         if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
 679684         if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
 680685         if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
 681686           && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 682687                 return( p->left->left->rval + 0200*(1+2) );
 683688         return( -1 );
 684689         }
 685690 
 686691 offset( p, tyl ) register NODE *p; int tyl; {
 687692 
 688693         if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
 689694         if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
 690695               (p->right->op==ICON && p->right->name[0]=='\0')
 691696               && (1<<p->right->lval)==tyl))
 692697                 return( p->left->rval );
 693698         return( -1 );
 694699         }
 695700 #endif
 696701 
 697702 #if 0
 698703 void
 699704 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
 700705         register NODE *t;
 701706         NODE *f;
 702707 
 703708         p->n_op = OREG;
 704709         f = p->n_left;  /* have to free this subtree later */
 705710 
 706711         /* init base */
 707712         switch (q->n_op) {
 708713                 case ICON:
 709714                 case REG:
 710715                 case OREG:
 711716                         t = q;
 712717                         break;
 713718 
 714719                 case MINUS:
 715720                         q->n_right->n_lval = -q->n_right->n_lval;
 716721                 case PLUS:
 717722                         t = q->n_right;
 718723                         break;
 719724 
 720725                 case UMUL:
 721726                         t = q->n_left->n_left;
 722727                         break;
 723728 
 724729                 default:
 725730                         cerror("illegal makeor2");
 726731                         t = NULL; /* XXX gcc */
 727732         }
 728733 
 729734         p->n_lval = t->n_lval;
 730735         p->n_name = t->n_name;
 731736 
 732737         /* init offset */
 733738         p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
 734739 
 735740         tfree(f);
 736741         return;
 737742         }
 738743 
 739744 int
 740745 canaddr( p ) NODE *p; {
 741746         register int o = p->n_op;
 742747 
 743748         if( o==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_left, STARNM|SOREG)) ) return(1);
 744749         return(0);
 745750         }
 746751 
 747752 shltype( o, p ) register NODE *p; {
 748753         return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 749754         }
 750755 #endif
 751756 
 752757 int
 753758 fldexpand(NODE *p, int cookie, char **cp)
 754759 {
 755760         return 0;
 756761 }
 757762 
 758763 int
 759764 flshape( p ) register NODE *p; {
 760765         return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
 761766                 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
 762767         }
 763768 
 764769 int
 765770 shtemp( p ) register NODE *p; {
 766771         if( p->n_op == STARG ) p = p->n_left;
 767772         return( p->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 768773         }
 769774 
 770775 /*
 771776  * Shape matches for UMUL.  Cooperates with offstar().
 772777  */
 773778 int
 774779 shumul(NODE *p, int shape)
 775780 {
 776781 
 777782         if (x2debug)
 778783                 printf("shumul(%p)\n", p);
 779784 
 780785         /* Turns currently anything into OREG on vax */
 781786         if (shape & SOREG)
 782787                 return SROREG;
 783788         return SRNOPE;
 784789 }
 785790 
 786791 
 787792 #ifdef notdef
 788793 int
 789794 shumul( p, shape ) register NODE *p; int shape; {
 790795         register int o;
 791796         extern int xdebug;
 792797 
 793798         if (xdebug) {
 794799                  printf("\nshumul:op=%d,lop=%d,rop=%d", p->n_op, p->n_left->n_op, p->n_right->n_op);
 795800                 printf(" prname=%s,plty=%d, prlval=%lld\n", p->n_right->n_name, p->n_left->n_type, p->n_right->n_lval);
 796801                 }
 797802 
 798803 
 799804         o = p->n_op;
 800805         if( o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
 801806                 if (shape & STARNM)
 802807                         return SRDIR;
 803808 
 804809         if( ( o == INCR || o == ASG MINUS ) &&
 805810             ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
 806811             p->n_right->n_name[0] == '\0' )
 807812                 {
 808813                 switch (p->n_left->n_type)
 809814                         {
 810815                         case CHAR|PTR:
 811816                         case UCHAR|PTR:
 812817                                 o = 1;
 813818                                 break;
 814819 
 815820                         case SHORT|PTR:
 816821                         case USHORT|PTR:
 817822                                 o = 2;
 818823                                 break;
 819824 
 820825                         case INT|PTR:
 821826                         case UNSIGNED|PTR:
 822827                         case LONG|PTR:
 823828                         case ULONG|PTR:
 824829                         case FLOAT|PTR:
 825830                                 o = 4;
 826831                                 break;
 827832 
 828833                         case DOUBLE|PTR:
 829834                                 o = 8;
 830835                                 break;
 831836 
 832837                         default:
 833838                                 if ( ISPTR(p->n_left->n_type) ) {
 834839                                         o = 4;
 835840                                         break;
 836841                                         }
 837842                                 else return(0);
 838843                         }
 839844                 return( p->n_right->n_lval == o ? STARREG : 0);
 840845                 }
 841846 
 842847         return( SRNOPE );
 843848         }
 844849 #endif
 845850 
 846851 void
 847852 adrcon( val ) CONSZ val; {
 848853         printf( "$" );
 849854         printf( CONFMT, val );
 850855         }
 851856 
 852857 void
 853858 conput(FILE *fp, NODE *p)
 854859 {
 855860         switch( p->n_op ){
 856861 
 857862         case ICON:
 858863                 acon( p );
 859864                 return;
 860865 
 861866         case REG:
 862867                 printf( "%s", rnames[p->n_rval] );
 863868                 return;
 864869 
 865870         default:
 866871                 cerror( "illegal conput" );
 867872                 }
 868873         }
 869874 
 870875 void
 871876 insput( p ) register NODE *p; {
 872877         cerror( "insput" );
 873878         }
 874879 
 875880 /*
 876881  * Write out the upper address, like the upper register of a 2-register
 877882  * reference, or the next memory location.
 878883  */
 879884 void
 880885 upput(NODE *p, int size)
 881886 {
 882887 
 883888         size /= SZCHAR;
 884889         switch (p->n_op) {
 885890         case REG:
 886891                 fprintf(stdout, "%s", rnames[regno(p)-16+1]);
 887892                 break;
 888893 
 889894         case NAME:
 890895         case OREG:
 891896                 p->n_lval += size;
 892897                 adrput(stdout, p);
 893898                 p->n_lval -= size;
 894899                 break;
 895900         case ICON:
 896901                 fprintf(stdout, "$" CONFMT, p->n_lval >> 32);
 897902                 break;
 898903         default:
 899904                 comperr("upput bad op %d size %d", p->n_op, size);
 900905         }
 901906 }
 902907 
 903908 void
 904909 adrput(FILE *fp, NODE *p)
 905910 {
 906911         register int r;
 907912         /* output an address, with offsets, from p */
 908913 
 909914         if( p->n_op == FLD ){
 910915                 p = p->n_left;
 911916                 }
 912917         switch( p->n_op ){
 913918 
 914919         case NAME:
 915920                 acon( p );
 916921                 return;
 917922 
 918923         case ICON:
 919924                 /* addressable value of the constant */
 920925                 if (p->n_name[0] == '\0') /* uses xxxab */
 921926                         printf("$");
 922927                 acon(p);
 923928                 return;
 924929 
 925930         case REG:
 926931                 printf( "%s", rnames[p->n_rval] );
 927932                 return;
 928933 
 929934         case OREG:
 930935                 r = p->n_rval;
 931936                 if( R2TEST(r) ){ /* double indexing */
 932937                         register int flags;
 933938 
 934939                         flags = R2UPK3(r);
 935940                         if( flags & 1 ) printf("*");
 936941                         if( flags & 4 ) printf("-");
 937942                         if( p->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
 938943                         if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
 939944                         if( flags & 2 ) printf("+");
 940945                         printf( "[%s]", rnames[R2UPK2(r)] );
 941946                         return;
 942947                         }
 943948                 if( r == AP ){  /* in the argument region */
 944949                         if( p->n_lval <= 0 || p->n_name[0] != '\0' )
 945950                                 werror( "bad arg temp" );
 946951                         printf( CONFMT, p->n_lval );
 947952                         printf( "(%%ap)" );
 948953                         return;
 949954                         }
 950955                 if( p->n_lval != 0 || p->n_name[0] != '\0') acon( p );
 951956                 printf( "(%s)", rnames[p->n_rval] );
 952957                 return;
 953958 
 954959         case UMUL:
 955960                 /* STARNM or STARREG found */
 956961                 if( tshape(p, STARNM) ) {
 957962                         printf( "*" );
 958963                         adrput(0p->n_left);
 959964                         }
 960965                 else {  /* STARREG - really auto inc or dec */
 961966                         register NODE *q;
 962967 
 963968 /* tbl
 964969                         p = p->n_left;
 965970                         p->n_left->n_op = OREG;
 966971                         if( p->n_op == INCR ) {
 967972                                 adrput( p->n_left );
 968973                                 printf( "+" );
 969974                                 }
 970975                         else {
 971976                                 printf( "-" );
 972977                                 adrput( p->n_left );
 973978                                 }
 974979    tbl */
 975980 #ifdef notyet
 976981                         printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
 977982                                 rnames[p->n_left->n_left->n_rval],
 978983                                 (p->n_left->n_op==INCR ? '+' : '\0') );
 979984 #else
 980985                         printf("%c(%s)%c", '-',
 981986                                 rnames[p->n_left->n_left->n_rval],
 982987                                 '\0' );
 983988 #endif
 984989                         p->n_op = OREG;
 985990                         p->n_rval = p->n_left->n_left->n_rval;
 986991                         q = p->n_left;
 987992 #ifdef notyet
 988993 
 989994                         p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
 990995 #else
 991996                         p->n_lval = 0;
 992997 #endif
 993998                         p->n_name[0] = '\0';
 994999                         tfree(q);
 9951000                 }
 9961001                 return;
 9971002 
 9981003         default:
 9991004                 cerror( "illegal address" );
 10001005                 return;
 10011006         }
 10021007 
 10031008 }
 10041009 
 10051010 /*
 10061011  * print out a constant
 10071012  */
 10081013 void
 10091014 acon(NODE *p)
 10101015 {
 10111016 
 10121017         if (p->n_name[0] == '\0') {
 10131018                 printf(CONFMT, p->n_lval);
 10141019         } else if( p->n_lval == 0 ) {
 10151020                 printf("%s", p->n_name);
 10161021         } else {
 10171022                 printf("%s+", p->n_name);
 10181023                 printf(CONFMT, p->n_lval);
 10191024         }
 10201025 }
 10211026 
 10221027 #if 0
 10231028 genscall( p, cookie ) register NODE *p; {
 10241029         /* structure valued call */
 10251030         return( gencall( p, cookie ) );
 10261031         }
 10271032 
 10281033 /* tbl */
 10291034 int gc_numbytes;
 10301035 /* tbl */
 10311036 
 10321037 gencall( p, cookie ) register NODE *p; {
 10331038         /* generate the call given by p */
 10341039         register NODE *p1, *ptemp;
 10351040         register temp, temp1;
 10361041         register m;
 10371042 
 10381043         if( p->right ) temp = argsize( p->right );
 10391044         else temp = 0;
 10401045 
 10411046         if( p->op == STCALL || p->op == UNARY STCALL ){
 10421047                 /* set aside room for structure return */
 10431048 
 10441049                 if( p->stsize > temp ) temp1 = p->stsize;
 10451050                 else temp1 = temp;
 10461051                 }
 10471052 
 10481053         if( temp > maxargs ) maxargs = temp;
 10491054         SETOFF(temp1,4);
 10501055 
 10511056         if( p->right ){ /* make temp node, put offset in, and generate args */
 10521057                 ptemp = talloc();
 10531058                 ptemp->op = OREG;
 10541059                 ptemp->lval = -1;
 10551060                 ptemp->rval = SP;
 10561061                 ptemp->name[0] = '\0';
 10571062                 ptemp->rall = NOPREF;
 10581063                 ptemp->su = 0;
 10591064                 genargs( p->right, ptemp );
 10601065                 nfree(ptemp);
 10611066                 }
 10621067 
 10631068         p1 = p->left;
 10641069         if( p1->op != ICON ){
 10651070                 if( p1->op != REG ){
 10661071                         if( p1->op != OREG || R2TEST(p1->rval) ){
 10671072                                 if( p1->op != NAME ){
 10681073                                         order( p1, INAREG );
 10691074                                         }
 10701075                                 }
 10711076                         }
 10721077                 }
 10731078 
 10741079 /*
 10751080         if( p1->op == REG && p->rval == R5 ){
 10761081                 cerror( "call register overwrite" );
 10771082                 }
 10781083  */
 10791084 /* tbl
 10801085         setup gc_numbytes so reference to ZC works */
 10811086 
 10821087         gc_numbytes = temp;
 10831088 /* tbl */
 10841089 
 10851090         p->op = UNARY CALL;
 10861091         m = match( p, INTAREG|INTBREG );
 10871092 /* tbl
 10881093         switch( temp ) {
 10891094         case 0:
 10901095                 break;
 10911096         case 2:
 10921097                 printf( "       tst     (%sp)+\n" );
 10931098                 break;
 10941099         case 4:
 10951100                 printf( "       cmp     (%sp)+,(%sp)+\n" );
 10961101                 break;
 10971102         default:
 10981103                 printf( "       add     $%d,%sp\n", temp);
 10991104                 }
 11001105    tbl */
 11011106         return(m != MDONE);
 11021107         }
 11031108 #endif
 11041109 
 11051110 static char *
 11061111 ccbranches[] = {
 11071112         "jeql",
 11081113         "jneq",
 11091114         "jleq",
 11101115         "jlss",
 11111116         "jgeq",
 11121117         "jgtr",
 11131118         "jlequ",
 11141119         "jlssu",
 11151120         "jgequ",
 11161121         "jgtru",
 11171122 };
 11181123 
 11191124 /*
 11201125  * printf conditional and unconditional branches
 11211126  */
 11221127 void
 11231128 cbgen(int o, int lab)
 11241129 {
 11251130 
 11261131         if (o == 0) {
 11271132                 printf("        jbr     " LABFMT "\n", lab);
 11281133         } else {
 11291134                 if (o > UGT)
 11301135                         comperr("bad conditional branch: %s", opst[o]);
 11311136                 printf("\t%s\t" LABFMT "\n", ccbranches[o-EQ], lab);
 11321137         }
 11331138 }
 11341139 
 11351140 static void
 11361141 mkcall(NODE *p, char *name)
 11371142 {
 11381143         p->n_op = CALL;
 11391144         p->n_right = mkunode(FUNARG, p->n_left, 0, p->n_left->n_type);
 11401145         p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
 11411146         p->n_left->n_name = "__fixunsdfdi";
 11421147 }
 11431148 
 11441149 /* do local tree transformations and optimizations */
 11451150 static void
 11461151 optim2(NODE *p, void *arg)
 11471152 {
 11481153         NODE *r, *s;
 11491154         TWORD lt;
 11501155 
 11511156         switch (p->n_op) {
 11521157         case MOD:
 11531158                 if (p->n_type == USHORT || p->n_type == UCHAR) {
 11541159                         r = mkunode(SCONV, p->n_left, 0, UNSIGNED);
 11551160                         r = mkunode(FUNARG, r, 0, UNSIGNED);
 11561161                         s = mkunode(SCONV, p->n_right, 0, UNSIGNED);
 11571162                         s = mkunode(FUNARG, s, 0, UNSIGNED);
 11581163                         r = mkbinode(CM, r, s, INT);
 11591164                         s = mklnode(ICON, 0, 0, FTN|UNSIGNED);
 11601165                         s->n_name = "__urem";
 11611166                         p->n_left = mkbinode(CALL, s, r, UNSIGNED);
 11621167                         p->n_op = SCONV;
 11631168                 } else if (p->n_type == UNSIGNED) {
 11641169                         p->n_left = mkunode(FUNARG, p->n_left, 0, UNSIGNED);
 11651170                         p->n_right = mkunode(FUNARG, p->n_right, 0, UNSIGNED);
 11661171                         p->n_right = mkbinode(CM, p->n_left, p->n_right, INT);
 11671172                         p->n_left = mklnode(ICON, 0, 0, FTN|UNSIGNED);
 11681173                         p->n_left->n_name = "__urem";
 11691174                         p->n_op = CALL;
 11701175                 }
 11711176                 break;
 11721177 
 11731178         case RS:
 11741179                 if (p->n_type == ULONGLONG) {
 11751180                         p->n_right = mkbinode(CM,
 11761181                             mkunode(FUNARG, p->n_left, 0, p->n_left->n_type),
 11771182                             mkunode(FUNARG, p->n_right, 0, p->n_right->n_type),
 11781183                             INT);
 11791184                         p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
 11801185                         p->n_left->n_name = "__lshrdi3";
 11811186                         p->n_op = CALL;
 11821187                 } else if (p->n_type == INT) {
 11831188                         /* convert >> to << with negative shift count */
 11841189                         /* RS of char & short must use extv */
 11851190                         if (p->n_right->n_op == ICON) {
 11861191                                 p->n_right->n_lval = -p->n_right->n_lval;
 11871192                         } else if (p->n_right->n_op == UMINUS) {
 11881193                                 r = p->n_right->n_left;
 11891194                                 nfree(p->n_right);
 11901195                                 p->n_right = r;
 11911196                         } else {
 11921197                                 p->n_right = mkunode(UMINUS, p->n_right,
 11931198                                     0, p->n_right->n_type);
 11941199                         }
 11951200                         p->n_op = LS;
 11961201                 }
 11971202                 break;
 11981203 
 11991204         case AND:
 12001205                 /* commute L and R to eliminate compliments and constants */
 12011206                 if ((p->n_left->n_op == ICON && p->n_left->n_name[0] == 0) ||
 12021207                     p->n_left->n_op==COMPL) {
 12031208                         r = p->n_left;
 12041209                         p->n_left = p->n_right;
 12051210                         p->n_right = r;
 12061211                 }
 12071212                 /* change meaning of AND to ~R&L - bic on pdp11 */
 12081213                 r = p->n_right;
 12091214                 if (r->n_op == ICON && r->n_name[0] == 0) {
 12101215                         /* compliment constant */
 12111216                         r->n_lval = ~r->n_lval;
 12121217                 } else if (r->n_op == COMPL) { /* ~~A => A */
 12131218                         s = r->n_left;
 12141219                         nfree(r);
 12151220                         p->n_right = s;
 12161221                 } else { /* insert complement node */
 12171222                         p->n_right = mkunode(COMPL, r, 0, r->n_type);
 12181223                 }
 12191224                 break;
 12201225         case SCONV:
 12211226                 lt = p->n_left->n_type;
 12221227                 switch (p->n_type) {
 12231228                 case LONGLONG:
 12241229                         if (lt == FLOAT)
 12251230                                 mkcall(p, "__fixsfdi");
 12261231                         else if (lt == DOUBLE)
 12271232                                 mkcall(p, "__fixdfdi");
 12281233                         break;
 12291234                 case ULONGLONG:
 12301235                         if (lt == FLOAT)
 12311236                                 mkcall(p, "__fixunssfdi");
 12321237                         else if (lt == DOUBLE)
 12331238                                 mkcall(p, "__fixunsdfdi");
 12341239                         break;
 12351240                 case FLOAT:
 12361241                         if (lt == LONGLONG)
 12371242                                 mkcall(p, "__floatdisf");
 12381243                         else if (lt == ULONGLONG) {
 12391244                                 p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
 12401245                                 p->n_type = FLOAT;
 12411246                                 mkcall(p->n_left, "__floatunsdidf");
 12421247                         } else if (lt == UNSIGNED) {
 12431248                                 /* insert an extra double-to-float sconv */
 12441249                                 p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
 12451250                         }
 12461251                         break;
 12471252                 case DOUBLE:
 12481253                         if (lt == LONGLONG)
 12491254                                 mkcall(p, "__floatdidf");
 12501255                         else if (lt == ULONGLONG)
 12511256                                 mkcall(p->n_left, "__floatunsdidf");
 12521257                         break;
 12531258                         
 12541259                 }
 12551260                 break;
 12561261         }
 12571262 }
 12581263 
 12591264 void
 12601265 myreader(struct interpass *ipole)
 12611266 {
 12621267         struct interpass *ip;
 12631268 
 12641269         DLIST_FOREACH(ip, ipole, qelem) {
 12651270                 if (ip->type != IP_NODE)
 12661271                         continue;
 12671272                 walkf(ip->ip_node, optim2, 0);
 12681273         }
 12691274 }
 12701275 
 12711276 void
 12721277 mycanon(NODE *p)
 12731278 {
 12741279 }
 12751280 
 12761281 void
 12771282 myoptim(struct interpass *ip)
 12781283 {
 12791284 }
 12801285 
 12811286 /*
 12821287  * Return argument size in regs.
 12831288  */
 12841289 static int
 12851290 argsiz(NODE *p)
 12861291 {
 12871292         TWORD t = p->n_type;
 12881293 
 12891294         if (t == STRTY || t == UNIONTY)
 12901295                 return p->n_stsize/(SZINT/SZCHAR);
 12911296         return szty(t);
 12921297 }
 12931298 
 12941299 /*
 12951300  * Last chance to do something before calling a function.
 12961301  */
 12971302 void
 12981303 lastcall(NODE *p)
 12991304 {
 13001305         NODE *op = p;
 13011306         int size = 0;
 13021307 
 13031308         /* Calculate argument sizes */
 13041309         p->n_qual = 0;
 13051310         if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
 13061311                 return;
 13071312         for (p = p->n_right; p->n_op == CM; p = p->n_left)
 13081313                 size += argsiz(p->n_right);
 13091314         if (p->n_op != ASSIGN)
 13101315                 size += argsiz(p);
 13111316         op->n_qual = size; /* XXX */
 13121317 }
 13131318 
 13141319 /*
 13151320  * Return a class suitable for a specific type.
 13161321  */
 13171322 int
 13181323 gclass(TWORD t)
 13191324 {
 13201325         return (szty(t) == 2 ? CLASSB : CLASSA);
 13211326 }
 13221327 
 13231328 /*
 13241329  * For class c, find worst-case displacement of the number of
 13251330  * registers in the array r[] indexed by class.
 13261331  */
 13271332 int
 13281333 COLORMAP(int c, int *r)
 13291334 {
 13301335         int num;
 13311336         int a,b;
 13321337 
 13331338         a = r[CLASSA];
 13341339         b = r[CLASSB];
 13351340         switch (c) {
 13361341         case CLASSA:
 13371342                 /* there are 12 classa, so min 6 classb are needed to block */
 13381343                 num = b * 2;
 13391344                 num += a;
 13401345                 return num < 12;
 13411346         case CLASSB:
 13421347                 if (b > 3) return 0;
 13431348                 if (b > 2 && a) return 0;
 13441349                 if (b > 1 && a > 2) return 0;
 13451350                 if (b && a > 3) return 0;
 13461351                 if (a > 5) return 0;
 13471352                 return 1;
 13481353         }
 13491354         comperr("COLORMAP");
 13501355         return 0; /* XXX gcc */
 13511356 }
 13521357 
 13531358 /*
 13541359  * Special shapes.
 13551360  */
 13561361 int
 13571362 special(NODE *p, int shape)
 13581363 {
 13591364         return SRNOPE;
 13601365 }
 13611366 
 13621367 /*
 13631368  * Target-dependent command-line options.
 13641369  */
 13651370 void
 13661371 mflags(char *str)
 13671372 {
 13681373 }
 13691374 /*
 13701375  * Do something target-dependent for xasm arguments.
 13711376  * Supposed to find target-specific constraints and rewrite them.
 13721377  */
 13731378 int
 13741379 myxasm(struct interpass *ip, NODE *p)
 13751380 {
 13761381         return 0;
 13771382 }
 13781383 
 13791384 int
 13801385 xasmconstregs(char *s)
 13811386 {
 13821387         int i;
 13831388 
 13841389         for (i = 0; i < 16; i++)
 13851390                 if (strcmp(&rnames[i][1], s) == 0)
 13861391                         return i;
 13871392         return -1;
 13881393 }
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-21 07:13 +0100