diff options
| author | Quentin Carbonneaux <[email protected]> | 2017-06-06 18:06:34 -0400 |
|---|---|---|
| committer | Quentin Carbonneaux <[email protected]> | 2017-06-06 18:12:17 -0400 |
| commit | 64c79edda0bc29d11b7efaffa9d051f64ea431d0 (patch) | |
| tree | 9175df2701786764df606e347ed5b1f347916262 /amd64/emit.c | |
| parent | 9908ae067af59cb6e43997552cb0e03e8f082f31 (diff) | |
fix fp subtractions on amd64
The stashing of constants in gas.c was also
changed to support 16-bytes constants.
Diffstat (limited to 'amd64/emit.c')
| -rw-r--r-- | amd64/emit.c | 22 |
1 files changed, 18 insertions, 4 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); |
