Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.36
 
1.37
 
MAIN:ragge:20121221214427
 
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         if (pflag) {
 5454                 int i = getlab2();
 5555                 printf("\tmovab\t" LABFMT ",%%r0\n", i);
 5656                 printf("\tjsb\t__mcount\n");
 5757                 printf("\t.data\n");
 5858                 printf("\t.align  2\n");
 5959                 printf(LABFMT ":\t.long\t0\n", i);
 6060                 printf("\t.text\n");
 6161         }
 6262 }
 6363 
 6464 /*
 6565  * Called after all instructions in a function are emitted.
 6666  * Generates code for epilog here.
 6767  */
 6868 void
 6969 eoftn(struct interpass_prolog *ipp)
 7070 {
 7171         if (ipp->ipp_ip.ip_lbl == 0)
 7272                 return; /* no code needs to be generated */
 7373         printf("        ret\n");
 7474 }
 7575 
 7676 struct hoptab { int opmask; char * opstring; } ioptab[] = {
 7777 
 7878         { PLUS"add", },
 7979         { MINUS,        "sub", },
 8080         { MUL,  "mul", },
 8181         { DIV,  "div", },
 8282         { OR,   "bis", },
 8383         { ER,   "xor", },
 8484         { AND,  "bic", },
 8585         { -1, ""     },
 8686 };
 8787 
 8888 void
 8989 hopcode( f, o ){
 9090         /* output the appropriate string from the above table */
 9191 
 9292         register struct hoptab *q;
 9393 
 9494         for( q = ioptabq->opmask>=0; ++q ){
 9595                 if( q->opmask == o ){
 9696                         printf( "%s", q->opstring );
 9797 /* tbl
 9898                         if( f == 'F' ) printf( "e" );
 9999                         else if( f == 'D' ) printf( "d" );
 100100    tbl */
 101101 /* tbl */
 102102                         switch( f ) {
 103103                                 case 'L':
 104104                                 case 'W':
 105105                                 case 'B':
 106106                                 case 'D':
 107107                                 case 'F':
 108108                                         printf("%c", tolower(f));
 109109                                         break;
 110110 
 111111                                 }
 112112 /* tbl */
 113113                         return;
 114114                         }
 115115                 }
 116116         cerror( "no hoptab for %s", opst[o] );
 117117         }
 118118 
 119119 char *
 120120 rnames[] = {  /* keyed to register number tokens */
 121121 
 122122         "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
 123123         "%r6", "%r7", "%r8", "%r9", "%r10", "%r11",
 124124         "%ap", "%fp", "%sp", "%pc",
 125125         /* The concatenated regs has the name of the lowest */
 126126         "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
 127127         "%r6", "%r7", "%r8", "%r9", "%r10"
 128128         };
 129129 
 130130 int
 131131 tlen(NODE *p)
 132132 {
 133133         switch(p->n_type) {
 134134         case CHAR:
 135135         case UCHAR:
 136136                 return(1);
 137137 
 138138         case SHORT:
 139139         case USHORT:
 140140                 return(2);
 141141 
 142142         case DOUBLE:
 143143         case LONGLONG:
 144144         case ULONGLONG:
 145145                 return(8);
 146146 
 147147         default:
 148148                 return(4);
 149149         }
 150150 }
 151151 
 152152 void
 153153 prtype(NODE *n)
 154154 {
 155155         static char pt[] = { 0, 0, 'b', 'b', 'w', 'w', 'l', 'l', 0, 0,
 156156             'q', 'q', 'f', 'd' };
 157157         TWORD t = n->n_type;
 158158 
 159159         if (ISPTR(t))
 160160                 t = UNSIGNED;
 161161 
 162162         if (t > DOUBLE || pt[t] == 0)
 163163                 comperr("prtype: bad type");
 164164         putchar(pt[t]);
 165165 }
 166166 
 167167 /*
 168168  * Emit conversions as given by the following table. Dest is always reg,
 169169  *   if it should be something else let peephole optimizer deal with it.
 170170  *   This code ensures type correctness in 32-bit registers.
 171171  *   XXX is that necessary?
 172172  *
 173173  * From                         To
 174174  *       char   uchar  short  ushort int    uint   ll    ull   float double
 175175  * char  movb   movb   cvtbw  cvtbw  cvtbl  cvtbl  A     A     cvtbf cvtbd
 176176  * uchar movb   movb   movzbw movzbw movzbl movzbl B     B     G     G
 177177  * short movb   movb   movw   movw   cvtwl  cvtwl  C(A)  C(A)  cvtwf cvtwd
 178178  * ushrt movb   movb   movw   movw   movzwl movzwl D(B)  D(B)  H     H
 179179  * int   movb   movb   movw   movw   movl   movl   E     E     cvtlf cvtld
 180180  * uint  movb   movb   movw   movw   movl   movl   F     F     I     I
 181181  * ll    movb   movb   movw   movw   movl   movl   movq  movq  J     K
 182182  * ull   movb   movb   movw   movw   movl   movl   movq  movq  L     M
 183183  * float cvtfb  cvtfb  cvtfw  cvtfw  cvtfl  cvtfl  N     O     movf  cvtfd
 184184  * doubl cvtdb  cvtdb  cvtdw  cvtdw  cvtdl  cvtdl  P     Q     cvtdf movd
 185185  *
 186186  *  A: cvtbl + sign extend
 187187  *  B: movzbl + zero extend
 188188  *  G: movzbw + cvtwX
 189189  *  H: movzwl + cvtwX
 190190  *  I: cvtld + addX
 191191  *  J: call __floatdisf
 192192  *  K: call __floatdidf
 193193  *  L: xxx + call __floatdisf
 194194  *  M: xxx + call __floatdidf
 195195  *  N: call __fixsfdi
 196196  *  O: call __fixunssfdi
 197197  *  P: call __fixdfdi
 198198  *  Q: call __fixunsdfdi
 199199  */
 200200 
 201201 #define MVD     1 /* mov + dest type */
 202202 #define CVT     2 /* cvt + src type + dst type */
 203203 #define MVZ     3 /* movz + src type + dst type */
 204204 #define CSE     4 /* cvt + src type + l + sign extend upper */
 205205 #define MZE     5 /* movz + src type + l + zero extend upper */
 206206 #define MLE     6 /* movl + sign extend upper */
 207207 #define MLZ     7 /* movl + zero extend upper */
 208208 #define MZC     8 /* movz + cvt */
 209209 
 210210 static char scary[][10] = {
 211211         { MVD, MVD, CVT, CVT, CVT, CVT, CSE, CSE, CVT, CVT },
 212212         { MVD, MVD, MVZ, MVZ, MVZ, MVZ, MZE, MZE, MZC, MZC },
 213213         { MVD, MVD, MVD, MVD, CVT, CVT, CSE, CSE, CVT, CVT },
 214214         { MVD, MVD, MVD, MVD, MVZ, MVZ, MZE, MZE, MZC, MZC },
 215215         { MVD, MVD, MVD, MVD, MVD, MVD, MLE, MLE, CVT, CVT },
 216216         { MVD, MVD, MVD, MVD, MVD, MVD, MLZ, MLZ, 'I', 'I' },
 217217         { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'J', 'K' },
 218218         { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'L', 'M' },
 219219         { CVT, CVT, CVT, CVT, CVT, CVT, 'N', 'O', MVD, CVT },
 220220         { CVT, CVT, CVT, CVT, CVT, CVT, 'P', 'Q', CVT, MVD },
 221221 };
 222222 
 223223 static void
 224224 sconv(NODE *p)
 225225 {
 226226         NODE *l = p->n_left;
 227227         TWORD ts, td;
 228228         int o;
 229229 
 230230         /*
 231231          * Source node may be in register or memory.
 232232          * Result is always in register.
 233233          */
 234234         ts = l->n_type;
 235235         if (ISPTR(ts))
 236236                 ts = UNSIGNED;
 237237         td = p->n_type;
 238238         ts = ts < LONG ? ts-2 : ts-4;
 239239         td = td < LONG ? td-2 : td-4;
 240240 
 241241         o = scary[ts][td];
 242242         switch (o) {
 243243         case MLE:
 244244         case MLZ:
 245245                 expand(p, INAREG|INBREG, "\tmovl\tAL,A1\n");
 246246                 break;
 247247 
 248248         case MVD:
 249249                 if (l->n_op == REG && regno(l) == regno(getlr(p, '1')))
 250250                         break; /* unneccessary move */
 251251                 expand(p, INAREG|INBREG, "\tmovZR\tAL,A1\n");
 252252                 break;
 253253 
 254254         case CSE:
 255255                 expand(p, INAREG|INBREG, "\tcvtZLl\tAL,A1\n");
 256256                 break;
 257257 
 258258         case CVT:
 259259                 expand(p, INAREG|INBREG, "\tcvtZLZR\tAL,A1\n");
 260260                 break;
 261261 
 262262         case MZE:
 263263                 expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
 264264                 break;
 265265 
 266266         case MVZ:
 267267                 expand(p, INAREG|INBREG, "\tmovzZLZR\tAL,A1\n");
 268268                 break;
 269269 
 270270         case MZC:
 271271                 expand(p, INAREG|INBREG, "\tmovzZLl\tAL,A1\n");
 272272                 expand(p, INAREG|INBREG, "\tcvtlZR\tA1,A1\n");
 273273                 break;
 274274 
 275275         case 'I': /* unsigned to double */
 276276                 expand(p, INAREG|INBREG, "\tcvtld\tAL,A1\n");
 277277                 printf("\tjgeq\t1f\n");
 278278                 expand(p, INAREG|INBREG, "\taddd2\t$0d4.294967296e+9,A1\n");
 279279                 printf("1:\n");
 280280                 break;
 281281         default:
 282282                 comperr("unsupported conversion %d", o);
 283283         }
 284284         switch (o) {
 285285         case MLE:
 286286         case CSE:
 287287                 expand(p, INBREG, "\tashl\t$-31,A1,U1\n");
 288288                 break;
 289289         case MLZ:
 290290         case MZE:
 291291                 expand(p, INAREG|INBREG, "\tclrl\tU1\n");
 292292                 break;
 293293         }
 294294 }
 295295 
 296296 /*
 297297  * Assign a constant from p to q.  Both are expected to be leaves by now.
 298298  * This is for 64-bit integers.
 299299  */
 300300 static void
 301301 casg64(NODE *p)
 302302 {
 303303         NODE *l, *r;
 304304         char *str;
 305305         int mneg = 1;
 306306         
 307307         l = p->n_left;
 308308         r = p->n_right;
 309309 
 310310 #ifdef PCC_DEBUG
 311311         if (r->n_op != ICON)
 312312                 comperr("casg");
 313313 #endif
 314314         if (r->n_name[0] != '\0') {
 315315                 /* named constant, nothing to do */
 316316                 str = "movq\tAR,AL";
 317317                 mneg = 0;
 318318         } else if (r->n_lval == 0) {
 319319                 str = "clrq\tAL";
 320320                 mneg = 0;
 321321         } else if (r->n_lval < 0) {
 322322                 if (r->n_lval >= -63) {
 323323                         r->n_lval = -r->n_lval;
 324324                         str = "mnegl\tAR,AL";
 325325                 } else if (r->n_lval >= -128) {
 326326                         str = "cvtbl\tAR,AL";
 327327                 } else if (r->n_lval >= -32768) {
 328328                         str = "cvtwl\tAR,AL";
 329329                 } else if (r->n_lval >= -4294967296LL) {
 330330                         str = "movl\tAR,AL";
 331331                 } else {
 332332                         str = "movq\tAR,AL";
 333333                         mneg = 0;
 334334                 }
 335335         } else {
 336336                 mneg = 0;
 337337                 if (r->n_lval <= 63 || r->n_lval > 4294967295LL) {
 338338                         str = "movq\tAR,AL";
 339339                 } else if (r->n_lval <= 255) {
 340340                         str = "movzbl\tAR,AL\n\tclrl\tUL";
 341341                 } else if (r->n_lval <= 65535) {
 342342                         str = "movzwl\tAR,AL\n\tclrl\tUL";
 343343                 } else /* if (r->n_lval <= 4294967295) */ {
 344344                         str = "movl\tAR,AL\n\tclrl\tUL";
 345345                 }
 346346         }
 347347         expand(p, FOREFF, str);
 348348         if (mneg)
<>349 -                expand(p, FOREFF, "\n\tmnegl $-1,UL");
  349+                expand(p, FOREFF, "\n\tmnegl $1,UL");
350350 }
 351351 
 352352 /*
 353353  * Assign a constant from p to q.  Both are expected to be leaves by now.
 354354  * This is only for 32-bit integer types.
 355355  */
 356356 static void
 357357 casg(NODE *p)
 358358 {
 359359         NODE *l, *r;
 360360         char *str;
 361361         
 362362         l = p->n_left;
 363363         r = p->n_right;
 364364 
 365365 #ifdef PCC_DEBUG
 366366         if (r->n_op != ICON)
 367367                 comperr("casg");
 368368 #endif
 369369         if (r->n_name[0] != '\0') {
 370370                 /* named constant, nothing to do */
 371371                 str = "movZL\tAR,AL";
 372372         } else if (r->n_lval == 0) {
 373373                 str = "clrZL\tAL";
 374374         } else if (r->n_lval < 0) {
 375375                 if (r->n_lval >= -63) {
 376376                         r->n_lval = -r->n_lval;
 377377                         str = "mnegZL\tAR,AL";
 378378                 } else if (r->n_lval >= -128) {
 379379                         if (l->n_type == CHAR)
 380380                                 str = "movb\tAR,AL";
 381381                         else
 382382                                 str = "cvtbZL\tAR,AL";
 383383                 } else if (r->n_lval >= -32768) {
 384384                         if (l->n_type == SHORT)
 385385                                 str = "movw\tAR,AL";
 386386                         else
 387387                                 str = "cvtwZL\tAR,AL";
 388388                 } else
 389389                         str = "movZL\tAR,AL";
 390390         } else {
 391391                 if (r->n_lval <= 63 || r->n_lval > 65535) {
 392392                         str = "movZL\tAR,AL";
 393393                 } else if (r->n_lval <= 255) {
 394394                         str = l->n_type < SHORT ?
 395395                             "movb\tAR,AL" : "movzbZL\tAR,AL";
 396396                 } else /* if (r->n_lval <= 65535) */ {
 397397                         str = l->n_type < INT ?
 398398                             "movw\tAR,AL" : "movzwZL\tAR,AL";
 399399                 }
 400400         }
 401401         expand(p, FOREFF, str);
 402402 }
 403403 
 404404 /*
 405405  * Emit code to compare two longlong numbers.
 406406  */
 407407 static void
 408408 twollcomp(NODE *p)
 409409 {
 410410         int u;
 411411         int s = getlab2();
 412412         int e = p->n_label;
 413413         int cb1, cb2;
 414414 
 415415         u = p->n_op;
 416416         switch (p->n_op) {
 417417         case NE:
 418418                 cb1 = 0;
 419419                 cb2 = NE;
 420420                 break;
 421421         case EQ:
 422422                 cb1 = NE;
 423423                 cb2 = 0;
 424424                 break;
 425425         case LE:
 426426         case LT:
 427427                 u += (ULE-LE);
 428428                 /* FALLTHROUGH */
 429429         case ULE:
 430430         case ULT:
 431431                 cb1 = GT;
 432432                 cb2 = LT;
 433433                 break;
 434434         case GE:
 435435         case GT:
 436436                 u += (ULE-LE);
 437437                 /* FALLTHROUGH */
 438438         case UGE:
 439439         case UGT:
 440440                 cb1 = LT;
 441441                 cb2 = GT;
 442442                 break;
 443443         
 444444         default:
 445445                 cb1 = cb2 = 0; /* XXX gcc */
 446446         }
 447447         if (p->n_op >= ULE)
 448448                 cb1 += 4, cb2 += 4;
 449449         expand(p, 0, "  cmpl UL,UR\n");
 450450         if (cb1) cbgen(cb1, s);
 451451         if (cb2) cbgen(cb2, e);
 452452         expand(p, 0, "  cmpl AL,AR\n");
 453453         cbgen(u, e);
 454454         deflab(s);
 455455 }
 456456 
 457457 
 458458 void
 459459 zzzcode(NODE *p, int c)
 460460 {
 461461         NODE *l, *r;
 462462         TWORD t;
 463463         int m;
 464464         char *ch;
 465465 
 466466         switch (c) {
 467467         case 'N'/* logical ops, turned into 0-1 */
 468468                 /* use register given by register 1 */
 469469                 cbgen( 0, m=getlab2());
 470470                 deflab( p->n_label );
 471471                 printf( "       clrl    %s\n", rnames[getlr( p, '1' )->n_rval] );
 472472                 deflab( m );
 473473                 return;
 474474 
 475475         case 'A': /* Assign a constant directly to a memory position */
 476476                 printf("\t");
 477477                 if (p->n_type < LONG || ISPTR(p->n_type))
 478478                         casg(p);
 479479                 else
 480480                         casg64(p);
 481481                 printf("\n");
 482482                 break;
 483483 
 484484         case 'B': /* long long compare */
 485485                 twollcomp(p);
 486486                 break;
 487487 
 488488         case 'C':       /* num words pushed on arg stack */
 489489                 printf("$%d", p->n_qual);
 490490                 break;
 491491 
 492492         case 'D':       /* INCR and DECR */
 493493                 zzzcode(p->n_left, 'A');
 494494                 printf("\n      ");
 495495 
 496496 #if 0
 497497         case 'E':       /* INCR and DECR, FOREFF */
 498498                 if (p->n_right->n_lval == 1)
 499499                         {
 500500                         printf("%s", (p->n_op == INCR ? "inc" : "dec") );
 501501                         prtype(p->n_left);
 502502                         printf("        ");
 503503                         adrput(stdout, p->n_left);
 504504                         return;
 505505                         }
 506506                 printf("%s", (p->n_op == INCR ? "add" : "sub") );
 507507                 prtype(p->n_left);
 508508                 printf("2       ");
 509509                 adrput(stdout, p->n_right);
 510510                 printf(",");
 511511                 adrput(p->n_left);
 512512                 return;
 513513 #endif
 514514 
 515515         case 'F':       /* register type of right operand */
 516516                 {
 517517                 register NODE *n;
 518518                 register int ty;
 519519 
 520520                 n = getlr( p, 'R' );
 521521                 ty = n->n_type;
 522522 
 523523                 if (x2debug) printf("->%d<-", ty);
 524524 
 525525                 if ( ty==DOUBLE) printf("d");
 526526                 else if ( ty==FLOAT ) printf("f");
 527527                 else printf("l");
 528528                 return;
 529529                 }
 530530 
 531531         case 'G': /* emit conversion instructions */
 532532                 sconv(p);
 533533                 break;
 534534 
 535535         case 'J': /* jump or ret? */
 536536                 {
 537537                         struct interpass *ip =
 538538                             DLIST_PREV((struct interpass *)p2env.epp, qelem);
 539539                         if (ip->type != IP_DEFLAB ||
 540540                             ip->ip_lbl != getlr(p, 'L')->n_lval)
 541541                                 expand(p, FOREFF, "jbr  LL");
 542542                         else
 543543                                 printf("ret");
 544544                 }
 545545                 break;
 546546 
 547547         case 'L':       /* type of left operand */
 548548         case 'R':       /* type of right operand */
 549549                 {
 550550                 register NODE *n;
 551551 
 552552                 n = getlr ( p, c);
 553553                 if (x2debug) printf("->%d<-", n->n_type);
 554554 
 555555                 prtype(n);
 556556                 return;
 557557                 }
 558558 
 559559         case 'O': /* print out emulated ops */
 560560                 expand(p, FOREFF, "\tmovq       AR,-(%sp)\n");
 561561                 expand(p, FOREFF, "\tmovq       AL,-(%sp)\n");
 562562                 if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
 563563                 else if (p->n_op == DIV) ch = "div";
 564564                 else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
 565565                 else if (p->n_op == MOD) ch = "mod";
 566566                 else if (p->n_op == MUL) ch = "mul";
 567567                 else ch = 0, comperr("ZO %d", p->n_op);
 568568                 printf("\tcalls $4,__%sdi3\n", ch);
 569569                 break;
 570570 
 571571 
 572572         case 'Z':       /* complement mask for bit instr */
 573573                 printf("$%Ld", ~p->n_right->n_lval);
 574574                 return;
 575575 
 576576         case 'U':       /* 32 - n, for unsigned right shifts */
 577577                 t = DEUNSIGN(p->n_left->n_type);
 578578                 m = t == CHAR ? 8 : t == SHORT ? 16 : 32;
 579579                 printf("$" CONFMT, m - p->n_right->n_lval);
 580580                 return;
 581581 
 582582         case 'T':       /* rounded structure length for arguments */
 583583                 {
 584584                 int size;
 585585 
 586586                 size = p->n_stsize;
 587587                 SETOFF( size, 4);
 588588                 printf("$%d", size);
 589589                 return;
 590590                 }
 591591 
 592592         case 'S'/* structure assignment */
 593593                 {
 594594                         register int size;
 595595 
 596596                         size = p->n_stsize;
 597597                         l = r = NULL; /* XXX gcc */
 598598                         if( p->n_op == STASG ){
 599599                                 l = p->n_left;
 600600                                 r = p->n_right;
 601601 
 602602                                 }
 603603                         else if( p->n_op == STARG ){
 604604                                 /* store an arg into a temporary */
 605605                                 printf("\tsubl2 $%d,%%sp\n",
 606606                                     size < 4 ? 4 : size);
 607607                                 l = mklnode(OREG, 0, SP, INT);
 608608                                 r = p->n_left;
 609609                                 }
 610610                         else cerror( "STASG bad" );
 611611 
 612612                         if( r->n_op == ICON ) r->n_op = NAME;
 613613                         else if( r->n_op == REG ) r->n_op = OREG;
 614614                         else if( r->n_op != OREG ) cerror( "STASG-r" );
 615615 
 616616                 if (size != 0) {
 617617                         if( size <= 0 || size > 65535 )
 618618                                 cerror("structure size <0=0 or >65535");
 619619 
 620620                         switch(size) {
 621621                                 case 1:
 622622                                         printf("        movb    ");
 623623                                         break;
 624624                                 case 2:
 625625                                         printf("        movw    ");
 626626                                         break;
 627627                                 case 4:
 628628                                         printf("        movl    ");
 629629                                         break;
 630630                                 case 8:
 631631                                         printf("        movq    ");
 632632                                         break;
 633633                                 default:
 634634                                         printf("        movc3   $%d,", size);
 635635                                         break;
 636636                         }
 637637                         adrput(stdout, r);
 638638                         printf(",");
 639639                         adrput(stdout, l);
 640640                         printf("\n");
 641641                 }
 642642 
 643643                         if( r->n_op == NAME ) r->n_op = ICON;
 644644                         else if( r->n_op == OREG ) r->n_op = REG;
 645645                         if (p->n_op == STARG)
 646646                                 tfree(l);
 647647 
 648648                         }
 649649                 break;
 650650 
 651651         default:
 652652                 comperr("illegal zzzcode '%c'", c);
 653653         }
 654654 }
 655655 
 656656 void
 657657 rmove(int rt, int rs, TWORD t)
 658658 {
 659659         printf( "       %s      %s,%s\n",
 660660                 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
 661661                 rnames[rt], rnames[rs] );
 662662 }
 663663 
 664664 int
 665665 rewfld(NODE *p)
 666666 {
 667667         return(1);
 668668 }
 669669 
 670670 #if 0
 671671 int
 672672 callreg(NODE *p)
 673673 {
 674674         return( R0 );
 675675 }
 676676 
 677677 int
 678678 base(register NODE *p)
 679679 {
 680680         register int o = p->op;
 681681 
 682682         if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
 683683         if( o==REG ) return( p->rval );
 684684     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
 685685                 return( p->left->rval );
 686686     if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 687687                 return( p->rval + 0200*1 );
 688688         if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
 689689         if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
 690690         if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
 691691           && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 692692                 return( p->left->left->rval + 0200*(1+2) );
 693693         return( -1 );
 694694 }
 695695 
 696696 int
 697697 offset(register NODE *p, int tyl)
 698698 {
 699699 
 700700         if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
 701701         if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
 702702               (p->right->op==ICON && p->right->name[0]=='\0')
 703703               && (1<<p->right->lval)==tyl))
 704704                 return( p->left->rval );
 705705         return( -1 );
 706706 }
 707707 #endif
 708708 
 709709 #if 0
 710710 void
 711711 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
 712712         register NODE *t;
 713713         NODE *f;
 714714 
 715715         p->n_op = OREG;
 716716         f = p->n_left;  /* have to free this subtree later */
 717717 
 718718         /* init base */
 719719         switch (q->n_op) {
 720720                 case ICON:
 721721                 case REG:
 722722                 case OREG:
 723723                         t = q;
 724724                         break;
 725725 
 726726                 case MINUS:
 727727                         q->n_right->n_lval = -q->n_right->n_lval;
 728728                 case PLUS:
 729729                         t = q->n_right;
 730730                         break;
 731731 
 732732                 case UMUL:
 733733                         t = q->n_left->n_left;
 734734                         break;
 735735 
 736736                 default:
 737737                         cerror("illegal makeor2");
 738738                         t = NULL; /* XXX gcc */
 739739         }
 740740 
 741741         p->n_lval = t->n_lval;
 742742         p->n_name = t->n_name;
 743743 
 744744         /* init offset */
 745745         p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
 746746 
 747747         tfree(f);
 748748         return;
 749749         }
 750750 
 751751 int
 752752 canaddr( p ) NODE *p; {
 753753         register int o = p->n_op;
 754754 
 755755         if( o==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_left, STARNM|SOREG)) ) return(1);
 756756         return(0);
 757757         }
 758758 
 759759 shltype( o, p ) register NODE *p; {
 760760         return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 761761         }
 762762 #endif
 763763 
 764764 int
 765765 fldexpand(NODE *p, int cookie, char **cp)
 766766 {
 767767         return 0;
 768768 }
 769769 
 770770 int
 771771 flshape(register NODE *p)
 772772 {
 773773         return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
 774774                 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
 775775 }
 776776 
 777777 int
 778778 shtemp(register NODE *p)
 779779 {
 780780         if( p->n_op == STARG ) p = p->n_left;
 781781         return( p->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 782782 }
 783783 
 784784 /*
 785785  * Shape matches for UMUL.  Cooperates with offstar().
 786786  */
 787787 int
 788788 shumul(NODE *p, int shape)
 789789 {
 790790 
 791791         if (x2debug)
 792792                 printf("shumul(%p)\n", p);
 793793 
 794794         /* Turns currently anything into OREG on vax */
 795795         if (shape & SOREG)
 796796                 return SROREG;
 797797         return SRNOPE;
 798798 }
 799799 
 800800 
 801801 #ifdef notdef
 802802 int
 803803 shumul( p, shape ) register NODE *p; int shape; {
 804804         register int o;
 805805 
 806806         if (x2debug) {
 807807                  printf("\nshumul:op=%d,lop=%d,rop=%d", p->n_op, p->n_left->n_op, p->n_right->n_op);
 808808                 printf(" prname=%s,plty=%d, prlval=%lld\n", p->n_right->n_name, p->n_left->n_type, p->n_right->n_lval);
 809809                 }
 810810 
 811811 
 812812         o = p->n_op;
 813813         if( o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
 814814                 if (shape & STARNM)
 815815                         return SRDIR;
 816816 
 817817         if( ( o == INCR || o == ASG MINUS ) &&
 818818             ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
 819819             p->n_right->n_name[0] == '\0' )
 820820                 {
 821821                 switch (p->n_left->n_type)
 822822                         {
 823823                         case CHAR|PTR:
 824824                         case UCHAR|PTR:
 825825                                 o = 1;
 826826                                 break;
 827827 
 828828                         case SHORT|PTR:
 829829                         case USHORT|PTR:
 830830                                 o = 2;
 831831                                 break;
 832832 
 833833                         case INT|PTR:
 834834                         case UNSIGNED|PTR:
 835835                         case LONG|PTR:
 836836                         case ULONG|PTR:
 837837                         case FLOAT|PTR:
 838838                                 o = 4;
 839839                                 break;
 840840 
 841841                         case DOUBLE|PTR:
 842842                                 o = 8;
 843843                                 break;
 844844 
 845845                         default:
 846846                                 if ( ISPTR(p->n_left->n_type) ) {
 847847                                         o = 4;
 848848                                         break;
 849849                                         }
 850850                                 else return(0);
 851851                         }
 852852                 return( p->n_right->n_lval == o ? STARREG : 0);
 853853                 }
 854854 
 855855         return( SRNOPE );
 856856         }
 857857 #endif
 858858 
 859859 void
 860860 adrcon(CONSZ val)
 861861 {
 862862         printf( "$" );
 863863         printf( CONFMT, val );
 864864 }
 865865 
 866866 void
 867867 conput(FILE *fp, NODE *p)
 868868 {
 869869         switch( p->n_op ){
 870870 
 871871         case ICON:
 872872                 acon( p );
 873873                 return;
 874874 
 875875         case REG:
 876876                 printf( "%s", rnames[p->n_rval] );
 877877                 return;
 878878 
 879879         default:
 880880                 cerror( "illegal conput" );
 881881                 }
 882882         }
 883883 
 884884 void
 885885 insput(register NODE *p)
 886886 {
 887887         cerror( "insput" );
 888888 }
 889889 
 890890 /*
 891891  * Write out the upper address, like the upper register of a 2-register
 892892  * reference, or the next memory location.
 893893  */
 894894 void
 895895 upput(NODE *p, int size)
 896896 {
 897897 
 898898         size /= SZCHAR;
 899899         switch (p->n_op) {
 900900         case REG:
 901901                 printf("%s", rnames[regno(p)-16+1]);
 902902                 break;
 903903 
 904904         case NAME:
 905905                 if (kflag)
 906906                         comperr("upput NAME");
 907907         case OREG:
 908908                 p->n_lval += size;
 909909                 adrput(stdout, p);
 910910                 p->n_lval -= size;
 911911                 break;
 912912         case ICON:
 913913                 printf("$" CONFMT, p->n_lval >> 32);
 914914                 break;
 915915         default:
 916916                 comperr("upput bad op %d size %d", p->n_op, size);
 917917         }
 918918 }
 919919 
 920920 void
 921921 adrput(FILE *fp, NODE *p)
 922922 {
 923923         register int r;
 924924         /* output an address, with offsets, from p */
 925925 
 926926         if( p->n_op == FLD ){
 927927                 p = p->n_left;
 928928                 }
 929929         switch( p->n_op ){
 930930 
 931931         case NAME:
 932932                 acon( p );
 933933                 return;
 934934 
 935935         case ICON:
 936936                 /* addressable value of the constant */
 937937                 if (p->n_name[0] == '\0') /* uses xxxab */
 938938                         printf("$");
 939939                 acon(p);
 940940                 return;
 941941 
 942942         case REG:
 943943                 printf( "%s", rnames[p->n_rval] );
 944944                 return;
 945945 
 946946         case OREG:
 947947                 r = p->n_rval;
 948948                 if( R2TEST(r) ){ /* double indexing */
 949949                         register int flags;
 950950 
 951951                         flags = R2UPK3(r);
 952952                         if( flags & 1 ) printf("*");
 953953                         if( flags & 4 ) printf("-");
 954954                         if( p->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
 955955                         if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
 956956                         if( flags & 2 ) printf("+");
 957957                         printf( "[%s]", rnames[R2UPK2(r)] );
 958958                         return;
 959959                         }
 960960                 if( r == AP ){  /* in the argument region */
 961961                         if( p->n_lval <= 0 || p->n_name[0] != '\0' )
 962962                                 werror( "bad arg temp" );
 963963                         printf( CONFMT, p->n_lval );
 964964                         printf( "(%%ap)" );
 965965                         return;
 966966                         }
 967967                 if( p->n_lval != 0 || p->n_name[0] != '\0') acon( p );
 968968                 printf( "(%s)", rnames[p->n_rval] );
 969969                 return;
 970970 
 971971         case UMUL:
 972972                 /* STARNM or STARREG found */
 973973                 if( tshape(p, STARNM) ) {
 974974                         printf( "*" );
 975975                         adrput(0p->n_left);
 976976                         }
 977977                 else {  /* STARREG - really auto inc or dec */
 978978                         register NODE *q;
 979979 
 980980 /* tbl
 981981                         p = p->n_left;
 982982                         p->n_left->n_op = OREG;
 983983                         if( p->n_op == INCR ) {
 984984                                 adrput( p->n_left );
 985985                                 printf( "+" );
 986986                                 }
 987987                         else {
 988988                                 printf( "-" );
 989989                                 adrput( p->n_left );
 990990                                 }
 991991    tbl */
 992992 #ifdef notyet
 993993                         printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
 994994                                 rnames[p->n_left->n_left->n_rval],
 995995                                 (p->n_left->n_op==INCR ? '+' : '\0') );
 996996 #else
 997997                         printf("%c(%s)%c", '-',
 998998                                 rnames[p->n_left->n_left->n_rval],
 999999                                 '\0' );
 10001000 #endif
 10011001                         p->n_op = OREG;
 10021002                         p->n_rval = p->n_left->n_left->n_rval;
 10031003                         q = p->n_left;
 10041004 #ifdef notyet
 10051005 
 10061006                         p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
 10071007 #else
 10081008                         p->n_lval = 0;
 10091009 #endif
 10101010                         p->n_name[0] = '\0';
 10111011                         tfree(q);
 10121012                 }
 10131013                 return;
 10141014 
 10151015         default:
 10161016                 cerror( "illegal address" );
 10171017                 return;
 10181018         }
 10191019 
 10201020 }
 10211021 
 10221022 /*
 10231023  * print out a constant
 10241024  */
 10251025 void
 10261026 acon(NODE *p)
 10271027 {
 10281028 
 10291029         if (p->n_name[0] == '\0') {
 10301030                 printf(CONFMT, p->n_lval);
 10311031         } else if( p->n_lval == 0 ) {
 10321032                 printf("%s", p->n_name);
 10331033         } else {
 10341034                 printf("%s+", p->n_name);
 10351035                 printf(CONFMT, p->n_lval);
 10361036         }
 10371037 }
 10381038 
 10391039 #if 0
 10401040 genscall( p, cookie ) register NODE *p; {
 10411041         /* structure valued call */
 10421042         return( gencall( p, cookie ) );
 10431043         }
 10441044 
 10451045 /* tbl */
 10461046 int gc_numbytes;
 10471047 /* tbl */
 10481048 
 10491049 gencall( p, cookie ) register NODE *p; {
 10501050         /* generate the call given by p */
 10511051         register NODE *p1, *ptemp;
 10521052         register temp, temp1;
 10531053         register m;
 10541054 
 10551055         if( p->right ) temp = argsize( p->right );
 10561056         else temp = 0;
 10571057 
 10581058         if( p->op == STCALL || p->op == UNARY STCALL ){
 10591059                 /* set aside room for structure return */
 10601060 
 10611061                 if( p->stsize > temp ) temp1 = p->stsize;
 10621062                 else temp1 = temp;
 10631063                 }
 10641064 
 10651065         if( temp > maxargs ) maxargs = temp;
 10661066         SETOFF(temp1,4);
 10671067 
 10681068         if( p->right ){ /* make temp node, put offset in, and generate args */
 10691069                 ptemp = talloc();
 10701070                 ptemp->op = OREG;
 10711071                 ptemp->lval = -1;
 10721072                 ptemp->rval = SP;
 10731073                 ptemp->name[0] = '\0';
 10741074                 ptemp->rall = NOPREF;
 10751075                 ptemp->su = 0;
 10761076                 genargs( p->right, ptemp );
 10771077                 nfree(ptemp);
 10781078                 }
 10791079 
 10801080         p1 = p->left;
 10811081         if( p1->op != ICON ){
 10821082                 if( p1->op != REG ){
 10831083                         if( p1->op != OREG || R2TEST(p1->rval) ){
 10841084                                 if( p1->op != NAME ){
 10851085                                         order( p1, INAREG );
 10861086                                         }
 10871087                                 }
 10881088                         }
 10891089                 }
 10901090 
 10911091 /*
 10921092         if( p1->op == REG && p->rval == R5 ){
 10931093                 cerror( "call register overwrite" );
 10941094                 }
 10951095  */
 10961096 /* tbl
 10971097         setup gc_numbytes so reference to ZC works */
 10981098 
 10991099         gc_numbytes = temp;
 11001100 /* tbl */
 11011101 
 11021102         p->op = UNARY CALL;
 11031103         m = match( p, INTAREG|INTBREG );
 11041104 /* tbl
 11051105         switch( temp ) {
 11061106         case 0:
 11071107                 break;
 11081108         case 2:
 11091109                 printf( "       tst     (%sp)+\n" );
 11101110                 break;
 11111111         case 4:
 11121112                 printf( "       cmp     (%sp)+,(%sp)+\n" );
 11131113                 break;
 11141114         default:
 11151115                 printf( "       add     $%d,%sp\n", temp);
 11161116                 }
 11171117    tbl */
 11181118         return(m != MDONE);
 11191119         }
 11201120 #endif
 11211121 
 11221122 static char *
 11231123 ccbranches[] = {
 11241124         "jeql",
 11251125         "jneq",
 11261126         "jleq",
 11271127         "jlss",
 11281128         "jgeq",
 11291129         "jgtr",
 11301130         "jlequ",
 11311131         "jlssu",
 11321132         "jgequ",
 11331133         "jgtru",
 11341134 };
 11351135 
 11361136 /*
 11371137  * printf conditional and unconditional branches
 11381138  */
 11391139 void
 11401140 cbgen(int o, int lab)
 11411141 {
 11421142 
 11431143         if (o == 0) {
 11441144                 printf("        jbr     " LABFMT "\n", lab);
 11451145         } else {
 11461146                 if (o > UGT)
 11471147                         comperr("bad conditional branch: %s", opst[o]);
 11481148                 printf("\t%s\t" LABFMT "\n", ccbranches[o-EQ], lab);
 11491149         }
 11501150 }
 11511151 
 11521152 static void
 11531153 mkcall(NODE *p, char *name)
 11541154 {
 11551155         p->n_op = CALL;
 11561156         p->n_right = mkunode(FUNARG, p->n_left, 0, p->n_left->n_type);
 11571157         p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
 11581158         p->n_left->n_name = name;
 11591159 }
 11601160 
 11611161 /* do local tree transformations and optimizations */
 11621162 static void
 11631163 optim2(NODE *p, void *arg)
 11641164 {
 11651165         NODE *r, *s;
 11661166         TWORD lt;
 11671167 
 11681168         switch (p->n_op) {
<> 1169+        case DIV:
11691170         case MOD:
 11701171                 if (p->n_type == USHORT || p->n_type == UCHAR) {
 11711172                         r = mkunode(SCONV, p->n_left, 0, UNSIGNED);
 11721173                         r = mkunode(FUNARG, r, 0, UNSIGNED);
 11731174                         s = mkunode(SCONV, p->n_right, 0, UNSIGNED);
 11741175                         s = mkunode(FUNARG, s, 0, UNSIGNED);
 11751176                         r = mkbinode(CM, r, s, INT);
 11761177                         s = mklnode(ICON, 0, 0, FTN|UNSIGNED);
<>1177 -                        s->n_name = "__urem";
  1178+                        s->n_name = p->n_op == MOD ? "__urem" : "__udiv";
11781179                         p->n_left = mkbinode(CALL, s, r, UNSIGNED);
 11791180                         p->n_op = SCONV;
 11801181                 } else if (p->n_type == UNSIGNED) {
 11811182                         p->n_left = mkunode(FUNARG, p->n_left, 0, UNSIGNED);
 11821183                         p->n_right = mkunode(FUNARG, p->n_right, 0, UNSIGNED);
 11831184                         p->n_right = mkbinode(CM, p->n_left, p->n_right, INT);
 11841185                         p->n_left = mklnode(ICON, 0, 0, FTN|UNSIGNED);
<>1185 -                        p->n_left->n_name = "__urem";
  1186+                        p->n_left->n_name = p->n_op == MOD ? "__urem" : "__udiv";
<_11861187                         p->n_op = CALL;
 11871188                 }
 11881189                 break;
 11891190 
 11901191         case RS:
 11911192                 if (p->n_type == ULONGLONG) {
 11921193                         p->n_right = mkbinode(CM,
 11931194                             mkunode(FUNARG, p->n_left, 0, p->n_left->n_type),
 11941195                             mkunode(FUNARG, p->n_right, 0, p->n_right->n_type),
 11951196                             INT);
 11961197                         p->n_left = mklnode(ICON, 0, 0, FTN|p->n_type);
 11971198                         p->n_left->n_name = "__lshrdi3";
 11981199                         p->n_op = CALL;
 11991200                 } else if (p->n_type == INT || p->n_type == LONGLONG) {
 12001201                         /* convert >> to << with negative shift count */
 12011202                         /* RS of char & short must use extv */
 12021203                         if (p->n_right->n_op == ICON) {
 12031204                                 p->n_right->n_lval = -p->n_right->n_lval;
 12041205                         } else if (p->n_right->n_op == UMINUS) {
 12051206                                 r = p->n_right->n_left;
 12061207                                 nfree(p->n_right);
 12071208                                 p->n_right = r;
 12081209                         } else {
 12091210                                 p->n_right = mkunode(UMINUS, p->n_right,
 12101211                                     0, p->n_right->n_type);
 12111212                         }
 12121213                         p->n_op = LS;
 12131214                 }
 12141215                 break;
 12151216 
 12161217         case AND:
 12171218                 /* commute L and R to eliminate compliments and constants */
 12181219                 if ((p->n_left->n_op == ICON && p->n_left->n_name[0] == 0) ||
 12191220                     p->n_left->n_op==COMPL) {
 12201221                         r = p->n_left;
 12211222                         p->n_left = p->n_right;
 12221223                         p->n_right = r;
 12231224                 }
 12241225                 /* change meaning of AND to ~R&L - bic on pdp11 */
 12251226                 r = p->n_right;
 12261227                 if (r->n_op == ICON && r->n_name[0] == 0) {
 12271228                         /* compliment constant */
 12281229                         r->n_lval = ~r->n_lval;
 12291230                 } else if (r->n_op == COMPL) { /* ~~A => A */
 12301231                         s = r->n_left;
 12311232                         nfree(r);
 12321233                         p->n_right = s;
 12331234                 } else { /* insert complement node */
 12341235                         p->n_right = mkunode(COMPL, r, 0, r->n_type);
 12351236                 }
 12361237                 break;
 12371238         case SCONV:
 12381239                 lt = p->n_left->n_type;
 12391240                 switch (p->n_type) {
 12401241                 case LONGLONG:
 12411242                         if (lt == FLOAT)
 12421243                                 mkcall(p, "__fixsfdi");
 12431244                         else if (lt == DOUBLE)
 12441245                                 mkcall(p, "__fixdfdi");
 12451246                         break;
 12461247                 case ULONGLONG:
 12471248                         if (lt == FLOAT)
 12481249                                 mkcall(p, "__fixunssfdi");
 12491250                         else if (lt == DOUBLE)
 12501251                                 mkcall(p, "__fixunsdfdi");
 12511252                         break;
 12521253                 case FLOAT:
 12531254                         if (lt == LONGLONG)
 12541255                                 mkcall(p, "__floatdisf");
 12551256                         else if (lt == ULONGLONG) {
 12561257                                 p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
 12571258                                 p->n_type = FLOAT;
 12581259                                 mkcall(p->n_left, "__floatundidf");
 12591260                         } else if (lt == UNSIGNED) {
 12601261                                 /* insert an extra double-to-float sconv */
 12611262                                 p->n_left = mkunode(SCONV, p->n_left,0, DOUBLE);
 12621263                         }
 12631264                         break;
 12641265                 case DOUBLE:
 12651266                         if (lt == LONGLONG)
 12661267                                 mkcall(p, "__floatdidf");
 12671268                         else if (lt == ULONGLONG)
 12681269                                 mkcall(p, "__floatundidf");
 12691270                         break;
 12701271                         
 12711272                 }
 12721273                 break;
 12731274         }
 12741275 }
 12751276 
 12761277 static void
 12771278 aofname(NODE *p, void *arg)
 12781279 {
 12791280         int o = optype(p->n_op);
 12801281         TWORD t;
 12811282 
 12821283         if (o == LTYPE || p->n_op == ADDROF)
 12831284                 return;
 12841285         t = p->n_left->n_type;
 12851286         if (p->n_left->n_op == NAME && ISLONGLONG(t))
 12861287                 p->n_left = mkunode(UMUL,
 12871288                     mkunode(ADDROF, p->n_left, 0, INCREF(t)), 0, t);
 12881289         if (o == BITYPE && p->n_right->n_op == NAME &&
 12891290             ISLONGLONG(p->n_right->n_type)) {
 12901291                 t = p->n_right->n_type;
 12911292                 p->n_right = mkunode(UMUL,
 12921293                     mkunode(ADDROF, p->n_right, 0, INCREF(t)), 0, t);
 12931294         }
 12941295 }
 12951296 
 12961297 void
 12971298 myreader(struct interpass *ipole)
 12981299 {
 12991300         struct interpass *ip;
 13001301 
 13011302         DLIST_FOREACH(ip, ipole, qelem) {
 13021303                 if (ip->type != IP_NODE)
 13031304                         continue;
 13041305                 if (kflag)
 13051306                         walkf(ip->ip_node, aofname, 0);
 13061307                 walkf(ip->ip_node, optim2, 0);
 13071308         }
 13081309 }
 13091310 
 13101311 void
 13111312 mycanon(NODE *p)
 13121313 {
 13131314 }
 13141315 
 13151316 void
 13161317 myoptim(struct interpass *ip)
 13171318 {
 13181319 }
 13191320 
 13201321 /*
 13211322  * Return argument size in regs.
 13221323  */
 13231324 static int
 13241325 argsiz(NODE *p)
 13251326 {
 13261327         TWORD t = p->n_type;
 13271328 
 13281329         if (t == STRTY || t == UNIONTY)
 13291330                 return p->n_stsize/(SZINT/SZCHAR);
 13301331         return szty(t);
 13311332 }
 13321333 
 13331334 /*
 13341335  * Last chance to do something before calling a function.
 13351336  */
 13361337 void
 13371338 lastcall(NODE *p)
 13381339 {
 13391340         NODE *op = p;
 13401341         int size = 0;
 13411342 
 13421343         /* Calculate argument sizes */
 13431344         p->n_qual = 0;
 13441345         if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
 13451346                 return;
 13461347         for (p = p->n_right; p->n_op == CM; p = p->n_left)
 13471348                 size += argsiz(p->n_right);
 13481349         if (p->n_op != ASSIGN)
 13491350                 size += argsiz(p);
 13501351         op->n_qual = size; /* XXX */
 13511352 }
 13521353 
 13531354 /*
 13541355  * Return a class suitable for a specific type.
 13551356  */
 13561357 int
 13571358 gclass(TWORD t)
 13581359 {
 13591360         return (szty(t) == 2 ? CLASSB : CLASSA);
 13601361 }
 13611362 
 13621363 /*
 13631364  * For class c, find worst-case displacement of the number of
 13641365  * registers in the array r[] indexed by class.
 13651366  */
 13661367 int
 13671368 COLORMAP(int c, int *r)
 13681369 {
 13691370         int num;
 13701371         int a,b;
 13711372 
 13721373         a = r[CLASSA];
 13731374         b = r[CLASSB];
 13741375         switch (c) {
 13751376         case CLASSA:
 13761377                 /* there are 12 classa, so min 6 classb are needed to block */
 13771378                 num = b * 2;
 13781379                 num += a;
 13791380                 return num < 12;
 13801381         case CLASSB:
 13811382                 if (b > 3) return 0;
 13821383                 if (b > 2 && a) return 0;
 13831384                 if (b > 1 && a > 2) return 0;
 13841385                 if (b && a > 3) return 0;
 13851386                 if (a > 5) return 0;
 13861387                 return 1;
 13871388         }
 13881389         comperr("COLORMAP");
 13891390         return 0; /* XXX gcc */
 13901391 }
 13911392 
 13921393 /*
 13931394  * Special shapes.
 13941395  */
 13951396 int
 13961397 special(NODE *p, int shape)
 13971398 {
 13981399         return SRNOPE;
 13991400 }
 14001401 
 14011402 /*
 14021403  * Target-dependent command-line options.
 14031404  */
 14041405 void
 14051406 mflags(char *str)
 14061407 {
 14071408 }
 14081409 /*
 14091410  * Do something target-dependent for xasm arguments.
 14101411  * Supposed to find target-specific constraints and rewrite them.
 14111412  */
 14121413 int
 14131414 myxasm(struct interpass *ip, NODE *p)
 14141415 {
 14151416         char *c;
 14161417         int i;
 14171418 
 14181419         /* Discard o<> constraints since they will not be generated */
 14191420         for (c = p->n_name; *c; c++) {
 14201421                 if (*c == 'o' || *c == '<' || *c == '>') {
 14211422                         for (i = 0; c[i]; i++)
 14221423                                 c[i] = c[i+1];
 14231424                         c--;
 14241425                 }
 14251426         }
 14261427         return 0;
 14271428 }
 14281429 
 14291430 int
 14301431 xasmconstregs(char *s)
 14311432 {
 14321433         int i;
 14331434 
 14341435         for (i = 0; i < 16; i++)
 14351436                 if (strcmp(&rnames[i][1], s) == 0)
 14361437                         return i;
 14371438         return -1;
 14381439 }
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-10-31 17:32 +0100