Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.18
 
1.19
 
MAIN:ragge:20110713123524
 
local2.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 44  *
 55  * Redistribution and use in source and binary forms, with or without
 66  * modification, are permitted provided that the following conditions
 77  * are met:
 88  *
 99  * Redistributions of source code and documentation must retain the above
 1010  * copyright notice, this list of conditions and the following disclaimer.
 1111  * Redistributions in binary form must reproduce the above copyright
 1212  * notice, this list of conditionsand the following disclaimer in the
 1313  * documentation and/or other materials provided with the distribution.
 1414  * All advertising materials mentioning features or use of this software
 1515  * must display the following acknowledgement:
 1616  *      This product includes software developed or owned by Caldera
 1717  *      International, Inc.
 1818  * Neither the name of Caldera International, Inc. nor the names of other
 1919  * contributors may be used to endorse or promote products derived from
 2020  * this software without specific prior written permission.
 2121  *
 2222  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 2323  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 2424  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 2525  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 2626  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 2727  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 2828  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 2929  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 3030  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 3131  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 3232  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 3333  * POSSIBILITY OF SUCH DAMAGE.
 3434  */
 3535 
 3636 # include "pass2.h"
 3737 # include "ctype.h"
 3838 /* a lot of the machine dependent parts of the second pass */
 3939 
 4040 static void prtype(NODE *n);
 4141 static void acon(NODE *p);
 4242 
 4343 /*
 4444  * Print out the prolog assembler.
 4545  * addto and regoff are already calculated.
 4646  */
 4747 void
 4848 prologue(struct interpass_prolog *ipp)
 4949 {
 5050         printf("        .word 0x%llx\n", (unsigned long long)ipp->ipp_regs[0]);
 5151         if (p2maxautooff)
 5252                 printf("        subl2 $%d,%%sp\n", p2maxautooff);
 5353 }
 5454 
 5555 /*
 5656  * Called after all instructions in a function are emitted.
 5757  * Generates code for epilog here.
 5858  */
 5959 void
 6060 eoftn(struct interpass_prolog *ipp)
 6161 {
 6262         if (ipp->ipp_ip.ip_lbl == 0)
 6363                 return; /* no code needs to be generated */
 6464         printf("        ret\n");
 6565 }
 6666 
 6767 struct hoptab { int opmask; char * opstring; } ioptab[] = {
 6868 
 6969         { PLUS"add", },
 7070         { MINUS,        "sub", },
 7171         { MUL,  "mul", },
 7272         { DIV,  "div", },
 7373         { OR,   "bis", },
 7474         { ER,   "xor", },
 7575         { AND,  "bic", },
 7676         { -1, ""     },
 7777 };
 7878 
 7979 void
 8080 hopcode( f, o ){
 8181         /* output the appropriate string from the above table */
 8282 
 8383         register struct hoptab *q;
 8484 
 8585         for( q = ioptabq->opmask>=0; ++q ){
 8686                 if( q->opmask == o ){
 8787                         printf( "%s", q->opstring );
 8888 /* tbl
 8989                         if( f == 'F' ) printf( "e" );
 9090                         else if( f == 'D' ) printf( "d" );
 9191    tbl */
 9292 /* tbl */
 9393                         switch( f ) {
 9494                                 case 'L':
 9595                                 case 'W':
 9696                                 case 'B':
 9797                                 case 'D':
 9898                                 case 'F':
 9999                                         printf("%c", tolower(f));
 100100                                         break;
 101101 
 102102                                 }
 103103 /* tbl */
 104104                         return;
 105105                         }
 106106                 }
 107107         cerror( "no hoptab for %s", opst[o] );
 108108         }
 109109 
 110110 char *
 111111 rnames[] = {  /* keyed to register number tokens */
 112112 
 113113         "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
 114114         "%r6", "%r7", "%r8", "%r9", "%r10", "%r11",
 115115         "%ap", "%fp", "%sp", "%pc",
 116116         /* The concatenated regs has the name of the lowest */
 117117         "%r0", "%r1", "%r2", "%r3", "%r4", "%r5",
 118118         "%r6", "%r7", "%r8", "%r9", "%r10"
 119119         };
 120120 
 121121 int
 122122 tlen(NODE *p)
 123123 {
 124124         switch(p->n_type) {
 125125         case CHAR:
 126126         case UCHAR:
 127127                 return(1);
 128128 
 129129         case SHORT:
 130130         case USHORT:
 131131                 return(2);
 132132 
 133133         case DOUBLE:
 134134         case LONGLONG:
 135135         case ULONGLONG:
 136136                 return(8);
 137137 
 138138         default:
 139139                 return(4);
 140140         }
 141141 }
 142142 
 143143 void
 144144 prtype(NODE *n)
 145145 {
 146146         static char pt[] = { 0, 0, 'b', 'b', 'w', 'w', 'l', 'l', 0, 0,
 147147             'q', 'q', 'f', 'd' };
 148148         TWORD t = n->n_type;
 149149 
 150150         if (ISPTR(t))
 151151                 t = UNSIGNED;
 152152 
 153153         if (t > DOUBLE || pt[t] == 0)
 154154                 comperr("prtype: bad type");
 155155         putchar(pt[t]);
 156156 }
 157157 
 158158 /*
 159159  * Emit conversions as given by the following table. Dest is always reg,
 160160  *   if it should be something else let peephole optimizer deal with it.
 161161  *   This code ensures type correctness in 32-bit registers.
 162162  *   XXX is that necessary?
 163163  *
 164164  * From                         To
 165165  *       char   uchar  short  ushort int    uint   ll    ull   float double
 166166  * char  movb   movb   cvtbw  cvtbw  cvtbl  cvtbl  A     A     cvtbf cvtbd
 167167  * uchar movb   movb   movzbw movzbw movzbl movzbl B     B     G     G
 168168  * short movb   movb   movw   movw   cvtwl  cvtwl  C(A)  C(A)  cvtwf cvtwd
 169169  * ushrt movb   movb   movw   movw   movzwl movzwl D(B)  D(B)  H     H
 170170  * int   movb   movb   movw   movw   movl   movl   E     E     cvtlf cvtld
 171171  * uint  movb   movb   movw   movw   movl   movl   F     F     I     I
 172172  * ll    movb   movb   movw   movw   movl   movl   movq  movq  J     K
 173173  * ull   movb   movb   movw   movw   movl   movl   movq  movq  L     M
 174174  * float cvtfb  cvtfb  cvtfw  cvtfw  cvtfl  cvtfl  N     O     movf  cvtfd
 175175  * doubl cvtdb  cvtdb  cvtdw  cvtdw  cvtdl  cvtdl  P     Q     cvtdf movd
 176176  *
 177177  *  A: cvtbl + sign extend
 178178  *  B: movzbl + zero extend
 179179  *  G: movzbw + cvtwX
 180180  *  H: movzwl + cvtwX
 181181  *  I: cvtld + addX
 182182  *  J: call __floatdisf
 183183  *  K: call __floatdidf
 184184  *  L: xxx + call __floatdisf
 185185  *  M: xxx + call __floatdidf
 186186  *  N: call __fixsfdi
 187187  *  O: call __fixunssfdi
 188188  *  P: call __fixdfdi
 189189  *  Q: call __fixunsdfdi
 190190  */
 191191 
 192192 #define MVD     1 /* mov + dest type */
 193193 #define CVT     2 /* cvt + src type + dst type */
 194194 #define MVZ     3 /* movz + src type + dst type */
 195195 #define CSE     4 /* cvt + src type + l + sign extend upper */
 196196 #define MZE     5 /* movz + src type + l + zero extend upper */
 197197 #define MLE     6 /* movl + sign extend upper */
 198198 #define MLZ     7 /* movl + zero extend upper */
 199199 #define MZC     8 /* movz + cvt */
 200200 
 201201 static char scary[][10] = {
 202202         { MVD, MVD, CVT, CVT, CVT, CVT, CSE, CSE, CVT, CVT },
 203203         { MVD, MVD, MVZ, MVZ, MVZ, MVZ, MZE, MZE, MZC, MZC },
 204204         { MVD, MVD, MVD, MVD, CVT, CVT, CSE, CSE, CVT, CVT },
 205205         { MVD, MVD, MVD, MVD, MVZ, MVZ, MZE, MZE, MZC, MZC },
 206206         { MVD, MVD, MVD, MVD, MVD, MVD, MLE, MLE, CVT, CVT },
 207207         { MVD, MVD, MVD, MVD, MVZ, MVZ, MLZ, MLZ, 'I', 'I' },
 208208         { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'J', 'K' },
 209209         { MVD, MVD, MVD, MVD, MVD, MVD, MVD, MVD, 'L', 'M' },
 210210         { CVT, CVT, CVT, CVT, CVT, CVT, 'N', 'O', MVD, CVT },
 211211         { CVT, CVT, CVT, CVT, CVT, CVT, 'P', 'Q', CVT, MVD },
 212212 };
 213213 
 214214 static void
 215215 sconv(NODE *p)
 216216 {
 217217         NODE *l = p->n_left;
 218218         TWORD ts, td;
 219219         int o;
 220220 
 221221         /*
 222222          * Source node may be in register or memory.
 223223          * Result is always in register.
 224224          */
 225225         ts = l->n_type;
 226226         if (ISPTR(ts))
 227227                 ts = UNSIGNED;
 228228         td = p->n_type;
 229229         ts = ts < LONG ? ts-2 : ts-4;
 230230         td = td < LONG ? td-2 : td-4;
 231231 
 232232         o = scary[ts][td];
 233233         switch (o) {
 234234         case MLE:
 235235         case MLZ:
 236236         case MVD:
 237237                 expand(p, INAREG|INBREG, "\tmovZL AL,A1\n");
 238238                 break;
 239239 
 240240         case CSE:
 241241                 expand(p, INAREG|INBREG, "\tcvtZLl AL,A1\n");
 242242                 break;
 243243 
 244244         case CVT:
 245245                 expand(p, INAREG|INBREG, "\tcvtZLZR AL,A1\n");
 246246                 break;
 247247 
 248248         case MZE:
 249249                 expand(p, INAREG|INBREG, "\tmovzZLl AL,A1\n");
 250250                 break;
 251251 
 252252         case MVZ:
 253253                 expand(p, INAREG|INBREG, "\tmovzZLZR AL,A1\n");
 254254                 break;
 255255 
 256256         case MZC:
 257257                 expand(p, INAREG|INBREG, "\tmovzZLl AL,A1\n");
 258258                 expand(p, INAREG|INBREG, "\tcvtlZR A1,A1\n");
 259259                 break;
 260260 
 261261         default:
 262262                 comperr("unsupported conversion %d", o);
 263263         }
 264264         switch (o) {
 265265         case MLE:
 266266         case CSE:
 267267                 expand(p, INBREG, "\tashl $-31,A1,U1\n");
 268268                 break;
 269269         case MLZ:
 270270         case MZE:
 271271                 expand(p, INAREG|INBREG, "\tclrl U1\n");
 272272                 break;
 273273         }
 274274 }
 275275 
 276276 /*
 277277  * Assign a constant from p to q.  Both are expected to be leaves by now.
 278278  * This is for 64-bit integers.
 279279  */
 280280 static void
 281281 casg64(NODE *p)
 282282 {
 283283         NODE *l, *r;
 284284         char *str;
 285285         int mneg = 1;
 286286         
 287287         l = p->n_left;
 288288         r = p->n_right;
 289289 
 290290 #ifdef PCC_DEBUG
 291291         if (r->n_op != ICON)
 292292                 comperr("casg");
 293293 #endif
 294294         if (r->n_name[0] != '\0') {
 295295                 /* named constant, nothing to do */
 296296                 str = "movq\tAR,AL";
 297297                 mneg = 0;
 298298         } else if (r->n_lval == 0) {
 299299                 str = "clrq\tAL";
 300300                 mneg = 0;
 301301         } else if (r->n_lval < 0) {
 302302                 if (r->n_lval >= -63) {
 303303                         r->n_lval = -r->n_lval;
 304304                         str = "mnegl\tAR,AL";
 305305                 } else if (r->n_lval >= -128) {
 306306                         str = "cvtbl\tAR,AL";
 307307                 } else if (r->n_lval >= -32768) {
 308308                         str = "cvtwl\tAR,AL";
 309309                 } else if (r->n_lval >= -4294967296LL) {
 310310                         str = "movl\tAR,AL";
 311311                 } else {
 312312                         str = "movq\tAR,AL";
 313313                         mneg = 0;
 314314                 }
 315315         } else {
 316316                 mneg = 0;
 317317                 if (r->n_lval <= 63 || r->n_lval > 4294967295) {
 318318                         str = "movq\tAR,AL";
 319319                 } else if (r->n_lval <= 255) {
 320320                         str = "movzbl\tAR,AL\n\tclrl\tUL";
 321321                 } else if (r->n_lval <= 65535) {
 322322                         str = "movzwl\tAR,AL\n\tclrl\tUL";
 323323                 } else /* if (r->n_lval <= 4294967295) */ {
 324324                         str = "movl\tAR,AL\n\tclrl\tUL";
 325325                 }
 326326         }
 327327         expand(p, FOREFF, str);
 328328         if (mneg)
 329329                 expand(p, FOREFF, "\tmnegl $-1,UL\n");
 330330 }
 331331 
 332332 /*
 333333  * Assign a constant from p to q.  Both are expected to be leaves by now.
 334334  * This is only for 32-bit integer types.
 335335  */
 336336 static void
 337337 casg(NODE *p)
 338338 {
 339339         NODE *l, *r;
 340340         char *str;
 341341         
 342342         l = p->n_left;
 343343         r = p->n_right;
 344344 
 345345 #ifdef PCC_DEBUG
 346346         if (r->n_op != ICON)
 347347                 comperr("casg");
 348348 #endif
 349349         if (r->n_name[0] != '\0') {
 350350                 /* named constant, nothing to do */
 351351                 str = "movZL\tAR,AL";
 352352         } else if (r->n_lval == 0) {
 353353                 str = "clrZL\tAL";
 354354         } else if (r->n_lval < 0) {
 355355                 if (r->n_lval >= -63) {
 356356                         r->n_lval = -r->n_lval;
 357357                         str = "mnegZL\tAR,AL";
 358358                 } else if (r->n_lval >= -128) {
 359359                         str = "cvtbZL\tAR,AL";
 360360                 } else if (r->n_lval >= -32768) {
 361361                         str = "cvtwZL\tAR,AL";
 362362                 } else
 363363                         str = "movZL\tAR,AL";
 364364         } else {
 365365                 if (r->n_lval <= 63 || r->n_lval > 65535) {
 366366                         str = "movZL\tAR,AL";
 367367                 } else if (r->n_lval <= 255) {
 368368                         str = "movzbZL\tAR,AL";
 369369                 } else /* if (r->n_lval <= 65535) */ {
 370370                         str = "movzwZL\tAR,AL";
 371371                 }
 372372         }
 373373         expand(p, FOREFF, str);
 374374 }
 375375 
 376376 /*
 377377  * Emit code to compare two longlong numbers.
 378378  */
 379379 static void
 380380 twollcomp(NODE *p)
 381381 {
 382382         int u;
 383383         int s = getlab2();
 384384         int e = p->n_label;
 385385         int cb1, cb2;
 386386 
 387387         u = p->n_op;
 388388         switch (p->n_op) {
 389389         case NE:
 390390                 cb1 = 0;
 391391                 cb2 = NE;
 392392                 break;
 393393         case EQ:
 394394                 cb1 = NE;
 395395                 cb2 = 0;
 396396                 break;
 397397         case LE:
 398398         case LT:
 399399                 u += (ULE-LE);
 400400                 /* FALLTHROUGH */
 401401         case ULE:
 402402         case ULT:
 403403                 cb1 = GT;
 404404                 cb2 = LT;
 405405                 break;
 406406         case GE:
 407407         case GT:
 408408                 u += (ULE-LE);
 409409                 /* FALLTHROUGH */
 410410         case UGE:
 411411         case UGT:
 412412                 cb1 = LT;
 413413                 cb2 = GT;
 414414                 break;
 415415         
 416416         default:
 417417                 cb1 = cb2 = 0; /* XXX gcc */
 418418         }
 419419         if (p->n_op >= ULE)
 420420                 cb1 += 4, cb2 += 4;
 421421         expand(p, 0, "  cmpl UR,UL\n");
 422422         if (cb1) cbgen(cb1, s);
 423423         if (cb2) cbgen(cb2, e);
 424424         expand(p, 0, "  cmpl AL,AR\n");
 425425         cbgen(u, e);
 426426         deflab(s);
 427427 }
 428428 
 429429 
 430430 void
 431431 zzzcode(NODE *p, int c)
 432432 {
 433433         NODE *l, *r;
 434434         int m;
 435435         char *ch;
 436436 
 437437         switch (c) {
 438438         case 'N'/* logical ops, turned into 0-1 */
 439439                 /* use register given by register 1 */
 440440                 cbgen( 0, m=getlab2());
 441441                 deflab( p->n_label );
 442442                 printf( "       clrl    %s\n", rnames[getlr( p, '1' )->n_rval] );
 443443                 deflab( m );
 444444                 return;
 445445 
 446446         case 'A': /* Assign a constant directly to a memory position */
 447447                 printf("\t");
 448448                 if (p->n_type < LONG || ISPTR(p->n_type))
 449449                         casg(p);
 450450                 else
 451451                         casg64(p);
 452452                 printf("\n");
 453453                 break;
 454454 
 455455         case 'B': /* long long compare */
 456456                 twollcomp(p);
 457457                 break;
 458458 
 459459         case 'C':       /* num words pushed on arg stack */
 460460                 printf("$%d", p->n_qual);
 461461                 break;
 462462 
 463463         case 'D':       /* INCR and DECR */
 464464                 zzzcode(p->n_left, 'A');
 465465                 printf("\n      ");
 466466 
 467467 #if 0
 468468         case 'E':       /* INCR and DECR, FOREFF */
 469469                 if (p->n_right->n_lval == 1)
 470470                         {
 471471                         printf("%s", (p->n_op == INCR ? "inc" : "dec") );
 472472                         prtype(p->n_left);
 473473                         printf("        ");
 474474                         adrput(stdout, p->n_left);
 475475                         return;
 476476                         }
 477477                 printf("%s", (p->n_op == INCR ? "add" : "sub") );
 478478                 prtype(p->n_left);
 479479                 printf("2       ");
 480480                 adrput(stdout, p->n_right);
 481481                 printf(",");
 482482                 adrput(p->n_left);
 483483                 return;
 484484 #endif
 485485 
 486486         case 'F':       /* register type of right operand */
 487487                 {
 488488                 register NODE *n;
 489489                 extern int xdebug;
 490490                 register int ty;
 491491 
 492492                 n = getlr( p, 'R' );
 493493                 ty = n->n_type;
 494494 
 495495                 if (xdebug) printf("->%d<-", ty);
 496496 
 497497                 if ( ty==DOUBLE) printf("d");
 498498                 else if ( ty==FLOAT ) printf("f");
 499499                 else printf("l");
 500500                 return;
 501501                 }
 502502 
 503503         case 'G': /* emit conversion instructions */
 504504                 sconv(p);
 505505                 break;
 506506 
 507507         case 'J': /* jump or ret? */
 508508                 {
 509509                         struct interpass *ip =
 510510                             DLIST_PREV((struct interpass *)p2env.epp, qelem);
 511511                         if (ip->type != IP_DEFLAB ||
 512512                             ip->ip_lbl != getlr(p, 'L')->n_lval)
 513513                                 expand(p, FOREFF, "jbr  LL");
 514514                         else
 515515                                 printf("ret");
 516516                 }
 517517                 break;
 518518 
 519519         case 'L':       /* type of left operand */
 520520         case 'R':       /* type of right operand */
 521521                 {
 522522                 register NODE *n;
 523523                 extern int xdebug;
 524524 
 525525                 n = getlr ( p, c);
 526526                 if (xdebug) printf("->%d<-", n->n_type);
 527527 
 528528                 prtype(n);
 529529                 return;
 530530                 }
 531531 
 532532         case 'O': /* print out emulated ops */
 533533                 expand(p, FOREFF, "\tmovq       AR,-(%sp)\n");
 534534                 expand(p, FOREFF, "\tmovq       AL,-(%sp)\n");
 535535                 if (p->n_op == DIV && p->n_type == ULONGLONG) ch = "udiv";
 536536                 else if (p->n_op == DIV) ch = "div";
 537537                 else if (p->n_op == MOD && p->n_type == ULONGLONG) ch = "umod";
 538538                 else if (p->n_op == MOD) ch = "mod";
 539539                 else ch = 0, comperr("ZO");
 540540                 printf("\tcalls $4,__%sdi3\n", ch);
 541541                 break;
 542542 
 543543 
 544544         case 'Z':       /* complement mask for bit instr */
 545545                 printf("$%Ld", ~p->n_right->n_lval);
 546546                 return;
 547547 
 548548         case 'U':       /* 32 - n, for unsigned right shifts */
 549549                 printf("$" CONFMT, 32 - p->n_right->n_lval );
 550550                 return;
 551551 
 552552         case 'T':       /* rounded structure length for arguments */
 553553                 {
 554554                 int size;
 555555 
 556556                 size = p->n_stsize;
 557557                 SETOFF( size, 4);
 558558                 printf("$%d", size);
 559559                 return;
 560560                 }
 561561 
 562562         case 'S'/* structure assignment */
 563563                 {
 564564                         register int size;
 565565 
 566566                         size = p->n_stsize;
 567567                         l = r = NULL; /* XXX gcc */
 568568                         if( p->n_op == STASG ){
 569569                                 l = p->n_left;
 570570                                 r = p->n_right;
 571571 
 572572                                 }
 573573                         else if( p->n_op == STARG ){
 574574                                 /* store an arg into a temporary */
 575575                                 printf("\tsubl2 $%d,%%sp\n",
 576576                                     size < 4 ? 4 : size);
 577577                                 l = mklnode(OREG, 0, SP, INT);
 578578                                 r = p->n_left;
 579579                                 }
 580580                         else cerror( "STASG bad" );
 581581 
 582582                         if( r->n_op == ICON ) r->n_op = NAME;
 583583                         else if( r->n_op == REG ) r->n_op = OREG;
 584584                         else if( r->n_op != OREG ) cerror( "STASG-r" );
 585585 
 586586                         if( size <= 0 || size > 65535 )
 587587                                 cerror("structure size <0=0 or >65535");
 588588 
 589589                         switch(size) {
 590590                                 case 1:
 591591                                         printf("        movb    ");
 592592                                         break;
 593593                                 case 2:
 594594                                         printf("        movw    ");
 595595                                         break;
 596596                                 case 4:
 597597                                         printf("        movl    ");
 598598                                         break;
 599599                                 case 8:
 600600                                         printf("        movq    ");
 601601                                         break;
 602602                                 default:
 603603                                         printf("        movc3   $%d,", size);
 604604                                         break;
 605605                         }
 606606                         adrput(stdout, r);
 607607                         printf(",");
 608608                         adrput(stdout, l);
 609609                         printf("\n");
 610610 
 611611                         if( r->n_op == NAME ) r->n_op = ICON;
 612612                         else if( r->n_op == OREG ) r->n_op = REG;
 613613                         if (p->n_op == STARG)
 614614                                 tfree(l);
 615615 
 616616                         }
 617617                 break;
 618618 
 619619         default:
 620620                 comperr("illegal zzzcode '%c'", c);
 621621         }
 622622 }
 623623 
 624624 void
 625625 rmove( int rt,int  rs, TWORD t ){
 626626         printf( "       %s      %s,%s\n",
 627627                 (t==FLOAT ? "movf" : (t==DOUBLE ? "movd" : "movl")),
 628628                 rnames[rs], rnames[rt] );
 629629         }
 630630 
 631631 #if 0
 632632 setregs(){ /* set up temporary registers */
 633633         fregs = 6;      /* tbl- 6 free regs on VAX (0-5) */
 634634         ;
 635635         }
 636636 
 637637 szty(t){ /* size, in registers, needed to hold thing of type t */
 638638         return( (t==DOUBLE||t==FLOAT) ? 2 : 1 );
 639639         }
 640640 #endif
 641641 
 642642 int
 643643 rewfld( p ) NODE *p; {
 644644         return(1);
 645645         }
 646646 
 647647 #if 0
 648648 callreg(p) NODE *p; {
 649649         return( R0 );
 650650         }
 651651 
 652652 base( p ) register NODE *p; {
 653653         register int o = p->op;
 654654 
 655655         if( (o==ICON && p->name[0] != '\0')) return( 100 ); /* ie no base reg */
 656656         if( o==REG ) return( p->rval );
 657657     if( (o==PLUS || o==MINUS) && p->left->op == REG && p->right->op==ICON)
 658658                 return( p->left->rval );
 659659     if( o==OREG && !R2TEST(p->rval) && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 660660                 return( p->rval + 0200*1 );
 661661         if( o==INCR && p->left->op==REG ) return( p->left->rval + 0200*2 );
 662662         if( o==ASG MINUS && p->left->op==REG) return( p->left->rval + 0200*4 );
 663663         if( o==UNARY MUL && p->left->op==INCR && p->left->left->op==REG
 664664           && (p->type==INT || p->type==UNSIGNED || ISPTR(p->type)) )
 665665                 return( p->left->left->rval + 0200*(1+2) );
 666666         return( -1 );
 667667         }
 668668 
 669669 offset( p, tyl ) register NODE *p; int tyl; {
 670670 
 671671         if( tyl==1 && p->op==REG && (p->type==INT || p->type==UNSIGNED) ) return( p->rval );
 672672         if( (p->op==LS && p->left->op==REG && (p->left->type==INT || p->left->type==UNSIGNED) &&
 673673               (p->right->op==ICON && p->right->name[0]=='\0')
 674674               && (1<<p->right->lval)==tyl))
 675675                 return( p->left->rval );
 676676         return( -1 );
 677677         }
 678678 #endif
 679679 
 680680 #if 0
 681681 void
 682682 makeor2( p, q, b, o) register NODE *p, *q; register int b, o; {
 683683         register NODE *t;
 684684         NODE *f;
 685685 
 686686         p->n_op = OREG;
 687687         f = p->n_left;  /* have to free this subtree later */
 688688 
 689689         /* init base */
 690690         switch (q->n_op) {
 691691                 case ICON:
 692692                 case REG:
 693693                 case OREG:
 694694                         t = q;
 695695                         break;
 696696 
 697697                 case MINUS:
 698698                         q->n_right->n_lval = -q->n_right->n_lval;
 699699                 case PLUS:
 700700                         t = q->n_right;
 701701                         break;
 702702 
 703703                 case UMUL:
 704704                         t = q->n_left->n_left;
 705705                         break;
 706706 
 707707                 default:
 708708                         cerror("illegal makeor2");
 709709                         t = NULL; /* XXX gcc */
 710710         }
 711711 
 712712         p->n_lval = t->n_lval;
 713713         p->n_name = t->n_name;
 714714 
 715715         /* init offset */
 716716         p->n_rval = R2PACK( (b & 0177), o, (b>>7) );
 717717 
 718718         tfree(f);
 719719         return;
 720720         }
 721721 
 722722 int
 723723 canaddr( p ) NODE *p; {
 724724         register int o = p->n_op;
 725725 
 726726         if( o==NAME || o==REG || o==ICON || o==OREG || (o==UMUL && shumul(p->n_left, STARNM|SOREG)) ) return(1);
 727727         return(0);
 728728         }
 729729 
 730730 shltype( o, p ) register NODE *p; {
 731731         return( o== REG || o == NAME || o == ICON || o == OREG || ( o==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 732732         }
 733733 #endif
 734734 
 735735 int
 736736 fldexpand(NODE *p, int cookie, char **cp)
 737737 {
 738738         return 0;
 739739 }
 740740 
 741741 int
 742742 flshape( p ) register NODE *p; {
 743743         return( p->n_op == REG || p->n_op == NAME || p->n_op == ICON ||
 744744                 (p->n_op == OREG && (!R2TEST(p->n_rval) || tlen(p) == 1)) );
 745745         }
 746746 
 747747 int
 748748 shtemp( p ) register NODE *p; {
 749749         if( p->n_op == STARG ) p = p->n_left;
 750750         return( p->n_op==NAME || p->n_op ==ICON || p->n_op == OREG || (p->n_op==UMUL && shumul(p->n_left, STARNM|SOREG)) );
 751751         }
 752752 
 753753 /*
 754754  * Shape matches for UMUL.  Cooperates with offstar().
 755755  */
 756756 int
 757757 shumul(NODE *p, int shape)
 758758 {
 759759 
 760760         if (x2debug)
 761761                 printf("shumul(%p)\n", p);
 762762 
 763763         /* Turns currently anything into OREG on vax */
 764764         if (shape & SOREG)
 765765                 return SROREG;
 766766         return SRNOPE;
 767767 }
 768768 
 769769 
 770770 #ifdef notdef
 771771 int
 772772 shumul( p, shape ) register NODE *p; int shape; {
 773773         register int o;
 774774         extern int xdebug;
 775775 
 776776         if (xdebug) {
 777777                  printf("\nshumul:op=%d,lop=%d,rop=%d", p->n_op, p->n_left->n_op, p->n_right->n_op);
 778778                 printf(" prname=%s,plty=%d, prlval=%lld\n", p->n_right->n_name, p->n_left->n_type, p->n_right->n_lval);
 779779                 }
 780780 
 781781 
 782782         o = p->n_op;
 783783         if( o == NAME || (o == OREG && !R2TEST(p->n_rval)) || o == ICON )
 784784                 if (shape & STARNM)
 785785                         return SRDIR;
 786786 
 787787         if( ( o == INCR || o == ASG MINUS ) &&
 788788             ( p->n_left->n_op == REG && p->n_right->n_op == ICON ) &&
 789789             p->n_right->n_name[0] == '\0' )
 790790                 {
 791791                 switch (p->n_left->n_type)
 792792                         {
 793793                         case CHAR|PTR:
 794794                         case UCHAR|PTR:
 795795                                 o = 1;
 796796                                 break;
 797797 
 798798                         case SHORT|PTR:
 799799                         case USHORT|PTR:
 800800                                 o = 2;
 801801                                 break;
 802802 
 803803                         case INT|PTR:
 804804                         case UNSIGNED|PTR:
 805805                         case LONG|PTR:
 806806                         case ULONG|PTR:
 807807                         case FLOAT|PTR:
 808808                                 o = 4;
 809809                                 break;
 810810 
 811811                         case DOUBLE|PTR:
 812812                                 o = 8;
 813813                                 break;
 814814 
 815815                         default:
 816816                                 if ( ISPTR(p->n_left->n_type) ) {
 817817                                         o = 4;
 818818                                         break;
 819819                                         }
 820820                                 else return(0);
 821821                         }
 822822                 return( p->n_right->n_lval == o ? STARREG : 0);
 823823                 }
 824824 
 825825         return( SRNOPE );
 826826         }
 827827 #endif
 828828 
 829829 void
 830830 adrcon( val ) CONSZ val; {
 831831         printf( "$" );
 832832         printf( CONFMT, val );
 833833         }
 834834 
 835835 void
 836836 conput(FILE *fp, NODE *p)
 837837 {
 838838         switch( p->n_op ){
 839839 
 840840         case ICON:
 841841                 acon( p );
 842842                 return;
 843843 
 844844         case REG:
 845845                 printf( "%s", rnames[p->n_rval] );
 846846                 return;
 847847 
 848848         default:
 849849                 cerror( "illegal conput" );
 850850                 }
 851851         }
 852852 
 853853 void
 854854 insput( p ) register NODE *p; {
 855855         cerror( "insput" );
 856856         }
 857857 
 858858 /*
 859859  * Write out the upper address, like the upper register of a 2-register
 860860  * reference, or the next memory location.
 861861  */
 862862 void
 863863 upput(NODE *p, int size)
 864864 {
 865865 
 866866         size /= SZCHAR;
 867867         switch (p->n_op) {
 868868         case REG:
 869869                 fprintf(stdout, "%s", rnames[regno(p)-16+1]);
 870870                 break;
 871871 
 872872         case NAME:
 873873         case OREG:
 874874                 p->n_lval += size;
 875875                 adrput(stdout, p);
 876876                 p->n_lval -= size;
 877877                 break;
 878878         case ICON:
 879879                 fprintf(stdout, "$" CONFMT, p->n_lval >> 32);
 880880                 break;
 881881         default:
 882882                 comperr("upput bad op %d size %d", p->n_op, size);
 883883         }
 884884 }
 885885 
 886886 void
 887887 adrput(FILE *fp, NODE *p)
 888888 {
 889889         register int r;
 890890         /* output an address, with offsets, from p */
 891891 
 892892         if( p->n_op == FLD ){
 893893                 p = p->n_left;
 894894                 }
 895895         switch( p->n_op ){
 896896 
 897897         case NAME:
 898898                 acon( p );
 899899                 return;
 900900 
 901901         case ICON:
 902902                 /* addressable value of the constant */
 903903                 if (p->n_name[0] == '\0') /* uses xxxab */
 904904                         printf("$");
 905905                 acon(p);
 906906                 return;
 907907 
 908908         case REG:
 909909                 printf( "%s", rnames[p->n_rval] );
 910910                 return;
 911911 
 912912         case OREG:
 913913                 r = p->n_rval;
 914914                 if( R2TEST(r) ){ /* double indexing */
 915915                         register int flags;
 916916 
 917917                         flags = R2UPK3(r);
 918918                         if( flags & 1 ) printf("*");
 919919                         if( flags & 4 ) printf("-");
 920920                         if( p->n_lval != 0 || p->n_name[0] != '\0' ) acon(p);
 921921                         if( R2UPK1(r) != 100) printf( "(%s)", rnames[R2UPK1(r)] );
 922922                         if( flags & 2 ) printf("+");
 923923                         printf( "[%s]", rnames[R2UPK2(r)] );
 924924                         return;
 925925                         }
 926926                 if( r == AP ){  /* in the argument region */
<>927 -                        if( p->n_lval <= 0 || p->n_name[0] != '\0' ) werror( "bad arg temp" );
  927+                        if( p->n_lval <= 0 || p->n_name[0] != '\0' )
  928+                                werror( "bad arg temp" );
<_928929                         printf( CONFMT, p->n_lval );
 929930                         printf( "(%%ap)" );
 930931                         return;
 931932                         }
 932933                 if( p->n_lval != 0 || p->n_name[0] != '\0') acon( p );
 933934                 printf( "(%s)", rnames[p->n_rval] );
 934935                 return;
 935936 
 936937         case UMUL:
 937938                 /* STARNM or STARREG found */
 938939                 if( tshape(p, STARNM) ) {
 939940                         printf( "*" );
 940941                         adrput(0p->n_left);
 941942                         }
 942943                 else {  /* STARREG - really auto inc or dec */
 943944                         register NODE *q;
 944945 
 945946 /* tbl
 946947                         p = p->n_left;
 947948                         p->n_left->n_op = OREG;
 948949                         if( p->n_op == INCR ) {
 949950                                 adrput( p->n_left );
 950951                                 printf( "+" );
 951952                                 }
 952953                         else {
 953954                                 printf( "-" );
 954955                                 adrput( p->n_left );
 955956                                 }
 956957    tbl */
 957958 #ifdef notyet
 958959                         printf("%c(%s)%c", (p->n_left->n_op==INCR ? '\0' : '-'),
 959960                                 rnames[p->n_left->n_left->n_rval],
 960961                                 (p->n_left->n_op==INCR ? '+' : '\0') );
 961962 #else
 962963                         printf("%c(%s)%c", '-',
 963964                                 rnames[p->n_left->n_left->n_rval],
 964965                                 '\0' );
 965966 #endif
 966967                         p->n_op = OREG;
 967968                         p->n_rval = p->n_left->n_left->n_rval;
 968969                         q = p->n_left;
 969970 #ifdef notyet
 970971 
 971972                         p->n_lval = (p->n_left->n_op == INCR ? -p->n_left->n_right->n_lval : 0);
 972973 #else
 973974                         p->n_lval = 0;
 974975 #endif
 975976                         p->n_name[0] = '\0';
 976977                         tfree(q);
 977978                 }
 978979                 return;
 979980 
 980981         default:
 981982                 cerror( "illegal address" );
 982983                 return;
 983984         }
 984985 
 985986 }
 986987 
 987988 /*
 988989  * print out a constant
 989990  */
 990991 void
 991992 acon(NODE *p)
 992993 {
 993994 
 994995         if (p->n_name[0] == '\0') {
 995996                 printf(CONFMT, p->n_lval);
 996997         } else if( p->n_lval == 0 ) {
 997998                 printf("%s", p->n_name);
 998999         } else {
 9991000                 printf("%s+", p->n_name);
 10001001                 printf(CONFMT, p->n_lval);
 10011002         }
 10021003 }
 10031004 
 10041005 #if 0
 10051006 genscall( p, cookie ) register NODE *p; {
 10061007         /* structure valued call */
 10071008         return( gencall( p, cookie ) );
 10081009         }
 10091010 
 10101011 /* tbl */
 10111012 int gc_numbytes;
 10121013 /* tbl */
 10131014 
 10141015 gencall( p, cookie ) register NODE *p; {
 10151016         /* generate the call given by p */
 10161017         register NODE *p1, *ptemp;
 10171018         register temp, temp1;
 10181019         register m;
 10191020 
 10201021         if( p->right ) temp = argsize( p->right );
 10211022         else temp = 0;
 10221023 
 10231024         if( p->op == STCALL || p->op == UNARY STCALL ){
 10241025                 /* set aside room for structure return */
 10251026 
 10261027                 if( p->stsize > temp ) temp1 = p->stsize;
 10271028                 else temp1 = temp;
 10281029                 }
 10291030 
 10301031         if( temp > maxargs ) maxargs = temp;
 10311032         SETOFF(temp1,4);
 10321033 
 10331034         if( p->right ){ /* make temp node, put offset in, and generate args */
 10341035                 ptemp = talloc();
 10351036                 ptemp->op = OREG;
 10361037                 ptemp->lval = -1;
 10371038                 ptemp->rval = SP;
 10381039                 ptemp->name[0] = '\0';
 10391040                 ptemp->rall = NOPREF;
 10401041                 ptemp->su = 0;
 10411042                 genargs( p->right, ptemp );
 10421043                 nfree(ptemp);
 10431044                 }
 10441045 
 10451046         p1 = p->left;
 10461047         if( p1->op != ICON ){
 10471048                 if( p1->op != REG ){
 10481049                         if( p1->op != OREG || R2TEST(p1->rval) ){
 10491050                                 if( p1->op != NAME ){
 10501051                                         order( p1, INAREG );
 10511052                                         }
 10521053                                 }
 10531054                         }
 10541055                 }
 10551056 
 10561057 /*
 10571058         if( p1->op == REG && p->rval == R5 ){
 10581059                 cerror( "call register overwrite" );
 10591060                 }
 10601061  */
 10611062 /* tbl
 10621063         setup gc_numbytes so reference to ZC works */
 10631064 
 10641065         gc_numbytes = temp;
 10651066 /* tbl */
 10661067 
 10671068         p->op = UNARY CALL;
 10681069         m = match( p, INTAREG|INTBREG );
 10691070 /* tbl
 10701071         switch( temp ) {
 10711072         case 0:
 10721073                 break;
 10731074         case 2:
 10741075                 printf( "       tst     (sp)+\n" );
 10751076                 break;
 10761077         case 4:
 10771078                 printf( "       cmp     (sp)+,(sp)+\n" );
 10781079                 break;
 10791080         default:
 10801081                 printf( "       add     $%d,sp\n", temp);
 10811082                 }
 10821083    tbl */
 10831084         return(m != MDONE);
 10841085         }
 10851086 #endif
 10861087 
 10871088 static char *
 10881089 ccbranches[] = {
 10891090         "jeql",
 10901091         "jneq",
 10911092         "jleq",
 10921093         "jlss",
 10931094         "jgeq",
 10941095         "jgtr",
 10951096         "jlequ",
 10961097         "jlssu",
 10971098         "jgequ",
 10981099         "jgtru",
 10991100 };
 11001101 
 11011102 /*
 11021103  * printf conditional and unconditional branches
 11031104  */
 11041105 void
 11051106 cbgen(int o, int lab)
 11061107 {
 11071108 
 11081109         if (o == 0) {
 11091110                 printf("        jbr     " LABFMT "\n", lab);
 11101111         } else {
 11111112                 if (o > UGT)
 11121113                         comperr("bad conditional branch: %s", opst[o]);
 11131114                 printf("\t%s\t" LABFMT "\n", ccbranches[o-EQ], lab);
 11141115         }
 11151116 }
 11161117 
 11171118 static void
 11181119 optim2(NODE *p, void *arg)
 11191120 {
 11201121         /* do local tree transformations and optimizations */
 11211122 
 11221123         register NODE *r;
 11231124 
 11241125         switch( p->n_op ) {
 11251126 
 11261127         case AND:
 11271128                 /* commute L and R to eliminate compliments and constants */
 11281129                 if( (p->n_left->n_op==ICON&&p->n_left->n_name[0]==0) || p->n_left->n_op==COMPL ) {
 11291130                         r = p->n_left;
 11301131                         p->n_left = p->n_right;
 11311132                         p->n_right = r;
 11321133                         }
 11331134 #if 0
 11341135         case ASG AND:
 11351136                 /* change meaning of AND to ~R&L - bic on pdp11 */
 11361137                 r = p->n_right;
 11371138                 if( r->op==ICON && r->name[0]==0 ) { /* compliment constant */
 11381139                         r->lval = ~r->lval;
 11391140                         }
 11401141                 else if( r->op==COMPL ) { /* ~~A => A */
 11411142                         r->op = FREE;
 11421143                         p->right = r->left;
 11431144                         }
 11441145                 else { /* insert complement node */
 11451146                         p->right = talloc();
 11461147                         p->right->op = COMPL;
 11471148                         p->right->rall = NOPREF;
 11481149                         p->right->type = r->type;
 11491150                         p->right->left = r;
 11501151                         p->right->right = NULL;
 11511152                         }
 11521153                 break;
 11531154 #endif
 11541155                 }
 11551156         }
 11561157 
 11571158 void
 11581159 myreader(struct interpass *ipole)
 11591160 {
 11601161         struct interpass *ip;
 11611162 
 11621163         DLIST_FOREACH(ip, ipole, qelem) {
 11631164                 if (ip->type != IP_NODE)
 11641165                         continue;
 11651166                 walkf(ip->ip_node, optim2, 0);
 11661167         }
 11671168 }
 11681169 
 11691170 void
 11701171 mycanon(NODE *p)
 11711172 {
 11721173 }
 11731174 
 11741175 void
 11751176 myoptim(struct interpass *ip)
 11761177 {
 11771178 }
 11781179 
 11791180 /*
 11801181  * Return argument size in regs.
 11811182  */
 11821183 static int
 11831184 argsiz(NODE *p)
 11841185 {
 11851186         TWORD t = p->n_type;
 11861187 
 11871188         if (t == STRTY || t == UNIONTY)
 11881189                 return p->n_stsize/(SZINT/SZCHAR);
 11891190         return szty(t);
 11901191 }
 11911192 
 11921193 /*
 11931194  * Last chance to do something before calling a function.
 11941195  */
 11951196 void
 11961197 lastcall(NODE *p)
 11971198 {
 11981199         NODE *op = p;
 11991200         int size = 0;
 12001201 
 12011202         /* Calculate argument sizes */
 12021203         p->n_qual = 0;
 12031204         if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
 12041205                 return;
 12051206         for (p = p->n_right; p->n_op == CM; p = p->n_left)
 12061207                 size += argsiz(p->n_right);
 12071208         if (p->n_op != ASSIGN)
 12081209                 size += argsiz(p);
 12091210         op->n_qual = size; /* XXX */
 12101211 }
 12111212 
 12121213 /*
 12131214  * Return a class suitable for a specific type.
 12141215  */
 12151216 int
 12161217 gclass(TWORD t)
 12171218 {
 12181219         return (szty(t) == 2 ? CLASSB : CLASSA);
 12191220 }
 12201221 
 12211222 /*
 12221223  * For class c, find worst-case displacement of the number of
 12231224  * registers in the array r[] indexed by class.
 12241225  */
 12251226 int
 12261227 COLORMAP(int c, int *r)
 12271228 {
 12281229         int num;
 12291230 
 12301231         switch (c) {
 12311232         case CLASSA:
 12321233                 /* there are 12 classa, so min 6 classb are needed to block */
 12331234                 num = r[CLASSB] * 2;
 12341235                 num += r[CLASSA];
 12351236                 return num < 12;
 12361237         case CLASSB:
 12371238                 /* 6 classa may block all classb */
 12381239                 num = r[CLASSB] + r[CLASSA];
 12391240                 return num < 6;
 12401241         }
 12411242         comperr("COLORMAP");
 12421243         return 0; /* XXX gcc */
 12431244 }
 12441245 
 12451246 /*
 12461247  * Special shapes.
 12471248  */
 12481249 int
 12491250 special(NODE *p, int shape)
 12501251 {
 12511252         return SRNOPE;
 12521253 }
 12531254 
 12541255 /*
 12551256  * Target-dependent command-line options.
 12561257  */
 12571258 void
 12581259 mflags(char *str)
 12591260 {
 12601261 }
 12611262 /*
 12621263  * Do something target-dependent for xasm arguments.
 12631264  * Supposed to find target-specific constraints and rewrite them.
 12641265  */
 12651266 int
 12661267 myxasm(struct interpass *ip, NODE *p)
 12671268 {
 12681269         return 0;
 12691270 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-22 09:31 +0100