aboutsummaryrefslogtreecommitdiff
path: root/arm64
diff options
context:
space:
mode:
authorQuentin Carbonneaux <[email protected]>2022-09-09 17:40:31 +0200
committerQuentin Carbonneaux <[email protected]>2022-10-08 21:48:42 +0200
commit00a30954aca97004cb6f586bdeeabb488f1e3c3f (patch)
tree951dc4c0a5be04fe7d5aed13f4201eb90c60f841 /arm64
parent5cea0c20ee3573949a2c24e4b3dea65fcbf6e48b (diff)
add support for thread-local storage
The apple targets are not done yet.
Diffstat (limited to 'arm64')
-rw-r--r--arm64/emit.c41
-rw-r--r--arm64/isel.c4
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);