Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.32
 
1.33
 
MAIN:ragge:20121201085340
 
local.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 44  * All rights reserved.
 55  *
 66  * Redistribution and use in source and binary forms, with or without
 77  * modification, are permitted provided that the following conditions
 88  * are met:
 99  * 1. Redistributions of source code must retain the above copyright
 1010  *    notice, this list of conditions and the following disclaimer.
 1111  * 2. Redistributions in binary form must reproduce the above copyright
 1212  *    notice, this list of conditions and the following disclaimer in the
 1313  *    documentation and/or other materials provided with the distribution.
 1414  *
 1515  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1616  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1717  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 1818  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 1919  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2020  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2121  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2222  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2323  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2424  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2525  */
 2626 
 2727 /*
 2828  * MIPS port by Jan Enoksson (janeno-1@student.ltu.se) and
 2929  * Simon Olsson (simols-1@student.ltu.se) 2005.
 3030  */
 3131 
 3232 #include <assert.h>
 3333 #include "pass1.h"
 3434 
 3535 #define IALLOC(sz) (isinlining ? permalloc(sz) : tmpalloc(sz))
 3636 
 3737 /* this is called to do local transformations on
 3838  * an expression tree preparitory to its being
 3939  * written out in intermediate code.
 4040  */
 4141 NODE *
 4242 clocal(NODE *p)
 4343 {
 4444         struct symtab *q;
 4545         NODE *r, *l;
 4646         int o;
 4747         int m;
 4848         TWORD ty;
 4949         int tmpnr, isptrvoid = 0;
 5050 
 5151 #ifdef PCC_DEBUG
 5252         if (xdebug) {
 5353                 printf("clocal in: %p\n", p);
 5454                 fwalk(p, eprint, 0);
 5555         }
 5656 #endif
 5757 
 5858         switch (o = p->n_op) {
 5959 
 6060         case UCALL:
 6161         case CALL:
 6262         case STCALL:
 6363         case USTCALL:
 6464                 if (p->n_type == VOID)
 6565                         break;
 6666                 /*
 6767                  * if the function returns void*, ecode() invokes
 6868                  * delvoid() to convert it to uchar*.
 6969                  * We just let this happen on the ASSIGN to the temp,
 7070                  * and cast the pointer back to void* on access
 7171                  * from the temp.
 7272                  */
 7373                 if (p->n_type == PTR+VOID)
 7474                         isptrvoid = 1;
 7575                 r = tempnode(0, p->n_type, p->n_df, p->n_ap);
 7676                 tmpnr = regno(r);
 7777                 r = block(ASSIGN, r, p, p->n_type, p->n_df, p->n_ap);
 7878 
 7979                 p = tempnode(tmpnr, r->n_type, r->n_df, r->n_ap);
 8080                 if (isptrvoid) {
 8181                         p = block(PCONV, p, NIL, PTR+VOID, p->n_df, 0);
 8282                 }
 8383                 p = buildtree(COMOP, r, p);
 8484                 break;
 8585 
 8686         case NAME:
 8787                 if ((q = p->n_sp) == NULL)
 8888                         return p; /* Nothing to care about */
 8989 
 9090                 switch (q->sclass) {
 9191 
 9292                 case PARAM:
 9393                 case AUTO:
 9494                         /* fake up a structure reference */
 9595                         r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
 9696                         r->n_lval = 0;
 9797                         r->n_rval = FP;
 9898                         p = stref(block(STREF, r, p, 0, 0, 0));
 9999                         break;
 100100 
 101101                 case STATIC:
 102102                         if (q->slevel == 0)
 103103                                 break;
 104104                         p->n_lval = 0;
 105105                         p->n_sp = q;
 106106                         break;
 107107 
 108108                 case REGISTER:
 109109                         p->n_op = REG;
 110110                         p->n_lval = 0;
 111111                         p->n_rval = q->soffset;
 112112                         break;
 113113 
 114114                 }
 115115                 break;
 116116 
 117117         case FUNARG:
 118118                 /* Args smaller than int are given as int */
 119119                 if (p->n_type != CHAR && p->n_type != UCHAR &&
 120120                     p->n_type != SHORT && p->n_type != USHORT)
 121121                         break;
 122122                 p->n_left = block(SCONV, p->n_left, NIL, INT, 0, 0);
 123123                 p->n_type = INT;
 124124                 p->n_ap = 0;
 125125                 p->n_rval = SZINT;
 126126                 break;
 127127 
 128128         case CBRANCH:
 129129                 l = p->n_left;
 130130 
 131131                 /*
 132132                  * Remove unnecessary conversion ops.
 133133                  */
 134134                 if (clogop(l->n_op) && l->n_left->n_op == SCONV) {
 135135                         if (coptype(l->n_op) != BITYPE)
 136136                                 break;
 137137                         if (l->n_right->n_op == ICON) {
 138138                                 r = l->n_left->n_left;
 139139                                 if (r->n_type >= FLOAT && r->n_type <= LDOUBLE)
 140140                                         break;
 141141                                 /* Type must be correct */
 142142                                 ty = r->n_type;
 143143                                 nfree(l->n_left);
 144144                                 l->n_left = r;
 145145                                 l->n_type = ty;
 146146                                 l->n_right->n_type = ty;
 147147                         }
 148148 #if 0
 149149                           else if (l->n_right->n_op == SCONV &&
 150150                             l->n_left->n_type == l->n_right->n_type) {
 151151                                 r = l->n_left->n_left;
 152152                                 nfree(l->n_left);
 153153                                 l->n_left = r;
 154154                                 r = l->n_right->n_left;
 155155                                 nfree(l->n_right);
 156156                                 l->n_right = r;
 157157                         }
 158158 #endif
 159159                 }
 160160                 break;
 161161 
 162162         case PCONV:
 163163                 /* Remove redundant PCONV's. Be careful */
 164164                 l = p->n_left;
 165165                 if (l->n_op == ICON) {
 166166                         l->n_lval = (unsigned)l->n_lval;
 167167                         goto delp;
 168168                 }
 169169                 if (l->n_type < INT || DEUNSIGN(l->n_type) == LONGLONG) {
 170170                         /* float etc? */
 171171                         p->n_left = block(SCONV, l, NIL, UNSIGNED, 0, 0);
 172172                         break;
 173173                 }
 174174                 /* if left is SCONV, cannot remove */
 175175                 if (l->n_op == SCONV)
 176176                         break;
 177177 
 178178                 /* avoid ADDROF TEMP */
 179179                 if (l->n_op == ADDROF && l->n_left->n_op == TEMP)
 180180                         break;
 181181 
 182182                 /* if conversion to another pointer type, just remove */
 183183                 if (p->n_type > BTMASK && l->n_type > BTMASK)
 184184                         goto delp;
 185185                 break;
 186186 
 187187         delp:   l->n_type = p->n_type;
 188188                 l->n_qual = p->n_qual;
 189189                 l->n_df = p->n_df;
 190190                 l->n_ap = p->n_ap;
 191191                 nfree(p);
 192192                 p = l;
 193193                 break;
 194194 
 195195         case SCONV:
 196196                 l = p->n_left;
 197197 
 198198                 if (p->n_type == l->n_type) {
 199199                         nfree(p);
 200200                         p = l;
 201201                         break;
 202202                 }
 203203 
 204204                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
 205205                     tsize(p->n_type, p->n_df, p->n_ap) ==
 206206                     tsize(l->n_type, l->n_df, l->n_ap)) {
 207207                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
 208208                             l->n_type != FLOAT && l->n_type != DOUBLE &&
 209209                             l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
 210210                                 if (l->n_op == NAME || l->n_op == UMUL ||
 211211                                     l->n_op == TEMP) {
 212212                                         l->n_type = p->n_type;
 213213                                         nfree(p);
 214214                                         p = l;
 215215                                         break;
 216216                                 }
 217217                         }
 218218                 }
 219219 
 220220                 if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
 221221                     coptype(l->n_op) == BITYPE) {
 222222                         l->n_type = p->n_type;
 223223                         nfree(p);
 224224                         p = l;
 225225                 }
 226226 
 227227                 if (DEUNSIGN(p->n_type) == SHORT &&
 228228                     DEUNSIGN(l->n_type) == SHORT) {
 229229                         nfree(p);
 230230                         p = l;
 231231                 }
 232232 
 233233                 /* convert float/double to int before to (u)char/(u)short */
 234234                 if ((DEUNSIGN(p->n_type) == CHAR ||
 235235                     DEUNSIGN(p->n_type) == SHORT) &&
 236236                     (l->n_type == FLOAT || l->n_type == DOUBLE ||
 237237                     l->n_type == LDOUBLE)) {
 238238                         p = block(SCONV, p, NIL, p->n_type, p->n_df, p->n_ap);
 239239                         p->n_left->n_type = INT;
 240240                         break;
 241241                 }
 242242 
 243243                 /* convert (u)char/(u)short to int before float/double */
 244244                 if  ((p->n_type == FLOAT || p->n_type == DOUBLE ||
 245245                     p->n_type == LDOUBLE) && (DEUNSIGN(l->n_type) == CHAR ||
 246246                     DEUNSIGN(l->n_type) == SHORT)) {
 247247                         p = block(SCONV, p, NIL, p->n_type, p->n_df, p->n_ap);
 248248                         p->n_left->n_type = INT;
 249249                         break;
 250250                 }
 251251 
 252252                 o = l->n_op;
 253253                 m = p->n_type;
 254254 
 255255                 if (o == ICON) {
 256256                         CONSZ val = l->n_lval;
 257257 
 258258                         if (!ISPTR(m)) /* Pointers don't need to be conv'd */
 259259                             switch (m) {
 260260                         case BOOL:
 261261                                 l->n_lval = l->n_lval != 0;
 262262                                 break;
 263263                         case CHAR:
 264264                                 l->n_lval = (char)val;
 265265                                 break;
 266266                         case UCHAR:
 267267                                 l->n_lval = val & 0377;
 268268                                 break;
 269269                         case SHORT:
 270270                                 l->n_lval = (short)val;
 271271                                 break;
 272272                         case USHORT:
 273273                                 l->n_lval = val & 0177777;
 274274                                 break;
 275275                         case ULONG:
 276276                         case UNSIGNED:
 277277                                 l->n_lval = val & 0xffffffff;
 278278                                 break;
 279279                         case LONG:
 280280                         case INT:
 281281                                 l->n_lval = (int)val;
 282282                                 break;
 283283                         case LONGLONG:
 284284                                 l->n_lval = (long long)val;
 285285                                 break;
 286286                         case ULONGLONG:
 287287                                 l->n_lval = val;
 288288                                 break;
 289289                         case VOID:
 290290                                 break;
 291291                         case LDOUBLE:
 292292                         case DOUBLE:
 293293                         case FLOAT:
 294294                                 l->n_op = FCON;
 295295                                 l->n_dcon = val;
 296296                                 break;
 297297                         default:
 298298                                 cerror("unknown type %d", m);
 299299                         }
 300300                         l->n_type = m;
 301301                         nfree(p);
 302302                         p = l;
 303303                 } else if (o == FCON) {
 304304                         l->n_lval = l->n_dcon;
 305305                         l->n_sp = NULL;
 306306                         l->n_op = ICON;
 307307                         l->n_type = m;
 308308                         l->n_ap = 0;
 309309                         nfree(p);
 310310                         p = clocal(l);
 311311                 }
 312312                 break;
 313313 
 314314         case MOD:
 315315         case DIV:
 316316                 if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
 317317                         break;
 318318                 if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
 319319                         break;
 320320                 /* make it an int division by inserting conversions */
 321321                 p->n_left = block(SCONV, p->n_left, NIL, INT, 0, 0);
 322322                 p->n_right = block(SCONV, p->n_right, NIL, INT, 0, 0);
 323323                 p = block(SCONV, p, NIL, p->n_type, 0, 0);
 324324                 p->n_left->n_type = INT;
 325325                 break;
 326326 
 327327         case FORCE:
 328328                 /* put return value in return reg */
 329329                 p->n_op = ASSIGN;
 330330                 p->n_right = p->n_left;
 331331                 p->n_left = block(REG, NIL, NIL, p->n_type, 0, 0);
 332332                 p->n_left->n_rval = RETREG(p->n_type);
 333333                 break;
 334334         }
 335335 
 336336 #ifdef PCC_DEBUG
 337337         if (xdebug) {
 338338                 printf("clocal out: %p\n", p);
 339339                 fwalk(p, eprint, 0);
 340340         }
 341341 #endif
 342342 
 343343         return(p);
 344344 }
 345345 
 346346 void
 347347 myp2tree(NODE *p)
 348348 {
 349349         struct symtab *sp;
 350350 
 351351         if (p->n_op != FCON)
 352352                 return;
 353353 
 354354         /* Write float constants to memory */
 355355  
 356356         sp = IALLOC(sizeof(struct symtab));
 357357         sp->sclass = STATIC;
 358358         sp->sap = 0;
 359359         sp->slevel = 1; /* fake numeric label */
 360360         sp->soffset = getlab();
 361361         sp->sflags = 0;
 362362         sp->stype = p->n_type;
 363363         sp->squal = (CON >> TSHIFT);
 364364 
 365365         defloc(sp);
 366366         ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p);
 367367 
 368368         p->n_op = NAME;
 369369         p->n_lval = 0;
 370370         p->n_sp = sp;
 371371 
 372372 }
 373373 
 374374 /*ARGSUSED*/
 375375 int
 376376 andable(NODE *p)
 377377 {
 378378         return(1);  /* all names can have & taken on them */
 379379 }
 380380 
 381381 /*
 382382  * is an automatic variable of type t OK for a register variable
 383383  */
 384384 int
 385385 cisreg(TWORD t)
 386386 {
 387387         if (t == INT || t == UNSIGNED || t == LONG || t == ULONG)
 388388                 return(1);
 389389         return 0; /* XXX - fix reg assignment in pftn.c */
 390390 }
 391391 
 392392 /*
 393393  * Allocate off bits on the stack.  p is a tree that when evaluated
 394394  * is the multiply count for off, t is a NAME node where to write
 395395  * the allocated address.
 396396  */
 397397 void
 398398 spalloc(NODE *t, NODE *p, OFFSZ off)
 399399 {
 400400         NODE *sp;
 401401         int nbytes = off / SZCHAR;
 402402 
 403403         p = buildtree(MUL, p, bcon(nbytes));
 404404         p = buildtree(PLUS, p, bcon(7));
 405405         p = buildtree(AND, p, bcon(~7));
 406406 
 407407         /* subtract the size from sp */
 408408         sp = block(REG, NIL, NIL, p->n_type, 0, 0);
 409409         sp->n_lval = 0;
 410410         sp->n_rval = SP;
 411411         ecomp(buildtree(MINUSEQ, sp, p));
 412412 
 413413         /* save the address of sp */
 414414         sp = block(REG, NIL, NIL, PTR+INT, t->n_df, t->n_ap);
 415415         sp->n_rval = SP;
 416416         t->n_type = sp->n_type;
 417417         ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */
 418418 }
 419419 
 420420 /*
 421421  * print out a constant node
 422422  * mat be associated with a label
 423423  */
 424424 int
 425425 ninval(CONSZ off, int fsz, NODE *p)
 426426 {
 427427         union { float f; double d; int i[2]; } u;
 428428         struct symtab *q;
 429429         TWORD t;
 430430 #ifndef USE_GAS
 431431         int i, j;
 432432 #endif
 433433 
 434434         t = p->n_type;
 435435         if (t > BTMASK)
 436436                 p->n_type = t = INT; /* pointer */
 437437 
 438438         if (p->n_op == ICON && p->n_sp != NULL && DEUNSIGN(t) != INT)
 439439                 uerror("element not constant");
 440440 
 441441         switch (t) {
 442442         case LONGLONG:
 443443         case ULONGLONG:
 444444 #ifdef USE_GAS
 445445                 printf("\t.dword %lld\n", (long long)p->n_lval);
 446446 #else
 447447                 i = p->n_lval >> 32;
 448448                 j = p->n_lval & 0xffffffff;
 449449                 p->n_type = INT;
 450450                 if (bigendian) {
 451451                         p->n_lval = j;
 452452                         ninval(off, 32, p);
 453453                         p->n_lval = i;
 454454                         ninval(off+32, 32, p);
 455455                 } else {
 456456                         p->n_lval = i;
 457457                         ninval(off, 32, p);
 458458                         p->n_lval = j;
 459459                         ninval(off+32, 32, p);
 460460                 }
 461461 #endif
 462462                 break;
 463463         case INT:
 464464         case UNSIGNED:
 465465                 printf("\t.word " CONFMT, (CONSZ)p->n_lval);
 466466                 if ((q = p->n_sp) != NULL) {
 467467                         if ((q->sclass == STATIC && q->slevel > 0)) {
 468468                                 printf("+" LABFMT, q->soffset);
 469469                         } else
 470470                                 printf("+%s",
 471471                                     q->soname ? q->soname : exname(q->sname));
 472472                 }
 473473                 printf("\n");
 474474                 break;
 475475         case SHORT:
 476476         case USHORT:
 477477                 astypnames[SHORT] = astypnames[USHORT] = "\t.half";
 478478                 return 0;
 479479         case LDOUBLE:
 480480         case DOUBLE:
 481481                 u.d = (double)p->n_dcon;
 482482                 if (bigendian) {
 483483                         printf("\t.word\t%d\n", u.i[0]);
 484484                         printf("\t.word\t%d\n", u.i[1]);
 485485                 } else {
 486486                         printf("\t.word\t%d\n", u.i[1]);
 487487                         printf("\t.word\t%d\n", u.i[0]);
 488488                 }
 489489                 break;
 490490         case FLOAT:
 491491                 u.f = (float)p->n_dcon;
 492492                 printf("\t.word\t0x%x\n", u.i[0]);
 493493                 break;
 494494         default:
 495495                 return 0;
 496496         }
 497497         return 1;
 498498 }
 499499 
 500500 /* make a name look like an external name in the local machine */
 501501 char *
 502502 exname(char *p)
 503503 {
 504504         if (p == NULL)
 505505                 return "";
 506506         return p;
 507507 }
 508508 
 509509 /*
 510510  * map types which are not defined on the local machine
 511511  */
 512512 TWORD
 513513 ctype(TWORD type)
 514514 {
 515515         switch (BTYPE(type)) {
 516516         case LONG:
 517517                 MODTYPE(type,INT);
 518518                 break;
 519519 
 520520         case ULONG:
 521521                 MODTYPE(type,UNSIGNED);
 522522 
 523523         }
 524524         return (type);
 525525 }
 526526 
 527527 void
 528528 calldec(NODE *p, NODE *q)
 529529 {
 530530 }
 531531 
 532532 void
 533533 extdec(struct symtab *q)
 534534 {
 535535 }
 536536 
 537537 /* make a common declaration for id, if reasonable */
 538538 void
 539539 defzero(struct symtab *sp)
 540540 {
 541541         int off;
 542542 
 543543         off = tsize(sp->stype, sp->sdf, sp->sap);
 544544         off = (off+(SZCHAR-1))/SZCHAR;
 545545         printf("        .%scomm ", sp->sclass == STATIC ? "l" : "");
 546546         if (sp->slevel == 0)
 547547                 printf("%s,0%o\n", sp->soname ? sp->soname : exname(sp->sname), off);
 548548         else
 549549                 printf(LABFMT ",0%o\n", sp->soffset, off);
 550550 }
 551551 
 552552 
 553553 #ifdef notdef
 554554 /* make a common declaration for id, if reasonable */
 555555 void
 556556 commdec(struct symtab *q)
 557557 {
 558558         int off;
 559559 
 560560         off = tsize(q->stype, q->sdf, q->ssue);
 561561         off = (off+(SZCHAR-1))/SZCHAR;
 562562 
 563563         printf("        .comm %s,%d\n", exname(q->soname), off);
 564564 }
 565565 
 566566 /* make a local common declaration for id, if reasonable */
 567567 void
 568568 lcommdec(struct symtab *q)
 569569 {
 570570         int off;
 571571 
 572572         off = tsize(q->stype, q->sdf, q->ssue);
 573573         off = (off+(SZCHAR-1))/SZCHAR;
 574574         if (q->slevel == 0)
 575575                 printf("\t.lcomm %s,%d\n", exname(q->soname), off);
 576576         else
 577577                 printf("\t.lcomm " LABFMT ",%d\n", q->soffset, off);
 578578 }
 579579 
 580580 /*
 581581  * print a (non-prog) label.
 582582  */
 583583 void
 584584 deflab1(int label)
 585585 {
 586586         printf(LABFMT ":\n", label);
 587587 }
 588588 
 589589 /* ro-text, rw-data, ro-data, ro-strings */
 590590 static char *loctbl[] = { "text", "data", "rdata", "rdata" };
 591591 
 592592 void
 593593 setloc1(int locc)
 594594 {
 595595         if (locc == lastloc && locc != STRNG)
 596596                 return;
 597597         if (locc == RDATA && lastloc == STRNG)
 598598                 return;
 599599 
 600600         if (locc != lastloc) {
 601601                 lastloc = locc;
 602602                 printf("\t.%s\n", loctbl[locc]);
 603603         }
 604604 
 605605         if (locc == STRNG)
 606606                 printf("\t.align 2\n");
 607607 }
 608608 #endif
 609609 
 610610 /*
 611611  * va_start(ap, last) implementation.
 612612  *
 613613  * f is the NAME node for this builtin function.
 614614  * a is the argument list containing:
 615615  *         CM
 616616  *      ap   last
 617617  *
 618618  * It turns out that this is easy on MIPS.  Just write the
 619619  * argument registers to the stack in va_arg_start() and
 620620  * use the traditional method of walking the stackframe.
 621621  */
 622622 NODE *
<>623 -mips_builtin_stdarg_start(NODE *f, NODE *a, TWORD t)
  623+mips_builtin_stdarg_start(const struct bitable *bt, NODE *a)
624624 {
 625625         NODE *p, *q;
 626626         int sz = 1;
 627627 
 628628         /* check num args and type */
 629629         if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
 630630             !ISPTR(a->n_left->n_type))
 631631                 goto bad;
 632632 
 633633         /* must first deal with argument size; use int size */
 634634         p = a->n_right;
 635635         if (p->n_type < INT) {
 636636                 /* round up to word */
 637637                 sz = SZINT / tsize(p->n_type, p->n_df, p->n_ap);
 638638         }
 639639 
 640640         p = buildtree(ADDROF, p, NIL);  /* address of last arg */
 641641         p = optim(buildtree(PLUS, p, bcon(sz)));
 642642         q = block(NAME, NIL, NIL, PTR+VOID, 0, 0);
 643643         q = buildtree(CAST, q, p);
 644644         p = q->n_right;
 645645         nfree(q->n_left);
 646646         nfree(q);
 647647         p = buildtree(ASSIGN, a->n_left, p);
<>648 -        tfree(f);
649648         nfree(a);
 650649 
 651650         return p;
 652651 
 653652 bad:
 654653         uerror("bad argument to __builtin_stdarg_start");
 655654         return bcon(0);
 656655 }
 657656 
 658657 NODE *
<>659 -mips_builtin_va_arg(NODE *f, NODE *a, TWORD t)
  658+mips_builtin_va_arg(const struct bitable *bt, NODE *a)
660659 {
 661660         NODE *p, *q, *r;
 662661         int sz, tmpnr;
 663662 
 664663         /* check num args and type */
 665664         if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
 666665             !ISPTR(a->n_left->n_type) || a->n_right->n_op != TYPE)
 667666                 goto bad;
 668667 
 669668         r = a->n_right;
 670669 
 671670         /* get type size */
 672671         sz = tsize(r->n_type, r->n_df, r->n_ap) / SZCHAR;
 673672         if (sz < SZINT/SZCHAR) {
 674673                 werror("%s%s promoted to int when passed through ...",
 675674                         r->n_type & 1 ? "unsigned " : "",
 676675                         DEUNSIGN(r->n_type) == SHORT ? "short" : "char");
 677676                 sz = SZINT/SZCHAR;
 678677         }
 679678 
 680679         /* alignment */
 681680         p = tcopy(a->n_left);
 682681         if (sz > SZINT/SZCHAR && r->n_type != UNIONTY && r->n_type != STRTY) {
 683682                 p = buildtree(PLUS, p, bcon(7));
 684683                 p = block(AND, p, bcon(-8), p->n_type, p->n_df, p->n_ap);
 685684         }
 686685 
 687686         /* create a copy to a temp node */
 688687         q = tempnode(0, p->n_type, p->n_df, p->n_ap);
 689688         tmpnr = regno(q);
 690689         p = buildtree(ASSIGN, q, p);
 691690 
 692691         q = tempnode(tmpnr, p->n_type, p->n_df,p->n_ap);
 693692         q = buildtree(PLUS, q, bcon(sz));
 694693         q = buildtree(ASSIGN, a->n_left, q);
 695694 
 696695         q = buildtree(COMOP, p, q);
 697696 
 698697         nfree(a->n_right);
 699698         nfree(a);
<>700 -        nfree(f);
701699 
 702700         p = tempnode(tmpnr, INCREF(r->n_type), r->n_df, r->n_ap);
 703701         p = buildtree(UMUL, p, NIL);
 704702         p = buildtree(COMOP, q, p);
 705703 
 706704         return p;
 707705 
 708706 bad:
 709707         uerror("bad argument to __builtin_va_arg");
 710708         return bcon(0);
 711709 }
 712710 
 713711 NODE *
<>714 -mips_builtin_va_end(NODE *f, NODE *a, TWORD t)
  712+mips_builtin_va_end(const struct bitable *bt, NODE *a)
715713 {
<>716 -        tfree(f);
717714         tfree(a);
 718715         return bcon(0);
 719716 }
 720717 
 721718 NODE *
<>722 -mips_builtin_va_copy(NODE *f, NODE *a, TWORD t)
  719+mips_builtin_va_copy(const struct bitable *bt, NODE *a)
723720 {
<> 721+        NODE *f;
  722+
724723         if (a == NULL || a->n_op != CM || a->n_left->n_op == CM)
 725724                 goto bad;
<>726 -        tfree(f);
<_727725         f = buildtree(ASSIGN, a->n_left, a->n_right);
 728726         nfree(a);
 729727         return f;
 730728 
 731729 bad:
 732730         uerror("bad argument to __buildtin_va_copy");
 733731         return bcon(0);
 734732 }
 735733 
 736734 static int constructor;
 737735 static int destructor;
 738736 
 739737 /*
 740738  * Give target the opportunity of handling pragmas.
 741739  */
 742740 int
 743741 mypragma(char *str)
 744742 {
 745743 
 746744         if (strcmp(str, "tls") == 0) {
 747745                 uerror("thread-local storage not supported for this target");
 748746                 return 1;
 749747         }
 750748         if (strcmp(str, "constructor") == 0 || strcmp(str, "init") == 0) {
 751749                 constructor = 1;
 752750                 return 1;
 753751         }
 754752         if (strcmp(str, "destructor") == 0 || strcmp(str, "fini") == 0) {
 755753                 destructor = 1;
 756754                 return 1;
 757755         }
 758756 
 759757         return 0;
 760758 }
 761759 
 762760 /*
 763761  * Called when a identifier has been declared, to give target last word.
 764762  */
 765763 void
 766764 fixdef(struct symtab *sp)
 767765 {
 768766         if ((constructor || destructor) && (sp->sclass != PARAM)) {
 769767                 printf("\t.section .%ctors,\"aw\",@progbits\n",
 770768                     constructor ? 'c' : 'd');
 771769                 printf("\t.p2align 2\n");
 772770                 printf("\t.long %s\n", exname(sp->sname));
 773771                 printf("\t.previous\n");
 774772                 constructor = destructor = 0;
 775773         }
 776774 }
 777775 
 778776 void
 779777 pass1_lastchance(struct interpass *ip)
 780778 {
 781779 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-21 03:36 +0100