Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.22
 
1.23
 
MAIN:ragge:20121201085340
 
code.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  * 3. The name of the author may not be used to endorse or promote products
 1515  *    derived from this software without specific prior written permission
 1616  *
 1717  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1818  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1919  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 2020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 2121  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2222  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2323  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2424  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2525  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2626  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2727  */
 2828 
 2929 
 3030 /*
 3131  * MIPS port by Jan Enoksson (janeno-1@student.ltu.se) and
 3232  * Simon Olsson (simols-1@student.ltu.se) 2005.
 3333  */
 3434 
 3535 #include <assert.h>
 3636 #include "pass1.h"
 3737 
 3838 /*
 3939  * Print out assembler segment name.
 4040  */
 4141 void
 4242 setseg(int seg, char *name)
 4343 {
 4444         switch (seg) {
 4545         case PROG: name = ".text"; break;
 4646         case DATA:
 4747         case LDATA: name = ".data"; break;
 4848         case STRNG:
 4949         case RDATA: name = ".section .rodata"; break;
 5050         case UDATA: break;
 5151         case PICLDATA:
 5252         case PICDATA: name = ".section .data.rel.rw,\"aw\",@progbits"; break;
 5353         case PICRDATA: name = ".section .data.rel.ro,\"aw\",@progbits"; break;
 5454         case TLSDATA: name = ".section .tdata,\"awT\",@progbits"; break;
 5555         case TLSUDATA: name = ".section .tbss,\"awT\",@nobits"; break;
 5656         case CTORS: name = ".section\t.ctors,\"aw\",@progbits"; break;
 5757         case DTORS: name = ".section\t.dtors,\"aw\",@progbits"; break;
 5858         case NMSEG:
 5959                 printf("\t.section %s,\"aw\",@progbits\n", name);
 6060                 return;
 6161         }
 6262         printf("\t%s\n", name);
 6363 }
 6464 
 6565 /*
 6666  * Define everything needed to print out some data (or text).
 6767  * This means segment, alignment, visibility, etc.
 6868  */
 6969 void
 7070 defloc(struct symtab *sp)
 7171 {
 7272         char *n;
 7373 
 7474         if (ISFTN(sp->stype))
 7575                 return; /* XXX until fixed */
 7676 
 7777         if ((n = sp->soname) == NULL)
 7878                 n = exname(sp->sname);
 7979 
 8080         if (sp->sclass == EXTDEF)
 8181                 printf("        .globl %s\n", n);
 8282         if (sp->slevel == 0) {
 8383 #ifdef USE_GAS
 8484                 printf("\t.type %s,@%s\n", n,
 8585                     ISFTN(sp->stype) ? "function" : "object");
 8686                 if (!ISFTN(sp->stype))
 8787                         printf("\t.size %s," CONFMT "\n", n,
 8888                             tsize(sp->stype, sp->sdf, sp->sap));
 8989 #endif
 9090                 printf("%s:\n", n);
 9191         } else
 9292                 printf(LABFMT ":\n", sp->soffset);
 9393 }
 9494 
 9595 
 9696 /*
 9797  * cause the alignment to become a multiple of n
 9898  */
 9999 void
 100100 defalign(int n)
 101101 {
 102102         n = ispow2(n / SZCHAR);
 103103         if (n == -1)
 104104                 cerror("defalign: n != 2^i");
 105105         printf("\t.p2align %d\n", n);
 106106 }
 107107 
 108108 static int rvnr;
 109109 
 110110 /*
 111111  * code for the end of a function
 112112  * deals with struct return here
 113113  */
 114114 void
 115115 efcode(void)
 116116 {
 117117         NODE *p, *q;
 118118         int tempnr;
 119119         int ty;
 120120 
 121121         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
 122122                 return;
 123123 
 124124         ty = cftnsp->stype - FTN;
 125125 
 126126         q = block(REG, NIL, NIL, INCREF(ty), 0, cftnsp->sap);
 127127         q->n_rval = V0;
 128128         p = tempnode(0, INCREF(ty), 0, cftnsp->sap);
 129129         tempnr = regno(p);
 130130         p = buildtree(ASSIGN, p, q);
 131131         ecomp(p);
 132132 
 133133         q = tempnode(tempnr, INCREF(ty), 0, cftnsp->sap);
 134134         q = buildtree(UMUL, q, NIL);
 135135 
 136136         p = tempnode(rvnr, INCREF(ty), 0, cftnsp->sap);
 137137         p = buildtree(UMUL, p, NIL);
 138138 
 139139         p = buildtree(ASSIGN, p, q);
 140140         ecomp(p);
 141141 
 142142         q = tempnode(rvnr, INCREF(ty), 0, cftnsp->sap);
 143143         p = block(REG, NIL, NIL, INCREF(ty), 0, cftnsp->sap);
 144144         p->n_rval = V0;
 145145         p = buildtree(ASSIGN, p, q);
 146146         ecomp(p);
 147147 }
 148148 
 149149 /* Put a symbol in a temporary
 150150  * used by bfcode() and its helpers */
 151151 static void
 152152 putintemp(struct symtab *sym)
 153153 {
 154154         NODE *p;
 155155         p = tempnode(0, sym->stype, sym->sdf, sym->sap);
 156156         p = buildtree(ASSIGN, p, nametree(sym));
 157157         sym->soffset = regno(p->n_left);
 158158         sym->sflags |= STNODE;
 159159         ecomp(p);
 160160 }
 161161 
 162162 /* setup the hidden pointer to struct return parameter
 163163  * used by bfcode() */
 164164 static void
 165165 param_retptr(void)
 166166 {
 167167         NODE *p, *q;
 168168 
 169169         p = tempnode(0, PTR+STRTY, 0, cftnsp->sap);
 170170         rvnr = regno(p);
 171171         q = block(REG, NIL, NIL, PTR+STRTY, 0, cftnsp->sap);
 172172         q->n_rval = A0;
 173173         p = buildtree(ASSIGN, p, q);
 174174         ecomp(p);
 175175 }
 176176 
 177177 /* setup struct parameter
 178178  * push the registers out to memory
 179179  * used by bfcode() */
 180180 static void
 181181 param_struct(struct symtab *sym, int *regp)
 182182 {
 183183         int reg = *regp;
 184184         NODE *p, *q;
 185185         int navail;
 186186         int sz;
 187187         int off;
 188188         int num;
 189189         int i;
 190190 
 191191         navail = nargregs - (reg - A0);
 192192         sz = tsize(sym->stype, sym->sdf, sym->sap) / SZINT;
 193193         off = ARGINIT/SZINT + (reg - A0);
 194194         num = sz > navail ? navail : sz;
 195195         for (i = 0; i < num; i++) {
 196196                 q = block(REG, NIL, NIL, INT, 0, 0);
 197197                 q->n_rval = reg++;
 198198                 p = block(REG, NIL, NIL, INT, 0, 0);
 199199                 p->n_rval = FP;
 200200                 p = block(PLUS, p, bcon(4*off++), INT, 0, 0);
 201201                 p = block(UMUL, p, NIL, INT, 0, 0);
 202202                 p = buildtree(ASSIGN, p, q);
 203203                 ecomp(p);
 204204         }
 205205 
 206206         *regp = reg;
 207207 }
 208208 
 209209 /* setup a 64-bit parameter (double/ldouble/longlong)
 210210  * used by bfcode() */
 211211 static void
 212212 param_64bit(struct symtab *sym, int *regp, int dotemps)
 213213 {
 214214         int reg = *regp;
 215215         NODE *p, *q;
 216216         int navail;
 217217 
 218218         /* alignment */
 219219         ++reg;
 220220         reg &= ~1;
 221221 
 222222         navail = nargregs - (reg - A0);
 223223 
 224224         if (navail < 2) {
 225225                 /* would have appeared half in registers/half
 226226                  * on the stack, but alignment ensures it
 227227                  * appears on the stack */
 228228                 if (dotemps)
 229229                         putintemp(sym);
 230230                 *regp = reg;
 231231                 return;
 232232         }
 233233 
 234234         q = block(REG, NIL, NIL, sym->stype, sym->sdf, sym->sap);
 235235         q->n_rval = A0A1 + (reg - A0);
 236236         if (dotemps) {
 237237                 p = tempnode(0, sym->stype, sym->sdf, sym->sap);
 238238                 sym->soffset = regno(p);
 239239                 sym->sflags |= STNODE;
 240240         } else {
 241241                 p = nametree(sym);
 242242         }
 243243         p = buildtree(ASSIGN, p, q);
 244244         ecomp(p);
 245245         *regp = reg + 2;
 246246 }
 247247 
 248248 /* setup a 32-bit param on the stack
 249249  * used by bfcode() */
 250250 static void
 251251 param_32bit(struct symtab *sym, int *regp, int dotemps)
 252252 {
 253253         NODE *p, *q;
 254254 
 255255         q = block(REG, NIL, NIL, sym->stype, sym->sdf, sym->sap);
 256256         q->n_rval = (*regp)++;
 257257         if (dotemps) {
 258258                 p = tempnode(0, sym->stype, sym->sdf, sym->sap);
 259259                 sym->soffset = regno(p);
 260260                 sym->sflags |= STNODE;
 261261         } else {
 262262                 p = nametree(sym);
 263263         }
 264264         p = buildtree(ASSIGN, p, q);
 265265         ecomp(p);
 266266 }
 267267 
 268268 /*
 269269  * XXX This is a hack.  We cannot have (l)doubles in more than one
 270270  * register class.  So we bounce them in and out of temps to
 271271  * move them in and out of the right registers.
 272272  */
 273273 static void
 274274 param_double(struct symtab *sym, int *regp, int dotemps)
 275275 {
 276276         int reg = *regp;
 277277         NODE *p, *q, *t;
 278278         int navail;
 279279         int tmpnr;
 280280 
 281281         /* alignment */
 282282         ++reg;
 283283         reg &= ~1;
 284284 
 285285         navail = nargregs - (reg - A0);
 286286 
 287287         if (navail < 2) {
 288288                 /* would have appeared half in registers/half
 289289                  * on the stack, but alignment ensures it
 290290                  * appears on the stack */
 291291                 if (dotemps)
 292292                         putintemp(sym);
 293293                 *regp = reg;
 294294                 return;
 295295         }
 296296 
 297297         t = tempnode(0, LONGLONG, 0, 0);
 298298         tmpnr = regno(t);
 299299         q = block(REG, NIL, NIL, LONGLONG, 0, 0);
 300300         q->n_rval = A0A1 + (reg - A0);
 301301         p = buildtree(ASSIGN, t, q);
 302302         ecomp(p);
 303303 
 304304         if (dotemps) {
 305305                 sym->soffset = tmpnr;
 306306                 sym->sflags |= STNODE;
 307307         } else {
 308308                 q = tempnode(tmpnr, sym->stype, sym->sdf, sym->sap);
 309309                 p = nametree(sym);
 310310                 p = buildtree(ASSIGN, p, q);
 311311                 ecomp(p);
 312312         }
 313313         *regp = reg + 2;
 314314 }
 315315 
 316316 /*
 317317  * XXX This is a hack.  We cannot have floats in more than one
 318318  * register class.  So we bounce them in and out of temps to
 319319  * move them in and out of the right registers.
 320320  */
 321321 static void
 322322 param_float(struct symtab *sym, int *regp, int dotemps)
 323323 {
 324324         NODE *p, *q, *t;
 325325         int tmpnr;
 326326 
 327327         t = tempnode(0, INT, 0, 0);
 328328         tmpnr = regno(t);
 329329         q = block(REG, NIL, NIL, INT, 0, 0);
 330330         q->n_rval = (*regp)++;
 331331         p = buildtree(ASSIGN, t, q);
 332332         ecomp(p);
 333333 
 334334         if (dotemps) {
 335335                 sym->soffset = tmpnr;
 336336                 sym->sflags |= STNODE;
 337337         } else {
 338338                 q = tempnode(tmpnr, sym->stype, sym->sdf, sym->sap);
 339339                 p = nametree(sym);
 340340                 p = buildtree(ASSIGN, p, q);
 341341                 ecomp(p);
 342342         }
 343343 }
 344344 
 345345 /*
 346346  * code for the beginning of a function; a is an array of
 347347  * indices in symtab for the arguments; n is the number
 348348  */
 349349 void
 350350 bfcode(struct symtab **sp, int cnt)
 351351 {
 352352         union arglist *usym;
 353353         int lastreg = A0 + nargregs - 1;
 354354         int saveallargs = 0;
 355355         int i, reg;
 356356 
 357357         /*
 358358          * Detect if this function has ellipses and save all
 359359          * argument register onto stack.
 360360          */
 361361         usym = cftnsp->sdf->dfun;
 362362         while (usym && usym->type != TNULL) {
 363363                 if (usym->type == TELLIPSIS) {
 364364                         saveallargs = 1;
 365365                         break;
 366366                 }
 367367                 ++usym;
 368368         }
 369369 
 370370         reg = A0;
 371371 
 372372         /* assign hidden return structure to temporary */
 373373         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
 374374                 param_retptr();
 375375                 ++reg;
 376376         }
 377377 
 378378         /* recalculate the arg offset and create TEMP moves */
 379379         for (i = 0; i < cnt; i++) {
 380380 
 381381                 if ((reg > lastreg) && !xtemps)
 382382                         break;
 383383                 else if (reg > lastreg)
 384384                         putintemp(sp[i]);
 385385                 else if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY)
 386386                         param_struct(sp[i], &reg);
 387387                 else if (DEUNSIGN(sp[i]->stype) == LONGLONG)
 388388                         param_64bit(sp[i], &reg, xtemps && !saveallargs);
 389389                 else if (sp[i]->stype == DOUBLE || sp[i]->stype == LDOUBLE)
 390390                         param_double(sp[i], &reg, xtemps && !saveallargs);
 391391                 else if (sp[i]->stype == FLOAT)
 392392                         param_float(sp[i], &reg, xtemps && !saveallargs);
 393393                 else
 394394                         param_32bit(sp[i], &reg, xtemps && !saveallargs);
 395395         }
 396396 
 397397         /* if saveallargs, save the rest of the args onto the stack */
 398398         if (!saveallargs)
 399399                 return;
 400400         while (reg <= lastreg) {
 401401                 NODE *p, *q;
 402402                 int off = ARGINIT/SZINT + (reg - A0);
 403403                 q = block(REG, NIL, NIL, INT, 0, 0);
 404404                 q->n_rval = reg++;
 405405                 p = block(REG, NIL, NIL, INT, 0, 0);
 406406                 p->n_rval = FP;
 407407                 p = block(PLUS, p, bcon(4*off), INT, 0, 0);
 408408                 p = block(UMUL, p, NIL, INT, 0, 0);
 409409                 p = buildtree(ASSIGN, p, q);
 410410                 ecomp(p);
 411411         }
 412412 
 413413 }
 414414 
 415415 
 416416 /* called just before final exit */
 417417 /* flag is 1 if errors, 0 if none */
 418418 void
 419419 ejobcode(int flag)
 420420 {
 421421 }
 422422 
 423423 void
 424424 bjobcode(void)
 425425 {
 426426         printf("\t.section .mdebug.abi32\n");
 427427         printf("\t.previous\n");
 428428         printf("\t.abicalls\n");
 429429 }
 430430 
 431431 #ifdef notdef
 432432 /*
 433433  * Print character t at position i in one string, until t == -1.
 434434  * Locctr & label is already defined.
 435435  */
 436436 void
 437437 bycode(int t, int i)
 438438 {
 439439         static int lastoctal = 0;
 440440 
 441441         /* put byte i+1 in a string */
 442442 
 443443         if (t < 0) {
 444444                 if (i != 0)
 445445                         puts("\\000\"");
 446446         } else {
 447447                 if (i == 0)
 448448                         printf("\t.ascii \"");
 449449                 if (t == 0)
 450450                         return;
 451451                 else if (t == '\\' || t == '"') {
 452452                         lastoctal = 0;
 453453                         putchar('\\');
 454454                         putchar(t);
 455455                 } else if (t == 011) {
 456456                         printf("\\t");
 457457                 } else if (t == 012) {
 458458                         printf("\\n");
 459459                 } else if (t < 040 || t >= 0177) {
 460460                         lastoctal++;
 461461                         printf("\\%o",t);
 462462                 } else if (lastoctal && '0' <= t && t <= '9') {
 463463                         lastoctal = 0;
 464464                         printf("\"\n\t.ascii \"%c", t);
 465465                 } else {        
 466466                         lastoctal = 0;
 467467                         putchar(t);
 468468                 }
 469469         }
 470470 }
 471471 #endif
 472472 
 473473 /* fix up type of field p */
 474474 void
 475475 fldty(struct symtab *p)
 476476 {
 477477 }
 478478 
 479479 /*
 480480  * XXX - fix genswitch.
 481481  */
 482482 int
 483483 mygenswitch(int num, TWORD type, struct swents **p, int n)
 484484 {
 485485         return 0;
 486486 }
 487487 
 488488 
 489489 /* setup call stack with a structure */
 490490 /* called from moveargs() */
 491491 static NODE *
 492492 movearg_struct(NODE *p, NODE *parent, int *regp)
 493493 {
 494494         int reg = *regp;
 495495         NODE *l, *q, *t, *r;
 496496         int tmpnr;
 497497         int navail;
 498498         int off;
 499499         int num;
 500500         int sz;
 501501         int ty;
 502502         int i;
 503503 
 504504         navail = nargregs - (reg - A0);
 505505         sz = tsize(p->n_type, p->n_df, p->n_ap) / SZINT;
 506506         num = sz > navail ? navail : sz;
 507507 
 508508         l = p->n_left;
 509509         nfree(p);
 510510         ty = l->n_type;
 511511         t = tempnode(0, l->n_type, l->n_df, l->n_ap);
 512512         tmpnr = regno(t);
 513513         l = buildtree(ASSIGN, t, l);
 514514 
 515515         if (p != parent) {
 516516                 q = parent->n_left;
 517517         } else
 518518                 q = NULL;
 519519 
 520520         /* copy structure into registers */
 521521         for (i = 0; i < num; i++) {
 522522                 t = tempnode(tmpnr, ty, 0, 0);
 523523                 t = block(SCONV, t, NIL, PTR+INT, 0, 0);
 524524                 t = block(PLUS, t, bcon(4*i), PTR+INT, 0, 0);
 525525                 t = buildtree(UMUL, t, NIL);
 526526 
 527527                 r = block(REG, NIL, NIL, INT, 0, 0);
 528528                 r->n_rval = reg++;
 529529 
 530530                 r = buildtree(ASSIGN, r, t);
 531531                 if (q == NULL)
 532532                         q = r;
 533533                 else
 534534                         q = block(CM, q, r, INT, 0, 0);
 535535         }
 536536         off = ARGINIT/SZINT + nargregs;
 537537         for (i = num; i < sz; i++) {
 538538                 t = tempnode(tmpnr, ty, 0, 0);
 539539                 t = block(SCONV, t, NIL, PTR+INT, 0, 0);
 540540                 t = block(PLUS, t, bcon(4*i), PTR+INT, 0, 0);
 541541                 t = buildtree(UMUL, t, NIL);
 542542 
 543543                 r = block(REG, NIL, NIL, INT, 0, 0);
 544544                 r->n_rval = FP;
 545545                 r = block(PLUS, r, bcon(4*off++), INT, 0, 0);
 546546                 r = block(UMUL, r, NIL, INT, 0, 0);
 547547 
 548548                 r = buildtree(ASSIGN, r, t);
 549549                 if (q == NULL)
 550550                         q = r;
 551551                 else
 552552                         q = block(CM, q, r, INT, 0, 0);
 553553         }
 554554 
 555555         if (parent->n_op == CM) {
 556556                 parent->n_left = q;
 557557                 q = l;
 558558         } else {
 559559                 q = block(CM, q, l, INT, 0, 0);
 560560         }
 561561 
 562562         *regp = reg;
 563563         return q;
 564564 }
 565565 
 566566 /* setup call stack with 64-bit argument */
 567567 /* called from moveargs() */
 568568 static NODE *
 569569 movearg_64bit(NODE *p, int *regp)
 570570 {
 571571         int reg = *regp;
 572572         NODE *q;
 573573         int lastarg;
 574574 
 575575         /* alignment */
 576576         ++reg;
 577577         reg &= ~1;
 578578 
 579579         lastarg = A0 + nargregs - 1;
 580580         if (reg > lastarg) {
 581581                 *regp = reg;
 582582                 return block(FUNARG, p, NIL, p->n_type, p->n_df, p->n_ap);
 583583         }
 584584 
 585585         q = block(REG, NIL, NIL, p->n_type, p->n_df, p->n_ap);
 586586         q->n_rval = A0A1 + (reg - A0);
 587587         q = buildtree(ASSIGN, q, p);
 588588 
 589589         *regp = reg + 2;
 590590         return q;
 591591 }
 592592 
 593593 /* setup call stack with 32-bit argument */
 594594 /* called from moveargs() */
 595595 static NODE *
 596596 movearg_32bit(NODE *p, int *regp)
 597597 {
 598598         int reg = *regp;
 599599         NODE *q;
 600600 
 601601         q = block(REG, NIL, NIL, p->n_type, p->n_df, p->n_ap);
 602602         q->n_rval = reg++;
 603603         q = buildtree(ASSIGN, q, p);
 604604 
 605605         *regp = reg;
 606606         return q;
 607607 }
 608608 
 609609 static NODE *
 610610 moveargs(NODE *p, int *regp)
 611611 {
 612612         NODE *r, **rp;
 613613         int lastreg;
 614614         int reg;
 615615 
 616616         if (p->n_op == CM) {
 617617                 p->n_left = moveargs(p->n_left, regp);
 618618                 r = p->n_right;
 619619                 rp = &p->n_right;
 620620         } else {
 621621                 r = p;
 622622                 rp = &p;
 623623         }
 624624 
 625625         lastreg = A0 + nargregs - 1;
 626626         reg = *regp;
 627627 
 628628         if (reg > lastreg && r->n_op != STARG)
 629629                 *rp = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_ap);
 630630         else if (r->n_op == STARG) {
 631631                 *rp = movearg_struct(r, p, regp);
 632632         } else if (DEUNSIGN(r->n_type) == LONGLONG) {
 633633                 *rp = movearg_64bit(r, regp);
 634634         } else if (r->n_type == DOUBLE || r->n_type == LDOUBLE) {
 635635                 /* XXX bounce in and out of temporary to change to longlong */
 636636                 NODE *t1 = tempnode(0, LONGLONG, 0, 0);
 637637                 int tmpnr = regno(t1);
 638638                 NODE *t2 = tempnode(tmpnr, r->n_type, r->n_df, r->n_ap);
 639639                 t1movearg_64bit(t1, regp);
 640640                 r = block(ASSIGN, t2, r, r->n_type, r->n_df, r->n_ap);
 641641                 if (p->n_op == CM) {
 642642                         p->n_left = buildtree(CM, p->n_left, t1);
 643643                         p->n_right = r;
 644644                 } else {
 645645                         p = buildtree(CM, t1, r);
 646646                 }
 647647         } else if (r->n_type == FLOAT) {
 648648                 /* XXX bounce in and out of temporary to change to int */
 649649                 NODE *t1 = tempnode(0, INT, 0, 0);
 650650                 int tmpnr = regno(t1);
 651651                 NODE *t2 = tempnode(tmpnr, r->n_type, r->n_df, r->n_ap);
 652652                 t1movearg_32bit(t1, regp);
 653653                 r = block(ASSIGN, t2, r, r->n_type, r->n_df, r->n_ap);
 654654                 if (p->n_op == CM) {
 655655                         p->n_left = buildtree(CM, p->n_left, t1);
 656656                         p->n_right = r;
 657657                 } else {
 658658                         p = buildtree(CM, t1, r);
 659659                 }
 660660         } else {
 661661                 *rp = movearg_32bit(r, regp);
 662662         }
 663663 
 664664         return p;
 665665 }
 666666 
 667667 /*
 668668  * Called with a function call with arguments as argument.
 669669  * This is done early in buildtree() and only done once.
 670670  */
 671671 NODE *
 672672 funcode(NODE *p)
 673673 {
 674674         int regnum = A0;
 675675         NODE *l, *r, *t, *q;
 676676         int ty;
 677677 
 678678         l = p->n_left;
 679679         r = p->n_right;
 680680 
 681681         /*
 682682          * if returning a structure, make the first argument
 683683          * a hidden pointer to return structure.
 684684          */
 685685         ty = DECREF(l->n_type);
 686686         if (ty == STRTY+FTN || ty == UNIONTY+FTN) {
 687687                 ty = DECREF(l->n_type) - FTN;
 688688                 q = tempnode(0, ty, l->n_df, l->n_ap);
 689689                 q = buildtree(ADDROF, q, NIL);
 690690                 if (r->n_op != CM) {
 691691                         p->n_right = block(CM, q, r, INCREF(ty),
 692692                             l->n_df, l->n_ap);
 693693                 } else {
 694694                         for (t = r; t->n_left->n_op == CM; t = t->n_left)
 695695                                 ;
 696696                         t->n_left = block(CM, q, t->n_left, INCREF(ty),
 697697                             l->n_df, l->n_ap);
 698698                 }
 699699         }
 700700 
 701701         p->n_right = moveargs(p->n_right, &regnum);
 702702 
 703703         return p;
 704704 }
<_ 705+
  706+NODE *
  707+builtin_cfa(const struct bitable *bt, NODE *a)
  708+{
  709+        uerror("missing builtin_cfa");
  710+        return bcon(0);
  711+}
  712+
  713+NODE *
  714+builtin_frame_address(const struct bitable *bt, NODE *a)
  715+{
  716+        uerror("missing builtin_frame_address");
  717+        return bcon(0);
  718+}
  719+
  720+NODE *
  721+builtin_return_address(const struct bitable *bt, NODE *a)
  722+{      
  723+        uerror("missing builtin_return_address");
  724+        return bcon(0);
  725+}
  726+
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 16:52 +0100