diff options
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | all.h | 23 | ||||
-rw-r--r-- | amd64/all.h | 3 | ||||
-rw-r--r-- | amd64/emit.c | 31 | ||||
-rw-r--r-- | amd64/isel.c | 2 | ||||
-rw-r--r-- | amd64/targ.c | 42 | ||||
-rw-r--r-- | arm64/emit.c | 24 | ||||
-rw-r--r-- | arm64/isel.c | 2 | ||||
-rw-r--r-- | arm64/targ.c | 2 | ||||
-rw-r--r-- | emit.c (renamed from gas.c) | 100 | ||||
-rw-r--r-- | main.c | 25 | ||||
-rw-r--r-- | rv64/emit.c | 2 | ||||
-rw-r--r-- | rv64/isel.c | 2 | ||||
-rw-r--r-- | rv64/targ.c | 2 |
14 files changed, 143 insertions, 123 deletions
diff --git a/Makefile b/Makefile index 18a5066..9c9b401 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ PREFIX = /usr/local BINDIR = $(PREFIX)/bin COMMOBJ = main.o util.o parse.o cfg.o mem.o ssa.o alias.o load.o copy.o \ - fold.o live.o spill.o rega.o gas.o + fold.o live.o spill.o rega.o emit.o AMD64OBJ = amd64/targ.o amd64/sysv.o amd64/isel.o amd64/emit.o ARM64OBJ = arm64/targ.o arm64/abi.o arm64/isel.o arm64/emit.o RV64OBJ = rv64/targ.o rv64/abi.o rv64/isel.o rv64/emit.o @@ -30,11 +30,9 @@ main.o: config.h config.h: @case `uname` in \ *Darwin*) \ - echo "#define Defasm Gasmacho"; \ - echo "#define Deftgt T_amd64_sysv"; \ + echo "#define Deftgt T_amd64_apple"; \ ;; \ *) \ - echo "#define Defasm Gaself"; \ case `uname -m` in \ *aarch64*) \ echo "#define Deftgt T_arm64"; \ diff --git a/all.h b/all.h index c8ec93c..1ecea8e 100644 --- a/all.h +++ b/all.h @@ -55,6 +55,9 @@ struct Target { void (*abi)(Fn *); void (*isel)(Fn *); void (*emitfn)(Fn *, FILE *); + void (*emitfin)(FILE *); + char asloc[4]; + char assym[4]; }; #define BIT(n) ((bits)1 << (n)) @@ -524,16 +527,10 @@ void spill(Fn *); /* rega.c */ void rega(Fn *); -/* gas.c */ -enum Asm { - Gasmacho, - Gaself, -}; -extern char *gasloc; -extern char *gassym; -void gasinit(enum Asm); -void gasemitlnk(char *, Lnk *, char *, FILE *); -void gasemitfntail(char *, FILE *); -void gasemitdat(Dat *, FILE *); -int gasstash(void *, int); -void gasemitfin(FILE *); +/* emit.c */ +void emitlnk(char *, Lnk *, char *, FILE *); +void emitdat(Dat *, FILE *); +int stashbits(void *, int); +void elf_emitfnfin(char *, FILE *); +void elf_emitfin(FILE *); +void macho_emitfin(FILE *); diff --git a/amd64/all.h b/amd64/all.h index 3a2db0e..f6ad227 100644 --- a/amd64/all.h +++ b/amd64/all.h @@ -67,4 +67,5 @@ void amd64_sysv_abi(Fn *); void amd64_isel(Fn *); /* emit.c */ -void amd64_emitfn(Fn *, FILE *); +void amd64_sysv_emitfn(Fn *, FILE *); +void amd64_apple_emitfn(Fn *, FILE *); diff --git a/amd64/emit.c b/amd64/emit.c index b8e9e8e..db6ead8 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -166,7 +166,7 @@ emitcon(Con *con, FILE *f) switch (con->type) { case CAddr: l = str(con->label); - p = con->local ? gasloc : l[0] == '"' ? "" : gassym; + p = con->local ? T.asloc : l[0] == '"' ? "" : T.assym; fprintf(f, "%s%s", p, l); if (con->bits.i) fprintf(f, "%+"PRId64, con->bits.i); @@ -425,8 +425,8 @@ emitins(Ins i, Fn *fn, FILE *f) fprintf(f, "\txorp%c %sfp%d(%%rip), %%%s\n", "xxsd"[i.cls], - gasloc, - gasstash(negmask[i.cls], 16), + T.asloc, + stashbits(negmask[i.cls], 16), regtoa(i.to.val, SLong) ); break; @@ -535,8 +535,8 @@ framesz(Fn *fn) return 4*f + 8*o + 176*fn->vararg; } -void -amd64_emitfn(Fn *fn, FILE *f) +static void +emitfn(Fn *fn, FILE *f) { static char *ctoa[] = { #define X(c, s) [c] = s, @@ -549,7 +549,7 @@ amd64_emitfn(Fn *fn, FILE *f) int *r, c, o, n, lbl; uint64_t fs; - gasemitlnk(fn->name, &fn->lnk, ".text", f); + emitlnk(fn->name, &fn->lnk, ".text", f); fputs("\tpushq %rbp\n\tmovq %rsp, %rbp\n", f); fs = framesz(fn); if (fs) @@ -570,7 +570,7 @@ amd64_emitfn(Fn *fn, FILE *f) for (lbl=0, b=fn->start; b; b=b->link) { if (lbl || b->npred > 1) - fprintf(f, "%sbb%d:\n", gasloc, id0+b->id); + fprintf(f, "%sbb%d:\n", T.asloc, id0+b->id); for (i=b->ins; i!=&b->ins[b->nins]; i++) emitins(*i, fn, f); lbl = 1; @@ -596,7 +596,7 @@ amd64_emitfn(Fn *fn, FILE *f) Jmp: if (b->s1 != b->link) fprintf(f, "\tjmp %sbb%d\n", - gasloc, id0+b->s1->id); + T.asloc, id0+b->s1->id); else lbl = 0; break; @@ -610,7 +610,7 @@ amd64_emitfn(Fn *fn, FILE *f) } else c = cmpneg(c); fprintf(f, "\tj%s %sbb%d\n", ctoa[c], - gasloc, id0+b->s2->id); + T.asloc, id0+b->s2->id); goto Jmp; } die("unhandled jump %d", b->jmp.type); @@ -618,3 +618,16 @@ amd64_emitfn(Fn *fn, FILE *f) } id0 += fn->nblk; } + +void +amd64_sysv_emitfn(Fn *fn, FILE *f) +{ + emitfn(fn, f); + elf_emitfnfin(fn->name, f); +} + +void +amd64_apple_emitfn(Fn *fn, FILE *f) +{ + emitfn(fn, f); +} diff --git a/amd64/isel.c b/amd64/isel.c index 5a64429..640bf12 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -79,7 +79,7 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) memset(&a, 0, sizeof a); a.offset.type = CAddr; a.offset.local = 1; - n = gasstash(&fn->con[r0.val].bits, KWIDE(k) ? 8 : 4); + n = stashbits(&fn->con[r0.val].bits, KWIDE(k) ? 8 : 4); sprintf(buf, "fp%d", n); a.offset.label = intern(buf); fn->mem[fn->nmem-1] = a; diff --git a/amd64/targ.c b/amd64/targ.c index 2cf1bdc..e58ba2f 100644 --- a/amd64/targ.c +++ b/amd64/targ.c @@ -12,20 +12,34 @@ amd64_memargs(int op) return amd64_op[op].nmem; } +#define AMD64_COMMON \ + .gpr0 = RAX, \ + .ngpr = NGPR, \ + .fpr0 = XMM0, \ + .nfpr = NFPR, \ + .rglob = BIT(RBP) | BIT(RSP), \ + .nrglob = 2, \ + .rsave = amd64_sysv_rsave, \ + .nrsave = {NGPS, NFPS}, \ + .retregs = amd64_sysv_retregs, \ + .argregs = amd64_sysv_argregs, \ + .memargs = amd64_memargs, \ + .abi = amd64_sysv_abi, \ + .isel = amd64_isel, \ + Target T_amd64_sysv = { .name = "amd64_sysv", - .gpr0 = RAX, - .ngpr = NGPR, - .fpr0 = XMM0, - .nfpr = NFPR, - .rglob = BIT(RBP) | BIT(RSP), - .nrglob = 2, - .rsave = amd64_sysv_rsave, - .nrsave = {NGPS, NFPS}, - .retregs = amd64_sysv_retregs, - .argregs = amd64_sysv_argregs, - .memargs = amd64_memargs, - .abi = amd64_sysv_abi, - .isel = amd64_isel, - .emitfn = amd64_emitfn, + .emitfn = amd64_sysv_emitfn, + .emitfin = elf_emitfin, + .asloc = ".L", + AMD64_COMMON +}; + +Target T_amd64_apple = { + .name = "amd64_apple", + .emitfn = amd64_apple_emitfn, + .emitfin = macho_emitfin, + .asloc = "L", + .assym = "_", + AMD64_COMMON }; diff --git a/arm64/emit.c b/arm64/emit.c index 2506eea..ec4d350 100644 --- a/arm64/emit.c +++ b/arm64/emit.c @@ -245,7 +245,7 @@ emitf(char *s, Ins *i, E *e) static void loadcon(Con *c, int r, int k, FILE *f) { - char *rn, *p, off[32]; + char *rn, *l, *p, off[32]; int64_t n; int w, sh; @@ -258,11 +258,12 @@ loadcon(Con *c, int r, int k, FILE *f) sprintf(off, "+%"PRIi64, n); else off[0] = 0; - p = c->local ? ".L" : ""; + l = str(c->label); + p = c->local ? T.asloc : l[0] == '"' ? "" : T.assym; fprintf(f, "\tadrp\t%s, %s%s%s\n", - rn, p, str(c->label), off); + rn, p, l, off); fprintf(f, "\tadd\t%s, %s, #:lo12:%s%s%s\n", - rn, rn, p, str(c->label), off); + rn, rn, p, l, off); return; } assert(c->type == CBits); @@ -451,7 +452,7 @@ arm64_emitfn(Fn *fn, FILE *out) Ins *i; E *e; - gasemitlnk(fn->name, &fn->lnk, ".text", out); + emitlnk(fn->name, &fn->lnk, ".text", out); e = &(E){.f = out, .fn = fn}; framelayout(e); @@ -500,7 +501,7 @@ arm64_emitfn(Fn *fn, FILE *out) for (lbl=0, b=e->fn->start; b; b=b->link) { if (lbl || b->npred > 1) - fprintf(e->f, ".L%d:\n", id0+b->id); + fprintf(e->f, "%s%d:\n", T.asloc, id0+b->id); for (i=b->ins; i!=&b->ins[b->nins]; i++) emitins(i, e); lbl = 1; @@ -550,7 +551,10 @@ arm64_emitfn(Fn *fn, FILE *out) case Jjmp: Jmp: if (b->s1 != b->link) - fprintf(e->f, "\tb\t.L%d\n", id0+b->s1->id); + fprintf(e->f, + "\tb\t%s%d\n", + T.asloc, id0+b->s1->id + ); else lbl = 0; break; @@ -564,9 +568,13 @@ arm64_emitfn(Fn *fn, FILE *out) b->s2 = t; } else c = cmpneg(c); - fprintf(e->f, "\tb%s\t.L%d\n", ctoa[c], id0+b->s2->id); + fprintf(e->f, + "\tb%s\t%s%d\n", + ctoa[c], T.asloc, id0+b->s2->id + ); goto Jmp; } } id0 += e->fn->nblk; + elf_emitfnfin(e->fn->name, e->f); } diff --git a/arm64/isel.c b/arm64/isel.c index bb5c12b..f064321 100644 --- a/arm64/isel.c +++ b/arm64/isel.c @@ -84,7 +84,7 @@ fixarg(Ref *pr, int k, int phi, Fn *fn) emit(Ocopy, k, r1, r0, R); } else { c = &fn->con[r0.val]; - n = gasstash(&c->bits, KWIDE(k) ? 8 : 4); + n = stashbits(&c->bits, KWIDE(k) ? 8 : 4); vgrow(&fn->con, ++fn->ncon); c = &fn->con[fn->ncon-1]; sprintf(buf, "fp%d", n); diff --git a/arm64/targ.c b/arm64/targ.c index 33b14f4..ddaee2f 100644 --- a/arm64/targ.c +++ b/arm64/targ.c @@ -41,6 +41,8 @@ Target T_arm64 = { .abi = arm64_abi, .isel = arm64_isel, .emitfn = arm64_emitfn, + .emitfin = elf_emitfin, + .asloc = ".L", }; MAKESURE(globals_are_not_arguments, diff --git a/gas.c b/emit.c index 865edba..372ce3d 100644 --- a/gas.c +++ b/emit.c @@ -1,27 +1,7 @@ #include "all.h" - -char *gasloc, *gassym; -static int gasasm; - void -gasinit(enum Asm asmmode) -{ - gasasm = asmmode; - switch (gasasm) { - case Gaself: - gasloc = ".L"; - gassym = ""; - break; - case Gasmacho: - gasloc = "L"; - gassym = "_"; - break; - } -} - -void -gasemitlnk(char *n, Lnk *l, char *s, FILE *f) +emitlnk(char *n, Lnk *l, char *s, FILE *f) { char *p; @@ -35,23 +15,14 @@ gasemitlnk(char *n, Lnk *l, char *s, FILE *f) fputc('\n', f); if (l->align) fprintf(f, ".balign %d\n", l->align); - p = n[0] == '"' ? "" : gassym; + p = n[0] == '"' ? "" : T.assym; if (l->export) fprintf(f, ".globl %s%s\n", p, n); fprintf(f, "%s%s:\n", p, n); } void -gasemitfntail(char *fn, FILE *f) -{ - if (gasasm == Gaself) { - fprintf(f, ".type %s, @function\n", fn); - fprintf(f, ".size %s, .-%s\n", fn, fn); - } -} - -void -gasemitdat(Dat *d, FILE *f) +emitdat(Dat *d, FILE *f) { static char *dtoa[] = { [DB] = "\t.byte", @@ -68,7 +39,7 @@ gasemitdat(Dat *d, FILE *f) break; case DEnd: if (zero != -1) { - gasemitlnk(d->name, d->lnk, ".bss", f); + emitlnk(d->name, d->lnk, ".bss", f); fprintf(f, "\t.fill %"PRId64",1,0\n", zero); } break; @@ -80,7 +51,7 @@ gasemitdat(Dat *d, FILE *f) break; default: if (zero != -1) { - gasemitlnk(d->name, d->lnk, ".data", f); + emitlnk(d->name, d->lnk, ".data", f); if (zero > 0) fprintf(f, "\t.fill %"PRId64",1,0\n", zero); zero = -1; @@ -91,7 +62,7 @@ gasemitdat(Dat *d, FILE *f) fprintf(f, "\t.ascii %s\n", d->u.str); } else if (d->isref) { - p = d->u.ref.name[0] == '"' ? "" : gassym; + p = d->u.ref.name[0] == '"' ? "" : T.assym; fprintf(f, "%s %s%s%+"PRId64"\n", dtoa[d->type], p, d->u.ref.name, d->u.ref.off); @@ -115,7 +86,7 @@ struct Asmbits { static Asmbits *stash; int -gasstash(void *bits, int size) +stashbits(void *bits, int size) { Asmbits **pb, *b; int i; @@ -133,38 +104,37 @@ gasstash(void *bits, int size) return i; } -void -gasemitfin(FILE *f) +static void +emitfin(FILE *f, char *sec[3]) { Asmbits *b; char *p; - int sz, i; + int lg, i; double d; - if (gasasm == Gaself) - fprintf(f, ".section .note.GNU-stack,\"\",@progbits\n\n"); if (!stash) return; - fprintf(f, "/* floating point constants */\n.data\n"); - for (sz=16; sz>=4; sz/=2) + fprintf(f, "/* floating point constants */\n"); + for (lg=4; lg>=2; lg--) for (b=stash, i=0; b; b=b->link, i++) { - if (b->size == sz) { + if (b->size == (1<<lg)) { fprintf(f, - ".balign %d\n" + ".section %s\n" + ".p2align %d\n" "%sfp%d:", - sz, gasloc, i + sec[lg-2], lg, T.asloc, i ); - for (p=b->bits; p<&b->bits[sz]; p+=4) + for (p=b->bits; p<&b->bits[b->size]; p+=4) fprintf(f, "\n\t.int %"PRId32, *(int32_t *)p); - if (sz <= 8) { - if (sz == 4) + if (lg <= 3) { + if (lg == 2) d = *(float *)b->bits; else d = *(double *)b->bits; - fprintf(f, " /* %f */\n", d); + fprintf(f, " /* %f */\n\n", d); } else - fprintf(f, "\n"); + fprintf(f, "\n\n"); } } while ((b=stash)) { @@ -172,3 +142,31 @@ gasemitfin(FILE *f) free(b); } } + +void +elf_emitfin(FILE *f) +{ + static char *sec[3] = { ".rodata", ".rodata", ".rodata" }; + + emitfin(f ,sec); + fprintf(f, ".section .note.GNU-stack,\"\",@progbits\n"); +} + +void +elf_emitfnfin(char *fn, FILE *f) +{ + fprintf(f, ".type %s, @function\n", fn); + fprintf(f, ".size %s, .-%s\n", fn, fn); +} + +void +macho_emitfin(FILE *f) +{ + static char *sec[3] = { + "__TEXT,__literal4,4byte_literals", + "__TEXT,__literal8,8byte_literals", + ".rodata", /* should not happen */ + }; + + emitfin(f, sec); +} diff --git a/main.c b/main.c index 5ea5704..e82b062 100644 --- a/main.c +++ b/main.c @@ -19,11 +19,13 @@ char debug['Z'+1] = { }; extern Target T_amd64_sysv; +extern Target T_amd64_apple; extern Target T_arm64; extern Target T_rv64; static Target *tlist[] = { &T_amd64_sysv, + &T_amd64_apple, &T_arm64, &T_rv64, 0 @@ -40,7 +42,7 @@ data(Dat *d) fputs("/* end data */\n\n", outf); freeall(); } - gasemitdat(d, outf); + emitdat(d, outf); } static void @@ -92,7 +94,6 @@ func(Fn *fn) fn->rpo[n]->link = fn->rpo[n+1]; if (!dbg) { T.emitfn(fn, outf); - gasemitfntail(fn->name, outf); fprintf(outf, "/* end function %s */\n\n", fn->name); } else fprintf(stderr, "\n"); @@ -105,12 +106,11 @@ main(int ac, char *av[]) Target **t; FILE *inf, *hf; char *f, *sep; - int c, asmmode; + int c; - asmmode = Defasm; T = Deftgt; outf = stdout; - while ((c = getopt(ac, av, "hd:o:G:t:")) != -1) + while ((c = getopt(ac, av, "hd:o:t:")) != -1) switch (c) { case 'd': for (; *optarg; optarg++) @@ -144,16 +144,6 @@ main(int ac, char *av[]) } } break; - case 'G': - if (strcmp(optarg, "e") == 0) - asmmode = Gaself; - else if (strcmp(optarg, "m") == 0) - asmmode = Gasmacho; - else { - fprintf(stderr, "unknown gas flavor '%s'\n", optarg); - exit(1); - } - break; case 'h': default: hf = c != 'h' ? stderr : stdout; @@ -168,13 +158,10 @@ main(int ac, char *av[]) fputs(" (default)", hf); } fprintf(hf, "\n"); - fprintf(hf, "\t%-11s generate gas (e) or osx (m) asm\n", "-G {e,m}"); fprintf(hf, "\t%-11s dump debug information\n", "-d <flags>"); exit(c != 'h'); } - gasinit(asmmode); - do { f = av[optind]; if (!f || strcmp(f, "-") == 0) { @@ -192,7 +179,7 @@ main(int ac, char *av[]) } while (++optind < ac); if (!dbg) - gasemitfin(outf); + T.emitfin(outf); exit(0); } diff --git a/rv64/emit.c b/rv64/emit.c index 2656c60..f976ade 100644 --- a/rv64/emit.c +++ b/rv64/emit.c @@ -415,7 +415,7 @@ rv64_emitfn(Fn *fn, FILE *f) Blk *b, *s; Ins *i; - gasemitlnk(fn->name, &fn->lnk, ".text", f); + emitlnk(fn->name, &fn->lnk, ".text", f); if (fn->vararg) { /* TODO: only need space for registers diff --git a/rv64/isel.c b/rv64/isel.c index e41578b..3d9884f 100644 --- a/rv64/isel.c +++ b/rv64/isel.c @@ -41,7 +41,7 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) * immediates */ assert(c->type == CBits); - n = gasstash(&c->bits, KWIDE(k) ? 8 : 4); + n = stashbits(&c->bits, KWIDE(k) ? 8 : 4); vgrow(&fn->con, ++fn->ncon); c = &fn->con[fn->ncon-1]; sprintf(buf, "fp%d", n); diff --git a/rv64/targ.c b/rv64/targ.c index 9360cf7..70701db 100644 --- a/rv64/targ.c +++ b/rv64/targ.c @@ -47,6 +47,8 @@ Target T_rv64 = { .abi = rv64_abi, .isel = rv64_isel, .emitfn = rv64_emitfn, + .emitfin = elf_emitfin, + .asloc = ".L", }; MAKESURE(rsave_size_ok, sizeof rv64_rsave == (NGPS+NFPS+1) * sizeof(int)); |