diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2022-09-09 17:40:31 +0200 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2022-10-08 21:48:42 +0200 |
commit | 00a30954aca97004cb6f586bdeeabb488f1e3c3f (patch) | |
tree | 951dc4c0a5be04fe7d5aed13f4201eb90c60f841 /arm64 | |
parent | 5cea0c20ee3573949a2c24e4b3dea65fcbf6e48b (diff) | |
download | roux-00a30954aca97004cb6f586bdeeabb488f1e3c3f.tar.gz |
add support for thread-local storage
The apple targets are not done yet.
Diffstat (limited to 'arm64')
-rw-r--r-- | arm64/emit.c | 41 | ||||
-rw-r--r-- | arm64/isel.c | 4 |
2 files changed, 30 insertions, 15 deletions
diff --git a/arm64/emit.c b/arm64/emit.c index 18c19d2..fc3f9ac 100644 --- a/arm64/emit.c +++ b/arm64/emit.c @@ -244,7 +244,7 @@ emitf(char *s, Ins *i, E *e) } static void -loadcon(Con *c, int r, int k, E *e) +loadaddr(Con *c, char *rn, E *e) { static char *ldsym[][2] = { /* arm64 */ @@ -254,7 +254,31 @@ loadcon(Con *c, int r, int k, E *e) [1][0] = "\tadrp\t%s, %s%s@page%s\n", [1][1] = "\tadd\t%s, %s, %s%s@pageoff%s\n", }; - char *rn, *l, *p, off[32]; + char *p, *l, off[32]; + + if (c->bits.i) + /* todo, handle large offsets */ + sprintf(off, "+%"PRIi64, c->bits.i); + else + off[0] = 0; + l = str(c->label); + p = l[0] == '"' ? "" : T.assym; + if (c->rel == RelThr) { + fprintf(e->f, "\tmrs\t%s, tpidr_el0\n", rn); + fprintf(e->f, "\tadd\t%s, %s, #:tprel_hi12:%s%s%s, lsl #12\n", + rn, rn, p, l, off); + fprintf(e->f, "\tadd\t%s, %s, #:tprel_lo12_nc:%s%s%s\n", + rn, rn, p, l, off); + } else { + fprintf(e->f, ldsym[e->apple][0], rn, p, l, off); + fprintf(e->f, ldsym[e->apple][1], rn, rn, p, l, off); + } +} + +static void +loadcon(Con *c, int r, int k, E *e) +{ + char *rn; int64_t n; int w, sh; @@ -262,16 +286,7 @@ loadcon(Con *c, int r, int k, E *e) rn = rname(r, k); n = c->bits.i; if (c->type == CAddr) { - rn = rname(r, Kl); - if (n) - /* todo, handle large offsets */ - sprintf(off, "+%"PRIi64, n); - else - off[0] = 0; - l = str(c->label); - p = c->local ? T.asloc : l[0] == '"' ? "" : T.assym; - fprintf(e->f, ldsym[e->apple][0], rn, p, l, off); - fprintf(e->f, ldsym[e->apple][1], rn, rn, p, l, off); + loadaddr(c, rn, e); return; } assert(c->type == CBits); @@ -471,7 +486,7 @@ emitfn(E *e) Blk *b, *t; Ins *i; - emitlnk(e->fn->name, &e->fn->lnk, ".text", e->f); + emitfnlnk(e->fn->name, &e->fn->lnk, e->f); framelayout(e); if (e->fn->vararg && !e->apple) { diff --git a/arm64/isel.c b/arm64/isel.c index c80e481..320cf33 100644 --- a/arm64/isel.c +++ b/arm64/isel.c @@ -87,8 +87,8 @@ fixarg(Ref *pr, int k, int phi, Fn *fn) n = stashbits(&c->bits, KWIDE(k) ? 8 : 4); vgrow(&fn->con, ++fn->ncon); c = &fn->con[fn->ncon-1]; - sprintf(buf, "fp%d", n); - *c = (Con){.type = CAddr, .local = 1}; + sprintf(buf, "\"%sfp%d\"", T.asloc, n); + *c = (Con){.type = CAddr}; c->label = intern(buf); r2 = newtmp("isel", Kl, fn); emit(Oload, k, r1, r2, R); |