Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.32
 
1.33
 
MAIN:ragge:20120829172051
 
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);
<> 53+        if (pflag) {
  54+                int i = getlab2();
  55+                printf("\tmovab\t" LABFMT ",%%r0\n", i);
  56+                printf("\tjsb\t__mcount\n");
  57+                printf("\t.data\n");
  58+                printf("\t.align  2\n");
  59+                printf(LABFMT ":\t.long\t0\n", i);
  60+                printf("\t.text\n");
  61+        }
5362 }
 5463 
 5564 /*
 5665  * Called after all instructions in a function are emitted.
 5766  * Generates code for epilog here.
 5867  */
 5968 void
 6069 eoftn(struct interpass_prolog *ipp)
 6170 {
 6271         if (ipp->ipp_ip.ip_lbl == 0)
 6372                 return; /* no code needs to be generated */
 6473         printf("        ret\n");
 6574 }
 6675 
 6776 struct hoptab { int opmask; char * opstring; } ioptab[] = {
 6877 
 6978         { PLUS"add", },
 7079         { MINUS,        "sub", },
 7180         { MUL,  "mul", },
 7281         { DIV,  "div", },
 7382         { OR,   "bis", },
 7483         { ER,   "xor", },
 7584         { AND,  "bic", },
 7685         { -1, ""     },
 7786 };
 7887 
 7988 void
 8089 hopcode( f, o ){
 8190         /* output the appropriate string from the above table */
 8291 
 8392         register struct hoptab *q;
 8493 
 8594         for( q = ioptabq->opmask>=0; ++q ){
 8695                 if( q->opmask == o ){
 8796                         printf( "%s", q->opstring );
 8897 /* tbl
 8998                         if( f == 'F' ) printf( "e" );
 9099                         else if( f == 'D' ) printf( "d" );
 91100    tbl */
 92101 /* tbl */
 93102                         switch( f ) {
 94103                                 case 'L':
 95104                                 case 'W':
 96105                                 case 'B':
 97106                                 case 'D':
 98107                                 case 'F':
 99108                                         printf("%c", tolower(f));
 100109                                         break;
 101110 
 102111                                 }
 103112 /* tbl */
 104113                         return;
 105114                         }
 106115                 }
 107116         cerror( "no hoptab for %s", opst[o] );
 108117         }
 109118 
 110119 char *
 111120 rnames[] = {  /* keyed to register number tokens */
 112121 
 113122         "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
 114123         "%r6", "%r7", "%r8", "%r9", "%r10", "%r11",
 115124         "%ap", "%fp", "%sp", "%pc",
 116125         /* The concatenated regs has the name of the lowest */
 117126         "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
 118127         "%r6", "%r7", "%r8", "%r9", "%r10"
 119128         };
 120129 
 121130 int
 122131 tlen(NODE *p)
 123132 {
 124133         switch(p->n_type) {
 125134         case CHAR:
 126135         case UCHAR:
 127136                 return(1);
 128137 
 129138         case SHORT:
 130139         case USHORT:
 131140                 return(2);
 132141 
 133142         case DOUBLE:
 134143         case LONGLONG:
 135144         case ULONGLONG:
 136145                 return(8);
 137146 
 138147         default:
 139148                 return(4);
 140149         }
 141150 }
 142151 
 143152 void
 144153 prtype(NODE *n)
 145154 {
 146155         static char pt[] = { 0, 0, 'b', 'b', 'w', 'w', 'l', 'l', 0, 0,
 147156             'q', 'q', 'f', 'd' };
 148157         TWORD t = n->n_type;
 149158 
 150159         if (ISPTR(t))
 151160                 t = UNSIGNED;
 152161 
 153162         if (t > DOUBLE || pt[t] == 0)
 154163                 comperr("prtype: bad type");
 155164         putchar(pt[t]);
 156165 }
 157166 
 158167 /*
 159168  * Emit conversions as given by the following table. Dest is always reg,
 160169  *   if it should be something else let peephole optimizer deal with it.
 161170  *   This code ensures type correctness in 32-bit registers.
 162171  *   XXX is that necessary?
 163172  *
 164173  * From                         To
 165174  *       char   uchar  short  ushort int    uint   ll    ull   float double
 166175  * char  movb   movb   cvtbw  cvtbw  cvtbl  cvtbl  A     A     cvtbf cvtbd
 167176  * uchar movb   movb   movzbw movzbw movzbl movzbl B     B     G     G
 168177  * short movb   movb   movw   movw   cvtwl  cvtwl  C(A)  C(A)  cvtwf cvtwd
 169178  * ushrt movb   movb   movw   movw   movzwl movzwl D(B)  D(B)  H     H
 170179  * int   movb   movb   movw   movw   movl   movl   E     E     cvtlf cvtld
 171180  * uint  movb   movb   movw   movw   movl   movl   F     F     I     I
 172181  * ll    movb   movb   movw   movw   movl   movl   movq  movq  J     K
 173182  * ull   movb   movb   movw   movw   movl   movl   movq  movq  L     M
 174183  * float cvtfb  cvtfb  cvtfw  cvtfw  cvtfl  cvtfl  N     O     movf  cvtfd
 175184  * doubl cvtdb  cvtdb  cvtdw  cvtdw  cvtdl  cvtdl  P     Q     cvtdf movd
 176185  *
 177186  *  A: cvtbl + sign extend
 178187  *  B: movzbl + zero extend
 179188  *  G: movzbw + cvtwX
 180189  *  H: movzwl + cvtwX
 181190  *  I: cvtld + addX
 182191  *  J: call __floatdisf
 183192  *  K: call __floatdidf
 184193  *  L: xxx + call __floatdisf
 185194  *  M: xxx + call __floatdidf
 186195  *  N: call __fixsfdi
 187196  *  O: call __fixunssfdi
 188197  *  P: call __fixdfdi
 189198  *  Q: call __fixunsdfdi
 190199  */
 191200 
 192201 #define MVD     1 /* mov + dest type */
 193202 #define CVT     2 /* cvt + src type + dst type */
 194203 #define MVZ     3 /* movz + src type + dst type */
 195204 #define CSE     4 /* cvt + src type + l + sign extend upper */
 196205 #define MZE     5 /* movz + src type + l + zero extend upper */
 197206 #define MLE     6 /* movl + sign extend upper */
 198207 #define MLZ     7 /* movl + zero extend upper */
 199208 #define MZC     8 /* movz + cvt */
 200209 
 201210 static char scary[][10] = {
 202211         { MVD, MVD, CVT, CVT, CVT, CVT, CSE, CSE, CVT, CVT },
 203212         { MVD, MVD, MVZ, MVZ, MVZ, MVZ, MZE, MZE, MZC, MZC },
 204213         { MVD, MVD, MVD, MVD, CVT, CVT, CSE, CSE, CVT, CVT },
 205214         { MVD, MVD, MVD, MVD, MVZ, MVZ, MZE, MZE, MZC, MZC },
 206215         { MVD, MVD, MVD, MVD, MVD, MVD, MLE, MLE, CVT, CVT },
 207216         { MVD, MVD, MVD, MVD, MVD, MVD, MLZ, MLZ, 'I', 'I' },
 208217         { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'J', 'K' },
 209218         { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'L', 'M' },
 210219         { CVT, CVT, CVT, CVT, CVT, CVT, 'N', 'O', MVD, CVT },
 211220         { CVT, CVT, CVT, CVT, CVT, CVT, 'P', 'Q', CVT, MVD },
 212221 };
 213222 
 214223 static void
 215224 sconv(NODE *p)
 216225 {
 217226         NODE *l = p->n_left;
 218227         TWORD ts, td;
 219228         int o;
 220229 
 221230         /*
 222231          * Source node may be in register or memory.
 223232          * Result is always in register.
 224233          */
 225234         ts = l->n_type;
 226235         if (ISPTR(ts))
 227236                 ts = UNSIGNED;
 228237         td = p->n_type;
 229238         ts = ts < LONG ? ts-2 : ts-4;
 230239         td = td < LONG ? td-2 : td-4;
 231240 
 232241         o = scary[ts][td];
 233242         switch (o) {
 234243         case MLE:
 235244         case MLZ:
 236245                 expand(p, INAREG|INBREG, "\tmovl\tAL,A1\n");
 237246                 break;
 238247 
 239248         case MVD:
 240249                 if (l->n_op == REG && regno(l) == regno(getlr(p, '1')))
 241250                         break; /* unneccessary move */
 242251                 expand(p, INAREG|INBREG, "\tmovZR\tAL,A1\n");
 243252                 break;
 244253 
 245254         case CSE:
 246255                 expand(p, INAREG|INBREG, "\tcvtZLl\tAL,A1\n");
 247256                 break;
 248257 
 249258         case CVT:
 250259                 expand(p, INAREG|INBREG, "\tcvtZLZR\tAL,A1\n");
 251260                 break;
 252261 
 253262         case MZE:
 254263                 expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
 255264                 break;
 256265 
 257266         case MVZ:
 258267                 expand(p, INAREG|INBREG, "\tmovzZLZR\tAL,A1\n");
 259268                 break;
 260269 
 261270         case MZC:
 262271                 expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
 263272                 expand(p, INAREG|INBREG, "\tcvtlZR\tA1,A1\n");
 264273                 break;
 265274 
 266275         case 'I': /* unsigned to double */
 267276                 expand(p, INAREG|INBREG, "\tcvtld\tAL,A1\n");
 268277                 printf("\tjgeq\t1f\n");
 269278                 expand(p, INAREG|INBREG, "\taddd2\t$0d4.294967296e+9,A1\n");
 270279                 printf("1:\n");
 271280                 break;
 272281         default:
 273282                 comperr("unsupported conversion %d", o);
 274283         }
 275284         switch (o) {
 276285         case MLE:
 277286         case CSE:
 278287                 expand(p, INBREG, "\tashl\t$-31,A1,U1\n");
 279288                 break;
 280289         case MLZ:
 281290         case MZE:
 282291                 expand(p, INAREG|INBREG, "\tclrl\tU1\n");
 283292                 break;
 284293         }
 285294 }
 286295 
 287296 /*
 288297  * Assign a constant from p to q.  Both are expected to be leaves by now.
 289298  * This is for 64-bit integers.
 290299  */
 291300 static void
 292301 casg64(NODE *p)
 293302 {
 294303         NODE *l, *r;
 295304         char *str;
 296305         int mneg = 1;
 297306         
 298307         l = p->n_left;
 299308         r = p->n_right;
 300309 
 301310 #ifdef PCC_DEBUG
 302311         if (r->n_op != ICON)
 303312                 comperr("casg");
 304313 #endif
 305314         if (r->n_name[0] != '\0') {
 306315                 /* named constant, nothing to do */
 307316                 str = "movq\tAR,AL";
 308317                 mneg = 0;
 309318         } else if (r->n_lval == 0) {
 310319                 str = "clrq\tAL";
 311320                 mneg = 0;
 312321         } else if (r->n_lval < 0) {
 313322                 if (r->n_lval >= -63) {
 314323                         r->n_lval = -r->n_lval;
 315324                         str = "mnegl\tAR,AL";
 316325                 } else if (r->n_lval >= -128) {
 317326                         str = "cvtbl\tAR,AL";
 318327                 } else if (r->n_lval >= -32768) {
 319328                         str = "cvtwl\tAR,AL";
 320329                 } else if (r->n_lval >= -4294967296LL) {
 321330                         str = "movl\tAR,AL";
 322331                 } else {
 323332                         str = "movq\tAR,AL";
 324333                         mneg = 0;
 325334                 }
 326335         } else {
 327336                 mneg = 0;
 328337                 if (r->n_lval <= 63 || r->n_lval > 4294967295LL) {
 329338                         str = "movq\tAR,AL";
 330339                 } else if (r->n_lval <= 255) {
 331340                         str = "movzbl\tAR,AL\n\tclrl\tUL";
 332341                 } else if (r->n_lval <= 65535) {
 333342                         str = "movzwl\tAR,AL\n\tclrl\tUL";
 334343                 } else /* if (r->n_lval <= 4294967295) */ {
 335344                         str = "movl\tAR,AL\n\tclrl\tUL";
 336345                 }
 337346         }
 338347         expand(p, FOREFF, str);
 339348         if (mneg)
 340349                 expand(p, FOREFF, "\n\tmnegl $-1,UL");
 341350 }
 342351 
 343352 /*
 344353  * Assign a constant from p to q.  Both are expected to be leaves by now.
 345354  * This is only for 32-bit integer types.
 346355  */
 347356 static void
 348357 casg(NODE *p)
 349358 {
 350359         NODE *l, *r;
 351360         char *str;
 352361         
 353362         l = p->n_left;
 354363         r = p->n_right;
 355364 
 356365 #ifdef PCC_DEBUG
 357366         if (r->n_op != ICON)
 358367                 comperr("casg");
 359368 #endif
 360369         if (r->n_name[0] != '\0') {
 361370                 /* named constant, nothing to do */
 362371                 str = "movZL\tAR,AL";
 363372         } else if (r->n_lval == 0) {
 364373                 str = "clrZL\tAL";
 365374         } else if (r->n_lval < 0) {
 366375                 if (r->n_lval >= -63) {
 367376                         r->n_lval = -r->n_lval;
 368377                         str = "mnegZL\tAR,AL";
 369378                 } else if (r->n_lval >= -128) {
 370379                         if (l->n_type == CHAR)
 371380                                 str = "movb\tAR,AL";
 372381                         else
 373382                                 str = "cvtbZL\tAR,AL";
 374383                 } else if (r->n_lval >= -32768) {
 375384                         if (l->n_type == SHORT)
 376385                                 str = "movw\tAR,AL";
 377386                         else
 378387                                 str = "cvtwZL\tAR,AL";
 379388                 } else
 380389                         str = "movZL\tAR,AL";
 381390         } else {
 382391                 if (r->n_lval <= 63 || r->n_lval > 65535) {
 383392                         str = "movZL\tAR,AL";
 384393                 } else if (r->n_lval <= 255) {
 385394                         str = l->n_type < SHORT ?
 386395                             "movb\tAR,AL" : "movzbZL\tAR,AL";
 387396                 } else /* if (r->n_lval <= 65535) */ {
 388397                         str = l->n_type < INT ?
 389398                             "movw\tAR,AL" : "movzwZL\tAR,AL";
 390399                 }
 391400         }
 392401         expand(p, FOREFF, str);
 393402 }
 394403 
 395404 /*
 396405  * Emit code to compare two longlong numbers.
 397406  */
 398407 static void
 399408 twollcomp(NODE *p)
 400409 {
 401410         int u;
 402411         int s = getlab2();
 403412         int e = p->n_label;
 404413         int cb1, cb2;
 405414 
 406415         u = p->n_op;
 407416         switch (p->n_op) {
 408417         case NE:
 409418                 cb1 = 0;
 410419                 cb2 = NE;
 411420                 break;
 412421         case EQ:
 413422                 cb1 = NE;
 414423                 cb2 = 0;
 415424                 break;
 416425         case LE:
 417426         case LT:
 418427                 u += (ULE-LE);
 419428                 /* FALLTHROUGH */
 420429         case ULE:
 421430         case ULT:
 422431                 cb1 = GT;
 423432                 cb2 = LT;
 424433                 break;
 425434         case GE:
 426435         case GT:
 427436                 u += (ULE-LE);
 428437                 /* FALLTHROUGH */
 429438         case UGE:
 430439         case UGT:
 431440                 cb1 = LT;
 432441                 cb2 = GT;
 433442                 break;
 434443         
 435444         default:
 436445                 cb1 = cb2 = 0; /* XXX gcc */
 437446         }
 438447         if (p->n_op >= ULE)
 439448                 cb1 += 4, cb2 += 4;
 440449         expand(p, 0, "  cmpl UL,UR\n");
 441450         if (cb1) cbgen(cb1, s);
 442451         if (cb2) cbgen(cb2, e);
 443452         expand(p, 0, "  cmpl AL,AR\n");
 444453         cbgen(u, e);
 445454         deflab(s);
 446455 }
 447456 
 448457 
 449458 void
 450459 zzzcode(NODE *p, int c)
 451460 {
 452461         NODE *l, *r;
 453462         int m;
 454463         char *ch;
 455464 
 456465         switch (c) {
 457466         case 'N'/* logical ops, turned into 0-1 */
 458467                 /* use register given by register 1 */
 459468                 cbgen( 0, m=getlab2());
 460469                 deflab( p->n_label );
 461470                 printf( "       clrl    %s\n", rnames[getlr( p, '1' )->n_rval] );
 462471                 deflab( m );
 463472                 return;
 464473 
 465474         case 'A': /* Assign a constant directly to a memory position */
 466475                 printf("\t");
 467476                 if (p->n_type < LONG || ISPTR(p->n_type))
 468477                         casg(p);
 469478                 else
 470479                         casg64(p);
 471480                 printf("\n");
 472481                 break;
 473482 
 474483         case 'B': /* long long compare */
 475484                 twollcomp(p);
 476485                 break;
 477486 
 478487         case 'C':       /* num words pushed on arg stack */
 479488                 printf("$%d", p->n_qual);
 480489                 break;
 481490 
 482491         case 'D':       /* INCR and DECR */
 483492                 zzzcode(p->n_left, 'A');
 484493                 printf("\n      ");
 485494 
 486495 #if 0
 487496         case 'E':       /* INCR and DECR, FOREFF */
 488497                 if (p->n_right->n_lval == 1)
 489498                         {
 490499                         printf("%s", (p->n_op == INCR ? "inc" : "dec") );
 491500                         prtype(p->n_left);
 492501                         printf("        ");
 493502                         adrput(stdout, p->n_left);
 494503                         return;
 495504                         }
 496505                 printf("%s", (p->n_op == INCR ? "add" : "sub") );
 497506                 prtype(p->n_left);
 498507                 printf("2       ");
 499508                 adrput(stdout, p->n_right);
 500509                 printf(",");
 501510                 adrput(p->n_left);
 502511                 return;
 503512 #endif
 504513 
 505514         case 'F':       /* register type of right operand */
 506515                 {
 507516                 register NODE *n;
 508517                 register int ty;
 509518 
 510519                 n = getlr( p, 'R' );
 511520                 ty = n->n_type;
 512521 
 513522                 if (x2debug) printf("->%d<-", ty);
 514523 
 515524                 if ( ty==DOUBLE) printf("d");
 516525                 else if ( ty==FLOAT ) printf("f");
 517526                 else printf("l");
 518527                 return;
 519528                 }
 520529 
 521530         case 'G': /* emit conversion instructions */
 522531                 sconv(p);
 523532                 break;
 524533 
 525534         case 'J': /* jump or ret? */
 526535                 {
 527536                         struct interpass *ip =
 528537                             DLIST_PREV((struct interpass *)p2env.epp, qelem);
 529538                         if (ip->type != IP_DEFLAB ||
 530539                             ip->ip_lbl != getlr(p, 'L')->n_lval)
 531540                                 expand(p, FOREFF, "jbr  LL");
 532541                         else
 533542                                 printf("ret");
 534543                 }
 535544                 break;
 536545 
 537546         case 'L':       /* type of left operand */
 538547         case 'R':       /* type of right operand */
 539548                 {
 540549                 register NODE *n;
 541550 
 542551                 n = getlr ( p, c);
 543552                 if (x2debug) printf("->%d<-", n->n_type);
 544553 
 545554                 prtype(n);
 546555                 return;
 547556                 }
 548557 
 549558         case 'O': /* print out emulated ops */
 550559                 expand(p, FOREFF, "\tmovq       AR,-(%sp)\n");
 551560                 expand(p, FOREFF, "\tmovq       AL,-(%sp)\n");
 552561                 if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
 553562                 else if (p->n_op == DIV) ch = "div";
 554563                 else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
 555564                 else if (p->n_op == MOD) ch = "mod";
 556565                 else if (p->n_op == MUL) ch = "mul";
 557566                 else ch = 0, comperr("ZO %d", p->n_op);
 558567                 printf("\tcalls $4,__%sdi3\n", ch);
 559568                 break;
 560569 
 561570 
 562571         case 'Z':       /* complement mask for bit instr */
 563572                 printf("$%Ld", ~p->n_right->n_lval);
 564573                 return;
 565574 
 566575         case 'U':       /* 32 - n, for unsigned right shifts */
 567576                 m = p->n_left->n_type == UCHAR ? 8 :
 568577                     p->n_left->n_type == USHORT ? 16 : 32;
 569578                 printf("$" CONFMT, m - p->n_right->n_lval);
 570579                 return;
 571580 
 572581         case 'T':       /* rounded structure length for arguments */
 573582                 {
 574583                 int size;
 575584 
 576585                 size = p->n_stsize;
 577586                 SETOFF( size, 4);
 578587                 printf("$%d", size);
 579588                 return;
 580589                 }
 581590 
 582591         case 'S'/* structure assignment */
 583592                 {
 584593                         register int size;
 585594 
 586595                         size = p->n_stsize;
 587596                         l = r = NULL; /* XXX gcc */
 588597                         if( p->n_op == STASG ){
 589598                                 l = p->n_left;
 590599                                 r = p->n_right;
 591600 
 592601                                 }
 593602                         else if( p->n_op == STARG ){
 594603                                 /* store an arg into a temporary */
 595604                                 printf("\tsubl2 $%d,%%sp\n",
 596605                                     size < 4 ? 4 : size);
 597606                                 l = mklnode(OREG, 0, SP, INT);
 598607                                 r = p->n_left;
 599608                                 }
 600609                         else cerror( "STASG bad" );
 601610 
 602611                         if( r->n_op == ICON ) r->n_op = NAME;
 603612                         else if( r->n_op == REG ) r->n_op = OREG;
 604613                         else if( r->n_op != OREG ) cerror( "STASG-r" );
 605614 
 606615                 if (size != 0) {
 607616                         if( size <= 0 || size > 65535 )
 608617                                 cerror("structure size <0=0 or >65535");
 609618 
 610619                         switch(size) {
 611620                                 case 1:
 612621                                         printf("        movb    ");
 613622                                         break;
 614623                                 case 2:
 615624                                         printf("        movw    ");
 616625                                         break;
 617626                                 case 4:
 618627                                         printf("        movl    ");
 619628                                         break;
 620629                                 case 8:
 621630                                         printf("        movq    ");
 622631                                         break;
 623632                                 default:
 624633                                         printf("        movc3   $%d,", size);
 625634                                         break;
 626635                         }
 627636                         adrput(stdout, r);
 628637                         printf(",");
 629638                         adrput(stdout, l);
 630639                         printf("\n");
 631640                 }
 632641 
 633642                         if( r->n_op == NAME ) r->n_op = ICON;
 634643                         else if( r->n_op == OREG ) r->n_op = REG;
 635644                         if (p->n_op == STARG)
 636645                                 tfree(l);
 637646 
 638647                         }
 639648                 break;
 640649 
 641650         default:
 642651                 comperr("illegal zzzcode '%c'", c);
 643652         }
 644653 }
 645654 
 646655 void
 647656 rmove(int rt, int rs, TWORD t)
 648657 {
 649658         printf( "       %s      %s,%s\n",
 650659                 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
 651660                 rnames[rt], rnames[rs] );
 652661 }
 653662 
 654663 int
 655664 rewfld(NODE *p)
 656665 {
 657666         return(1);
 658667 }
 659668 
 660669 #if 0
 661670 int
 662671 callreg(NODE *p)
 663672 {
 664673         return( R0 );
 665674 }
 666675 
 667676 int
 668677 base(register NODE *p)
 669678 {
 670679         register int o = p->op;
 671680 
 672681         if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
 673682         if( o==REG ) return( p->rval );
 674683     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
 675684                 return( p->left->rval );
 676685     if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 677686                 return( p->rval + 0200*1 );
 678687         if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
 679688         if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
 680689         if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
 681690           && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 682691                 return( p->left->left->rval + 0200*(1+2) );
 683692         return( -1 );
 684693 }
 685694 
 686695 int
 687696 offset(register NODE *p, int tyl)
 688697 {
 689698 
 690699         if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
 691700         if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
 692701               (p->right->op==ICON && p->right->name[0]=='\0')
 693702               && (1<<p->right->lval)==tyl))
 694703                 return( p->left->rval );
 695704         return( -1 );
 696705 }
 697706 #endif
 698707 
 699708 #if 0
 700709 void
 701710 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
 702711         register NODE *t;
 703712         NODE *f;
 704713 
 705714         p->n_op = OREG;
 706715         f = p->n_left;  /* have to free this subtree later */
 707716 
 708717         /* init base */
 709718         switch (q->n_op) {
 710719                 case ICON:
 711720                 case REG:
 712721                 case OREG:
 713722                         t = q;
 714723                         break;
 715724 
 716725                 case MINUS:
 717726                         q->n_right->n_lval = -q->n_right->n_lval;
 718727                 case PLUS:
 719728                         t = q->n_right;
 720729                         break;
 721730 
 722731                 case UMUL:
 723732                         t = q->n_left->n_left;
 724733                         break;
 725734 
 726735                 default:
 727736                         cerror("illegal makeor2");
 728737                         t = NULL; /* XXX gcc */
 729738         }
 730739 
 731740         p->n_lval = t->n_lval;
 732741         p->n_name = t->n_name;
 733742 
 734743         /* init offset */
 735744         p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
 736745 
 737746         tfree(f);
 738747         return;
 739748         }
 740749 
 741750 int
 742751 canaddr( p ) NODE *p; {
 743752         register int o = p->n_op;
 744753 
 745754         if( o==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_left, STARNM|SOREG)) ) return(1);
 746755         return(0);
 747756         }
 748757 
 749758 shltype( o, p ) register NODE *p; {
 750759         return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 751760         }
 752761 #endif
 753762 
 754763 int
 755764 fldexpand(NODE *p, int cookie, char **cp)
 756765 {
 757766         return 0;
 758767 }
 759768 
 760769 int
 761770 flshape(register NODE *p)
 762771 {
 763772         return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
 764773                 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
 765774 }
 766775 
 767776 int
 768777 shtemp(register NODE *p)
 769778 {
 770779         if( p->n_op == STARG ) p = p->n_left;
 771780         return( p->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 772781 }
 773782 
 774783 /*
 775784  * Shape matches for UMUL.  Cooperates with offstar().
 776785  */
 777786 int
 778787 shumul(NODE *p, int shape)
 779788 {
 780789 
 781790         if (x2debug)
 782791                 printf("shumul(%p)\n", p);
 783792 
 784793         /* Turns currently anything into OREG on vax */
 785794         if (shape & SOREG)
 786795                 return SROREG;
 787796         return SRNOPE;
 788797 }
 789798 
 790799 
 791800 #ifdef notdef
 792801 int
 793802 shumul( p, shape ) register NODE *p; int shape; {
 794803         register int o;
 795804 
 796805         if (x2debug) {
 797806                  printf("\nshumul:op=%d,lop=%d,rop=%d", p->n_op, p->n_left->n_op, p->n_right->n_op);
 798807                 printf(" prname=%s,plty=%d, prlval=%lld\n", p->n_right->n_name, p->n_left->n_type, p->n_right->n_lval);
 799808                 }
 800809 
 801810 
 802811         o = p->n_op;
 803812         if( o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
 804813                 if (shape & STARNM)
 805814                         return SRDIR;
 806815 
 807816         if( ( o == INCR || o == ASG MINUS ) &&
 808817             ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
 809818             p->n_right->n_name[0] == '\0' )
 810819                 {
 811820                 switch (p->n_left->n_type)
 812821                         {
 813822                         case CHAR|PTR:
 814823                         case UCHAR|PTR:
 815824                                 o = 1;
 816825                                 break;
 817826 
 818827                         case SHORT|PTR:
 819828                         case USHORT|PTR:
 820829                                 o = 2;
 821830                                 break;
 822831 
 823832                         case INT|PTR:
 824833                         case UNSIGNED|PTR:
 825834                         case LONG|PTR:
 826835                         case ULONG|PTR:
 827836                         case FLOAT|PTR:
 828837                                 o = 4;
 829838                                 break;
 830839 
 831840                         case DOUBLE|PTR:
 832841                                 o = 8;
 833842                                 break;
 834843 
 835844                         default:
 836845                                 if ( ISPTR(p->n_left->n_type) ) {
 837846                                         o = 4;
 838847                                         break;
 839848                                         }
 840849                                 else return(0);
 841850                         }
 842851                 return( p->n_right->n_lval == o ? STARREG : 0);
 843852                 }
 844853 
 845854         return( SRNOPE );
 846855         }
 847856 #endif
 848857 
 849858 void
 850859 adrcon(CONSZ val)
 851860 {
 852861         printf( "$" );
 853862         printf( CONFMT, val );
 854863 }
 855864 
 856865 void
 857866 conput(FILE *fp, NODE *p)
 858867 {
 859868         switch( p->n_op ){
 860869 
 861870         case ICON:
 862871                 acon( p );
 863872                 return;
 864873 
 865874         case REG:
 866875                 printf( "%s", rnames[p->n_rval] );
 867876                 return;
 868877 
 869878         default:
 870879                 cerror( "illegal conput" );
 871880                 }
 872881         }
 873882 
 874883 void
 875884 insput(register NODE *p)
 876885 {
 877886         cerror( "insput" );
 878887 }
 879888 
 880889 /*
 881890  * Write out the upper address, like the upper register of a 2-register
 882891  * reference, or the next memory location.
 883892  */
 884893 void
 885894 upput(NODE *p, int size)
 886895 {
 887896 
 888897         size /= SZCHAR;
 889898         switch (p->n_op) {
 890899         case REG:
 891900                 fprintf(stdout, "%s", rnames[regno(p)-16+1]);
 892901                 break;
 893902 
 894903         case NAME:
<> 904+                comperr("upput NAME");
895905         case OREG:
 896906                 p->n_lval += size;
 897907                 adrput(stdout, p);
 898908                 p->n_lval -= size;
 899909                 break;
 900910         case ICON:
 901911                 fprintf(stdout, "$" CONFMT, p->n_lval >> 32);
 902912                 break;
 903913         default:
 904914                 comperr("upput bad op %d size %d", p->n_op, size);
 905915         }
 906916 }
 907917 
 908918 void
 909919 adrput(FILE *fp, NODE *p)
 910920 {
 911921         register int r;
 912922         /* output an address, with offsets, from p */
 913923 
 914924         if( p->n_op == FLD ){
 915925                 p = p->n_left;
 916926                 }
 917927         switch( p->n_op ){
 918928 
 919929         case NAME:
 920930                 acon( p );
 921931                 return;
 922932 
 923933         case ICON:
 924934                 /* addressable value of the constant */
 925935                 if (p->n_name[0] == '\0') /* uses xxxab */
 926936                         printf("$");
 927937                 acon(p);
 928938                 return;
 929939 
 930940         case REG:
 931941                 printf( "%s", rnames[p->n_rval] );
 932942                 return;
 933943 
 934944         case OREG:
 935945                 r = p->n_rval;
 936946                 if( R2TEST(r) ){ /* double indexing */
 937947                         register int flags;
 938948 
 939949                         flags = R2UPK3(r);
 940950                         if( flags & 1 ) printf("*");
 941951                         if( flags & 4 ) printf("-");
 942952                         if( p->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
 943953                         if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
 944954                         if( flags & 2 ) printf("+");
 945955                         printf( "[%s]", rnames[R2UPK2(r)] );
 946956                         return;
 947957                         }
 948958                 if( r == AP ){  /* in the argument region */
 949959                         if( p->n_lval <= 0 || p->n_name[0] != '\0' )
 950960                                 werror( "bad arg temp" );
 951961                         printf( CONFMT, p->n_lval );
 952962                         printf( "(%%ap)" );
 953963                         return;
 954964                         }
 955965                 if( p->n_lval != 0 || p->n_name[0] != '\0') acon( p );
 956966                 printf( "(%s)", rnames[p->n_rval] );
 957967                 return;
 958968 
 959969         case UMUL:
 960970                 /* STARNM or STARREG found */
 961971                 if( tshape(p, STARNM) ) {
 962972                         printf( "*" );
 963973                         adrput(0p->n_left);
 964974                         }
 965975                 else {  /* STARREG - really auto inc or dec */
 966976                         register NODE *q;
 967977 
 968978 /* tbl
 969979                         p = p->n_left;
 970980                         p->n_left->n_op = OREG;
 971981                         if( p->n_op == INCR ) {
 972982                                 adrput( p->n_left );
 973983                                 printf( "+" );
 974984                                 }
 975985                         else {
 976986                                 printf( "-" );
 977987                                 adrput( p->n_left );
 978988                                 }
 979989    tbl */
 980990 #ifdef notyet
 981991                         printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
 982992                                 rnames[p->n_left->n_left->n_rval],
 983993                                 (p->n_left->n_op==INCR ? '+' : '\0') );
 984994 #else
 985995                         printf("%c(%s)%c", '-',
 986996                                 rnames[p->n_left->n_left->n_rval],
 987997                                 '\0' );
 988998 #endif
 989999                         p->n_op = OREG;
 9901000                         p->n_rval = p->n_left->n_left->n_rval;
 9911001                         q = p->n_left;
 9921002 #ifdef notyet
 9931003 
 9941004                         p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
 9951005 #else
 9961006                         p->n_lval = 0;
 9971007 #endif
 9981008                         p->n_name[0] = '\0';
 9991009                         tfree(q);
 10001010                 }
 10011011                 return;
 10021012 
 10031013         default:
 10041014                 cerror( "illegal address" );
 10051015                 return;
 10061016         }
 10071017 
 10081018 }
 10091019 
 10101020 /*
 10111021  * print out a constant
 10121022  */
 10131023 void
 10141024 acon(NODE *p)
 10151025 {
 10161026 
 10171027         if (p->n_name[0] == '\0') {
 10181028                 printf(CONFMT, p->n_lval);
 10191029         } else if( p->n_lval == 0 ) {
 10201030                 printf("%s", p->n_name);
 10211031         } else {
 10221032                 printf("%s+", p->n_name);
 10231033                 printf(CONFMT, p->n_lval);
 10241034         }
 10251035 }
 10261036 
 10271037 #if 0
 10281038 genscall( p, cookie ) register NODE *p; {
 10291039         /* structure valued call */
 10301040         return( gencall( p, cookie ) );
 10311041         }
 10321042 
 10331043 /* tbl */
 10341044 int gc_numbytes;
 10351045 /* tbl */
 10361046 
 10371047 gencall( p, cookie ) register NODE *p; {
 10381048         /* generate the call given by p */
 10391049         register NODE *p1, *ptemp;
 10401050         register temp, temp1;
 10411051         register m;
 10421052 
 10431053         if( p->right ) temp = argsize( p->right );
 10441054         else temp = 0;
 10451055 
 10461056         if( p->op == STCALL || p->op == UNARY STCALL ){
 10471057                 /* set aside room for structure return */
 10481058 
 10491059                 if( p->stsize > temp ) temp1 = p->stsize;
 10501060                 else temp1 = temp;
 10511061                 }
 10521062 
 10531063         if( temp > maxargs ) maxargs = temp;
 10541064         SETOFF(temp1,4);
 10551065 
 10561066         if( p->right ){ /* make temp node, put offset in, and generate args */
 10571067                 ptemp = talloc();
 10581068                 ptemp->op = OREG;
 10591069                 ptemp->lval = -1;
 10601070                 ptemp->rval = SP;
 10611071                 ptemp->name[0] = '\0';
 10621072                 ptemp->rall = NOPREF;
 10631073                 ptemp->su = 0;
 10641074                 genargs( p->right, ptemp );
 10651075                 nfree(ptemp);
 10661076                 }
 10671077 
 10681078         p1 = p->left;
 10691079         if( p1->op != ICON ){
 10701080                 if( p1->op != REG ){
 10711081                         if( p1->op != OREG || R2TEST(p1->rval) ){
 10721082                                 if( p1->op != NAME ){
 10731083                                         order( p1, INAREG );
 10741084                                         }
 10751085                                 }
 10761086                         }
 10771087                 }
 10781088 
 10791089 /*
 10801090         if( p1->op == REG && p->rval == R5 ){
 10811091                 cerror( "call register overwrite" );
 10821092                 }
 10831093  */
 10841094 /* tbl
 10851095         setup gc_numbytes so reference to ZC works */
 10861096 
 10871097         gc_numbytes = temp;
 10881098 /* tbl */
 10891099 
 10901100         p->op = UNARY CALL;
 10911101         m = match( p, INTAREG|INTBREG );
 10921102 /* tbl
 10931103         switch( temp ) {
 10941104         case 0:
 10951105                 break;
 10961106         case 2:
 10971107                 printf( "       tst     (%sp)+\n" );
 10981108                 break;
 10991109         case 4:
 11001110                 printf( "       cmp     (%sp)+,(%sp)+\n" );
 11011111                 break;
 11021112         default:
 11031113                 printf( "       add     $%d,%sp\n", temp);
 11041114                 }
 11051115    tbl */
 11061116         return(m != MDONE);
 11071117         }
 11081118 #endif
 11091119 
 11101120 static char *
 11111121 ccbranches[] = {
 11121122         "jeql",
 11131123         "jneq",
 11141124         "jleq",
 11151125         "jlss",
 11161126         "jgeq",
 11171127         "jgtr",
 11181128         "jlequ",
 11191129         "jlssu",
 11201130         "jgequ",
 11211131         "jgtru",
 11221132 };
 11231133 
 11241134 /*
 11251135  * printf conditional and unconditional branches
 11261136  */
 11271137 void
 11281138 cbgen(int o, int lab)
 11291139 {
 11301140 
 11311141         if (o == 0) {
 11321142                 printf("        jbr     " LABFMT "\n", lab);
 11331143         } else {
 11341144                 if (o > UGT)
 11351145                         comperr("bad conditional branch: %s", opst[o]);
 11361146                 printf("\t%s\t" LABFMT "\n", ccbranches[o-EQ], lab);
 11371147         }
 11381148 }
 11391149 
 11401150 static void
 11411151 mkcall(NODE *p, char *name)
 11421152 {
 11431153         p->n_op = CALL;
 11441154         p->n_right = mkunode(FUNARG, p->n_left, 0, p->n_left->n_type);
 11451155         p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
 11461156         p->n_left->n_name = name;
 11471157 }
 11481158 
 11491159 /* do local tree transformations and optimizations */
 11501160 static void
 11511161 optim2(NODE *p, void *arg)
 11521162 {
 11531163         NODE *r, *s;
 11541164         TWORD lt;
 11551165 
 11561166         switch (p->n_op) {
 11571167         case MOD:
 11581168                 if (p->n_type == USHORT || p->n_type == UCHAR) {
 11591169                         r = mkunode(SCONV, p->n_left, 0, UNSIGNED);
 11601170                         r = mkunode(FUNARG, r, 0, UNSIGNED);
 11611171                         s = mkunode(SCONV, p->n_right, 0, UNSIGNED);
 11621172                         s = mkunode(FUNARG, s, 0, UNSIGNED);
 11631173                         r = mkbinode(CM, r, s, INT);
 11641174                         s = mklnode(ICON, 0, 0, FTN|UNSIGNED);
 11651175                         s->n_name = "__urem";
 11661176                         p->n_left = mkbinode(CALL, s, r, UNSIGNED);
 11671177                         p->n_op = SCONV;
 11681178                 } else if (p->n_type == UNSIGNED) {
 11691179                         p->n_left = mkunode(FUNARG, p->n_left, 0, UNSIGNED);
 11701180                         p->n_right = mkunode(FUNARG, p->n_right, 0, UNSIGNED);
 11711181                         p->n_right = mkbinode(CM, p->n_left, p->n_right, INT);
 11721182                         p->n_left = mklnode(ICON, 0, 0, FTN|UNSIGNED);
 11731183                         p->n_left->n_name = "__urem";
 11741184                         p->n_op = CALL;
 11751185                 }
 11761186                 break;
 11771187 
 11781188         case RS:
 11791189                 if (p->n_type == ULONGLONG) {
 11801190                         p->n_right = mkbinode(CM,
 11811191                             mkunode(FUNARG, p->n_left, 0, p->n_left->n_type),
 11821192                             mkunode(FUNARG, p->n_right, 0, p->n_right->n_type),
 11831193                             INT);
 11841194                         p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
 11851195                         p->n_left->n_name = "__lshrdi3";
 11861196                         p->n_op = CALL;
 11871197                 } else if (p->n_type == INT) {
 11881198                         /* convert >> to << with negative shift count */
 11891199                         /* RS of char & short must use extv */
 11901200                         if (p->n_right->n_op == ICON) {
 11911201                                 p->n_right->n_lval = -p->n_right->n_lval;
 11921202                         } else if (p->n_right->n_op == UMINUS) {
 11931203                                 r = p->n_right->n_left;
 11941204                                 nfree(p->n_right);
 11951205                                 p->n_right = r;
 11961206                         } else {
 11971207                                 p->n_right = mkunode(UMINUS, p->n_right,
 11981208                                     0, p->n_right->n_type);
 11991209                         }
 12001210                         p->n_op = LS;
 12011211                 }
 12021212                 break;
 12031213 
 12041214         case AND:
 12051215                 /* commute L and R to eliminate compliments and constants */
 12061216                 if ((p->n_left->n_op == ICON && p->n_left->n_name[0] == 0) ||
 12071217                     p->n_left->n_op==COMPL) {
 12081218                         r = p->n_left;
 12091219                         p->n_left = p->n_right;
 12101220                         p->n_right = r;
 12111221                 }
 12121222                 /* change meaning of AND to ~R&L - bic on pdp11 */
 12131223                 r = p->n_right;
 12141224                 if (r->n_op == ICON && r->n_name[0] == 0) {
 12151225                         /* compliment constant */
 12161226                         r->n_lval = ~r->n_lval;
 12171227                 } else if (r->n_op == COMPL) { /* ~~A => A */
 12181228                         s = r->n_left;
 12191229                         nfree(r);
 12201230                         p->n_right = s;
 12211231                 } else { /* insert complement node */
 12221232                         p->n_right = mkunode(COMPL, r, 0, r->n_type);
 12231233                 }
 12241234                 break;
 12251235         case SCONV:
 12261236                 lt = p->n_left->n_type;
 12271237                 switch (p->n_type) {
 12281238                 case LONGLONG:
 12291239                         if (lt == FLOAT)
 12301240                                 mkcall(p, "__fixsfdi");
 12311241                         else if (lt == DOUBLE)
 12321242                                 mkcall(p, "__fixdfdi");
 12331243                         break;
 12341244                 case ULONGLONG:
 12351245                         if (lt == FLOAT)
 12361246                                 mkcall(p, "__fixunssfdi");
 12371247                         else if (lt == DOUBLE)
 12381248                                 mkcall(p, "__fixunsdfdi");
 12391249                         break;
 12401250                 case FLOAT:
 12411251                         if (lt == LONGLONG)
 12421252                                 mkcall(p, "__floatdisf");
 12431253                         else if (lt == ULONGLONG) {
 12441254                                 p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
 12451255                                 p->n_type = FLOAT;
 12461256                                 mkcall(p->n_left, "__floatundidf");
 12471257                         } else if (lt == UNSIGNED) {
 12481258                                 /* insert an extra double-to-float sconv */
 12491259                                 p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
 12501260                         }
 12511261                         break;
 12521262                 case DOUBLE:
 12531263                         if (lt == LONGLONG)
 12541264                                 mkcall(p, "__floatdidf");
 12551265                         else if (lt == ULONGLONG)
 12561266                                 mkcall(p, "__floatundidf");
 12571267                         break;
 12581268                         
 12591269                 }
 12601270                 break;
 12611271         }
 12621272 }
 12631273 
<> 1274+static void
  1275+aofname(NODE *p, void *arg)
  1276+{
  1277+        int o = optype(p->n_op);
  1278+        TWORD t;
  1279+
  1280+        if (o == LTYPE || p->n_op == ADDROF)
  1281+                return;
  1282+        t = p->n_left->n_type;
  1283+        if (p->n_left->n_op == NAME && ISLONGLONG(t))
  1284+                p->n_left = mkunode(UMUL,
  1285+                    mkunode(ADDROF, p->n_left, 0, INCREF(t)), 0, t);
  1286+        if (o == BITYPE && p->n_right->n_op == NAME &&
  1287+            ISLONGLONG(p->n_right->n_type)) {
  1288+                t = p->n_right->n_type;
  1289+                p->n_right = mkunode(UMUL,
  1290+                    mkunode(ADDROF, p->n_right, 0, INCREF(t)), 0, t);
  1291+        }
  1292+}
  1293+
12641294 void
 12651295 myreader(struct interpass *ipole)
 12661296 {
 12671297         struct interpass *ip;
 12681298 
 12691299         DLIST_FOREACH(ip, ipole, qelem) {
 12701300                 if (ip->type != IP_NODE)
 12711301                         continue;
<> 1302+                if (kflag)
  1303+                        walkf(ip->ip_node, aofname, 0);
<_12721304                 walkf(ip->ip_node, optim2, 0);
 12731305         }
 12741306 }
 12751307 
 12761308 void
 12771309 mycanon(NODE *p)
 12781310 {
 12791311 }
 12801312 
 12811313 void
 12821314 myoptim(struct interpass *ip)
 12831315 {
 12841316 }
 12851317 
 12861318 /*
 12871319  * Return argument size in regs.
 12881320  */
 12891321 static int
 12901322 argsiz(NODE *p)
 12911323 {
 12921324         TWORD t = p->n_type;
 12931325 
 12941326         if (t == STRTY || t == UNIONTY)
 12951327                 return p->n_stsize/(SZINT/SZCHAR);
 12961328         return szty(t);
 12971329 }
 12981330 
 12991331 /*
 13001332  * Last chance to do something before calling a function.
 13011333  */
 13021334 void
 13031335 lastcall(NODE *p)
 13041336 {
 13051337         NODE *op = p;
 13061338         int size = 0;
 13071339 
 13081340         /* Calculate argument sizes */
 13091341         p->n_qual = 0;
 13101342         if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
 13111343                 return;
 13121344         for (p = p->n_right; p->n_op == CM; p = p->n_left)
 13131345                 size += argsiz(p->n_right);
 13141346         if (p->n_op != ASSIGN)
 13151347                 size += argsiz(p);
 13161348         op->n_qual = size; /* XXX */
 13171349 }
 13181350 
 13191351 /*
 13201352  * Return a class suitable for a specific type.
 13211353  */
 13221354 int
 13231355 gclass(TWORD t)
 13241356 {
 13251357         return (szty(t) == 2 ? CLASSB : CLASSA);
 13261358 }
 13271359 
 13281360 /*
 13291361  * For class c, find worst-case displacement of the number of
 13301362  * registers in the array r[] indexed by class.
 13311363  */
 13321364 int
 13331365 COLORMAP(int c, int *r)
 13341366 {
 13351367         int num;
 13361368         int a,b;
 13371369 
 13381370         a = r[CLASSA];
 13391371         b = r[CLASSB];
 13401372         switch (c) {
 13411373         case CLASSA:
 13421374                 /* there are 12 classa, so min 6 classb are needed to block */
 13431375                 num = b * 2;
 13441376                 num += a;
 13451377                 return num < 12;
 13461378         case CLASSB:
 13471379                 if (b > 3) return 0;
 13481380                 if (b > 2 && a) return 0;
 13491381                 if (b > 1 && a > 2) return 0;
 13501382                 if (b && a > 3) return 0;
 13511383                 if (a > 5) return 0;
 13521384                 return 1;
 13531385         }
 13541386         comperr("COLORMAP");
 13551387         return 0; /* XXX gcc */
 13561388 }
 13571389 
 13581390 /*
 13591391  * Special shapes.
 13601392  */
 13611393 int
 13621394 special(NODE *p, int shape)
 13631395 {
 13641396         return SRNOPE;
 13651397 }
 13661398 
 13671399 /*
 13681400  * Target-dependent command-line options.
 13691401  */
 13701402 void
 13711403 mflags(char *str)
 13721404 {
 13731405 }
 13741406 /*
 13751407  * Do something target-dependent for xasm arguments.
 13761408  * Supposed to find target-specific constraints and rewrite them.
 13771409  */
 13781410 int
 13791411 myxasm(struct interpass *ip, NODE *p)
 13801412 {
 13811413         return 0;
 13821414 }
 13831415 
 13841416 int
 13851417 xasmconstregs(char *s)
 13861418 {
 13871419         int i;
 13881420 
 13891421         for (i = 0; i < 16; i++)
 13901422                 if (strcmp(&rnames[i][1], s) == 0)
 13911423                         return i;
 13921424         return -1;
 13931425 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-11-01 10:45 +0100