diff options
| -rw-r--r-- | amd64/isel.c | 10 | ||||
| -rw-r--r-- | c/c.c | 2 | ||||
| -rw-r--r-- | ir/dump.c | 67 | ||||
| -rw-r--r-- | ir/ir.c | 4 | ||||
| -rw-r--r-- | ir/ir.h | 3 |
5 files changed, 61 insertions, 25 deletions
diff --git a/amd64/isel.c b/amd64/isel.c index 86eeb56..a010b90 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -73,14 +73,18 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi) /* float immediates & 64bit immediates are loaded from memory */ uchar data[8]; uint ksiz = cls2siz[con->cls]; + union type ctype; if (con->cls <= KPTR && in_range(ins->op, Ocopy, Omove)) /* in this case we can use movabs */ return; - if (con->cls != KF4) wr64le(data, con->i); - else { + if (con->cls != KF4) { + wr64le(data, con->i); + ctype = mktype(con->cls == KF8 ? TYDOUBLE : TYVLONG); + } else { union { float f; int i; } pun = { con->f }; wr32le(data, pun.i); + ctype = mktype(TYFLOAT); } - *r = mkdatref(NULL, ksiz, /*align*/ksiz, data, ksiz, /*deref*/1); + *r = mkdatref(NULL, ctype, ksiz, /*align*/ksiz, data, ksiz, /*deref*/1); if (&ins->l != r && ins->l.t == RADDR) { /* can't use memory arg in rhs if lhs is memory */ *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, con->cls, *r)); @@ -2658,7 +2658,7 @@ expraddr(struct function *fn, const struct expr *ex) break; case ESTRLIT: /* XXX endian for wide strs */ - return mkdatref(NULL, typesize(ex->ty), typealign(ex->ty), ex->s.p, ex->s.n * typesize(typechild(ex->ty)), /*deref*/0); + return mkdatref(NULL, ex->ty, typesize(ex->ty), typealign(ex->ty), ex->s.p, ex->s.n * typesize(typechild(ex->ty)), /*deref*/0); case EDEREF: return exprvalue(fn, ex->sub); case EGETF: @@ -1,10 +1,27 @@ #include "ir.h" #include "../obj/obj.h" +#include "../endian.h" static int nextdat; static struct wbuf *out; +static bool +prilitdat(const struct irdat *dat, const char *prefix) +{ + uchar *p = (dat->section == Sdata ? objout.data.p : objout.rodata.p) + dat->off; + if (dat->ctype.t == TYARRAY && typechild(dat->ctype).t == TYCHAR && dat->siz-1 < 60 && p[dat->siz-1] == 0) { + bfmt(out, "%s%'S", prefix, p, dat->siz-1); + } else if (dat->ctype.t == TYFLOAT) { + bfmt(out, "%s%f", prefix, rdf32targ(p)); + } else if (dat->ctype.t == TYDOUBLE) { + bfmt(out, "%s%f", prefix, rdf64targ(p)); + } else if (dat->ctype.t == TYVLONG) { + bfmt(out, "%s0x%lx", prefix, rd64targ(p)); + } else return 0; + return 1; +} + static void pridat(const struct irdat *dat) { @@ -16,25 +33,27 @@ pridat(const struct irdat *dat) int npri = 0; int strbegin = 0, nstr = 0; assert(dat->section == Sdata || dat->section == Srodata); - bfmt(out, "%s %y(align %d, size %d):\n\t", dat->section == Sdata ? "data" : "rodata", dat->name, dat->align, dat->siz); - for (int i = 0; i < dat->siz; ++i) { - int c = p[i]; - if (npri > MAXLINE) { - npri = 0; - bfmt(out, "\n\t"); - } - if (aisprint(c)) { - if (!nstr++) strbegin = i; - } else { - if (nstr) { - npri += bfmt(out, "asc %'S,", p+strbegin, nstr); - nstr = 0; - bfmt(out, "b "); + bfmt(out, "%s %ty %y(align %d, size %d):\n\t", dat->section == Sdata ? "data" : "rodata", dat->ctype, dat->name, dat->align, dat->siz); + if (!prilitdat(dat, "lit: ")) { + for (int i = 0; i < dat->siz; ++i) { + int c = p[i]; + if (npri > MAXLINE) { + npri = 0; + bfmt(out, "\n\t"); + } + if (aisprint(c)) { + if (!nstr++) strbegin = i; + } else { + if (nstr) { + npri += bfmt(out, "asc %'S,", p+strbegin, nstr); + nstr = 0; + bfmt(out, "b "); + } + npri += bfmt(out, "%d,", c); } - npri += bfmt(out, "%d,", c); } + if (nstr) npri += bfmt(out, "asc %'S,", p+strbegin, nstr); } - if (nstr) npri += bfmt(out, "asc %'S,", p+strbegin, nstr); bfmt(out, "\n"); } @@ -90,8 +109,20 @@ dumpref(enum op o, union ref ref) case RXCON: con = &conht[ref.i]; if (con->deref) bfmt(out, "*["); - if (con->issym || con->isdat) bfmt(out, "$%y", xcon2sym(ref.i)); - else switch (con->cls) { + if (con->issym || con->isdat) { + bfmt(out, "$%y", xcon2sym(ref.i)); + if (con->isdat) { + struct irdat *dat = &dattab.p[con->dat]; + if (prilitdat(dat, " (= ")) { + if (isscalar(dat->ctype)) { + struct wbuf tmp = MEMBUF((char [1]){0}, 1); + bfmt(&tmp, "%ty", dat->ctype); + ioputc(out, *tmp.buf); + } + ioputc(out, ')'); + } + } + } else switch (con->cls) { case KI4: bfmt(out, "%d", (int)con->i); break; case KI8: bfmt(out, "%ld", con->i); break; case KPTR: bfmt(out, "%'lx", con->i); break; @@ -144,9 +144,9 @@ mksymref(const char *s) } union ref -mkdatref(const char *name, uint siz, uint align, const void *bytes, uint n, bool deref) +mkdatref(const char *name, union type ctype, uint siz, uint align, const void *bytes, uint n, bool deref) { - struct irdat dat = { .align = align, .siz = siz, .name = name, .section = Srodata }; + struct irdat dat = { .ctype = ctype, .align = align, .siz = siz, .name = name, .section = Srodata }; assert(n <= siz && siz && align); if (!name) { @@ -19,6 +19,7 @@ union irtype { struct irdat { uchar align : 6, globl : 1; uchar section; + union type ctype; uint siz; uint off; const char *name; @@ -240,7 +241,7 @@ union ref mkfltcon(enum irclass, double); #define intconval(r) ((r).t == RICON ? (r).i : conht[(r).i].i) #define fltconval(r) ((r).t == RICON ? (r).i : conht[(r).i].f) union ref mksymref(const char *); -union ref mkdatref(const char *name, uint siz, uint align, const void *, uint n, bool deref); +union ref mkdatref(const char *name, union type ctype, uint siz, uint align, const void *, uint n, bool deref); const char *xcon2sym(int ref); struct instr mkalloca(uint siz, uint align); union ref mkcallarg(union irtype ret, uint narg, int vararg); |