diff options
author | Quentin Carbonneaux <quentin@c9x.me> | 2017-06-06 18:06:34 -0400 |
---|---|---|
committer | Quentin Carbonneaux <quentin@c9x.me> | 2017-06-06 18:12:17 -0400 |
commit | 64c79edda0bc29d11b7efaffa9d051f64ea431d0 (patch) | |
tree | 9175df2701786764df606e347ed5b1f347916262 /amd64 | |
parent | 9908ae067af59cb6e43997552cb0e03e8f082f31 (diff) | |
download | roux-64c79edda0bc29d11b7efaffa9d051f64ea431d0.tar.gz |
fix fp subtractions on amd64
The stashing of constants in gas.c was also changed to support 16-bytes constants.
Diffstat (limited to 'amd64')
-rw-r--r-- | amd64/emit.c | 22 | ||||
-rw-r--r-- | amd64/isel.c | 2 |
2 files changed, 19 insertions, 5 deletions
diff --git a/amd64/emit.c b/amd64/emit.c index 4d4d3be..51833b4 100644 --- a/amd64/emit.c +++ b/amd64/emit.c @@ -350,6 +350,11 @@ Next: goto Next; } +static void *negmask[4] = { + [Ks] = (uint32_t[4]){ 0x80000000 }, + [Kd] = (uint64_t[2]){ 0x8000000000000000 }, +}; + static void emitins(Ins i, Fn *fn, FILE *f) { @@ -398,16 +403,25 @@ emitins(Ins i, Fn *fn, FILE *f) goto Table; case Osub: /* we have to use the negation trick to handle - * some 3-address substractions */ + * some 3-address subtractions */ if (req(i.to, i.arg[1])) { - emitf("neg%k %=", &i, fn, f); + if (KBASE(i.cls) == 0) + emitf("neg%k %=", &i, fn, f); + else + fprintf(f, + "\txorp%c %sfp%d(%%rip), %%%s\n", + "xxsd"[i.cls], + gasloc, + gasstash(negmask[i.cls], 16), + regtoa(i.to.val, SLong) + ); emitf("add%k %0, %=", &i, fn, f); break; } goto Table; case Odiv: - /* adjust the instruction when the conversion to - * a 2-address division is impossible */ + /* use xmm15 to adjust the instruction when the + * conversion to 2-address in emitf() would fail */ if (req(i.to, i.arg[1])) { i.arg[1] = TMP(XMM0+15); emitf("mov%k %=, %1", &i, fn, f); diff --git a/amd64/isel.c b/amd64/isel.c index 180439b..4202610 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -80,7 +80,7 @@ fixarg(Ref *r, int k, int op, Fn *fn) memset(&a, 0, sizeof a); a.offset.type = CAddr; a.offset.local = 1; - n = gasstashfp(fn->con[r0.val].bits.i, KWIDE(k)); + n = gasstash(&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; |