Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.75
 
1.76
 
MAIN:ragge:20121028135928
 
local.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright (c) 2008 Michael Shalayeff
 44  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 55  * All rights reserved.
 66  *
 77  * Redistribution and use in source and binary forms, with or without
 88  * modification, are permitted provided that the following conditions
 99  * are met:
 1010  * 1. Redistributions of source code must retain the above copyright
 1111  *    notice, this list of conditions and the following disclaimer.
 1212  * 2. Redistributions in binary form must reproduce the above copyright
 1313  *    notice, this list of conditions and the following disclaimer in the
 1414  *    documentation and/or other materials provided with the distribution.
 1515  *
 1616  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1717  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1818  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 1919  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 2020  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2121  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2222  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2323  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2424  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2525  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2626  */
 2727 
 2828 
 2929 #include "pass1.h"
 3030 
 3131 /*      this file contains code which is dependent on the target machine */
 3232 
 3333 /*
 3434  * Check if a constant is too large for a type.
 3535  */
 3636 #ifdef notyet
 3737 static int
 3838 toolarge(TWORD t, CONSZ con)
 3939 {
 4040         U_CONSZ ucon = con;
 4141 
 4242         switch (t) {
 4343         case ULONG:
 4444         case LONG:
 4545         case ULONGLONG:
 4646         case LONGLONG:
 4747                 break; /* cannot be too large */
 4848 #define SCHK(i) case i: if (con > MAX_##i || con < MIN_##i) return 1; break
 4949 #define UCHK(i) case i: if (ucon > MAX_##i) return 1; break
 5050         SCHK(INT);
 5151         SCHK(SHORT);
 5252         case BOOL:
 5353         SCHK(CHAR);
 5454         UCHK(UNSIGNED);
 5555         UCHK(USHORT);
 5656         UCHK(UCHAR);
 5757         default:
 5858                 cerror("toolarge");
 5959         }
 6060         return 0;
 6161 }
 6262 #endif
 6363 
 6464 #define IALLOC(sz)      (isinlining ? permalloc(sz) : tmpalloc(sz))
 6565 
 6666 /*
 6767  * Make a symtab entry for PIC use.
 6868  */
 6969 static struct symtab *
 7070 picsymtab(char *p, char *s, char *s2)
 7171 {
 7272         struct symtab *sp = IALLOC(sizeof(struct symtab));
 7373         size_t len = strlen(p) + strlen(s) + strlen(s2) + 1;
 7474 
 7575         sp->sname = sp->soname = IALLOC(len);
 7676         strlcpy(sp->soname, p, len);
 7777         strlcat(sp->soname, s, len);
 7878         strlcat(sp->soname, s2, len);
 7979         sp->sclass = EXTERN;
 8080         sp->sflags = sp->slevel = 0;
 8181         return sp;
 8282 }
 8383 
 8484 int gotnr; /* tempnum for GOT register */
 8585 int argstacksize;
 8686 
 8787 /*
 8888  * Create a reference for an extern variable or function.
 8989  */
 9090 static NODE *
 9191 picext(NODE *p)
 9292 {
 9393 #if defined(ELFABI)
 9494 
<> 95+        struct attr *ga;
9596         NODE *q;
 9697         struct symtab *sp;
 9798         char *c;
 9899 
 99100         if (p->n_sp->sflags & SBEENHERE)
 100101                 return p;
<> 102+        if ((ga = attr_find(p->n_sp->sap, GCC_ATYP_VISIBILITY)) &&
  103+            strcmp(ga->sarg(0), "hidden") == 0)
  104+                return p; /* no GOT reference */
<_101105 
 102106         c = p->n_sp->soname ? p->n_sp->soname : exname(p->n_sp->sname);
 103107         sp = picsymtab("", c, "@GOTPCREL");
 104108         sp->sflags |= SBEENHERE;
 105109         q = block(NAME, NIL, NIL, INCREF(p->n_type), p->n_df, p->n_ap);
 106110         q->n_sp = sp;
 107111         q = block(UMUL, q, 0, p->n_type, p->n_df, p->n_ap);
 108112         q->n_sp = sp;
 109113         nfree(p);
 110114         return q;
 111115 
 112116 #elif defined(MACHOABI)
 113117 
 114118         return p;
 115119 
 116120 #endif
 117121 }
 118122 
 119123 static NODE *
 120124 cmop(NODE *l, NODE *r)
 121125 {
 122126         return block(CM, l, r, INT, 0, 0);
 123127 }
 124128 
 125129 static NODE *
 126130 mkx(char *s, NODE *p)
 127131 {
 128132         p = block(XARG, p, NIL, INT, 0, 0);
 129133         p->n_name = s;
 130134         return p;
 131135 }
 132136 
 133137 static char *
 134138 mk3str(char *s1, char *s2, char *s3)
 135139 {
 136140         int len = strlen(s1) + strlen(s2) + strlen(s3) + 1;
 137141         char *sd;
 138142 
 139143         sd = inlalloc(len);
 140144         strlcpy(sd, s1, len);
 141145         strlcat(sd, s2, len);
 142146         strlcat(sd, s3, len);
 143147         return sd;
 144148 }
 145149 
 146150 /*
 147151  * Create a reference for a TLS variable.
 148152  * This is the "General dynamic" version.
 149153  */
 150154 static NODE *
 151155 tlspic(NODE *p)
 152156 {
 153157         NODE *q, *r, *s;
 154158         char *s1, *s2;
 155159 
 156160         /*
 157161          * .byte   0x66
 158162          * leaq x@TLSGD(%rip),%rdi
 159163          * .word   0x6666
 160164          * rex64
 161165          * call __tls_get_addr@PLT
 162166          */
 163167 
 164168         /* Need the .byte stuff around.  Why? */
 165169         /* Use inline assembler */
 166170         q = mkx("%rdx", bcon(0));
 167171         q = cmop(q, mkx("%rcx", bcon(0)));
 168172         q = cmop(q, mkx("%rsi", bcon(0)));
 169173         q = cmop(q, mkx("%rdi", bcon(0)));
 170174         q = cmop(q, mkx("%r8", bcon(0)));
 171175         q = cmop(q, mkx("%r9", bcon(0)));
 172176         q = cmop(q, mkx("%r10", bcon(0)));
 173177         q = cmop(q, mkx("%r11", bcon(0)));
 174178 
 175179         s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
 176180         r = mkx("=a", r);
 177181         r = block(XASM, r, q, INT, 0, 0);
 178182 
 179183         /* Create the magic string */
 180184         s1 = ".byte 0x66\n\tleaq ";
 181185         s2 = "@TLSGD(%%rip),%%rdi\n"
 182186             "\t.word 0x6666\n\trex64\n\tcall __tls_get_addr@PLT";
 183187         if (p->n_sp->soname == NULL)
 184188                 p->n_sp->soname = p->n_sp->sname;
 185189         r->n_name = mk3str(s1, p->n_sp->soname, s2);
 186190 
 187191         r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
 188192         r = buildtree(UMUL, r, NIL);
 189193         tfree(p);
 190194         return r;
 191195 }
 192196 
 193197 /*
 194198  * The "initial exec" tls model.
 195199  */
 196200 static NODE *
 197201 tlsinitialexec(NODE *p)
 198202 {
 199203         NODE *q, *r, *s;
 200204         char *s1, *s2;
 201205 
 202206         /*
 203207          * movq %fs:0,%rax
 204208          * addq x@GOTTPOFF(%rip),%rax
 205209          */
 206210 
 207211         q = bcon(0);
 208212         q->n_type = STRTY;
 209213 
 210214         s = ccopy(r = tempnode(0, INCREF(p->n_type), p->n_df, p->n_ap));
 211215         r = mkx("=r", r);
 212216         r = block(XASM, r, q, INT, 0, 0);
 213217 
 214218         s1 = "movq %%fs:0,%0\n\taddq ";
 215219         s2 = "@GOTTPOFF(%%rip),%0";
 216220         if (p->n_sp->soname == NULL)
 217221                 p->n_sp->soname = p->n_sp->sname;
 218222         r->n_name = mk3str(s1, p->n_sp->soname, s2);
 219223 
 220224         r = block(COMOP, r, s, INCREF(p->n_type), p->n_df, p->n_ap);
 221225         r = buildtree(UMUL, r, NIL);
 222226         tfree(p);
 223227         return r;
 224228 }
 225229 
 226230 static NODE *
 227231 tlsref(NODE *p)
 228232 {
 229233         struct symtab *sp = p->n_sp;
 230234         struct attr *ga;
 231235         char *c;
 232236 
 233237         if ((ga = attr_find(sp->sap, GCC_ATYP_TLSMODEL)) != NULL) {
 234238                 c = ga->sarg(0);
 235239                 if (strcmp(c, "initial-exec") == 0)
 236240                         return tlsinitialexec(p);
 237241                 else if (strcmp(c, "global-dynamic") == 0)
 238242                         ;
 239243                 else
 240244                         werror("unsupported tls model '%s'", c);
 241245         }
 242246         return tlspic(p);
 243247 }
 244248 
 245249 /* clocal() is called to do local transformations on
 246250  * an expression tree preparitory to its being
 247251  * written out in intermediate code.
 248252  *
 249253  * the major essential job is rewriting the
 250254  * automatic variables and arguments in terms of
 251255  * REG and OREG nodes
 252256  * conversion ops which are not necessary are also clobbered here
 253257  * in addition, any special features (such as rewriting
 254258  * exclusive or) are easily handled here as well
 255259  */
 256260 NODE *
 257261 clocal(NODE *p)
 258262 {
 259263 
 260264         register struct symtab *q;
 261265         register NODE *r, *l;
 262266         register int o;
 263267         register int m;
 264268         TWORD t;
 265269 
 266270 #ifdef PCC_DEBUG
 267271         if (xdebug) {
 268272                 printf("clocal: %p\n", p);
 269273                 fwalk(p, eprint, 0);
 270274         }
 271275 #endif
 272276         switch( o = p->n_op ){
 273277 
 274278         case NAME:
 275279                 if ((q = p->n_sp) == NULL)
 276280                         return p; /* Nothing to care about */
 277281 
 278282                 switch (q->sclass) {
 279283 
 280284                 case PARAM:
 281285                 case AUTO:
 282286                         /* fake up a structure reference */
 283287                         r = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
 284288                         r->n_lval = 0;
 285289                         r->n_rval = FPREG;
 286290                         p = stref(block(STREF, r, p, 0, 0, 0));
 287291                         break;
 288292 
 289293                 case USTATIC:
 290294                         if (kflag == 0)
 291295                                 break;
 292296                         /* FALLTHROUGH */
 293297                 case STATIC:
 294298 #ifdef TLS
 295299                         if (q->sflags & STLS) {
 296300                                 p = tlsref(p);
 297301                                 break;
 298302                         }
 299303 #endif
 300304                         break;
 301305 
 302306                 case REGISTER:
 303307                         p->n_op = REG;
 304308                         p->n_lval = 0;
 305309                         p->n_rval = q->soffset;
 306310                         break;
 307311 
 308312                 case EXTERN:
 309313                 case EXTDEF:
 310314                         if (q->sflags & STLS) {
 311315                                 p = tlsref(p);
 312316                                 break;
 313317                         }
 314318                         if (kflag == 0 || statinit)
 315319                                 break;
 316320                         if (blevel > 0)
 317321                                 p = picext(p);
 318322                         break;
 319323                 }
 320324                 break;
 321325 
 322326         case UCALL:
 323327         case USTCALL:
 324328                 /* For now, always clear eax */
 325329                 l = block(REG, NIL, NIL, INT, 0, 0);
 326330                 regno(l) = RAX;
 327331                 p->n_right = clocal(buildtree(ASSIGN, l, bcon(0)));
 328332                 p->n_op -= (UCALL-CALL);
 329333                 break;
 330334 
 331335         case SCONV:
 332336                 /* Special-case shifts */
 333337                 if (p->n_type == LONG && (l = p->n_left)->n_op == LS &&
 334338                     l->n_type == INT && l->n_right->n_op == ICON) {
 335339                         p->n_left = l->n_left;
 336340                         p = buildtree(LS, p, l->n_right);
 337341                         nfree(l);
 338342                         break;
 339343                 }
 340344 
 341345                 l = p->n_left;
 342346 
 343347                 /* Float conversions may need extra casts */
 344348                 if (p->n_type == FLOAT || p->n_type == DOUBLE ||
 345349                     p->n_type == LDOUBLE) {
 346350                         if (l->n_type < INT || l->n_type == BOOL) {
 347351                                 p->n_left = block(SCONV, l, NIL,
 348352                                     ISUNSIGNED(l->n_type) ? UNSIGNED : INT,
 349353                                     l->n_df, l->n_ap);
 350354                                 break;
 351355                         }
 352356                 }
 353357 
 354358                 if (p->n_type == l->n_type) {
 355359                         nfree(p);
 356360                         return l;
 357361                 }
 358362 
 359363                 if ((p->n_type & TMASK) == 0 && (l->n_type & TMASK) == 0 &&
 360364                     tsize(p->n_type, p->n_df, p->n_ap) ==
 361365                     tsize(l->n_type, l->n_df, l->n_ap)) {
 362366                         if (p->n_type != FLOAT && p->n_type != DOUBLE &&
 363367                             l->n_type != FLOAT && l->n_type != DOUBLE &&
 364368                             l->n_type != LDOUBLE && p->n_type != LDOUBLE) {
 365369                                 if (l->n_op == NAME || l->n_op == UMUL ||
 366370                                     l->n_op == TEMP) {
 367371                                         l->n_type = p->n_type;
 368372                                         nfree(p);
 369373                                         return l;
 370374                                 }
 371375                         }
 372376                 }
 373377 
 374378                 if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == INT &&
 375379                     coptype(l->n_op) == BITYPE && l->n_op != COMOP &&
 376380                     l->n_op != QUEST) {
 377381                         l->n_type = p->n_type;
 378382                         nfree(p);
 379383                         return l;
 380384                 }
 381385 
 382386                 o = l->n_op;
 383387                 m = p->n_type;
 384388 
 385389                 if (o == ICON) {
 386390                         CONSZ val = l->n_lval;
 387391 
 388392                         if (!ISPTR(m)) /* Pointers don't need to be conv'd */
 389393                             switch (m) {
 390394                         case BOOL:
 391395                                 l->n_lval = nncon(l) ? (l->n_lval != 0) : 1;
 392396                                 l->n_sp = NULL;
 393397                                 break;
 394398                         case CHAR:
 395399                                 l->n_lval = (char)val;
 396400                                 break;
 397401                         case UCHAR:
 398402                                 l->n_lval = val & 0377;
 399403                                 break;
 400404                         case SHORT:
 401405                                 l->n_lval = (short)val;
 402406                                 break;
 403407                         case USHORT:
 404408                                 l->n_lval = val & 0177777;
 405409                                 break;
 406410                         case UNSIGNED:
 407411                                 l->n_lval = val & 0xffffffff;
 408412                                 break;
 409413                         case INT:
 410414                                 l->n_lval = (int)val;
 411415                                 break;
 412416                         case LONG:
 413417                         case LONGLONG:
 414418                                 l->n_lval = (long long)val;
 415419                                 break;
 416420                         case ULONG:
 417421                         case ULONGLONG:
 418422                                 l->n_lval = val;
 419423                                 break;
 420424                         case VOID:
 421425                                 break;
 422426                         case LDOUBLE:
 423427                         case DOUBLE:
 424428                         case FLOAT:
 425429                                 l->n_op = FCON;
 426430                                 l->n_dcon = val;
 427431                                 break;
 428432                         default:
 429433                                 cerror("unknown type %d", m);
 430434                         }
 431435                         l->n_type = m;
 432436                         l->n_ap = NULL;
 433437                         nfree(p);
 434438                         return l;
 435439                 } else if (l->n_op == FCON) {
 436440                         if (p->n_type == BOOL)
 437441                                 l->n_lval = l->n_dcon != 0.0;
 438442                         else
 439443                                 l->n_lval = l->n_dcon;
 440444                         l->n_sp = NULL;
 441445                         l->n_op = ICON;
 442446                         l->n_type = m;
 443447                         l->n_ap = NULL;
 444448                         nfree(p);
 445449                         return clocal(l);
 446450                 }
 447451                 if ((p->n_type == CHAR || p->n_type == UCHAR ||
 448452                     p->n_type == SHORT || p->n_type == USHORT) &&
 449453                     (l->n_type == FLOAT || l->n_type == DOUBLE ||
 450454                     l->n_type == LDOUBLE)) {
 451455                         p = block(SCONV, p, NIL, p->n_type, p->n_df, p->n_ap);
 452456                         p->n_left->n_type = INT;
 453457                         return p;
 454458                 }
 455459                 break;
 456460 
 457461         case MOD:
 458462         case DIV:
 459463                 if (o == DIV && p->n_type != CHAR && p->n_type != SHORT)
 460464                         break;
 461465                 if (o == MOD && p->n_type != CHAR && p->n_type != SHORT)
 462466                         break;
 463467                 /* make it an int division by inserting conversions */
 464468                 p->n_left = makety(p->n_left, INT, 0, 0, 0);
 465469                 p->n_right = makety(p->n_right, INT, 0, 0, 0);
 466470                 p = makety(p, p->n_type, 0, 0, 0);
 467471                 p->n_left->n_type = INT;
 468472                 break;
 469473 
 470474         case FORCE:
 471475                 /* put return value in return reg */
 472476                 p->n_op = ASSIGN;
 473477                 p->n_right = p->n_left;
 474478                 p->n_left = block(REG, NIL, NIL, p->n_type, 0, 0);
 475479                 t = p->n_type;
 476480                 if (ISITY(t))
 477481                         t = t - (FIMAG-FLOAT);
 478482                 p->n_left->n_rval = p->n_left->n_type == BOOL ?
 479483                     RETREG(CHAR) : RETREG(t);
 480484                 break;
 481485 
 482486         case LS:
 483487         case RS:
 484488                 /* shift count must be in a char */
 485489                 if (p->n_right->n_type == CHAR || p->n_right->n_type == UCHAR)
 486490                         break;
 487491                 p->n_right = makety(p->n_right, CHAR, 0, 0, 0);
 488492                 break;
 489493         }
 490494 #ifdef PCC_DEBUG
 491495         if (xdebug) {
 492496                 printf("clocal end: %p\n", p);
 493497                 fwalk(p, eprint, 0);
 494498         }
 495499 #endif
 496500         return(p);
 497501 }
 498502 
 499503 void
 500504 myp2tree(NODE *p)
 501505 {
 502506         struct symtab *sp, sps;
 503507         static int dblxor, fltxor;
 504508 
 505509         if (p->n_op == UMINUS && (p->n_type == FLOAT || p->n_type == DOUBLE)) {
 506510                 /* Store xor code for sign change */
 507511                 if (dblxor == 0) {
 508512                         dblxor = getlab();
 509513                         fltxor = getlab();
 510514                         sps.stype = LDOUBLE;
 511515                         sps.squal = CON >> TSHIFT;
 512516                         sps.sflags = sps.sclass = 0;
 513517                         sps.sname = sps.soname = "";
 514518                         sps.slevel = 1;
 515519                         sps.sap = NULL;
 516520                         sps.soffset = dblxor;
 517521                         locctr(DATA, &sps);
 518522                         defloc(&sps);
 519523                         printf("\t.long 0,0x80000000,0,0\n");
 520524                         printf(LABFMT ":\n", fltxor);
 521525                         printf("\t.long 0x80000000,0,0,0\n");
 522526                 }
 523527                 p->n_label = p->n_type == FLOAT ? fltxor : dblxor;
 524528                 return;
 525529         }
 526530         if (kflag && (cdope(p->n_op) & CALLFLG) && p->n_left->n_op == NAME) {
 527531                 /* Convert @GOTPCREL to @PLT */
 528532                 char *s;
 529533 
 530534                 sp = p->n_left->n_sp;
 531535                 if ((s = strstr(sp->sname, "@GOTPCREL")) != NULL) {
 532536                         memcpy(s, "@PLT", sizeof("@PLT"));
 533537                         p->n_left->n_op = ICON;
 534538                 }
 535539                 return;
 536540         }
 537541         if (p->n_op != FCON)
 538542                 return;
 539543 
 540544 #ifdef mach_amd64
 541545         {
 542546                 /* Do not lose negative zeros */
 543547                 long double *d = &p->n_dcon;
 544548                 long long *llp = (long long *)d;
 545549                 short *ssp = (short *)&llp[1];
 546550                 if (*llp == 0 && *ssp == 0)
 547551                         return;
 548552         }
 549553 #else
 550554 #error fixme
 551555 #endif
 552556 
 553557         /* XXX should let float constants follow */
 554558         sp = IALLOC(sizeof(struct symtab));
 555559         sp->sclass = STATIC;
 556560         sp->sap = NULL;
 557561         sp->slevel = 1; /* fake numeric label */
 558562         sp->soffset = getlab();
 559563         sp->sflags = 0;
 560564         sp->stype = p->n_type;
 561565         sp->squal = (CON >> TSHIFT);
 562566         sp->sname = sp->soname = NULL;
 563567 
 564568         locctr(DATA, sp);
 565569         defloc(sp);
 566570         ninval(0, tsize(sp->stype, sp->sdf, sp->sap), p);
 567571 
 568572         p->n_op = NAME;
 569573         p->n_lval = 0;
 570574         p->n_sp = sp;
 571575 }
 572576 
 573577 /*
 574578  * Convert ADDROF NAME to ICON?
 575579  */
 576580 int
 577581 andable(NODE *p)
 578582 {
 579583 #ifdef notdef
 580584         /* shared libraries cannot have direct referenced static syms */
 581585         if (p->n_sp->sclass == STATIC || p->n_sp->sclass == USTATIC)
 582586                 return 1;
 583587 #endif
 584588         return !kflag;
 585589 }
 586590 
 587591 /*
 588592  * Return 1 if a variable of type type is OK to put in register.
 589593  */
 590594 int
 591595 cisreg(TWORD t)
 592596 {
 593597         if (t == LDOUBLE)
 594598                 return 0;
 595599         return 1;
 596600 }
 597601 
 598602 /*
 599603  * Allocate off bits on the stack.  p is a tree that when evaluated
 600604  * is the multiply count for off, t is a storeable node where to write
 601605  * the allocated address.
 602606  */
 603607 void
 604608 spalloc(NODE *t, NODE *p, OFFSZ off)
 605609 {
 606610         NODE *sp;
 607611 
 608612         p = buildtree(MUL, p, bcon(off/SZCHAR));
 609613         p = buildtree(PLUS, p, bcon(30));
 610614         p = buildtree(AND, p, xbcon(-16, NULL, LONG));
 611615 
 612616         /* sub the size from sp */
 613617         sp = block(REG, NIL, NIL, p->n_type, 0, 0);
 614618         sp->n_lval = 0;
 615619         sp->n_rval = STKREG;
 616620         ecomp(buildtree(MINUSEQ, sp, p));
 617621 
 618622         /* save the address of sp */
 619623         sp = block(REG, NIL, NIL, PTR+LONG, t->n_df, t->n_ap);
 620624         sp->n_lval = 0;
 621625         sp->n_rval = STKREG;
 622626         t->n_type = sp->n_type;
 623627         ecomp(buildtree(ASSIGN, t, sp)); /* Emit! */
 624628 
 625629 }
 626630 
 627631 /*
 628632  * print out a constant node, may be associated with a label.
 629633  * Do not free the node after use.
 630634  * off is bit offset from the beginning of the aggregate
 631635  * fsz is the number of bits this is referring to
 632636  */
 633637 int
 634638 ninval(CONSZ off, int fsz, NODE *p)
 635639 {
 636640         union { float f; double d; long double l; int i[3]; } u;
 637641 
 638642         switch (p->n_type) {
 639643         case LDOUBLE:
 640644                 u.i[2] = 0;
 641645                 u.l = (long double)p->n_dcon;
 642646 #if defined(HOST_BIG_ENDIAN)
 643647                 /* XXX probably broken on most hosts */
 644648                 printf("\t.long\t0x%x,0x%x,0x%x,0\n", u.i[2], u.i[1], u.i[0]);
 645649 #else
 646650                 printf("\t.long\t0x%x,0x%x,0x%x,0\n", u.i[0], u.i[1], u.i[2]);
 647651 #endif
 648652                 break;
 649653         case DOUBLE:
 650654                 u.d = (double)p->n_dcon;
 651655 #if defined(HOST_BIG_ENDIAN)
 652656                 printf("\t.long\t0x%x,0x%x\n", u.i[1], u.i[0]);
 653657 #else
 654658                 printf("\t.long\t0x%x,0x%x\n", u.i[0], u.i[1]);
 655659 #endif
 656660                 break;
 657661         case FLOAT:
 658662                 u.f = (float)p->n_dcon;
 659663                 printf("\t.long\t0x%x\n", u.i[0]);
 660664                 break;
 661665         default:
 662666                 return 0;
 663667         }
 664668         return 1;
 665669 }
 666670 
 667671 /* make a name look like an external name in the local machine */
 668672 char *
 669673 exname(char *p)
 670674 {
 671675 #ifdef MACHOABI
 672676 
 673677 #define NCHNAM  256
 674678         static char text[NCHNAM+1];
 675679         int i;
 676680 
 677681         if (p == NULL)
 678682                 return "";
 679683 
 680684         text[0] = '_';
 681685         for (i=1; *p && i<NCHNAM; ++i)
 682686                 text[i] = *p++;
 683687 
 684688         text[i] = '\0';
 685689         text[NCHNAM] = '\0'/* truncate */
 686690 
 687691         return (text);
 688692 #else
 689693         return (p == NULL ? "" : p);
 690694 #endif
 691695 }
 692696 
 693697 /*
 694698  * map types which are not defined on the local machine
 695699  */
 696700 TWORD
 697701 ctype(TWORD type)
 698702 {
 699703         switch (BTYPE(type)) {
 700704         case LONGLONG:
 701705                 MODTYPE(type,LONG);
 702706                 break;
 703707 
 704708         case ULONGLONG:
 705709                 MODTYPE(type,ULONG);
 706710 
 707711         }
 708712         return (type);
 709713 }
 710714 
 711715 void
 712716 calldec(NODE *p, NODE *q)
 713717 {
 714718 }
 715719 
 716720 void
 717721 extdec(struct symtab *q)
 718722 {
 719723 }
 720724 
 721725 /* make a common declaration for id, if reasonable */
 722726 void
 723727 defzero(struct symtab *sp)
 724728 {
 725729         int off, al;
 726730         char *name;
 727731 
 728732         if ((name = sp->soname) == NULL)
 729733                 name = exname(sp->sname);
 730734         off = tsize(sp->stype, sp->sdf, sp->sap);
 731735         SETOFF(off,SZCHAR);
 732736         off /= SZCHAR;
 733737         al = talign(sp->stype, sp->sap)/SZCHAR;
 734738 
 735739         if (sp->sclass == STATIC) {
 736740                 if (sp->slevel == 0) {
 737741                         printf("\t.local %s\n", name);
 738742                 } else
 739743                         printf("\t.local " LABFMT "\n", sp->soffset);
 740744         }
 741745         if (sp->slevel == 0) {
 742746                 printf("\t.comm %s,0%o,%d\n", name, off, al);
 743747         } else
 744748                 printf("\t.comm " LABFMT ",0%o,%d\n", sp->soffset, off, al);
 745749 }
 746750 
 747751 static char *
 748752 section2string(char *name)
 749753 {
 750754         int len = strlen(name);
 751755 
 752756         if (strncmp(name, "link_set", 8) == 0) {
 753757                 const char postfix[] = ",\"aw\",@progbits";
 754758                 char *s;
 755759 
 756760                 s = IALLOC(len + sizeof(postfix));
 757761                 memcpy(s, name, len);
 758762                 memcpy(s + len, postfix, sizeof(postfix));
 759763                 return s;
 760764         }
 761765 
 762766         return newstring(name, len);
 763767 }
 764768 
 765769 char *nextsect;
 766770 static int gottls;
 767771 static char *alias;
 768772 static int constructor;
 769773 static int destructor;
 770774 
 771775 /*
 772776  * Give target the opportunity of handling pragmas.
 773777  */
 774778 int
 775779 mypragma(char *str)
 776780 {
 777781         char *a2 = pragtok(NULL);
 778782 
 779783         if (strcmp(str, "tls") == 0 && a2 == NULL) {
 780784                 gottls = 1;
 781785                 return 1;
 782786         }
 783787         if (strcmp(str, "constructor") == 0 || strcmp(str, "init") == 0) {
 784788                 constructor = 1;
 785789                 return 1;
 786790         }
 787791         if (strcmp(str, "destructor") == 0 || strcmp(str, "fini") == 0) {
 788792                 destructor = 1;
 789793                 return 1;
 790794         }
 791795         if (strcmp(str, "section") == 0 && a2 != NULL) {
 792796                 nextsect = section2string(a2);
 793797                 return 1;
 794798         }
 795799         if (strcmp(str, "alias") == 0 && a2 != NULL) {
 796800                 alias = tmpstrdup(a2);
 797801                 return 1;
 798802         }
 799803 
 800804         return 0;
 801805 }
 802806 
 803807 /*
 804808  * Called when a identifier has been declared.
 805809  */
 806810 void
 807811 fixdef(struct symtab *sp)
 808812 {
 809813         struct attr *ga;
 810814 
 811815         /* may have sanity checks here */
 812816         if (gottls)
 813817                 sp->sflags |= STLS;
 814818         gottls = 0;
 815819 
 816820 #ifdef HAVE_WEAKREF
 817821         /* not many as'es have this directive */
 818822         if ((ga = gcc_get_attr(sp->sap, GCC_ATYP_WEAKREF)) != NULL) {
 819823                 char *wr = ga->a1.sarg;
 820824                 char *sn = sp->soname ? sp->soname : sp->sname;
 821825                 if (wr == NULL) {
 822826                         if ((ga = gcc_get_attr(sp->sap, GCC_ATYP_ALIAS))) {
 823827                                 wr = ga->a1.sarg;
 824828                         }
 825829                 }
 826830                 if (wr == NULL)
 827831                         printf("\t.weak %s\n", sn);
 828832                 else
 829833                         printf("\t.weakref %s,%s\n", sn, wr);
 830834         } else
 831835 #endif
 832836                if ((ga = attr_find(sp->sap, GCC_ATYP_ALIAS)) != NULL) {
 833837                 char *an = ga->sarg(0);
 834838                 char *sn = sp->soname ? sp->soname : sp->sname;
 835839                 char *v;
 836840 
 837841                 v = attr_find(sp->sap, GCC_ATYP_WEAK) ? "weak" : "globl";
 838842                 printf("\t.%s %s\n", v, sn);
 839843                 printf("\t.set %s,%s\n", sn, an);
 840844         }
 841845         if (alias != NULL && (sp->sclass != PARAM)) {
 842846                 printf("\t.globl %s\n", exname(sp->soname));
 843847                 printf("%s = ", exname(sp->soname));
 844848                 printf("%s\n", exname(alias));
 845849                 alias = NULL;
 846850         }
 847851         if ((constructor || destructor) && (sp->sclass != PARAM)) {
 848852                 NODE *p = talloc();
 849853 
 850854                 p->n_op = NAME;
 851855                 p->n_sp =
 852856                   (struct symtab *)(constructor ? "constructor" : "destructor");
 853857                 sp->sap = attr_add(sp->sap, gcc_attr_parse(p));
 854858                 constructor = destructor = 0;
 855859         }
 856860 }
 857861 
 858862 void
 859863 pass1_lastchance(struct interpass *ip)
 860864 {
 861865 }
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-09-02 18:44 +0200