diff options
Diffstat (limited to 'src/dynarec/rv64/dynarec_rv64_d8.c')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_d8.c | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_d8.c b/src/dynarec/rv64/dynarec_rv64_d8.c index beadb202..7f14468b 100644 --- a/src/dynarec/rv64/dynarec_rv64_d8.c +++ b/src/dynarec/rv64/dynarec_rv64_d8.c @@ -1,7 +1,6 @@ #include <stdio.h> #include <stdlib.h> #include <stddef.h> -#include <pthread.h> #include <errno.h> #include "debug.h" @@ -50,13 +49,73 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xD0 ... 0xD7: case 0xD8 ... 0xDF: - + INST_NAME("FCOMP ST0, STx"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + LHU(x3, xEmu, offsetof(x64emu_t, sw)); + MOV32w(x1, 0b1110100011111111); // mask off c0,c1,c2,c3 + AND(x3, x3, x1); + if(ST_IS_F(0)) { + FEQS(x5, v1, v1); + FEQS(x4, v2, v2); + AND(x5, x5, x4); + BEQZ(x5, 24); // undefined/NaN + FEQS(x5, v1, v2); + BNEZ(x5, 28); // equal + FLTS(x3, v1, v2); // x3 = (v1<v2)?1:0 + SLLI(x1, x3, 8); + J(20); // end + // undefined/NaN + LUI(x1, 1); + ADDI(x1, x1, 0b010100000000); + J(8); // end + // equal + LUI(x1, 1); + // end + } else { + FEQD(x5, v1, v1); + FEQD(x4, v2, v2); + AND(x5, x5, x4); + BEQZ(x5, 24); // undefined/NaN + FEQD(x5, v1, v2); + BNEZ(x5, 28); // equal + FLTD(x3, v1, v2); // x3 = (v1<v2)?1:0 + SLLI(x1, x3, 8); + J(20); // end + // undefined/NaN + LUI(x1, 1); + ADDI(x1, x1, 0b010100000000); + J(8); // end + // equal + LUI(x1, 1); + // end + } + OR(x3, x3, x1); + SH(x3, xEmu, offsetof(x64emu_t, sw)); + x87_do_pop(dyn, ninst, x3); + break; case 0xE0 ... 0xE7: - + INST_NAME("FSUB ST0, STx"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FSUBS(v1, v1, v2); + } else { + FSUBD(v1, v1, v2); + } + break; case 0xE8 ... 0xEF: case 0xF0 ... 0xF7: - + INST_NAME("FDIV ST0, STx"); + v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); + v2 = x87_get_st(dyn, ninst, x1, x2, nextop&7, X87_COMBINE(0, nextop&7)); + if(ST_IS_F(0)) { + FDIVS(v1, v1, v2); + } else { + FDIVD(v1, v1, v2); + } + break; case 0xF8 ... 0xFF: DEFAULT; break; |