The apple targets are not done yet.
Unified · Split
| @@ -324,8 +324,11 @@ struct Con { · 323 unmodified lines | ||
| 324 | 324 | double d; |
| 325 | 325 | float s; |
| 326 | 326 | } bits; |
| 327 | + enum { | |
| 328 | + RelDef, | |
| 329 | + RelThr, | |
| 330 | + } rel; | |
| 327 | 331 | char flt; /* 1 to print as s, 2 to print as d */ |
| 328 | − char local; | |
| 329 | 332 | }; |
| 330 | 333 | |
| 331 | 334 | typedef struct Addr Addr; |
| @@ -339,6 +342,7 @@ struct Addr { /* amd64 addressing */ · 7 unmodified lines | ||
| 339 | 342 | |
| 340 | 343 | struct Lnk { |
| 341 | 344 | char export; |
| 345 | + char thread; | |
| 342 | 346 | char align; |
| 343 | 347 | char *sec; |
| 344 | 348 | char *secf; |
| @@ -536,7 +540,7 @@ void spill(Fn *); · 191 unmodified lines | ||
| 536 | 540 | void rega(Fn *); |
| 537 | 541 | |
| 538 | 542 | /* emit.c */ |
| 539 | −void emitlnk(char *, Lnk *, char *, FILE *); | |
| 543 | +void emitfnlnk(char *, Lnk *, FILE *); | |
| 540 | 544 | void emitdat(Dat *, FILE *); |
| 541 | 545 | int stashbits(void *, int); |
| 542 | 546 | void elf_emitfnfin(char *, FILE *); |
| @@ -166,8 +166,11 @@ emitcon(Con *con, FILE *f) · 165 unmodified lines | ||
| 166 | 166 | switch (con->type) { |
| 167 | 167 | case CAddr: |
| 168 | 168 | l = str(con->label); |
| 169 | − p = con->local ? T.asloc : l[0] == '"' ? "" : T.assym; | |
| 170 | − fprintf(f, "%s%s", p, l); | |
| 169 | + p = l[0] == '"' ? "" : T.assym; | |
| 170 | + if (con->rel == RelThr) | |
| 171 | + fprintf(f, "%%fs:%s%s@tpoff", p, l); | |
| 172 | + else | |
| 173 | + fprintf(f, "%s%s", p, l); | |
| 171 | 174 | if (con->bits.i) |
| 172 | 175 | fprintf(f, "%+"PRId64, con->bits.i); |
| 173 | 176 | break; |
| @@ -337,7 +340,7 @@ Next: · 163 unmodified lines | ||
| 337 | 340 | case RCon: |
| 338 | 341 | off = fn->con[ref.val]; |
| 339 | 342 | emitcon(&off, f); |
| 340 | − if (off.type == CAddr) | |
| 343 | + if (off.type == CAddr && off.rel != RelThr) | |
| 341 | 344 | fprintf(f, "(%%rip)"); |
| 342 | 345 | break; |
| 343 | 346 | case RTmp: |
| @@ -549,7 +552,7 @@ emitfn(Fn *fn, FILE *f) · 205 unmodified lines | ||
| 549 | 552 | int *r, c, o, n, lbl; |
| 550 | 553 | uint64_t fs; |
| 551 | 554 | |
| 552 | − emitlnk(fn->name, &fn->lnk, ".text", f); | |
| 555 | + emitfnlnk(fn->name, &fn->lnk, f); | |
| 553 | 556 | fputs("\tpushq %rbp\n\tmovq %rsp, %rbp\n", f); |
| 554 | 557 | fs = framesz(fn); |
| 555 | 558 | if (fs) |
| @@ -78,9 +78,8 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) · 77 unmodified lines | ||
| 78 | 78 | vgrow(&fn->mem, ++fn->nmem); |
| 79 | 79 | memset(&a, 0, sizeof a); |
| 80 | 80 | a.offset.type = CAddr; |
| 81 | − a.offset.local = 1; | |
| 82 | 81 | n = stashbits(&fn->con[r0.val].bits, KWIDE(k) ? 8 : 4); |
| 83 | − sprintf(buf, "fp%d", n); | |
| 82 | + sprintf(buf, "\"%sfp%d\"", T.asloc, n); | |
| 84 | 83 | a.offset.label = intern(buf); |
| 85 | 84 | fn->mem[fn->nmem-1] = a; |
| 86 | 85 | } |
| @@ -244,7 +244,7 @@ emitf(char *s, Ins *i, E *e) · 243 unmodified lines | ||
| 244 | 244 | } |
| 245 | 245 | |
| 246 | 246 | static void |
| 247 | −loadcon(Con *c, int r, int k, E *e) | |
| 247 | +loadaddr(Con *c, char *rn, E *e) | |
| 248 | 248 | { |
| 249 | 249 | static char *ldsym[][2] = { |
| 250 | 250 | /* arm64 */ |
| @@ -254,7 +254,31 @@ loadcon(Con *c, int r, int k, E *e) · 3 unmodified lines | ||
| 254 | 254 | [1][0] = "\tadrp\t%s, %s%s@page%s\n", |
| 255 | 255 | [1][1] = "\tadd\t%s, %s, %s%s@pageoff%s\n", |
| 256 | 256 | }; |
| 257 | − char *rn, *l, *p, off[32]; | |
| 257 | + char *p, *l, off[32]; | |
| 258 | + | |
| 259 | + if (c->bits.i) | |
| 260 | + /* todo, handle large offsets */ | |
| 261 | + sprintf(off, "+%"PRIi64, c->bits.i); | |
| 262 | + else | |
| 263 | + off[0] = 0; | |
| 264 | + l = str(c->label); | |
| 265 | + p = l[0] == '"' ? "" : T.assym; | |
| 266 | + if (c->rel == RelThr) { | |
| 267 | + fprintf(e->f, "\tmrs\t%s, tpidr_el0\n", rn); | |
| 268 | + fprintf(e->f, "\tadd\t%s, %s, #:tprel_hi12:%s%s%s, lsl #12\n", | |
| 269 | + rn, rn, p, l, off); | |
| 270 | + fprintf(e->f, "\tadd\t%s, %s, #:tprel_lo12_nc:%s%s%s\n", | |
| 271 | + rn, rn, p, l, off); | |
| 272 | + } else { | |
| 273 | + fprintf(e->f, ldsym[e->apple][0], rn, p, l, off); | |
| 274 | + fprintf(e->f, ldsym[e->apple][1], rn, rn, p, l, off); | |
| 275 | + } | |
| 276 | +} | |
| 277 | + | |
| 278 | +static void | |
| 279 | +loadcon(Con *c, int r, int k, E *e) | |
| 280 | +{ | |
| 281 | + char *rn; | |
| 258 | 282 | int64_t n; |
| 259 | 283 | int w, sh; |
| 260 | 284 | |
| @@ -262,16 +286,7 @@ loadcon(Con *c, int r, int k, E *e) · 1 unmodified line | ||
| 262 | 286 | rn = rname(r, k); |
| 263 | 287 | n = c->bits.i; |
| 264 | 288 | if (c->type == CAddr) { |
| 265 | − rn = rname(r, Kl); | |
| 266 | − if (n) | |
| 267 | − /* todo, handle large offsets */ | |
| 268 | − sprintf(off, "+%"PRIi64, n); | |
| 269 | − else | |
| 270 | − off[0] = 0; | |
| 271 | − l = str(c->label); | |
| 272 | − p = c->local ? T.asloc : l[0] == '"' ? "" : T.assym; | |
| 273 | − fprintf(e->f, ldsym[e->apple][0], rn, p, l, off); | |
| 274 | − fprintf(e->f, ldsym[e->apple][1], rn, rn, p, l, off); | |
| 289 | + loadaddr(c, rn, e); | |
| 275 | 290 | return; |
| 276 | 291 | } |
| 277 | 292 | assert(c->type == CBits); |
| @@ -471,7 +486,7 @@ emitfn(E *e) · 193 unmodified lines | ||
| 471 | 486 | Blk *b, *t; |
| 472 | 487 | Ins *i; |
| 473 | 488 | |
| 474 | − emitlnk(e->fn->name, &e->fn->lnk, ".text", e->f); | |
| 489 | + emitfnlnk(e->fn->name, &e->fn->lnk, e->f); | |
| 475 | 490 | framelayout(e); |
| 476 | 491 | |
| 477 | 492 | if (e->fn->vararg && !e->apple) { |
| @@ -87,8 +87,8 @@ fixarg(Ref *pr, int k, int phi, Fn *fn) · 86 unmodified lines | ||
| 87 | 87 | n = stashbits(&c->bits, KWIDE(k) ? 8 : 4); |
| 88 | 88 | vgrow(&fn->con, ++fn->ncon); |
| 89 | 89 | c = &fn->con[fn->ncon-1]; |
| 90 | − sprintf(buf, "fp%d", n); | |
| 91 | − *c = (Con){.type = CAddr, .local = 1}; | |
| 90 | + sprintf(buf, "\"%sfp%d\"", T.asloc, n); | |
| 91 | + *c = (Con){.type = CAddr}; | |
| 92 | 92 | c->label = intern(buf); |
| 93 | 93 | r2 = newtmp("isel", Kl, fn); |
| 94 | 94 | emit(Oload, k, r1, r2, R); |
| @@ -1,17 +1,30 @@ | ||
| 1 | 1 | #include "all.h" |
| 2 | 2 | |
| 3 | +enum { | |
| 4 | + SecText, | |
| 5 | + SecData, | |
| 6 | + SecBss, | |
| 7 | +}; | |
| 8 | + | |
| 3 | 9 | void |
| 4 | −emitlnk(char *n, Lnk *l, char *s, FILE *f) | |
| 10 | +emitlnk(char *n, Lnk *l, int s, FILE *f) | |
| 5 | 11 | { |
| 12 | + static char *sec[2][3] = { | |
| 13 | + [0][SecText] = ".text", | |
| 14 | + [0][SecData] = ".data", | |
| 15 | + [0][SecBss] = ".bss", | |
| 16 | + [1][SecText] = ".abort \"unreachable\"", | |
| 17 | + [1][SecData] = ".section .tdata,\"awT\"", | |
| 18 | + [1][SecBss] = ".section .tbss,\"awT\"", | |
| 19 | + }; | |
| 6 | 20 | char *p; |
| 7 | 21 | |
| 8 | 22 | if (l->sec) { |
| 9 | 23 | fprintf(f, ".section %s", l->sec); |
| 10 | 24 | if (l->secf) |
| 11 | − fprintf(f, ", %s", l->secf); | |
| 12 | − } else { | |
| 13 | − fputs(s, f); | |
| 14 | − } | |
| 25 | + fprintf(f, ",%s", l->secf); | |
| 26 | + } else | |
| 27 | + fputs(sec[l->thread != 0][s], f); | |
| 15 | 28 | fputc('\n', f); |
| 16 | 29 | if (l->align) |
| 17 | 30 | fprintf(f, ".balign %d\n", l->align); |
| @@ -21,6 +34,12 @@ emitlnk(char *n, Lnk *l, char *s, FILE *f) · 3 unmodified lines | ||
| 21 | 34 | fprintf(f, "%s%s:\n", p, n); |
| 22 | 35 | } |
| 23 | 36 | |
| 37 | +void | |
| 38 | +emitfnlnk(char *n, Lnk *l, FILE *f) | |
| 39 | +{ | |
| 40 | + emitlnk(n, l, SecText, f); | |
| 41 | +} | |
| 42 | + | |
| 24 | 43 | void |
| 25 | 44 | emitdat(Dat *d, FILE *f) |
| 26 | 45 | { |
| @@ -39,7 +58,7 @@ emitdat(Dat *d, FILE *f) · 12 unmodified lines | ||
| 39 | 58 | break; |
| 40 | 59 | case DEnd: |
| 41 | 60 | if (zero != -1) { |
| 42 | − emitlnk(d->name, d->lnk, ".bss", f); | |
| 61 | + emitlnk(d->name, d->lnk, SecBss, f); | |
| 43 | 62 | fprintf(f, "\t.fill %"PRId64",1,0\n", zero); |
| 44 | 63 | } |
| 45 | 64 | break; |
| @@ -51,7 +70,7 @@ emitdat(Dat *d, FILE *f) · 5 unmodified lines | ||
| 51 | 70 | break; |
| 52 | 71 | default: |
| 53 | 72 | if (zero != -1) { |
| 54 | − emitlnk(d->name, d->lnk, ".data", f); | |
| 73 | + emitlnk(d->name, d->lnk, SecData, f); | |
| 55 | 74 | if (zero > 0) |
| 56 | 75 | fprintf(f, "\t.fill %"PRId64",1,0\n", zero); |
| 57 | 76 | zero = -1; |
| @@ -165,7 +184,7 @@ macho_emitfin(FILE *f) · 107 unmodified lines | ||
| 165 | 184 | static char *sec[3] = { |
| 166 | 185 | "__TEXT,__literal4,4byte_literals", |
| 167 | 186 | "__TEXT,__literal8,8byte_literals", |
| 168 | − ".rodata", /* should not happen */ | |
| 187 | + ".abort \"unreachable\"", | |
| 169 | 188 | }; |
| 170 | 189 | |
| 171 | 190 | emitfin(f, sec); |
| @@ -334,9 +334,10 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 333 unmodified lines | ||
| 334 | 334 | } l, r; |
| 335 | 335 | uint64_t x; |
| 336 | 336 | uint32_t lab; |
| 337 | − int typ; | |
| 337 | + int typ, rel; | |
| 338 | 338 | |
| 339 | 339 | typ = CBits; |
| 340 | + rel = RelDef; | |
| 340 | 341 | lab = 0; |
| 341 | 342 | l.s = cl->bits.i; |
| 342 | 343 | r.s = cr->bits.i; |
| @@ -345,10 +346,12 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 2 unmodified lines | ||
| 345 | 346 | if (cr->type == CAddr) |
| 346 | 347 | return 1; |
| 347 | 348 | lab = cl->label; |
| 349 | + rel = cl->rel; | |
| 348 | 350 | typ = CAddr; |
| 349 | 351 | } |
| 350 | 352 | else if (cr->type == CAddr) { |
| 351 | 353 | lab = cr->label; |
| 354 | + rel = cr->rel; | |
| 352 | 355 | typ = CAddr; |
| 353 | 356 | } |
| 354 | 357 | } |
| @@ -356,6 +359,7 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 1 unmodified line | ||
| 356 | 359 | if (cl->type == CAddr) { |
| 357 | 360 | if (cr->type != CAddr) { |
| 358 | 361 | lab = cl->label; |
| 362 | + rel = cl->rel; | |
| 359 | 363 | typ = CAddr; |
| 360 | 364 | } else if (cl->label != cr->label) |
| 361 | 365 | return 1; |
| @@ -404,6 +408,7 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 42 unmodified lines | ||
| 404 | 408 | x = l.u; |
| 405 | 409 | if (cl->type == CAddr) { |
| 406 | 410 | lab = cl->label; |
| 411 | + rel = cl->rel; | |
| 407 | 412 | typ = CAddr; |
| 408 | 413 | } |
| 409 | 414 | break; |
| @@ -457,7 +462,7 @@ foldint(Con *res, int op, int w, Con *cl, Con *cr) · 47 unmodified lines | ||
| 457 | 462 | else |
| 458 | 463 | die("unreachable"); |
| 459 | 464 | } |
| 460 | − *res = (Con){.type=typ, .label=lab, .bits={.i=x}}; | |
| 465 | + *res = (Con){.type=typ, .label=lab, .rel=rel, .bits={.i=x}}; | |
| 461 | 466 | return 0; |
| 462 | 467 | } |
| 463 | 468 | |
| @@ -155,7 +155,7 @@ load(Slice sl, bits msk, Loc *l) · 154 unmodified lines | ||
| 155 | 155 | c.type = CAddr; |
| 156 | 156 | c.label = a->label; |
| 157 | 157 | c.bits.i = a->offset; |
| 158 | − c.local = 0; | |
| 158 | + c.rel = RelDef; | |
| 159 | 159 | r = newcon(&c, curf); |
| 160 | 160 | break; |
| 161 | 161 | } |
| @@ -45,6 +45,7 @@ enum { · 44 unmodified lines | ||
| 45 | 45 | Tjnz, |
| 46 | 46 | Tret, |
| 47 | 47 | Texport, |
| 48 | + Tthread, | |
| 48 | 49 | Tfunc, |
| 49 | 50 | Ttype, |
| 50 | 51 | Tdata, |
| @@ -99,6 +100,7 @@ static char *kwmap[Ntok] = { · 48 unmodified lines | ||
| 99 | 100 | [Tjnz] = "jnz", |
| 100 | 101 | [Tret] = "ret", |
| 101 | 102 | [Texport] = "export", |
| 103 | + [Tthread] = "thread", | |
| 102 | 104 | [Tfunc] = "function", |
| 103 | 105 | [Ttype] = "type", |
| 104 | 106 | [Tdata] = "data", |
| @@ -399,30 +401,34 @@ parseref() · 294 unmodified lines | ||
| 399 | 401 | |
| 400 | 402 | memset(&c, 0, sizeof c); |
| 401 | 403 | switch (next()) { |
| 404 | + default: | |
| 405 | + return R; | |
| 402 | 406 | case Ttmp: |
| 403 | 407 | return tmpref(tokval.str); |
| 404 | 408 | case Tint: |
| 405 | 409 | c.type = CBits; |
| 406 | 410 | c.bits.i = tokval.num; |
| 407 | − goto Look; | |
| 411 | + break; | |
| 408 | 412 | case Tflts: |
| 409 | 413 | c.type = CBits; |
| 410 | 414 | c.bits.s = tokval.flts; |
| 411 | 415 | c.flt = 1; |
| 412 | − goto Look; | |
| 416 | + break; | |
| 413 | 417 | case Tfltd: |
| 414 | 418 | c.type = CBits; |
| 415 | 419 | c.bits.d = tokval.fltd; |
| 416 | 420 | c.flt = 2; |
| 417 | − goto Look; | |
| 421 | + break; | |
| 422 | + case Tthread: | |
| 423 | + c.rel = RelThr; | |
| 424 | + expect(Tglo); | |
| 425 | + /* fall through */ | |
| 418 | 426 | case Tglo: |
| 419 | 427 | c.type = CAddr; |
| 420 | 428 | c.label = intern(tokval.str); |
| 421 | − Look: | |
| 422 | − return newcon(&c, curf); | |
| 423 | − default: | |
| 424 | − return R; | |
| 429 | + break; | |
| 425 | 430 | } |
| 431 | + return newcon(&c, curf); | |
| 426 | 432 | } |
| 427 | 433 | |
| 428 | 434 | static int |
| @@ -1101,6 +1107,9 @@ parselnk(Lnk *lnk) · 672 unmodified lines | ||
| 1101 | 1107 | case Texport: |
| 1102 | 1108 | lnk->export = 1; |
| 1103 | 1109 | break; |
| 1110 | + case Tthread: | |
| 1111 | + lnk->thread = 1; | |
| 1112 | + break; | |
| 1104 | 1113 | case Tsection: |
| 1105 | 1114 | if (lnk->sec) |
| 1106 | 1115 | err("only one section allowed"); |
| @@ -1113,9 +1122,9 @@ parselnk(Lnk *lnk) · 6 unmodified lines | ||
| 1113 | 1122 | } |
| 1114 | 1123 | break; |
| 1115 | 1124 | default: |
| 1116 | − if (haslnk) | |
| 1117 | − if (t != Tdata) | |
| 1118 | − if (t != Tfunc) | |
| 1125 | + if (t == Tfunc && lnk->thread) | |
| 1126 | + err("only data may have thread linkage"); | |
| 1127 | + if (haslnk && t != Tdata && t != Tfunc) | |
| 1119 | 1128 | err("only data and function have linkage"); |
| 1120 | 1129 | return t; |
| 1121 | 1130 | } |
| @@ -1244,8 +1253,6 @@ printfn(Fn *fn, FILE *f) · 122 unmodified lines | ||
| 1244 | 1253 | Ins *i; |
| 1245 | 1254 | uint n; |
| 1246 | 1255 | |
| 1247 | − if (fn->lnk.export) | |
| 1248 | − fprintf(f, "export "); | |
| 1249 | 1256 | fprintf(f, "function $%s() {\n", fn->name); |
| 1250 | 1257 | for (b=fn->start; b; b=b->link) { |
| 1251 | 1258 | fprintf(f, "@%s\n", b->name); |
| @@ -129,14 +129,10 @@ slot(int s, Fn *fn) · 128 unmodified lines | ||
| 129 | 129 | static void |
| 130 | 130 | emitaddr(Con *c, FILE *f) |
| 131 | 131 | { |
| 132 | − char off[32], *p; | |
| 133 | − | |
| 132 | + assert(c->rel == RelDef); | |
| 133 | + fputs(str(c->label), f); | |
| 134 | 134 | if (c->bits.i) |
| 135 | − sprintf(off, "+%"PRIi64, c->bits.i); | |
| 136 | − else | |
| 137 | − off[0] = 0; | |
| 138 | − p = c->local ? ".L" : ""; | |
| 139 | − fprintf(f, "%s%s%s", p, str(c->label), off); | |
| 135 | + fprintf(f, "+%"PRIi64, c->bits.i); | |
| 140 | 136 | } |
| 141 | 137 | |
| 142 | 138 | static void |
| @@ -228,26 +224,45 @@ emitf(char *s, Ins *i, Fn *fn, FILE *f) · 85 unmodified lines | ||
| 228 | 224 | } |
| 229 | 225 | } |
| 230 | 226 | |
| 227 | +static void | |
| 228 | +loadaddr(Con *c, char *rn, FILE *f) | |
| 229 | +{ | |
| 230 | + char off[32]; | |
| 231 | + | |
| 232 | + if (c->rel == RelThr) { | |
| 233 | + if (c->bits.i) | |
| 234 | + sprintf(off, "+%"PRIi64, c->bits.i); | |
| 235 | + else | |
| 236 | + off[0] = 0; | |
| 237 | + fprintf(f, "\tlui %s, %%tprel_hi(%s)%s\n", | |
| 238 | + rn, str(c->label), off); | |
| 239 | + fprintf(f, "\tadd %s, %s, tp, %%tprel_add(%s)%s\n", | |
| 240 | + rn, rn, str(c->label), off); | |
| 241 | + fprintf(f, "\taddi %s, %s, %%tprel_lo(%s)%s\n", | |
| 242 | + rn, rn, str(c->label), off); | |
| 243 | + } else { | |
| 244 | + fprintf(f, "\tla %s, ", rn); | |
| 245 | + emitaddr(c, f); | |
| 246 | + fputc('\n', f); | |
| 247 | + } | |
| 248 | +} | |
| 249 | + | |
| 231 | 250 | static void |
| 232 | 251 | loadcon(Con *c, int r, int k, FILE *f) |
| 233 | 252 | { |
| 234 | 253 | char *rn; |
| 235 | 254 | int64_t n; |
| 236 | − int w; | |
| 237 | 255 | |
| 238 | − w = KWIDE(k); | |
| 239 | 256 | rn = rname[r]; |
| 240 | 257 | switch (c->type) { |
| 241 | 258 | case CAddr: |
| 242 | − fprintf(f, "\tla %s, ", rn); | |
| 243 | − emitaddr(c, f); | |
| 244 | − fputc('\n', f); | |
| 259 | + loadaddr(c, rn, f); | |
| 245 | 260 | break; |
| 246 | 261 | case CBits: |
| 247 | 262 | n = c->bits.i; |
| 248 | − if (!w) | |
| 263 | + if (!KWIDE(k)) | |
| 249 | 264 | n = (int32_t)n; |
| 250 | − fprintf(f, "\tli %s, %"PRIu64"\n", rn, n); | |
| 265 | + fprintf(f, "\tli %s, %"PRIi64"\n", rn, n); | |
| 251 | 266 | break; |
| 252 | 267 | default: |
| 253 | 268 | die("invalid constant"); |
| @@ -255,12 +270,20 @@ loadcon(Con *c, int r, int k, FILE *f) · 1 unmodified line | ||
| 255 | 270 | } |
| 256 | 271 | |
| 257 | 272 | static void |
| 258 | −fixslot(Ref *pr, Fn *fn, FILE *f) | |
| 273 | +fixmem(Ref *pr, Fn *fn, FILE *f) | |
| 259 | 274 | { |
| 260 | 275 | Ref r; |
| 261 | 276 | int64_t s; |
| 277 | + Con *c; | |
| 262 | 278 | |
| 263 | 279 | r = *pr; |
| 280 | + if (rtype(r) == RCon) { | |
| 281 | + c = &fn->con[r.val]; | |
| 282 | + if (c->type == CAddr && c->rel == RelThr) { | |
| 283 | + loadcon(c, T6, Kl, f); | |
| 284 | + *pr = TMP(T6); | |
| 285 | + } | |
| 286 | + } | |
| 264 | 287 | if (rtype(r) == RSlot) { |
| 265 | 288 | s = slot(r.val, fn); |
| 266 | 289 | if (s < -2048 || s > 2047) { |
| @@ -282,9 +305,9 @@ emitins(Ins *i, Fn *fn, FILE *f) · 15 unmodified lines | ||
| 282 | 305 | switch (i->op) { |
| 283 | 306 | default: |
| 284 | 307 | if (isload(i->op)) |
| 285 | − fixslot(&i->arg[0], fn, f); | |
| 308 | + fixmem(&i->arg[0], fn, f); | |
| 286 | 309 | else if (isstore(i->op)) |
| 287 | − fixslot(&i->arg[1], fn, f); | |
| 310 | + fixmem(&i->arg[1], fn, f); | |
| 288 | 311 | Table: |
| 289 | 312 | /* most instructions are just pulled out of |
| 290 | 313 | * the table omap[], some special cases are |
| @@ -321,7 +344,7 @@ emitins(Ins *i, Fn *fn, FILE *f) · 30 unmodified lines | ||
| 321 | 344 | case Ks: i->op = Ostores; break; |
| 322 | 345 | case Kd: i->op = Ostored; break; |
| 323 | 346 | } |
| 324 | − fixslot(&i->arg[1], fn, f); | |
| 347 | + fixmem(&i->arg[1], fn, f); | |
| 325 | 348 | goto Table; |
| 326 | 349 | } |
| 327 | 350 | break; |
| @@ -333,7 +356,7 @@ emitins(Ins *i, Fn *fn, FILE *f) · 5 unmodified lines | ||
| 333 | 356 | break; |
| 334 | 357 | case RSlot: |
| 335 | 358 | i->op = Oload; |
| 336 | − fixslot(&i->arg[0], fn, f); | |
| 359 | + fixmem(&i->arg[0], fn, f); | |
| 337 | 360 | goto Table; |
| 338 | 361 | default: |
| 339 | 362 | assert(isreg(i->arg[0])); |
| @@ -415,7 +438,7 @@ rv64_emitfn(Fn *fn, FILE *f) · 75 unmodified lines | ||
| 415 | 438 | Blk *b, *s; |
| 416 | 439 | Ins *i; |
| 417 | 440 | |
| 418 | − emitlnk(fn->name, &fn->lnk, ".text", f); | |
| 441 | + emitfnlnk(fn->name, &fn->lnk, f); | |
| 419 | 442 | |
| 420 | 443 | if (fn->vararg) { |
| 421 | 444 | /* TODO: only need space for registers |
| @@ -44,8 +44,8 @@ fixarg(Ref *r, int k, Ins *i, Fn *fn) · 43 unmodified lines | ||
| 44 | 44 | n = stashbits(&c->bits, KWIDE(k) ? 8 : 4); |
| 45 | 45 | vgrow(&fn->con, ++fn->ncon); |
| 46 | 46 | c = &fn->con[fn->ncon-1]; |
| 47 | − sprintf(buf, "fp%d", n); | |
| 48 | − *c = (Con){.type = CAddr, .local = 1}; | |
| 47 | + sprintf(buf, "\"%sfp%d\"", T.asloc, n); | |
| 48 | + *c = (Con){.type = CAddr}; | |
| 49 | 49 | c->label = intern(buf); |
| 50 | 50 | emit(Oload, k, r1, CON(c-fn->con), R); |
| 51 | 51 | break; |
| @@ -358,9 +358,9 @@ newcon(Con *c0, Fn *fn) · 357 unmodified lines | ||
| 358 | 358 | for (i=0; i<fn->ncon; i++) { |
| 359 | 359 | c1 = &fn->con[i]; |
| 360 | 360 | if (c0->type == c1->type |
| 361 | − && c0->bits.i == c1->bits.i | |
| 362 | 361 | && c0->label == c1->label |
| 363 | − && c0->local == c1->local) | |
| 362 | + && c0->bits.i == c1->bits.i | |
| 363 | + && c0->rel == c1->rel) | |
| 364 | 364 | return CON(i); |
| 365 | 365 | } |
| 366 | 366 | vgrow(&fn->con, ++fn->ncon); |