aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--all.h23
-rw-r--r--amd64/all.h3
-rw-r--r--amd64/emit.c31
-rw-r--r--amd64/isel.c2
-rw-r--r--amd64/targ.c42
-rw-r--r--arm64/emit.c24
-rw-r--r--arm64/isel.c2
-rw-r--r--arm64/targ.c2
-rw-r--r--emit.c (renamed from gas.c)100
-rw-r--r--main.c25
-rw-r--r--rv64/emit.c2
-rw-r--r--rv64/isel.c2
-rw-r--r--rv64/targ.c2
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));