Quick Search:

Mode

Context

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

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.10
 
1.11
 
MAIN:ragge:20090619130305
 
code.c
_>3030 
 3131 # include "pass1.h"
 3232 
<>33 -static int nsse, ngpr, nrsp;
  33+static int nsse, ngpr, nrsp, rsaoff;
3434 enum { INTEGER = 1, INTMEM, SSE, SSEMEM, X87, STRREG, STRMEM };
 3535 static const int argregsi[] = { RDI, RSI, RDX, RCX, R08, R09 };
<> 36+/*
  37+ * The Register Save Area looks something like this.
  38+ * It is put first on stack with fixed offsets.
  39+ * struct {
  40+ *      long regs[6];
  41+ *      double xmm[8][2]; // 16 byte in width
  42+ * };
  43+ */
  44+#define RSASZ           (6*SZLONG+8*2*SZDOUBLE)
  45+#define RSALONGOFF(x)   (RSASZ-(x)*SZLONG)
  46+#define RSADBLOFF(x)    ((8*2*SZDOUBLE)-(x)*SZDOUBLE*2)
  47+/* va_list */
  48+#define VAARGSZ         (SZINT*2+SZPOINT(CHAR)*2)
  49+#define VAGPOFF(x)      (x)
  50+#define VAFPOFF(x)      (x-SZINT)
  51+#define VAOFA(x)        (x-SZINT-SZINT)
  52+#define VARSA(x)        (x-SZINT-SZINT-SZPOINT(0))
3653 
 3754 int lastloc = -1;
 3855 
 3956 static int argtyp(TWORD t, union dimfun *df, struct suedef *sue);
<> 57+static NODE *movtomem(NODE *p, int off);
4058 
 4159 /*
 4260  * Define everything needed to print out some data (or text).
     
 !
134152 void
 135153 bfcode(struct symtab **s, int cnt)
 136154 {
<> 155+        union arglist *al;
137156         struct symtab *sp;
 138157         NODE *p, *r;
 139158         int i, rno, typ;
     
 !
185204                         cerror("bfcode: %d", typ);
 186205                 }
 187206         }
<> 207+
  208+        /* Check if there are varargs */
  209+        if (cftnsp->sdf == NULL || cftnsp->sdf->dfun == NULL)
  210+                return; /* no prototype */
  211+        al = cftnsp->sdf->dfun;
  212+        for (; al->type != TELLIPSIS; al++) {
  213+                if (al->type == TNULL)
  214+                        return;
  215+                if (al->type == STRTY || ISARY(al->type))
  216+                        al++;
  217+        }
  218+
  219+        /* fix stack offset */
  220+        SETOFF(autooff, ALMAX);
  221+
  222+        /* Save reg arguments in the reg save area */
  223+        p = NIL;
  224+        for (i = ngpr; i < 6; i++) {
  225+                r = block(REG, NIL, NIL, LONG, 0, MKSUE(LONG));
  226+                regno(r) = argregsi[i];
  227+                r = movtomem(r, -RSALONGOFF(i)-autooff);
  228+                p = (p == NIL ? r : block(COMOP, p, r, INT, 0, MKSUE(INT)));
  229+        }
  230+        for (i = nsse; i < 8; i++) {
  231+                r = block(REG, NIL, NIL, DOUBLE, 0, MKSUE(DOUBLE));
  232+                regno(r) = i + XMM0;
  233+                r = movtomem(r, -RSADBLOFF(i)-autooff);
  234+                p = (p == NIL ? r : block(COMOP, p, r, INT, 0, MKSUE(INT)));
  235+        }
  236+        autooff += RSASZ;
  237+        rsaoff = autooff;
  238+
  239+        ecomp(p);
188240 }
 189241 
 190242 
     
 !
208260         printf("\t.ident \"PCC: %s (%s)\"\n\t.end\n", PACKAGE_STRING, OS);
 209261 }
 210262 
<> 263+/*
  264+ * Varargs stuff:
  265+ * The ABI says that va_list should be declared as this typedef.
  266+ * We handcraft it here and then just reference it.
  267+ *
  268+ * typedef struct {
  269+ *      unsigned int gp_offset;
  270+ *      unsigned int fp_offset;
  271+ *      void *overflow_arg_area;
  272+ *      void *reg_save_area;
  273+ * } __builtin_va_list[1];
  274+ */
  275+static char *gp_offset, *fp_offset, *overflow_arg_area, *reg_save_area;
211276 void
 212277 bjobcode()
 213278 {
<> 279+        struct rstack *rp;
  280+        NODE *p, *q;
  281+        char *c;
  282+
  283+        gp_offset = addname("gp_offset");
  284+        fp_offset = addname("fp_offset");
  285+        overflow_arg_area = addname("overflow_arg_area");
  286+        reg_save_area = addname("reg_save_area");
  287+
  288+        rp = bstruct(NULL, STNAME, NULL);
  289+        p = block(NAME, NIL, NIL, UNSIGNED, 0, MKSUE(UNSIGNED));
  290+        soumemb(p, gp_offset, 0);
  291+        soumemb(p, fp_offset, 0);
  292+        p->n_type = VOID+PTR;
  293+        p->n_sue = MKSUE(VOID);
  294+        soumemb(p, overflow_arg_area, 0);
  295+        soumemb(p, reg_save_area, 0);
  296+        nfree(p);
  297+        q = dclstruct(rp);
  298+        c = addname("__builtin_va_list");
  299+        p = block(LB, bdty(NAME, c), bcon(1), INT, 0, MKSUE(INT));
  300+        p = tymerge(q, p);
  301+        p->n_sp = lookup(c, 0);
  302+        defid(p, TYPEDEF);
  303+        nfree(q);
  304+        nfree(p);
214305 }
 215306 
 216307 static NODE *
<> 308+mkstkref(int off, TWORD typ)
  309+{
  310+        NODE *p;
  311+
  312+        p = block(REG, NIL, NIL, PTR|typ, 0, MKSUE(LONG));
  313+        regno(p) = FPREG;
  314+        return buildtree(PLUS, p, bcon(off/SZCHAR));
  315+}
  316+
  317+NODE *
  318+amd64_builtin_stdarg_start(NODE *f, NODE *a)
  319+{
  320+        NODE *p, *r;
  321+
  322+        /* check num args and type */
  323+        if (a == NULL || a->n_op != CM || a->n_left->n_op == CM ||
  324+            !ISPTR(a->n_left->n_type))
  325+                goto bad;
  326+
  327+        /* use the values from the function header */
  328+        p = a->n_left;
  329+        r = buildtree(ASSIGN, structref(ccopy(p), STREF, reg_save_area),
  330+            mkstkref(-rsaoff, VOID));
  331+        r = buildtree(COMOP, r,
  332+            buildtree(ASSIGN, structref(ccopy(p), STREF, overflow_arg_area),
  333+            mkstkref(ARGINIT, VOID)));
  334+        r = buildtree(COMOP, r,
  335+            buildtree(ASSIGN, structref(ccopy(p), STREF, gp_offset),
  336+            bcon(ngpr*(SZLONG/SZCHAR))));
  337+        r = buildtree(COMOP, r,
  338+            buildtree(ASSIGN, structref(ccopy(p), STREF, fp_offset),
  339+            bcon(nsse*(SZDOUBLE*2/SZCHAR)+48)));
  340+
  341+        tfree(f);
  342+        tfree(a);
  343+        return r;
  344+bad:
  345+        uerror("bad argument to __builtin_stdarg_start");
  346+        return bcon(0);
  347+}
  348+
  349+NODE *
  350+amd64_builtin_va_arg(NODE *f, NODE *a) { cerror("amd64_builtin_va_arg"); return NULL; }
  351+
  352+NODE *
  353+amd64_builtin_va_end(NODE *f, NODE *a) { cerror("amd64_builtin_va_end"); return NULL; }
  354+
  355+NODE *
  356+amd64_builtin_va_copy(NODE *f, NODE *a) { cerror("amd64_builtin_va_copy"); return NULL; }
  357+
  358+static NODE *
217359 movtoreg(NODE *p, int rno)
 218360 {
 219361         NODE *r;
     
 !
233375         s.sdf = p->n_df;
 234376         s.ssue = p->n_sue;
 235377         s.soffset = off;
<> 378+        s.sclass = AUTO;
236379 
 237380         l = block(REG, NIL, NIL, PTR+STRTY, 0, 0);
 238381         l->n_lval = 0;
<>239 -        regno(l) = STKREG;
  382+        regno(l) = FPREG;
<_240383 
 241384         r = block(NAME, NIL, NIL, p->n_type, p->n_df, p->n_sue);
 242385         r->n_sp = &s;
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-22 16:39 +0100