diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b4cde9c7..1ab6de74c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1001,6 +1001,11 @@ add_test(bswap ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64} -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref24.txt -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) +add_test(x87cache ${CMAKE_COMMAND} -D TEST_PROGRAM=${CMAKE_BINARY_DIR}/${BOX64} + -D TEST_ARGS=${CMAKE_SOURCE_DIR}/tests/test25 -D TEST_OUTPUT=tmpfile25.txt + -D TEST_REFERENCE=${CMAKE_SOURCE_DIR}/tests/ref25.txt + -P ${CMAKE_SOURCE_DIR}/runTest.cmake ) + file(GLOB extension_tests "${CMAKE_SOURCE_DIR}/tests/extensions/*.c") foreach(file ${extension_tests}) diff --git a/src/dynarec/arm64/dynarec_arm64_d8.c b/src/dynarec/arm64/dynarec_arm64_d8.c index a363945e4..0fd7c7c45 100644 --- a/src/dynarec/arm64/dynarec_arm64_d8.c +++ b/src/dynarec/arm64/dynarec_arm64_d8.c @@ -108,7 +108,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, v2); } FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: case 0xE1: @@ -178,7 +178,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FDIVD(v1, v2, v1); } break; - + default: switch((nextop>>3)&7) { case 0: @@ -234,7 +234,7 @@ uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, s0); } FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 4: INST_NAME("FSUB ST0, float[ED]"); diff --git a/src/dynarec/arm64/dynarec_arm64_d9.c b/src/dynarec/arm64/dynarec_arm64_d9.c index fcb44d157..2a95b10a8 100644 --- a/src/dynarec/arm64/dynarec_arm64_d9.c +++ b/src/dynarec/arm64/dynarec_arm64_d9.c @@ -51,7 +51,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xC6: case 0xC7: INST_NAME("FLD STx"); - v2 = x87_do_push(dyn, ninst, x1, X87_ST(nextop&7)); + X87_PUSH_OR_FAIL(v2, dyn, ninst, x1, X87_ST(nextop&7)); v1 = x87_get_st(dyn, ninst, x1, x2, (nextop&7)+1, X87_COMBINE(0, (nextop&7)+1)); if(ST_IS_F(0)) { FMOVS(v2, v1); @@ -84,7 +84,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xD8: INST_NAME("FSTPNCE ST0, ST0"); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD9: case 0xDA: @@ -98,7 +98,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7)); x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0); x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: INST_NAME("FCHS"); @@ -138,7 +138,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xE8: INST_NAME("FLD1"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F); if(ST_IS_F(0)) { FMOVS_8(v1, 0b01110000); } else { @@ -147,32 +147,32 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xE9: INST_NAME("FLDL2T"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D); FTABLE64(v1, L2T); break; - case 0xEA: + case 0xEA: INST_NAME("FLDL2E"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D); FTABLE64(v1, L2E); break; case 0xEB: INST_NAME("FLDPI"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D); FTABLE64(v1, PI); break; case 0xEC: INST_NAME("FLDLG2"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D); FTABLE64(v1, LG2); break; case 0xED: INST_NAME("FLDLN2"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D); FTABLE64(v1, LN2); break; case 0xEE: INST_NAME("FLDZ"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F); VEOR(v1, v1, v1); break; @@ -188,14 +188,14 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin x87_forget(dyn, ninst, x1, x2, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fyl2x, -1); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xF2: INST_NAME("FPTAN"); MESSAGE(LOG_DUMP, "Need Optimization\n"); x87_forget(dyn, ninst, x1, x2, 0); CALL(native_ftan, -1); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F); if(ST_IS_F(0)) { FMOVS_8(v1, 0b01110000); } else { @@ -208,12 +208,12 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin x87_forget(dyn, ninst, x1, x2, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fpatan, -1); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xF4: INST_NAME("FXTRACT"); MESSAGE(LOG_DUMP, "Need Optimization\n"); - x87_do_push_empty(dyn, ninst, 0); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fxtract, -1); break; @@ -253,7 +253,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin x87_forget(dyn, ninst, x1, x2, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fyl2xp1, -1); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xFA: INST_NAME("FSQRT"); @@ -267,7 +267,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xFB: INST_NAME("FSINCOS"); MESSAGE(LOG_DUMP, "Need Optimization\n"); - x87_do_push_empty(dyn, ninst, 0); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fsincos, -1); break; @@ -322,12 +322,12 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xEF: DEFAULT; break; - + default: switch((nextop>>3)&7) { case 0: INST_NAME("FLD ST0, float[ED]"); - v1 = x87_do_push(dyn, ninst, x1, box64_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, box64_dynarec_x87double?NEON_CACHE_ST_D:NEON_CACHE_ST_F); addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0); VLD32(v1, ed, fixedaddress); if(!ST_IS_F(0)) { @@ -354,7 +354,7 @@ uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCVT_S_D(v1, v1); } VST32(v1, ed, fixedaddress); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 4: INST_NAME("FLDENV Ed"); diff --git a/src/dynarec/arm64/dynarec_arm64_da.c b/src/dynarec/arm64/dynarec_arm64_da.c index 101978e79..e1735b87a 100644 --- a/src/dynarec/arm64/dynarec_arm64_da.c +++ b/src/dynarec/arm64/dynarec_arm64_da.c @@ -119,7 +119,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { FCSELD(v1, v2, v1, cNE); // F_PF==0 } - break; + break; case 0xE9: INST_NAME("FUCOMPP ST0, ST1"); v1 = x87_get_st(dyn, ninst, x1, x2, 0, X87_COMBINE(0, nextop&7)); @@ -130,8 +130,8 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, v2); } FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE4: @@ -190,7 +190,7 @@ uintptr_t dynarec64_DA(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SCVTFDD(v2, v2); // i64 -> double FCMPD(v1, v2); FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 4: INST_NAME("FISUB ST0, Ed"); diff --git a/src/dynarec/arm64/dynarec_arm64_db.c b/src/dynarec/arm64/dynarec_arm64_db.c index 897435164..f7cb93580 100644 --- a/src/dynarec/arm64/dynarec_arm64_db.c +++ b/src/dynarec/arm64/dynarec_arm64_db.c @@ -156,7 +156,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } FCOMI(x1, x2); break; - case 0xF0: + case 0xF0: case 0xF1: case 0xF2: case 0xF3: @@ -188,7 +188,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch((nextop>>3)&7) { case 0: INST_NAME("FILD ST0, Ed"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D); addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, &unscaled, 0xfff<<2, 3, rex, NULL, 0, 0); VLD32(v1, ed, fixedaddress); SXTL_32(v1, v1); // i32 -> i64 @@ -218,7 +218,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STW(x5, wback, fixedaddress); MARK3; #endif - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 2: INST_NAME("FIST Ed, ST0"); @@ -273,7 +273,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MARK3; #endif x87_restoreround(dyn, ninst, u8); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 5: INST_NAME("FLD tbyte"); @@ -296,13 +296,13 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STRH_U12(x6, ed, 8); } else { if(box64_x87_no80bits) { - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_D); VLDR64_U12(v1, ed, fixedaddress); } else { if(ed!=x1) { MOVx_REG(x1, ed); } - x87_do_push_empty(dyn, ninst, x3); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3); CALL(native_fld, -1); } } @@ -344,7 +344,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin CMPSw_REG(x3, x4); B_MARK2(cNE); // NaN and Infinite - ORRw_mask(x3, x5, 0, 0b1110); //x3 = sign | 0x7fff + ORRw_mask(x3, x5, 0, 0b1110); //x3 = sign | 0x7fff TSTx_mask(x1, 1, 0, 0b110011); //0x000fffffffffffffL ORRx_mask(x5, xZR, 1, 1, 0); //0x8000000000000000 ORRx_mask(x4, xZR, 1, 0b10, 0b01); //0xc000000000000000 @@ -372,7 +372,7 @@ uintptr_t dynarec64_DB(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STRH_U12(x3, wback, 8); #endif } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; default: DEFAULT; diff --git a/src/dynarec/arm64/dynarec_arm64_dc.c b/src/dynarec/arm64/dynarec_arm64_dc.c index bd6c98d1e..67be2c25e 100644 --- a/src/dynarec/arm64/dynarec_arm64_dc.c +++ b/src/dynarec/arm64/dynarec_arm64_dc.c @@ -106,7 +106,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, v2); } FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: case 0xE1: @@ -158,7 +158,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { FDIVD(v1, v2, v1); } - break; + break; case 0xF8: case 0xF9: case 0xFA: @@ -211,7 +211,7 @@ uintptr_t dynarec64_DC(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin VLD64(v2, wback, fixedaddress); FCMPD(v1, v2); FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 4: INST_NAME("FSUB ST0, double[ED]"); diff --git a/src/dynarec/arm64/dynarec_arm64_dd.c b/src/dynarec/arm64/dynarec_arm64_dd.c index b26979128..7c689bbfa 100644 --- a/src/dynarec/arm64/dynarec_arm64_dd.c +++ b/src/dynarec/arm64/dynarec_arm64_dd.c @@ -74,7 +74,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0xD8: INST_NAME("FSTP ST0, ST0"); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD9: case 0xDA: @@ -88,7 +88,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7)); x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0); x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: @@ -126,7 +126,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, v2); } FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xC8: @@ -160,7 +160,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch((nextop>>3)&7) { case 0: INST_NAME("FLD double"); - v1 = x87_do_push(dyn, ninst, x3, NEON_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x3, NEON_CACHE_ST_D); addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0); VLD64(v1, ed, fixedaddress); break; @@ -187,7 +187,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin STx(x5, ed, fixedaddress); MARK3; #endif - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 2: INST_NAME("FST double"); @@ -200,9 +200,9 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin v1 = x87_get_st(dyn, ninst, x1, x2, 0, NEON_CACHE_ST_D); addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0); VST64(v1, ed, fixedaddress); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; - case 4: + case 4: INST_NAME("FRSTOR m108byte"); MESSAGE(LOG_DUMP, "Need Optimization\n"); fpu_purgecache(dyn, ninst, 0, x1, x2, x3); @@ -210,7 +210,7 @@ uintptr_t dynarec64_DD(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin if(ed!=x1) {MOVx_REG(x1, ed);} CALL(native_frstor, -1); break; - case 6: + case 6: INST_NAME("FSAVE m108byte"); MESSAGE(LOG_DUMP, "Need Optimization\n"); fpu_purgecache(dyn, ninst, 0, x1, x2, x3); diff --git a/src/dynarec/arm64/dynarec_arm64_de.c b/src/dynarec/arm64/dynarec_arm64_de.c index c045d23ce..c46b0817f 100644 --- a/src/dynarec/arm64/dynarec_arm64_de.c +++ b/src/dynarec/arm64/dynarec_arm64_de.c @@ -53,7 +53,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { FADDD(v1, v1, v2); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xC8: case 0xC9: @@ -71,7 +71,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { FMULD(v1, v1, v2); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD0: case 0xD1: @@ -90,7 +90,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, v2); } FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD9: INST_NAME("FCOMPP ST0, STx"); @@ -102,8 +102,8 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, v2); } FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: case 0xE1: @@ -121,7 +121,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { FSUBD(v1, v2, v1); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE8: case 0xE9: @@ -139,7 +139,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { FSUBD(v1, v1, v2); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xF0: case 0xF1: @@ -157,8 +157,8 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { FDIVD(v1, v2, v1); } - x87_do_pop(dyn, ninst, x3); - break; + X87_POP_OR_FAIL(dyn, ninst, x3); + break; case 0xF8: case 0xF9: case 0xFA: @@ -175,7 +175,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { FDIVD(v1, v1, v2); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD8: case 0xDA: @@ -233,7 +233,7 @@ uintptr_t dynarec64_DE(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin SCVTFDD(v2, v2); FCMPD(v1, v2); FCOM(x1, x2, x3); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 4: INST_NAME("FISUB ST0, word[ED]"); diff --git a/src/dynarec/arm64/dynarec_arm64_df.c b/src/dynarec/arm64/dynarec_arm64_df.c index c1ae66a3c..40ad5066d 100644 --- a/src/dynarec/arm64/dynarec_arm64_df.c +++ b/src/dynarec/arm64/dynarec_arm64_df.c @@ -51,7 +51,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 0xC7: INST_NAME("FFREEP STx"); // not handling Tag... - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: @@ -81,7 +81,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, v2); } FCOMI(x1, x2); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xF0: case 0xF1: @@ -102,7 +102,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin FCMPD(v1, v2); } FCOMI(x1, x2); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xC8: @@ -151,7 +151,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin switch((nextop>>3)&7) { case 0: INST_NAME("FILD ST0, Ew"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_F); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<1, 1, rex, NULL, 0, 0); LDSHw(x1, wback, fixedaddress); if(ST_IS_F(0)) { @@ -196,7 +196,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MARK3; STH(x3, wback, fixedaddress); #endif - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 2: INST_NAME("FIST Ew, ST0"); @@ -275,19 +275,19 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MARK3; STH(x3, wback, fixedaddress); #endif - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); x87_restoreround(dyn, ninst, u8); break; case 4: INST_NAME("FBLD ST0, tbytes"); - x87_do_push_empty(dyn, ninst, x1); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x1); addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0); if(ed!=x1) {MOVx_REG(x1, ed);} CALL(fpu_fbld, -1); break; case 5: INST_NAME("FILD ST0, i64"); - v1 = x87_do_push(dyn, ninst, x1, NEON_CACHE_ST_I64); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, NEON_CACHE_ST_I64); addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<3, 7, rex, NULL, 0, 0); VLD64(v1, wback, fixedaddress); if(!ST_IS_I64(0)) { @@ -319,7 +319,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0); if(ed!=x1) {MOVx_REG(x1, ed);} CALL(fpu_fbst, -1); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 7: INST_NAME("FISTP i64, ST0"); @@ -375,7 +375,7 @@ uintptr_t dynarec64_DF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin #endif x87_restoreround(dyn, ninst, u8); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; default: DEFAULT; diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c index d74746869..874c2ce71 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -256,7 +256,7 @@ static uintptr_t geted_32(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t } if(nextop&0x80) i32 = F32S; - else + else i32 = F8S; if(i32==0 || ((i32>=absmin) && (i32<=absmax) && !(i32&mask)) || (unscaled && (i32>-256) && (i32<256))) { *fixaddress = i32; @@ -2098,4 +2098,4 @@ void fpu_propagate_stack(dynarec_arm_t* dyn, int ninst) dyn->n.news = 0; dyn->n.stack_push = 0; dyn->n.swapped = 0; -} \ No newline at end of file +} diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index dad782c55..8a8f9fb50 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -759,6 +759,27 @@ LDP_REGS(R12, R13); \ LDP_REGS(R14, R15) +#define X87_PUSH_OR_FAIL(var, dyn, ninst, scratch, t) \ + if (dyn->n.stack == +8) { \ + *ok = 0; \ + break; \ + } \ + var = x87_do_push(dyn, ninst, scratch, t); + +#define X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, scratch) \ + if (dyn->n.stack == +8) { \ + *ok = 0; \ + break; \ + } \ + x87_do_push_empty(dyn, ninst, scratch); + +#define X87_POP_OR_FAIL(dyn, ninst, scratch) \ + if (dyn->n.stack == -8) { \ + *ok = 0; \ + break; \ + } \ + x87_do_pop(dyn, ninst, scratch); + #define SET_DFNONE(S) if(!dyn->f.dfnone) {STRw_U12(wZR, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=1;} #define SET_DF(S, N) if((N)!=d_none) {MOVZw(S, (N)); STRw_U12(S, xEmu, offsetof(x64emu_t, df)); dyn->f.dfnone=0;} else SET_DFNONE(S) #define SET_NODF() dyn->f.dfnone = 0 @@ -989,9 +1010,9 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define emit_pf STEPNAME(emit_pf) -#define x87_do_push STEPNAME(x87_do_push) -#define x87_do_push_empty STEPNAME(x87_do_push_empty) -#define x87_do_pop STEPNAME(x87_do_pop) +#define x87_do_push STEPNAME(x87_do_push) +#define x87_do_push_empty STEPNAME(x87_do_push_empty) +#define x87_do_pop STEPNAME(x87_do_pop) #define x87_get_current_cache STEPNAME(x87_get_current_cache) #define x87_get_cache STEPNAME(x87_get_cache) #define x87_get_neoncache STEPNAME(x87_get_neoncache) diff --git a/src/dynarec/rv64/dynarec_rv64_d8.c b/src/dynarec/rv64/dynarec_rv64_d8.c index 7f14468bc..e293236e7 100644 --- a/src/dynarec/rv64/dynarec_rv64_d8.c +++ b/src/dynarec/rv64/dynarec_rv64_d8.c @@ -43,7 +43,7 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni switch(nextop) { case 0xC0 ... 0xC7: - + case 0xC8 ... 0xCF: case 0xD0 ... 0xD7: @@ -92,7 +92,7 @@ uintptr_t dynarec64_D8(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } OR(x3, x3, x1); SH(x3, xEmu, offsetof(x64emu_t, sw)); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0 ... 0xE7: INST_NAME("FSUB ST0, STx"); diff --git a/src/dynarec/rv64/dynarec_rv64_d9.c b/src/dynarec/rv64/dynarec_rv64_d9.c index 4940d6b41..d5f2ad6dc 100644 --- a/src/dynarec/rv64/dynarec_rv64_d9.c +++ b/src/dynarec/rv64/dynarec_rv64_d9.c @@ -54,7 +54,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xC6: case 0xC7: INST_NAME("FLD STx"); - v2 = x87_do_push(dyn, ninst, x1, X87_ST(nextop&7)); + X87_PUSH_OR_FAIL(v2, dyn, ninst, x1, X87_ST(nextop&7)); v1 = x87_get_st(dyn, ninst, x1, x2, (nextop&7)+1, X87_COMBINE(0, (nextop&7)+1)); if(ST_IS_F(0)) { FMVS(v2, v1); @@ -87,7 +87,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xD8: INST_NAME("FSTPNCE ST0, ST0"); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD9: case 0xDA: @@ -101,7 +101,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7)); x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0); x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: INST_NAME("FCHS"); @@ -135,7 +135,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xE8: INST_NAME("FLD1"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_F); if(ST_IS_F(0)) { MOV32w(x1, 0x3f800000); FMVWX(v1, x1); @@ -146,32 +146,32 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni break; case 0xE9: INST_NAME("FLDL2T"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); FTABLE64(v1, L2T); break; - case 0xEA: + case 0xEA: INST_NAME("FLDL2E"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); FTABLE64(v1, L2E); break; case 0xEB: INST_NAME("FLDPI"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); FTABLE64(v1, PI); break; case 0xEC: INST_NAME("FLDLG2"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); FTABLE64(v1, LG2); break; case 0xED: INST_NAME("FLDLN2"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); FTABLE64(v1, LN2); break; case 0xEE: INST_NAME("FLDZ"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_F); if(ST_IS_F(0)) { FMVWX(v1, xZR); } else { @@ -191,14 +191,14 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni x87_forget(dyn, ninst, x1, x2, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fyl2x, -1); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xF2: INST_NAME("FPTAN"); MESSAGE(LOG_DUMP, "Need Optimization\n"); x87_forget(dyn, ninst, x1, x2, 0); CALL(native_ftan, -1); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_F); if(ST_IS_F(0)) { MOV32w(x1, 0x3f800000); FMVWX(v1, x1); @@ -213,12 +213,12 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni x87_forget(dyn, ninst, x1, x2, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fpatan, -1); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xF4: INST_NAME("FXTRACT"); MESSAGE(LOG_DUMP, "Need Optimization\n"); - x87_do_push_empty(dyn, ninst, 0); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fxtract, -1); break; @@ -258,7 +258,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni x87_forget(dyn, ninst, x1, x2, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fyl2xp1, -1); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xFA: INST_NAME("FSQRT"); @@ -272,7 +272,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xFB: INST_NAME("FSINCOS"); MESSAGE(LOG_DUMP, "Need Optimization\n"); - x87_do_push_empty(dyn, ninst, 0); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0); x87_forget(dyn, ninst, x1, x2, 1); CALL(native_fsincos, -1); break; @@ -349,12 +349,12 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xEF: DEFAULT; break; - + default: switch((nextop>>3)&7) { case 0: INST_NAME("FLD ST0, float[ED]"); - v1 = x87_do_push(dyn, ninst, x1, box64_dynarec_x87double?EXT_CACHE_ST_D:EXT_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, box64_dynarec_x87double?EXT_CACHE_ST_D:EXT_CACHE_ST_F); addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); FLW(v1, ed, fixedaddress); if(!ST_IS_F(0)) { @@ -381,7 +381,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni FCVTSD(v1, v1); } FSW(v1, ed, fixedaddress); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 4: INST_NAME("FLDENV Ed"); diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c index 7a5dddb0e..362861971 100644 --- a/src/dynarec/rv64/dynarec_rv64_db.c +++ b/src/dynarec/rv64/dynarec_rv64_db.c @@ -189,7 +189,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } } break; - case 0xF0: + case 0xF0: case 0xF1: case 0xF2: case 0xF3: @@ -213,7 +213,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni switch((nextop>>3)&7) { case 0: INST_NAME("FILD ST0, Ed"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); LW(x1, ed, fixedaddress); FCVTDW(v1, x1, RD_RNE); // i32 -> double @@ -245,7 +245,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } MARK2; SW(x4, wback, fixedaddress); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 5: INST_NAME("FLD tbyte"); @@ -268,13 +268,13 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SH(x6, ed, fixedaddress+8); } else { if(box64_x87_no80bits) { - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); FLD(v1, ed, fixedaddress); } else { if(ed!=x1) { MV(x1, ed); } - x87_do_push_empty(dyn, ninst, x3); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3); CALL(native_fld, -1); } } @@ -293,7 +293,7 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } CALL(native_fstp, -1); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; default: DEFAULT; diff --git a/src/dynarec/rv64/dynarec_rv64_dc.c b/src/dynarec/rv64/dynarec_rv64_dc.c index d802e2fbc..6a84c6037 100644 --- a/src/dynarec/rv64/dynarec_rv64_dc.c +++ b/src/dynarec/rv64/dynarec_rv64_dc.c @@ -101,7 +101,7 @@ uintptr_t dynarec64_DC(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni OR(x3, x3, x1); SH(x3, xEmu, offsetof(x64emu_t, sw)); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 6: INST_NAME("FDIV ST0, double[ED]"); diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c index 044f9aab0..b5a282e1f 100644 --- a/src/dynarec/rv64/dynarec_rv64_dd.c +++ b/src/dynarec/rv64/dynarec_rv64_dd.c @@ -68,7 +68,7 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni break; case 0xD8: INST_NAME("FSTP ST0, ST0"); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD9: case 0xDA: @@ -82,7 +82,7 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni x87_get_st_empty(dyn, ninst, x1, x2, nextop&7, X87_ST(nextop&7)); x87_get_st(dyn, ninst, x1, x2, 0, X87_ST0); x87_swapreg(dyn, ninst, x1, x2, 0, nextop&7); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE0: case 0xE1: @@ -137,7 +137,7 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni switch((nextop>>3)&7) { case 0: INST_NAME("FLD double"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0); FLD(v1, wback, fixedaddress); break; @@ -152,7 +152,7 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0); FSD(v1, wback, fixedaddress); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 7: INST_NAME("FNSTSW m2byte"); diff --git a/src/dynarec/rv64/dynarec_rv64_de.c b/src/dynarec/rv64/dynarec_rv64_de.c index a2341b40c..6712a97ca 100644 --- a/src/dynarec/rv64/dynarec_rv64_de.c +++ b/src/dynarec/rv64/dynarec_rv64_de.c @@ -52,7 +52,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { FADDD(v1, v1, v2); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xC8: case 0xC9: @@ -70,7 +70,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { FMULD(v1, v1, v2); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD0: case 0xD1: @@ -103,7 +103,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { FSUBD(v1, v2, v1); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xE8: case 0xE9: @@ -121,7 +121,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { FSUBD(v1, v1, v2); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xF0: case 0xF1: @@ -139,8 +139,8 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { FDIVD(v1, v2, v1); } - x87_do_pop(dyn, ninst, x3); - break; + X87_POP_OR_FAIL(dyn, ninst, x3); + break; case 0xF8: case 0xF9: case 0xFA: @@ -157,7 +157,7 @@ uintptr_t dynarec64_DE(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { FDIVD(v1, v1, v2); } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xD8: case 0xDA: diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c index de99b02a5..01d7b67ae 100644 --- a/src/dynarec/rv64/dynarec_rv64_df.c +++ b/src/dynarec/rv64/dynarec_rv64_df.c @@ -103,7 +103,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // end } } - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 0xC8 ... 0xDF: case 0xE1 ... 0xE7: @@ -115,7 +115,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni switch((nextop>>3)&7) { case 0: INST_NAME("FILD ST0, Ew"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_F); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_F); addr = geted(dyn, addr, ninst, nextop, &wback, x3, x4, &fixedaddress, rex, NULL, 1, 0); LH(x1, wback, fixedaddress); if(ST_IS_F(0)) { @@ -144,7 +144,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } MARK2; SH(x4, wback, fixedaddress); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 3: INST_NAME("FISTP Ew, ST0"); @@ -168,11 +168,11 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } MARK2; SH(x4, wback, fixedaddress); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 5: INST_NAME("FILD ST0, i64"); - v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D); + X87_PUSH_OR_FAIL(v1, dyn, ninst, x1, EXT_CACHE_ST_D); addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0); LD(x1, wback, fixedaddress); if (rex.is32bits) { @@ -233,7 +233,7 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SD(x4, wback, fixedaddress); MARK3; x87_restoreround(dyn, ninst, u8); - x87_do_pop(dyn, ninst, x3); + X87_POP_OR_FAIL(dyn, ninst, x3); break; default: DEFAULT; diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c index 541ac45fc..f01c638bf 100644 --- a/src/dynarec/rv64/dynarec_rv64_functions.c +++ b/src/dynarec/rv64/dynarec_rv64_functions.c @@ -58,7 +58,7 @@ void fpu_free_reg(dynarec_rv64_t* dyn, int reg) int idx = EXTIDX(reg); // TODO: check upper limit? dyn->e.fpuused[idx] = 0; - if(dyn->e.extcache[reg].t!=EXT_CACHE_ST_F && dyn->e.extcache[reg].t!=EXT_CACHE_ST_D) + if(dyn->e.extcache[idx].t!=EXT_CACHE_ST_F && dyn->e.extcache[idx].t!=EXT_CACHE_ST_D) dyn->e.extcache[idx].v = 0; } // Get an MMX double reg @@ -494,7 +494,7 @@ const char* getCacheName(int t, int n) void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex) { static const char* fnames[] = { - "ft0"," ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", + "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", "fs8", "fs9", "fs10", "fs11", @@ -561,4 +561,4 @@ void print_newinst(dynarec_native_t* dyn, int ninst) ninst, dyn->block, dyn->native_size, (box64_dynarec_dump>1)?"\e[m":"" ); -} \ No newline at end of file +} diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 294db0ee9..ecb1bf550 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -1675,9 +1675,9 @@ static void swapCache(dynarec_rv64_t* dyn, int ninst, int i, int j, extcache_t * // SWAP ext_cache_t tmp; MESSAGE(LOG_DUMP, "\t - Swapping %d <-> %d\n", i, j); - // There is no VSWP in Arm64 NEON to swap 2 register contents! + // There is no swap instruction in RV64 to swap 2 float registers! // so use a scratch... - #define SCRATCH 0 + #define SCRATCH 2 if(i_single) FMVS(SCRATCH, reg_i); else diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 02bc52112..78a9cecef 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -864,6 +864,28 @@ SLLI(dst, dst, 11 - 5); \ OR(dst, dst, s1) +#define X87_PUSH_OR_FAIL(var, dyn, ninst, scratch, t) \ + if (dyn->e.stack == +8) { \ + *ok = 0; \ + break; \ + } \ + var = x87_do_push(dyn, ninst, scratch, t); + +#define X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, scratch) \ + if (dyn->e.stack == +8) { \ + *ok = 0; \ + break; \ + } \ + x87_do_push_empty(dyn, ninst, scratch); + +#define X87_POP_OR_FAIL(dyn, ninst, scratch) \ + if (dyn->e.stack == -8) { \ + *ok = 0; \ + break; \ + } \ + x87_do_pop(dyn, ninst, scratch); + + #ifndef MAYSETFLAGS #define MAYSETFLAGS() #endif diff --git a/tests/ref25.txt b/tests/ref25.txt new file mode 100644 index 000000000..374f79b41 --- /dev/null +++ b/tests/ref25.txt @@ -0,0 +1,10 @@ +8.000000 +7.000000 +6.000000 +5.000000 +4.000000 +3.000000 +2.000000 +1.000000 +0.000000 +0.000000 diff --git a/tests/test25 b/tests/test25 new file mode 100755 index 000000000..2d65eadf9 Binary files /dev/null and b/tests/test25 differ diff --git a/tests/test25.c b/tests/test25.c new file mode 100644 index 000000000..6f0be714a --- /dev/null +++ b/tests/test25.c @@ -0,0 +1,47 @@ +#include +// Build with `gcc -march=core2 -O2 test25.c -o test25` + +asm( +"foo: \n\t" + "flds 0(%rdi) \n\t" + "flds 4(%rdi) \n\t" + "flds 8(%rdi) \n\t" + "flds 12(%rdi) \n\t" + "flds 16(%rdi) \n\t" + "flds 20(%rdi) \n\t" + "flds 24(%rdi) \n\t" + "flds 28(%rdi) \n\t" + "cmp $0, %rdi \n\t" + "je 1f \n\t" + "jne 1f \n\t" + "flds 32(%rdi) \n\t" + "flds 36(%rdi) \n\t" +"1: \n\t" + "fstps 0(%rsi) \n\t" + "fstps 4(%rsi) \n\t" + "fstps 8(%rsi) \n\t" + "fstps 12(%rsi) \n\t" + "fstps 16(%rsi) \n\t" + "fstps 20(%rsi) \n\t" + "fstps 24(%rsi) \n\t" + "fstps 28(%rsi) \n\t" + "je 1f \n\t" + "jne 1f \n\t" + "fstps 32(%rdi) \n\t" + "fstps 36(%rdi) \n\t" +"1: \n\t" + "ret \n\t" +); + +extern void foo(float* src, float* dst); + +int main(void) +{ + float src[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + float dst[10] = { 0 }; + foo(src, dst); + for (int i = 0; i < 10; ++i) { + printf("%f\n", dst[i]); + } + return 0; +}