Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.6
 
1.7
 
MAIN:gmcgarry:20071129055756
 
local.c
_>3131  * Simon Olsson (simols-1@student.ltu.se) 2005.
 3232  */
 3333 
<> 34+#include <assert.h>
3435 #include "pass1.h"
 3536 
 3637 static int inbits, inval;
     
 !
4546         struct symtab *q;
 4647         NODE *r, *l;
 4748         int o;
<>48 -        int m, ml;
  49+        int m;
4950         TWORD ty;
 5051 
<>51 -//printf("in:\n");
 52 -//fwalk(p, eprint, 0);
  52+#ifdef PCC_DEBUG
  53+        if (xdebug) {
  54+                printf("clocal: %p\n", p);
  55+                fwalk(p, eprint, 0);
  56+        }
  57+#endif
5358 
 5459         switch (o = p->n_op) {
 5560 
     
 !
8186                         p->n_rval = q->soffset;
 8287                         break;
 8388 
<>84 -                        }
  89+                }
8590                 break;
 8691 
 8792         case FUNARG:
     
 !
130135                 break;
 131136 
 132137         case PCONV:
<>133 -                ml = p->n_left->n_type;
  138+                /* Remove redundant PCONV's. Be careful */
134139                 l = p->n_left;
<>135 -                if ((ml == CHAR || ml == UCHAR || ml == SHORT || ml == USHORT)
 136 -                    && l->n_op != ICON)
  140+                if (l->n_op == ICON) {
  141+                        l->n_lval = (unsigned)l->n_lval;
  142+                        goto delp;
  143+                }
  144+                if (l->n_type < INT || l->n_type == LONGLONG ||
  145+                    l->n_type == ULONGLONG) {
  146+                        /* float etc? */
  147+                        p->n_left = block(SCONV, l, NIL,
  148+                            UNSIGNED, 0, MKSUE(UNSIGNED));
137149                         break;
<>138 -                l->n_type = p->n_type;
  150+                }
  151+                /* if left is SCONV, cannot remove */
  152+                if (l->n_op == SCONV)
  153+                        break;
  154+
  155+                /* avoid ADDROF TEMP */
  156+                if (l->n_op == ADDROF && l->n_left->n_op == TEMP)
  157+                        break;
  158+
  159+                /* if conversion to another pointer type, just remove */
  160+                if (p->n_type > BTMASK && l->n_type > BTMASK)
  161+                        goto delp;
  162+                break;
  163+
  164+        delp:   l->n_type = p->n_type;
139165                 l->n_qual = p->n_qual;
 140166                 l->n_df = p->n_df;
 141167                 l->n_sue = p->n_sue;
     
 !
603629  * a is the argument list containing:
 604630  *         CM
 605631  *      ap   last
<> 632+ *
  633+ * It turns out that this is easy on MIPS.  Just write the
  634+ * argument registers to the stack in va_arg_start() and
  635+ * use the traditional method of walking the stackframe.
606636  */
 607637 NODE *
 608638 mips_builtin_stdarg_start(NODE *f, NODE *a)
 609639 {
<>610 -        NODE *p;
  640+        NODE *p, *q;
611641         int sz = 1;
<> 642+        int i;
612643 
 613644         /* check num args and type */
 614645         if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
 615646             !ISPTR(a->n_left->n_type))
 616647                 goto bad;
 617648 
<> 649+        /*
  650+         * look at the offset of the last org to calculate the
  651+         * number of remain registers that need to be written
  652+         * to the stack.
  653+         */
  654+        if (xtemps) {
  655+                for (i = 0; i < nargregs; i++) {
  656+                        q = block(REG, NIL, NIL, PTR+INT, 0, MKSUE(INT));
  657+                        q->n_rval = A0 + i;
  658+                        p = block(REG, NIL, NIL, PTR+INT, 0, MKSUE(INT));
  659+                        p->n_rval = SP;
  660+                        p = block(PLUS, p, bcon(ARGINIT+i), PTR+INT, 0, MKSUE(INT));
  661+                        p = buildtree(UMUL, p, NIL);
  662+                        p = buildtree(ASSIGN, p, q);
  663+                        ecomp(p);
  664+                }
  665+        }
  666+
618667         /* must first deal with argument size; use int size */
 619668         p = a->n_right;
<>620 -        if (p->n_type < INT)
  669+        if (p->n_type < INT) {
  670+                /* round up to word */
621671                 sz = SZINT / tsize(p->n_type, p->n_df, p->n_sue);
<> 672+        }
622673 
<> 674+        /*
  675+         * Once again, if xtemps, the register is written to a
  676+         * temp.  We cannot take the address of the temp and
  677+         * walk from there.
  678+         *
  679+         * No solution at the moment...
  680+         */
  681+        assert(!xtemps);
  682+
  683+        p = buildtree(ADDROF, p, NIL);  /* address of last arg */
  684+        p = optim(buildtree(PLUS, p, bcon(sz)));
  685+        q = block(NAME, NIL, NIL, PTR+VOID, 0, 0);
  686+        q = buildtree(CAST, q, p);
  687+        p = q->n_right;
  688+        nfree(q->n_left);
  689+        nfree(q);
  690+        p = buildtree(ASSIGN, a->n_left, p);
  691+        tfree(f);
  692+        nfree(a);
  693+
  694+        return p;
  695+
  696+        //tfree(a->n_left); // XXX need this?
  697+
623698 bad:
<>624 -        return f;
  699+        uerror("bad argument to __builtin_stdarg_start");
  700+        return bcon(0);
625701 }
 626702 
 627703 NODE *
 628704 mips_builtin_va_arg(NODE *f, NODE *a)
 629705 {
<>630 -        return f;
  706+        NODE *p, *q, *r;
  707+        int sz, tmpnr;
  708+
  709+        /* check num args and type */
  710+        if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
  711+            !ISPTR(a->n_left->n_type) || a->n_right->n_op != TYPE)
  712+                goto bad;
  713+
  714+        /* create a copy to a temp node */
  715+        p = tcopy(a->n_left);
  716+        q = tempnode(0, p->n_type, p->n_df, p->n_sue);
  717+        tmpnr = q->n_lval;
  718+        p = buildtree(ASSIGN, q, p);
  719+
  720+        r = a->n_right;
  721+        sz = tsize(r->n_type, r->n_df, r->n_sue) / SZCHAR;
  722+        q = buildtree(PLUSEQ, a->n_left, bcon(sz));
  723+        q = buildtree(COMOP, p, q);
  724+
  725+        nfree(a->n_right);
  726+        nfree(a);
  727+        nfree(f);
  728+
  729+        p = tempnode(tmpnr, INCREF(r->n_type), r->n_df, r->n_sue);
  730+        p = buildtree(UMUL, p, NIL);
  731+        p = buildtree(COMOP, q, p);
  732+
  733+        return p;
  734+
  735+bad:
  736+        uerror("bad argument to __builtin_va_arg");
  737+        return bcon(0);
631738 }
 632739 
 633740 NODE *
 634741 mips_builtin_va_end(NODE *f, NODE *a)
 635742 {
<>636 -        return f;
  743+        tfree(f);
  744+        tfree(a);
  745+        return bcon(0);
637746 }
 638747 
 639748 NODE *
 640749 mips_builtin_va_copy(NODE *f, NODE *a)
 641750 {
<> 751+        if (a == NULL || a->n_op != CM || a->n_left->n_op == CM)
  752+                goto bad;
  753+        tfree(f);
  754+        f = buildtree(ASSIGN, a->n_left, a->n_right);
  755+        nfree(a);
642756         return f;
<> 757+
  758+bad:
  759+        uerror("bad argument to __buildtin_va_copy");
  760+        return bcon(0);
<_643761 }
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-19 13:51 +0200