From ed47a54958f5bd48dc364d4a0f77f778768696bb Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 5 Jun 2023 10:28:57 +0200 Subject: strlits --- ir.c | 24 +++++++++------ ir.h | 13 ++++---- irdump.c | 57 ++++++++++++++++++++++++++++++++--- parse.c | 6 ++-- test.c | 97 ------------------------------------------------------------ test/hello.c | 5 ++++ test/test.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/test2.c | 23 ++++++++++++++ test2.c | 23 -------------- 9 files changed, 205 insertions(+), 140 deletions(-) delete mode 100644 test.c create mode 100644 test/hello.c create mode 100644 test/test.c create mode 100644 test/test2.c delete mode 100644 test2.c diff --git a/ir.c b/ir.c index cb4cc27..2f1c622 100644 --- a/ir.c +++ b/ir.c @@ -4,12 +4,12 @@ uchar type2cls[NTYPETAG]; uchar cls2siz[KF8+1]; const uchar siz2intcls[] = { [1] = KI4, [2] = KI4, [4] = KI4, [8] = KI8 }; -static vec_of(struct irdat) dats; struct instr instrtab[1<<14]; static int ninstr; static int instrfreelist; struct calltab calltab; struct phitab phitab; +struct dattab dattab; void irinit(struct function *fn) @@ -59,14 +59,6 @@ addcon(const struct xcon *con) } } -/* union ref -adddat(struct function *fn, const struct irdat *dat) -{ - assert(dats.n < 1u<<29); - vpush(&dats, *dat); - return mkref(RDAT, dats.n - 1); -} */ - static void targwrite2(uchar *d, ushort x) { @@ -163,6 +155,19 @@ mksymref(struct function *fn, const char *s) return mkref(RXCON, addcon(&con)); } +union ref +mkdatref(struct function *fn, uint siz, uint align, const void *bytes, uint n) +{ + struct irdat dat = { align, 0, siz }; + if (siz <= 8) memcpy(dat.sdat, bytes, n < siz ? n : siz); + else { + while (((uchar *)bytes)[n-1] == 0) --n; /* nip trailing zeroes */ + vpushn(&dat.dat, bytes, n); + } + vpush(&dattab, dat); + return mkref(RDAT, dattab.n - 1); +} + struct instr mkalloca(uint siz, uint align) { @@ -220,6 +225,7 @@ insertinstr(struct block *blk, int idx, struct instr ins) else { assert(idx >= 0 && idx < blk->ins.n); vpush_((void **)&blk->ins.p, &blk->ins._cap, &blk->ins.n, sizeof *blk->ins.p); + vresize(&blk->ins, blk->ins.n); for (int i = blk->ins.n++; i > idx; --i) blk->ins.p[i] = blk->ins.p[i - 1]; blk->ins.p[idx] = new; diff --git a/ir.h b/ir.h index a08bbce..4cce899 100644 --- a/ir.h +++ b/ir.h @@ -65,12 +65,13 @@ struct phi { enum refkind { RNONE, - RTMP, /* reference to another instruction's result */ - RPARAM, /* function param */ - RICON, /* small integer constants */ - RXCON, /* other constants (incl. external symbols) */ + RTMP, /* reference to another instruction's result */ + RPARAM, /* function param */ + RICON, /* small integer constants */ + RXCON, /* other constants (incl. external symbols) */ + RDAT, /* reference to irdat */ RMORE, /* reference to extra data for Ocall and Ophi */ - RREG, /* machine register */ + RREG, /* machine register */ }; union ref { @@ -163,6 +164,7 @@ extern const uchar siz2intcls[]; extern struct instr instrtab[]; extern struct calltab {vec_of(struct call);} calltab; extern struct phitab {vec_of(struct phi);} phitab; +extern struct dattab {vec_of(struct irdat);} dattab; #define NOREF ((union ref) {0}) #define mkref(t, x) ((union ref) {{ (t), (x) }}) #define mkzerocon() ((union ref) {{ RICON, 0 }}) @@ -173,6 +175,7 @@ union irtype mkirtype(union type); union ref mkintcon(struct function *, enum irclass, vlong); union ref mkfltcon(struct function *, enum irclass, double); union ref mksymref(struct function *, const char *); +union ref mkdatref(struct function *, uint siz, uint align, const void *, uint n); struct instr mkalloca(uint siz, uint align); void conputdat(struct irdat *, uint off, enum typetag t, const void *dat); union ref mkcallarg(struct function *, bool sret, uint narg, int vararg, union ref *, union irtype *); diff --git a/irdump.c b/irdump.c index aa815e4..1e5302e 100644 --- a/irdump.c +++ b/irdump.c @@ -1,6 +1,49 @@ #include "ir.h" extern struct xcon conht[]; +static int nextdat; + +#define aisprint(c) in_range(c, ' ', '~') + +static void +pridat(const struct irdat *dat) +{ + efmt("dat ^%d(align %d, size %d):\n\t", dat - dattab.p, dat->align, dat->siz); + assert(!dat->syms); + if (dat->siz <= 8) { + efmt("b "); + for (int i = 0; i < dat->siz; ++i) + efmt("%d,", dat->sdat[i]); + } else { + enum { + MINZERO = 4, + MAXLINE = 60, + }; + int npri = 0; + int nzero = dat->siz - dat->dat.n; + int strbegin = 0, nstr = 0; + for (int i = 0; i < dat->dat.n + (nzero & -(nzero <= MINZERO)); ++i) { + int c = i < dat->dat.n ? dat->dat.p[i] : 0; + if (npri > MAXLINE) { + npri = 0; + efmt("\n\t"); + } + if (aisprint(c)) { + if (!nstr++) strbegin = i; + } else { + if (nstr) { + npri += efmt("asc %'S,", dat->dat.p+strbegin, nstr); + nstr = 0; + efmt("b "); + } + npri += efmt("%d,", c); + } + } + if (nstr) npri += efmt("asc %'S,", dat->dat.p+strbegin, nstr); + if ((nzero -= MINZERO) > 0) efmt("z %d", nzero); + } + efmt("\n"); +} static const char *clsname[] = { "?", "i4", "i8", "ptr", "f4", "f8" @@ -51,6 +94,9 @@ dumpref(enum op o, union ref ref) default: assert(0); } break; + case RDAT: + efmt("$^%d", ref.i); + break; case RMORE: if (o == Ocall || o == Ointrin) { struct call *call = &calltab.p[ref.idx]; @@ -74,7 +120,7 @@ dumpref(enum op o, union ref ref) struct phi *phi = &phitab.p[ref.idx]; for (int i = 0; i < phi->n; ++i) { if (i > 0) efmt(", "); - efmt("[.L%d ", phi->blk[i]->id); + efmt("[@%d ", phi->blk[i]->id); dumpref(0, phi->ref[i]); efmt("]"); } @@ -120,7 +166,7 @@ dumpblk(struct function *fn, struct block *blk) { static const char *jnames[] = { 0, "b", "ret" }; int i; - efmt(" .L%d:\n", blk->id); + efmt(" @%d:\n", blk->id); for (i = 0; i < blk->phi.n; ++i) { dumpinst(&instrtab[blk->phi.p[i]]); } @@ -138,8 +184,8 @@ dumpblk(struct function *fn, struct block *blk) dumpref(0, blk->jmp.arg[i]); } if (i && blk->s1) efmt(", "); - if (blk->s1 && blk->s2) efmt(".L%d, .L%d", blk->s1->id, blk->s2->id); - else if (blk->s1) efmt(".L%d", blk->s1->id); + if (blk->s1 && blk->s2) efmt("@%d, @%d", blk->s1->id, blk->s2->id); + else if (blk->s1) efmt("@%d", blk->s1->id); efmt("\n"); } @@ -148,6 +194,9 @@ irdump(struct function *fn, const char *fname) { struct block *blk; + /* print datas that have never been printed before */ + while (nextdat < dattab.n) pridat(&dattab.p[nextdat++]); + efmt("function %s : %ty\n", fname, fn->fnty); if (fn->abiarg || fn->nabiret) { efmt("abi: ("); diff --git a/parse.c b/parse.c index 4ed63c7..0dd984d 100644 --- a/parse.c +++ b/parse.c @@ -977,7 +977,6 @@ exprvalue(struct function *fn, const struct expr *ex) { return compileexpr(fn, ex, /*discard*/ 0); } - static inline void expreffects(struct function *fn, const struct expr *ex) { @@ -1025,6 +1024,8 @@ expraddr(struct function *fn, const struct expr *ex) assert(0); } break; + case ESTRLIT: + return mkdatref(fn, ex->s.n+1, /*align*/ 1, ex->s.p, ex->s.n); case EDEREF: return exprvalue(fn, ex->sub); case EGETF: @@ -1352,7 +1353,8 @@ compileexpr(struct function *fn, const struct expr *ex, bool discard) sub = ex->sub; if (ex->ty.t != TYVOID && !isscalar(ex->ty)) - /* fn & array designators evaluate to their address; so do aggregates for the purpose of code generation */ + /* fn & array designators evaluate to their address; + * so do aggregates for the purpose of code generation */ return expraddr(fn, ex); switch (ex->t) { case ENUMLIT: diff --git a/test.c b/test.c deleted file mode 100644 index 40b59e6..0000000 --- a/test.c +++ /dev/null @@ -1,97 +0,0 @@ -/* coment */ - -#if 1+1 < (-2*'a') -wawa -#elif 9<<1 -#define wow 3 -#else -boop -#endif - -#define NULL ((void *)0) -int glob [ wow+wow]; - -struct foo { - int x, y, z; -}; - -struct v2f { double x, y; }; -struct big { int x[10]; }; - -struct v2f add(struct v2f a, struct v2f b, struct big B, struct { char c; } small, void *prt) { - struct v2f r; - r.y = a.y + b.y; - return r; -} - -struct pair { - long x, y; -}; - -struct pair pair(long x, long y) { - struct pair p; - p.x = x; - p.y = y; - return p; -} - -struct quad { - long x, y, z, w; -}; - -struct quad quad(long x, long y, long z, long w) { - struct quad q; - q.x = x, q.y = y, q.z = z, q.w = w; - return q; -} - -void silly(struct pair *p, struct quad *q) -{ - *p = pair(1,2); - *q = quad(1,2,3,4); -} - -void test2(struct big *b) { - struct big s = *b; - extern void h(int, struct big, float); - s.x[5] += 2; - h(0, s, 0); -} - -struct f2 { float f,g; }; -struct f2 f2test(struct f2 *r) { - return *r; -} - -void fill(char *p, int c, unsigned long n) -{ - int t; - if (n) do t = *p++ = c; while (--n); -} - -void zero(void *p, unsigned long n) { fill(p,0,n); } - -enum ball { - neg = -1, - Zero, - Two = 2, - Three, - One = Zero + 1, - X = 2147483647, - Y, - Z, - W = ~0ull -}; -enum ball x; - -_Bool t(int t) -{ - return t; -} - -struct f{ - union { int x,y;} ; - char flex[]; -}; - -// diff --git a/test/hello.c b/test/hello.c new file mode 100644 index 0000000..98a93a0 --- /dev/null +++ b/test/hello.c @@ -0,0 +1,5 @@ +int printf(const char *, ...); + +int main() { + printf("hello world\n"); +} diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..40b59e6 --- /dev/null +++ b/test/test.c @@ -0,0 +1,97 @@ +/* coment */ + +#if 1+1 < (-2*'a') +wawa +#elif 9<<1 +#define wow 3 +#else +boop +#endif + +#define NULL ((void *)0) +int glob [ wow+wow]; + +struct foo { + int x, y, z; +}; + +struct v2f { double x, y; }; +struct big { int x[10]; }; + +struct v2f add(struct v2f a, struct v2f b, struct big B, struct { char c; } small, void *prt) { + struct v2f r; + r.y = a.y + b.y; + return r; +} + +struct pair { + long x, y; +}; + +struct pair pair(long x, long y) { + struct pair p; + p.x = x; + p.y = y; + return p; +} + +struct quad { + long x, y, z, w; +}; + +struct quad quad(long x, long y, long z, long w) { + struct quad q; + q.x = x, q.y = y, q.z = z, q.w = w; + return q; +} + +void silly(struct pair *p, struct quad *q) +{ + *p = pair(1,2); + *q = quad(1,2,3,4); +} + +void test2(struct big *b) { + struct big s = *b; + extern void h(int, struct big, float); + s.x[5] += 2; + h(0, s, 0); +} + +struct f2 { float f,g; }; +struct f2 f2test(struct f2 *r) { + return *r; +} + +void fill(char *p, int c, unsigned long n) +{ + int t; + if (n) do t = *p++ = c; while (--n); +} + +void zero(void *p, unsigned long n) { fill(p,0,n); } + +enum ball { + neg = -1, + Zero, + Two = 2, + Three, + One = Zero + 1, + X = 2147483647, + Y, + Z, + W = ~0ull +}; +enum ball x; + +_Bool t(int t) +{ + return t; +} + +struct f{ + union { int x,y;} ; + char flex[]; +}; + +// diff --git a/test/test2.c b/test/test2.c new file mode 100644 index 0000000..7d39164 --- /dev/null +++ b/test/test2.c @@ -0,0 +1,23 @@ +typedef struct v2d { double x,y; } v2d; + + + +void addp(v2d *a, const v2d *b) +{ + a->x += b->x; + a->y += b->y; +} + +v2d add(v2d a, v2d b) +{ + addp(&a, &b); + return a; +} + +short s(int a, int b) { + return a + b; +} + +int i() { + return s(1,2); +} diff --git a/test2.c b/test2.c deleted file mode 100644 index 7d39164..0000000 --- a/test2.c +++ /dev/null @@ -1,23 +0,0 @@ -typedef struct v2d { double x,y; } v2d; - - - -void addp(v2d *a, const v2d *b) -{ - a->x += b->x; - a->y += b->y; -} - -v2d add(v2d a, v2d b) -{ - addp(&a, &b); - return a; -} - -short s(int a, int b) { - return a + b; -} - -int i() { - return s(1,2); -} -- cgit v1.2.3