Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.8
 
1.9
 
MAIN:gmcgarry:20071213042014
 
code.c
_>110110         ecomp(p);
 111111 }
 112112 
<> 113+/* Put a symbol in a temporary
  114+ * used by bfcode() and its helpers */
  115+static void
  116+putintemp(struct symtab *sym)
  117+{
  118+        NODE *p;
  119+        spname = sym;
  120+        p = tempnode(0, sym->stype, sym->sdf, sym->ssue);
  121+        p = buildtree(ASSIGN, p, buildtree(NAME, 0, 0));
  122+        sym->soffset = p->n_left->n_lval;
  123+        sym->sflags |= STNODE;
  124+        ecomp(p);
  125+}
  126+
  127+/* setup the hidden pointer to struct return parameter
  128+ * used by bfcode() */
  129+static void
  130+param_retptr(void)
  131+{
  132+        NODE *p, *q;
  133+
  134+        p = tempnode(0, PTR+STRTY, 0, cftnsp->ssue);
  135+        rvnr = p->n_lval;
  136+        q = block(REG, NIL, NIL, PTR+STRTY, 0, cftnsp->ssue);
  137+        q->n_rval = A0;
  138+        p = buildtree(ASSIGN, p, q);
  139+        ecomp(p);
  140+}
  141+
  142+/* setup struct parameter
  143+ * push the registers out to memory
  144+ * used by bfcode() */
  145+static void
  146+param_struct(struct symtab *sym, int *regp)
  147+{
  148+        int reg = *regp;
  149+        NODE *p, *q;
  150+        int navail;
  151+        int sz;
  152+        int off;
  153+        int num;
  154+        int i;
  155+
  156+        navail = nargregs - (reg - A0);
  157+        sz = tsize(sym->stype, sym->sdf, sym->ssue) / SZINT;
  158+        off = ARGINIT/SZINT + (reg - A0);
  159+        num = sz > navail ? navail : sz;
  160+        for (i = 0; i < num; i++) {
  161+                q = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
  162+                q->n_rval = reg++;
  163+                p = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
  164+                p->n_rval = FP;
  165+                p = block(PLUS, p, bcon(4*off++), INT, 0, MKSUE(INT));
  166+                p = block(UMUL, p, NIL, INT, 0, MKSUE(INT));
  167+                p = buildtree(ASSIGN, p, q);
  168+                ecomp(p);
  169+        }
  170+
  171+        *regp = reg;
  172+}
  173+
  174+/* setup a 64-bit parameter (double/ldouble/longlong)
  175+ * used by bfcode() */
  176+static void
  177+param_64bit(struct symtab *sym, int *regp, int dotemps)
  178+{
  179+        int reg = *regp;
  180+        NODE *p, *q;
  181+        int navail;
  182+        int sz;
  183+
  184+        /* alignment */
  185+        ++reg;
  186+        reg &= ~1;
  187+
  188+        navail = nargregs - (reg - A0);
  189+        sz = szty(sym->stype);
  190+
  191+        if (sz > navail) {
  192+                /* would have appeared half in registers/half
  193+                 * on the stack, but alignment ensures it
  194+                 * appears on the stack */
  195+                if (dotemps)
  196+                        putintemp(sym);
  197+        } else {
  198+                q = block(REG, NIL, NIL,
  199+                    sym->stype, sym->sdf, sym->ssue);
  200+                q->n_rval = A0A1 + (reg - A0);
  201+                if (dotemps) {
  202+                        p = tempnode(0, sym->stype, sym->sdf, sym->ssue);
  203+                        sym->soffset = p->n_lval;
  204+                        sym->sflags |= STNODE;
  205+                } else {
  206+                        spname = sym;
  207+                        p = buildtree(NAME, 0, 0);
  208+                }
  209+                p = buildtree(ASSIGN, p, q);
  210+                ecomp(p);
  211+                reg += 2;
  212+        }
  213+
  214+        *regp = reg;
  215+}
  216+
  217+/* setup a 32-bit param on the stack
  218+ * used by bfcode() */
  219+static void
  220+param_32bit(struct symtab *sym, int *regp, int dotemps)
  221+{
  222+        NODE *p, *q;
  223+
  224+        q = block(REG, NIL, NIL, sym->stype, sym->sdf, sym->ssue);
  225+        q->n_rval = (*regp)++;
  226+        if (dotemps) {
  227+                p = tempnode(0, sym->stype, sym->sdf, sym->ssue);
  228+                sym->soffset = p->n_lval;
  229+                sym->sflags |= STNODE;
  230+        } else {
  231+                spname = sym;
  232+                p = buildtree(NAME, 0, 0);
  233+        }
  234+        p = buildtree(ASSIGN, p, q);
  235+        ecomp(p);
  236+}
  237+
113238 /*
 114239  * code for the beginning of a function; a is an array of
 115240  * indices in symtab for the arguments; n is the number
 116241  */
 117242 void
 118243 bfcode(struct symtab **sp, int cnt)
 119244 {
<>120 -        NODE *p, *q;
 121 -        int i, n, start = 0;
 122 -        int sz, tsz;
  245+        union arglist *usym;
  246+        int lastreg = A0 + nargregs - 1;
  247+        int saveallargs = 0;
  248+        int i, reg;
123249 
<> 250+        /*
  251+         * Detect if this function has ellipses and save all
  252+         * argument register onto stack.
  253+         */
  254+        usym = cftnsp->sdf->dfun;
  255+        while (usym && usym->type != TNULL) {
  256+                if (usym->type == TELLIPSIS) {
  257+                        saveallargs = 1;
  258+                        break;
  259+                }
  260+                ++usym;
  261+        }
  262+
  263+        reg = A0;
  264+
124265         /* assign hidden return structure to temporary */
 125266         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
<>126 -                p = tempnode(0, PTR+STRTY, 0, cftnsp->ssue);
 127 -                rvnr = p->n_lval;
 128 -                q = block(REG, NIL, NIL, PTR+STRTY, 0, cftnsp->ssue);
 129 -                q->n_rval = A0 + start++;
 130 -                p = buildtree(ASSIGN, p, q);
 131 -                ecomp(p);
  267+                param_retptr();
  268+                ++reg;
132269         }
 133270 
 134271         /* recalculate the arg offset and create TEMP moves */
<>135 -        for (n = start, i = 0; i < cnt; i++) {
  272+        for (i = 0; i < cnt; i++) {
136273 
<>137 -                sz = tsize(sp[i]->stype, sp[i]->sdf, sp[i]->ssue) / SZINT;
  274+                if ((reg > lastreg) && !xtemps)
  275+                        break;
  276+                else if (reg > lastreg)
  277+                        putintemp(sp[i]);
  278+                else if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY)
  279+                        param_struct(sp[i], &reg);
  280+                else if (sp[i]->stype == DOUBLE || sp[i]->stype == LDOUBLE ||
  281+                     DEUNSIGN(sp[i]->stype) == LONGLONG)
  282+                        param_64bit(sp[i], &reg, xtemps && !saveallargs);
  283+                else
  284+                        param_32bit(sp[i], &reg, xtemps && !saveallargs);
  285+        }
138286 
<>139 -                /* A structure argument */
 140 -                if (n < nargregs &&
 141 -                    (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY)) {
 142 -                        tsz = sz > nargregs - n ? nargregs - n : sz;
 143 -                        spname = sp[i];
 144 -                        for (i = 0; i < tsz; i++) {
 145 -                                q = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
 146 -                                q->n_rval = A0 + n + i;
 147 -                                p = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
 148 -                                p->n_rval = FP;
 149 -                                p = block(PLUS, p, bcon(ARGINIT/SZCHAR+(n+i)*4),
 150 -                                    INT, 0, MKSUE(INT));
 151 -                                p = block(UMUL, p, NIL, INT, 0, MKSUE(INT));
 152 -                                p = buildtree(ASSIGN, p, q);
 153 -                                ecomp(p);
 154 -                        }
 155 -                } else if (n + sz <= nargregs) {
 156 -                        if (xtemps) {
 157 -                                p = tempnode(0, sp[i]->stype,
 158 -                                    sp[i]->sdf, sp[i]->ssue);
 159 -                                spname = sp[i];
 160 -                                q = block(REG, NIL, NIL,
 161 -                                    sp[i]->stype, sp[i]->sdf, sp[i]->ssue);
 162 -                                q->n_rval = sz == 2 ? A0A1 + n : A0 + n;
 163 -                                p = buildtree(ASSIGN, p, q);
 164 -                                sp[i]->soffset = p->n_left->n_lval;
 165 -                                sp[i]->sflags |= STNODE;
 166 -                        } else {
 167 -                                // sp[i]->soffset += ARGINIT;
 168 -                                spname = sp[i];
 169 -                                q = block(REG, NIL, NIL,
 170 -                                    sp[i]->stype, sp[i]->sdf, sp[i]->ssue);
 171 -                                q->n_rval = sz == 2 ? A0A1 + n : A0 + n;
 172 -                                p = buildtree(ASSIGN, buildtree(NAME, 0, 0), q);
 173 -                        }
 174 -                        ecomp(p);
 175 -                } else {
 176 -                        // sp[i]->soffset += ARGINIT;
 177 -                        if (xtemps) {
 178 -                                /* put stack args in temps if optimizing */
 179 -                                spname = sp[i];
 180 -                                p = tempnode(0, sp[i]->stype,
 181 -                                    sp[i]->sdf, sp[i]->ssue);
 182 -                                p = buildtree(ASSIGN, p, buildtree(NAME, 0, 0));
 183 -                                sp[i]->soffset = p->n_left->n_lval;
 184 -                                sp[i]->sflags |= STNODE;
 185 -                                ecomp(p);
 186 -                        }
 187 -               
 188 -                }
 189 -                n += sz;
 190 -        }
  287+        /* if saveallargs, save the rest of the args onto the stack */
  288+        if (!saveallargs)
  289+                return;
  290+        while (reg <= lastreg) {
  291+                NODE *p, *q;
  292+                int off = ARGINIT/SZINT + (reg - A0);
  293+                q = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
  294+                q->n_rval = reg++;
  295+                p = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
  296+                p->n_rval = FP;
  297+                p = block(PLUS, p, bcon(4*off), INT, 0, MKSUE(INT));
  298+                p = block(UMUL, p, NIL, INT, 0, MKSUE(INT));
  299+                p = buildtree(ASSIGN, p, q);
  300+                ecomp(p);
  301+        }
191302 
 192303 }
 193304 
     
 !
279390         return 0;
 280391 }
 281392 
<>282 -static void
 283 -moveargs(NODE **p, int *regp)
  393+
  394+/* setup call stack with a structure */
  395+/* called from moveargs() */
  396+static NODE *
  397+movearg_struct(NODE *p, NODE *parent, int *regp)
284398 {
<>285 -        NODE *r = *p;
 286 -        NODE *t, *q;
 287 -        int sz, tsz, n;
 288 -        int regnum;
  399+        int reg = *regp;
  400+        NODE *q, *t, *r;
  401+        int navail;
  402+        int off;
  403+        int num;
  404+        int sz;
  405+        int i;
289406 
<>290 -        if (r->n_op == CM) {
 291 -                moveargs(&r->n_left, regp);
 292 -                p = &r->n_right;
 293 -                r = r->n_right;
 294 -        }
  407+        navail = nargregs - (reg - A0);
  408+        sz = tsize(p->n_type, p->n_df, p->n_sue) / SZINT;
  409+        num = sz > navail ? navail : sz;
295410 
<>296 -        regnum = *regp;
 297 -        sz = tsize(r->n_type, r->n_df, r->n_sue) / SZINT;
  411+        if (p != parent)
  412+                q = parent->n_left;
  413+        else
  414+                q = NULL;
298415 
<>299 -        if (regnum <= A0 + nargregs &&
 300 -            (r->n_type == STRTY || r->n_type == UNIONTY)) {
 301 -                /* copy structure into registers */
 302 -                n = regnum - A0;
 303 -                tsz = sz > nargregs - n ? nargregs - n : sz;
 304 -#if 0
 305 -                printf("[should copy %d words into registers]\n", tsz);
 306 -                while (tsz > 0) {
 307 -                        q = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
 308 -                        q->n_rval = regnum + tsz;
 309 -                        q = buildtree(ASSIGN, q, r);
 310 -                        tsz--;
 311 -                        if (tsz > 0)
 312 -                                r = block(CM, q, NIL, INT, 0, MKSUE(INT));
 313 -                        else
 314 -                                r = q;
 315 -                }
 316 -#endif
 317 -                q = r;
 318 -                t = r;
  416+        /* copy structure into registers */
  417+        for (i = 0; i < num; i++) {
  418+                t = tcopy(p->n_left);
  419+                t = block(SCONV, t, NIL, PTR+INT, 0, MKSUE(PTR+INT));
  420+                t = block(PLUS, t, bcon(4*i), PTR+INT, 0, MKSUE(PTR+INT));
  421+                t = buildtree(UMUL, t, NIL);
319422 
<>320 -        } else if (regnum + sz <= A0 + nargregs &&
 321 -                (r->n_type != STRTY && r->n_type != UNIONTY)) {
 322 -                t = block(REG, NIL, NIL, r->n_type, r->n_df, r->n_sue);
 323 -                switch(r->n_type) {
 324 -                case DOUBLE:
 325 -                case LDOUBLE:
 326 -                        t->n_rval = regnum + F0;
 327 -                        break;
 328 -                case LONGLONG:
 329 -                case ULONGLONG:
 330 -                        t->n_rval = regnum + A0A1;
 331 -                        break;
 332 -                default:
 333 -                        t->n_rval = regnum;
 334 -                }
 335 -                t = buildtree(ASSIGN, t, r);
 336 -        } else {
 337 -                if (r->n_op == STARG)
 338 -                        t = r;
  423+                r = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
  424+                r->n_rval = reg++;
  425+
  426+                r = buildtree(ASSIGN, r, t);
  427+                if (q == NULL)
  428+                        q = r;
339429                 else
<>340 -                        t = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_sue);
  430+                        q = block(CM, q, r, INT, 0, MKSUE(INT));
341431         }
<> 432+        off = ARGINIT/SZINT + nargregs;
  433+        for (i = num; i < sz; i++) {
  434+                t = tcopy(p->n_left);
  435+                t = block(SCONV, t, NIL, PTR+INT, 0, MKSUE(PTR+INT));
  436+                t = block(PLUS, t, bcon(4*i), PTR+INT, 0, MKSUE(PTR+INT));
  437+                t = buildtree(UMUL, t, NIL);
342438 
<>343 -        *p = t;
 344 -        *regp += sz;
  439+                r = block(REG, NIL, NIL, INT, 0, MKSUE(INT));
  440+                r->n_rval = FP;
  441+                r = block(PLUS, r, bcon(4*off++), INT, 0, MKSUE(INT));
  442+                r = block(UMUL, r, NIL, INT, 0, MKSUE(INT));
  443+
  444+                r = buildtree(ASSIGN, r, t);
  445+                if (q == NULL)
  446+                        q = r;
  447+                else
  448+                        q = block(CM, q, r, INT, 0, MKSUE(INT));
  449+        }
  450+        tfree(p);
  451+
  452+        if (parent->n_op == CM) {
  453+                parent->n_left = q->n_left;
  454+                t = q;
  455+                q = q->n_right;
  456+                nfree(t);
  457+        }
  458+
  459+        *regp = reg;
  460+        return q;
345461 }
 346462 
<> 463+/* setup call stack with 64-bit argument */
  464+/* called from moveargs() */
  465+static NODE *
  466+movearg_64bit(NODE *p, int *regp)
  467+{
  468+        int reg = *regp;
  469+        NODE *q;
  470+
  471+        /* alignment */
  472+        ++reg;
  473+        reg &= ~1;
  474+
  475+        q = block(REG, NIL, NIL, p->n_type, p->n_df, p->n_sue);
  476+        q->n_rval = A0A1 + (reg++ - A0);
  477+        q = buildtree(ASSIGN, q, p);
  478+
  479+        *regp = reg;
  480+        return q;
  481+}
  482+
  483+/* setup call stack with 32-bit argument */
  484+/* called from moveargs() */
  485+static NODE *
  486+movearg_32bit(NODE *p, int *regp)
  487+{
  488+        int reg = *regp;
  489+        NODE *q;
  490+
  491+        q = block(REG, NIL, NIL, p->n_type, p->n_df, p->n_sue);
  492+        q->n_rval = reg++;
  493+        q = buildtree(ASSIGN, q, p);
  494+
  495+        *regp = reg;
  496+        return q;
  497+}
  498+
  499+static NODE *
  500+moveargs(NODE *p, int *regp)
  501+{
  502+        NODE *r, **rp;
  503+        int lastreg;
  504+        int reg;
  505+
  506+        if (p->n_op == CM) {
  507+                p->n_left = moveargs(p->n_left, regp);
  508+                r = p->n_right;
  509+                rp = &p->n_right;
  510+        } else {
  511+                r = p;
  512+                rp = &p;
  513+        }
  514+
  515+        lastreg = A0 + nargregs - 1;
  516+        reg = *regp;
  517+
  518+        if (reg > lastreg && r->n_op != STARG)
  519+                *rp = block(FUNARG, r, NIL, r->n_type, r->n_df, r->n_sue);
  520+        else if (r->n_op == STARG) {
  521+                *rp = movearg_struct(r, p, regp);
  522+        } else if (DEUNSIGN(r->n_type) == LONGLONG || r->n_type == DOUBLE ||
  523+            r->n_type == LDOUBLE)
  524+                *rp = movearg_64bit(r, regp);
  525+        else
  526+                *rp = movearg_32bit(r, regp);
  527+
  528+        return p;
  529+}
  530+
347531 /*
 348532  * Called with a function call with arguments as argument.
 349533  * This is done early in buildtree() and only done once.
     
 !
358542         l = p->n_left;
 359543         r = p->n_right;
 360544 
<> 545+        /*
  546+         * if returning a structure, make the first argument
  547+         * a hidden pointer to return structure.
  548+         */
361549         ty = DECREF(l->n_type);
 362550         if (ty == STRTY+FTN || ty == UNIONTY+FTN) {
 363551                 ty = DECREF(l->n_type) - FTN;
     
 !
374562                 }
 375563         }
 376564 
<>377 -        moveargs(&p->n_right, &regnum);
  565+        p->n_right = moveargs(p->n_right, &regnum);
  566+
<_378567         return p;
 379568 }
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-10-31 11:27 +0100