Quick Search:

Mode

Context

Displaying 3 lines of context. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.32
 
1.33
 
MAIN:ragge:20101031181452
 
code.c
_>5555 int lastloc = -1;
 5656 static int stroffset;
 5757 
<> 58+static int varneeds;
  59+#define NEED_GPNEXT     001
  60+#define NEED_FPNEXT     002
  61+#define NEED_1REGREF    004
  62+#define NEED_2REGREF    010
  63+#define NEED_MEMREF     020
  64+
5865 static int argtyp(TWORD t, union dimfun *df, struct attr *ap);
 5966 static NODE *movtomem(NODE *p, int off, int reg);
 6067 static NODE *movtoreg(NODE *p, int rno);
     
 !
350357 void
 351358 ejobcode(int flag )
 352359 {
<> 360+        if (flag)
  361+                return;
  362+
  363+        /* printout varargs routines if used */
  364+        if (varneeds & NEED_GPNEXT) {
  365+                printf(".text\n.align 4\n.type __pcc_gpnext,@function\n");
  366+                printf("__pcc_gpnext:\n");
  367+                printf("cmpl $48,(%%rdi)\njae 1f\n");
  368+                printf("movl (%%rdi),%%eax\naddq 16(%%rdi),%%rax\n");
  369+                printf("movq (%%rax),%%rax\naddl $8,(%%rdi)\nret\n");
  370+                printf("1:movq 8(%%rdi),%%rax\nmovq (%%rax),%%rax\n");
  371+                printf("addq $8,8(%%rdi)\nret\n");
  372+        }
  373+        if (varneeds & NEED_FPNEXT) {
  374+                printf(".text\n.align 4\n.type __pcc_fpnext,@function\n");
  375+                printf("__pcc_fpnext:\n");
  376+                printf("cmpl $176,4(%%rdi)\njae 1f\n");
  377+                printf("movl 4(%%rdi),%%eax\naddq 16(%%rdi),%%rax\n");
  378+                printf("movsd (%%rax),%%xmm0\naddl $16,4(%%rdi)\nret\n");
  379+                printf("1:movq 8(%%rdi),%%rax\nmovsd (%%rax),%%xmm0\n");
  380+                printf("addq $8,8(%%rdi)\nret\n");
  381+        }
  382+        if (varneeds & NEED_1REGREF) {
  383+                printf(".text\n.align 4\n.type __pcc_1regref,@function\n");
  384+                printf("__pcc_1regref:\n");
  385+                printf("cmpl $48,(%%rdi)\njae 1f\n");
  386+                printf("movl (%%rdi),%%eax\naddq 16(%%rdi),%%rax\n");
  387+                printf("addl $8,(%%rdi)\nret\n");
  388+                printf("1:movq 8(%%rdi),%%rax\n");
  389+                printf("addq $8,8(%%rdi)\nret\n");
  390+        }
  391+        if (varneeds & NEED_2REGREF) {
  392+                printf(".text\n.align 4\n.type __pcc_2regref,@function\n");
  393+                printf("__pcc_2regref:\n");
  394+                printf("cmpl $40,(%%rdi)\njae 1f\n");
  395+                printf("movl (%%rdi),%%eax\naddq 16(%%rdi),%%rax\n");
  396+                printf("addl $16,(%%rdi)\nret\n");
  397+                printf("1:movq 8(%%rdi),%%rax\n");
  398+                printf("addq $16,8(%%rdi)\nret\n");
  399+        }
  400+        if (varneeds & NEED_MEMREF) {
  401+                printf(".text\n.align 4\n.type __pcc_memref,@function\n");
  402+                printf("__pcc_memref:\n");
  403+                printf("movq 8(%%rdi),%%rax\n");
  404+                printf("addq %%rsi,8(%%rdi)\nret\n");
  405+        }
  406+                
  407+
353408 #define _MKSTR(x) #x
 354409 #define MKSTR(x) _MKSTR(x)
 355410 #define OS MKSTR(TARGOS)
     
 !
367422  *      void *overflow_arg_area;
 368423  *      void *reg_save_area;
 369424  * } __builtin_va_list[1];
<> 425+ *
  426+ * There are a number of asm routines printed out if varargs are used:
  427+ *      long __pcc_gpnext(va)   - get a gpreg value
  428+ *      long __pcc_fpnext(va)   - get a fpreg value
  429+ *      void *__pcc_1regref(va) - get reference to a onereg struct
  430+ *      void *__pcc_2regref(va) - get reference to a tworeg struct
  431+ *      void *__pcc_memref(va,sz)       - get reference to a large struct
370432  */
 371433 
 372434 static char *gp_offset, *fp_offset, *overflow_arg_area, *reg_save_area;
<> 435+static char *gpnext, *fpnext, *_1regref, *_2regref, *memref;
373436 
 374437 void
 375438 bjobcode()
 376439 {
<> 440+        struct symtab *sp;
377441         struct rstack *rp;
 378442         NODE *p, *q;
 379443         char *c;
     
 !
400464         defid(p, TYPEDEF);
 401465         nfree(q);
 402466         nfree(p);
<> 467+
  468+        /* for the static varargs functions */
  469+#define MKN(vn, rn, tp) \
  470+        { vn = addname(rn); sp = lookup(vn, SNORMAL); \
  471+          sp->sclass = USTATIC; sp->stype = tp; }
  472+
  473+        MKN(gpnext, "__pcc_gpnext", FTN|LONG);
  474+        MKN(fpnext, "__pcc_fpnext", FTN|DOUBLE);
  475+        MKN(_1regref, "__pcc_1regref", FTN|VOID|(PTR<<TSHIFT));
  476+        MKN(_2regref, "__pcc_2regref", FTN|VOID|(PTR<<TSHIFT));
  477+        MKN(memref, "__pcc_memref", FTN|VOID|(PTR<<TSHIFT));
403478 }
 404479 
 405480 static NODE *
     
 !
436511         return r;
 437512 }
 438513 
<>439 -/*
 440 - * Create a tree that should be like the expression
 441 - *      ((long *)(l->gp_offset >= 48 ?
 442 - *          l->overflow_arg_area += 8, l->overflow_arg_area :
 443 - *          l->gp_offset += 8, l->reg_save_area + l->gp_offset))[-1]
 444 - * ...or similar for floats.
 445 - */
 446 -static NODE *
 447 -bva(NODE *ap, NODE *dp, char *ot, int addto, int max)
 448 -{
 449 -        NODE *cm1, *cm2, *gpo, *ofa, *l1, *qc;
 450 -        TWORD nt;
 451 -
 452 -        ofa = structref(ccopy(ap), STREF, overflow_arg_area);
 453 -        l1 = buildtree(PLUSEQ, ccopy(ofa), bcon(addto));
 454 -        cm1 = buildtree(COMOP, l1, ofa);
 455 -
 456 -        gpo = structref(ccopy(ap), STREF, ot);
 457 -        l1 = buildtree(PLUSEQ, ccopy(gpo), bcon(addto));
 458 -        cm2 = buildtree(COMOP, l1, buildtree(PLUS, ccopy(gpo),
 459 -            structref(ccopy(ap), STREF, reg_save_area)));
 460 -        qc = buildtree(QUEST,
 461 -            buildtree(GE, gpo, bcon(max)),
 462 -            buildtree(COLON, cm1, cm2));
 463 -
 464 -        nt = (dp->n_type == DOUBLE ? DOUBLE : LONG);
 465 -        l1 = block(NAME, NIL, NIL, nt|PTR, 0, MKAP(nt));
 466 -        l1 = buildtree(CAST, l1, qc);
 467 -        qc = l1->n_right;
 468 -        nfree(l1->n_left);
 469 -        nfree(l1);
 470 -
 471 -        /* qc has now a real type, for indexing */
 472 -        addto = dp->n_type == DOUBLE ? 2 : 1;
 473 -        qc = buildtree(UMUL, buildtree(PLUS, qc, bcon(-addto)), NIL);
 474 -
 475 -        l1 = block(NAME, NIL, NIL, dp->n_type, dp->n_df, dp->n_ap);
 476 -        l1 = buildtree(CAST, l1, qc);
 477 -        qc = l1->n_right;
 478 -        nfree(l1->n_left);
 479 -        nfree(l1);
 480 -
 481 -        return qc;
 482 -}
 483 -
484514 NODE *
 485515 amd64_builtin_va_arg(NODE *f, NODE *a, TWORD t)
 486516 {
 487517         NODE *ap, *r, *dp;
 488518 
 489519         ap = a->n_left;
 490520         dp = a->n_right;
<>491 -        if (dp->n_type <= ULONGLONG || ISPTR(dp->n_type)) {
  521+        if (dp->n_type <= ULONGLONG || ISPTR(dp->n_type) ||
  522+            dp->n_type == FLOAT || dp->n_type == DOUBLE) {
492523                 /* type might be in general register */
<>493 -                r = bva(ap, dp, gp_offset, 8, 48);
 494 -        } else if (dp->n_type == FLOAT || dp->n_type == DOUBLE) {
 495 -                /* Float are promoted to double here */
 496 -                if (dp->n_type == FLOAT)
 497 -                        dp->n_type = DOUBLE;
 498 -                r = bva(ap, dp, fp_offset, 16, RSASZ/SZCHAR);
  524+                if (dp->n_type == FLOAT || dp->n_type == DOUBLE) {
  525+                        f->n_sp = lookup(fpnext, SNORMAL);
  526+                        varneeds |= NEED_FPNEXT;
  527+                } else {
  528+                        f->n_sp = lookup(gpnext, SNORMAL);
  529+                        varneeds |= NEED_GPNEXT;
  530+                }
  531+                f->n_type = f->n_sp->stype;
  532+                f = clocal(f);
  533+                r = buildtree(CALL, f, ccopy(ap));
  534+        } else if (ISSOU(dp->n_type)) {
  535+                /* put a reference directly to the stack */
  536+                int sz = tsize(dp->n_type, dp->n_df, dp->n_ap);
  537+                int al = talign(dp->n_type, dp->n_ap);
  538+                if (al < ALLONG)
  539+                        al = ALLONG;
  540+                if (sz <= SZLONG*2 && al == ALLONG) {
  541+                        if (sz <= SZLONG) {
  542+                                f->n_sp = lookup(_1regref, SNORMAL);
  543+                                varneeds |= NEED_1REGREF;
  544+                        } else {
  545+                                f->n_sp = lookup(_2regref, SNORMAL);
  546+                                varneeds |= NEED_2REGREF;
  547+                        }
  548+                        f->n_type = f->n_sp->stype;
  549+                        f = clocal(f);
  550+                        r = buildtree(CALL, f, ccopy(ap));
  551+                        r = ccast(r, INCREF(dp->n_type), 0, dp->n_df, dp->n_ap);
  552+                        r = buildtree(UMUL, r, NIL);
  553+                } else {
  554+                        f->n_sp = lookup(memref, SNORMAL);
  555+                        varneeds |= NEED_MEMREF;
  556+                        f->n_type = f->n_sp->stype;
  557+                        f = clocal(f);
  558+                        SETOFF(sz, al);
  559+                        r = buildtree(CALL, f,
  560+                            buildtree(CM, ccopy(ap), bcon(sz/SZCHAR)));
  561+                        r = ccast(r, INCREF(dp->n_type), 0, dp->n_df, dp->n_ap);
  562+                        r = buildtree(UMUL, r, NIL);
  563+                }
499564         } else {
 500565                 uerror("amd64_builtin_va_arg not supported type");
 501566                 goto bad;
 502567         }
 503568         tfree(a);
<>504 -        tfree(f);
505569         return r;
 506570 bad:
 507571         uerror("bad argument to __builtin_va_arg");
     
 !
517581 }
 518582 
 519583 NODE *
<>520 -amd64_builtin_va_copy(NODE *f, NODE *a, TWORD t) { cerror("amd64_builtin_va_copy"); return NULL; }
  584+amd64_builtin_va_copy(NODE *f, NODE *a, TWORD t)
  585+{
  586+        tfree(f);
  587+        f = buildtree(ASSIGN, buildtree(UMUL, a->n_left, NIL),
  588+            buildtree(UMUL, a->n_right, NIL));
  589+        nfree(a);
  590+        return f;
  591+}
521592 
 522593 static NODE *
 523594 movtoreg(NODE *p, int rno)
     
 !
634705                         q = buildtree(UMUL, q, NIL);
 635706                         p = movtoreg(q, argregsi[ngpr++]);
 636707                 } else if (ssz <= SZLONG*2) {
<>637 -                        NODE *qt, *q1, *q2, *ql, *qr;
  708+                        NODE *ql, *qr;
638709 
<>639 -                        qt = tempnode(0, LONG+PTR, 0, MKAP(LONG));
 640 -                        q1 = ccopy(qt);
 641 -                        q2 = ccopy(qt);
 642 -                        ql = buildtree(ASSIGN, qt, cast(p->n_left,LONG+PTR, 0));
 643 -                        nfree(p);
 644 -                        qr = movtoreg(buildtree(UMUL, q1, NIL),
  710+                        qr = cast(ccopy(p->n_left), LONG+PTR, 0);
  711+                        qr = movtoreg(buildtree(UMUL, qr, NIL),
645712                             argregsi[ngpr++]);
<>646 -                        ql = buildtree(COMOP, ql, qr);
 647 -                        qr = buildtree(UMUL, buildtree(PLUS, q2, bcon(1)), NIL);
 648 -                        qr = movtoreg(qr, argregsi[ngpr++]);
 649 -                        p = buildtree(COMOP, ql, qr);
  713+
  714+                        ql = cast(p->n_left, LONG+PTR, 0);
  715+                        ql = buildtree(UMUL, buildtree(PLUS, ql, bcon(1)), NIL);
  716+                        ql = movtoreg(ql, argregsi[ngpr++]);
  717+
  718+                        nfree(p);
  719+                        p = buildtree(CM, ql, qr);
650720                 } else
 651721                         cerror("STRREG");
 652722                 break;
     
 !
698768 
 699769         if (p->n_op != CM)
 700770                 return rv;
<> 771+        if (p->n_right->n_op == CM) {
  772+                /* fixup for small structs in regs */
  773+                q = p->n_right->n_left;
  774+                p->n_right->n_left = p->n_left;
  775+                p->n_left = p->n_right;
  776+                p->n_right = q;
  777+        }
<_701778         if (p->n_right->n_op == ASSIGN && p->n_right->n_left->n_op == REG) {
 702779                 if (p->n_left->n_op == CM &&
 703780                     p->n_left->n_right->n_op == STASG) {
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-27 02:38 +0100