diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-11-21 15:06:47 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-11-21 08:06:47 +0100 |
| commit | d1a253f4694588ad6efafc36a3240687034f8780 (patch) | |
| tree | f73d1870f8490c48dd98ac6f459a2d5bd62523b5 /src | |
| parent | 6aa57f5c73d2450964f1f47ee0c68b836da22a0f (diff) | |
| download | box64-d1a253f4694588ad6efafc36a3240687034f8780.tar.gz box64-d1a253f4694588ad6efafc36a3240687034f8780.zip | |
[DYNAREC] Reuse strongmem infra for all backends (#2052)
Diffstat (limited to 'src')
105 files changed, 302 insertions, 636 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index facfd3df..2e7dec88 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" int isSimpleWrapper(wrapper_t fun); int isRetX87Wrapper(wrapper_t fun); diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c index d7ea133d..91a78dfb 100644 --- a/src/dynarec/arm64/dynarec_arm64_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_0f.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_64.c b/src/dynarec/arm64/dynarec_arm64_64.c index 636b9b02..5cea1394 100644 --- a/src/dynarec/arm64/dynarec_arm64_64.c +++ b/src/dynarec/arm64/dynarec_arm64_64.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog) diff --git a/src/dynarec/arm64/dynarec_arm64_66.c b/src/dynarec/arm64/dynarec_arm64_66.c index 0d2b69c6..e8880dc2 100644 --- a/src/dynarec/arm64/dynarec_arm64_66.c +++ b/src/dynarec/arm64/dynarec_arm64_66.c @@ -20,7 +20,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c index d2deeb3b..51426742 100644 --- a/src/dynarec/arm64/dynarec_arm64_660f.c +++ b/src/dynarec/arm64/dynarec_arm64_660f.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "emu/x64compstrings.h" uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) diff --git a/src/dynarec/arm64/dynarec_arm64_6664.c b/src/dynarec/arm64/dynarec_arm64_6664.c index 6131c4d3..dfc1bef1 100644 --- a/src/dynarec/arm64/dynarec_arm64_6664.c +++ b/src/dynarec/arm64/dynarec_arm64_6664.c @@ -18,7 +18,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" uintptr_t dynarec64_6664(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog) diff --git a/src/dynarec/arm64/dynarec_arm64_66f0.c b/src/dynarec/arm64/dynarec_arm64_66f0.c index b1fead1a..7f2b2d0f 100644 --- a/src/dynarec/arm64/dynarec_arm64_66f0.c +++ b/src/dynarec/arm64/dynarec_arm64_66f0.c @@ -18,7 +18,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_66f20f.c b/src/dynarec/arm64/dynarec_arm64_66f20f.c index 869cf308..6c94873a 100644 --- a/src/dynarec/arm64/dynarec_arm64_66f20f.c +++ b/src/dynarec/arm64/dynarec_arm64_66f20f.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "emu/x64compstrings.h" uintptr_t dynarec64_66F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) diff --git a/src/dynarec/arm64/dynarec_arm64_66f30f.c b/src/dynarec/arm64/dynarec_arm64_66f30f.c index 66e349df..b33c7528 100644 --- a/src/dynarec/arm64/dynarec_arm64_66f30f.c +++ b/src/dynarec/arm64/dynarec_arm64_66f30f.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "emu/x64compstrings.h" uintptr_t dynarec64_66F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) diff --git a/src/dynarec/arm64/dynarec_arm64_67.c b/src/dynarec/arm64/dynarec_arm64_67.c index f570f0a1..9d6059a1 100644 --- a/src/dynarec/arm64/dynarec_arm64_67.c +++ b/src/dynarec/arm64/dynarec_arm64_67.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" #define GETGm gd = ((nextop&0x38)>>3) diff --git a/src/dynarec/arm64/dynarec_arm64_6764_32.c b/src/dynarec/arm64/dynarec_arm64_6764_32.c index 58abbf4b..c5ef6fdc 100644 --- a/src/dynarec/arm64/dynarec_arm64_6764_32.c +++ b/src/dynarec/arm64/dynarec_arm64_6764_32.c @@ -18,7 +18,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" #define GETGm gd = ((nextop&0x38)>>3) diff --git a/src/dynarec/arm64/dynarec_arm64_67_32.c b/src/dynarec/arm64/dynarec_arm64_67_32.c index 61556716..6a1e1d7e 100644 --- a/src/dynarec/arm64/dynarec_arm64_67_32.c +++ b/src/dynarec/arm64/dynarec_arm64_67_32.c @@ -18,7 +18,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" #define GETGm gd = ((nextop&0x38)>>3) diff --git a/src/dynarec/arm64/dynarec_arm64_67_avx.c b/src/dynarec/arm64/dynarec_arm64_67_avx.c index 6c00a9dc..fd78ff24 100644 --- a/src/dynarec/arm64/dynarec_arm64_67_avx.c +++ b/src/dynarec/arm64/dynarec_arm64_67_avx.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" static const char* avx_prefix_string(uint16_t p) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx.c b/src/dynarec/arm64/dynarec_arm64_avx.c index 10a122a0..0fa47ec0 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx.c +++ b/src/dynarec/arm64/dynarec_arm64_avx.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" static const char* avx_prefix_string(uint16_t p) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_0f.c index 4a048e00..2cdc6e51 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_0f.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_0f38.c b/src/dynarec/arm64/dynarec_arm64_avx_0f38.c index fa18d943..d07f6d6f 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_0f38.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_0f38.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c index 8f6dfe7a..4acb4d31 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c index 2c5947cf..9582a810 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" static const float addsubps[4] = {-1.f, 1.f, -1.f, 1.f}; static const double addsubpd[2] = {-1., 1.}; diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c index 853f3207..f92c2a71 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c index 65dfb240..9845fa5d 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_f2_0f.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_F2_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_f2_0f38.c b/src/dynarec/arm64/dynarec_arm64_avx_f2_0f38.c index 779fb217..30d6d331 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_f2_0f38.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_f2_0f38.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_F2_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_f2_0f3a.c b/src/dynarec/arm64/dynarec_arm64_avx_f2_0f3a.c index 0fa4f010..2c7f6191 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_f2_0f3a.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_f2_0f3a.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_F2_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_f3_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_f3_0f.c index d4e0400e..cb7d7cdb 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_f3_0f.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_f3_0f.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_F3_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_avx_f3_0f38.c b/src/dynarec/arm64/dynarec_arm64_avx_f3_0f38.c index b1bfd39e..aa554c08 100644 --- a/src/dynarec/arm64/dynarec_arm64_avx_f3_0f38.c +++ b/src/dynarec/arm64/dynarec_arm64_avx_f3_0f38.c @@ -22,7 +22,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_F3_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_d8.c b/src/dynarec/arm64/dynarec_arm64_d8.c index fc481aea..e8f002a4 100644 --- a/src/dynarec/arm64/dynarec_arm64_d8.c +++ b/src/dynarec/arm64/dynarec_arm64_d8.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_d9.c b/src/dynarec/arm64/dynarec_arm64_d9.c index 9c8610be..9a002202 100644 --- a/src/dynarec/arm64/dynarec_arm64_d9.c +++ b/src/dynarec/arm64/dynarec_arm64_d9.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_da.c b/src/dynarec/arm64/dynarec_arm64_da.c index afb5130d..52965b3f 100644 --- a/src/dynarec/arm64/dynarec_arm64_da.c +++ b/src/dynarec/arm64/dynarec_arm64_da.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_db.c b/src/dynarec/arm64/dynarec_arm64_db.c index 9dc1d673..68e36ef4 100644 --- a/src/dynarec/arm64/dynarec_arm64_db.c +++ b/src/dynarec/arm64/dynarec_arm64_db.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_dc.c b/src/dynarec/arm64/dynarec_arm64_dc.c index 76f43bc5..ee5b2c62 100644 --- a/src/dynarec/arm64/dynarec_arm64_dc.c +++ b/src/dynarec/arm64/dynarec_arm64_dc.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_dd.c b/src/dynarec/arm64/dynarec_arm64_dd.c index afef3358..6ce37042 100644 --- a/src/dynarec/arm64/dynarec_arm64_dd.c +++ b/src/dynarec/arm64/dynarec_arm64_dd.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_de.c b/src/dynarec/arm64/dynarec_arm64_de.c index 7ea3b357..7dbbb210 100644 --- a/src/dynarec/arm64/dynarec_arm64_de.c +++ b/src/dynarec/arm64/dynarec_arm64_de.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_df.c b/src/dynarec/arm64/dynarec_arm64_df.c index 79c59bfd..cef734bf 100644 --- a/src/dynarec/arm64/dynarec_arm64_df.c +++ b/src/dynarec/arm64/dynarec_arm64_df.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_emit_logic.c b/src/dynarec/arm64/dynarec_arm64_emit_logic.c index 7433dc86..fc7e6ef0 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_logic.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_logic.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" // emit OR32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch void emit_or32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4) diff --git a/src/dynarec/arm64/dynarec_arm64_emit_math.c b/src/dynarec/arm64/dynarec_arm64_emit_math.c index d8873e76..91e7a932 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_math.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_math.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" // emit ADD32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch void emit_add32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4) diff --git a/src/dynarec/arm64/dynarec_arm64_emit_shift.c b/src/dynarec/arm64/dynarec_arm64_emit_shift.c index f57aea7d..d9e5174f 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_shift.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_shift.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" // emit SHL32 instruction, from s1 , shift s2, store result in s1 using s3 and s4 as scratch. s3 can be same as s2. s2 must be non-0 void emit_shl32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4) diff --git a/src/dynarec/arm64/dynarec_arm64_emit_tests.c b/src/dynarec/arm64/dynarec_arm64_emit_tests.c index 1c78fa53..9933934f 100644 --- a/src/dynarec/arm64/dynarec_arm64_emit_tests.c +++ b/src/dynarec/arm64/dynarec_arm64_emit_tests.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" // emit CMP32 instruction, from cmp s1, s2, using s3 and s4 as scratch void emit_cmp32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c index 00cb91f2..9ddc0b3a 100644 --- a/src/dynarec/arm64/dynarec_arm64_f0.c +++ b/src/dynarec/arm64/dynarec_arm64_f0.c @@ -18,7 +18,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_arm64_functions.h" diff --git a/src/dynarec/arm64/dynarec_arm64_f20f.c b/src/dynarec/arm64/dynarec_arm64_f20f.c index 6563aea1..4b03143c 100644 --- a/src/dynarec/arm64/dynarec_arm64_f20f.c +++ b/src/dynarec/arm64/dynarec_arm64_f20f.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_f30f.c b/src/dynarec/arm64/dynarec_arm64_f30f.c index 752595fd..e223f321 100644 --- a/src/dynarec/arm64/dynarec_arm64_f30f.c +++ b/src/dynarec/arm64/dynarec_arm64_f30f.c @@ -19,7 +19,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c index 1b56127e..aca3e788 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -23,7 +23,7 @@ #include "arm64_printer.h" #include "dynarec_arm64_private.h" #include "dynarec_arm64_functions.h" -#include "dynarec_arm64_helper.h" +#include "../dynarec_helper.h" static uintptr_t geted_32(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, int64_t* fixaddress, int* unscaled, int absmax, uint32_t mask, int* l, int s); diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 1979c90e..c07ba709 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -36,189 +36,6 @@ #define FEMIT(A) EMIT(A) #endif -/* Box64 Strong Memory Model Emulation - * - * Definition of a SEQ: - * A SEQ is a sequence of opcodes that writes to guest memory, terminated by JMP, RET, CALL, etc. - * - * Memory barriers are added in the following cases to emulate the strong memory model: - * 1. End of a SEQ: - * - Scalar operations (a1) - * - SIMD operations (a2) - * 2. Start of a SEQ: - * - Scalar operations (b1) - * - SIMD operations (b2) - * 3. Right before the last guest memory store in a SEQ: - * - Scalar operations (c1) - * - SIMD operations (c2) - * 4. After every third guest memory store in a SEQ (d) - * - * STRONGMEM levels (coarse-grained): - * 1: Includes a1, b1, c1 - * 2: Includes LEVEL1, plus a2, b2, c2 - * 3: Includes LEVEL2, plus d - * - * WEAKBARRIER levels (fine-grained): - * 1: Use dmb.ishld and dmb.ishst over dmb.ish for more performance - * 2. All 1. Plus disabled the last write barriers (c1, c2) - */ - -#define STRONGMEM_SIMD_WRITE 2 // The level of SIMD memory writes will be tracked -#define STRONGMEM_LAST_WRITE 1 // The level of a barrier before the last guest memory store will be put -#define STRONGMEM_SEQ_WRITE 3 // The level of a barrier at every third memory store will be put - -#if STEP == 1 - -#define SMWRITE() \ - do { \ - /* Mark that current sequence writes to guest memory. */ \ - /* This will be used in SMEND for last_write. */ \ - dyn->smwrite = 1; \ - /* Mark that current opcode writes to guest memory. */ \ - dyn->insts[ninst].will_write = 1; \ - } while (0) - -#define SMWRITELOCK(lock) \ - do { \ - dyn->insts[ninst].lock = lock; \ - SMWRITE(); \ - } while (0) - -#define SMWRITE2() \ - do { \ - if (box64_dynarec_strongmem >= STRONGMEM_SIMD_WRITE) { \ - dyn->smwrite = 1; \ - dyn->insts[ninst].will_write = 2; \ - } \ - } while (0) - -#define SMREAD() -#define SMREADLOCK(lock) -#define WILLWRITE() -#define WILLWRITELOCK(lock) - -#define SMSTART() \ - do { \ - /* Clear current state at the start of a potential SEQ. */ \ - dyn->smwrite = 0; \ - } while (0) - -#define SMEND() \ - do { \ - /* If there is any guest memory write, which is a SEQ, then compute the last_write. */ \ - if (dyn->smwrite && (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE)) { \ - int i = ninst; \ - while (i >= 0 && !dyn->insts[i].will_write) \ - --i; \ - if (i >= 0) { dyn->insts[i].last_write = 1; } \ - } \ - dyn->smwrite = 0; \ - } while (0) - -#define SMDMB() - -#else - -// An opcode writes guest memory, this need to be put after the STORE instruction manually. -#define SMWRITE() \ - do { \ - /* Put a barrier at every third memory write. */ \ - if (box64_dynarec_strongmem >= STRONGMEM_SEQ_WRITE) { \ - if (++dyn->smwrite >= 3 /* Every third memory write */) { \ - DMB_ISH(); \ - dyn->smwrite = 1; \ - } \ - } else { \ - /* Mark that current sequence writes to guest memory. */ \ - dyn->smwrite = 1; \ - } \ - } while (0) - -// Similar to SMWRITE, but checks lock. -#define SMWRITELOCK(lock) \ - do { \ - if (lock) { \ - DMB_ISH(); \ - } else { \ - SMWRITE(); \ - } \ - } while (0) - -// Similar to SMWRITE, but for SIMD instructions. -#define SMWRITE2() \ - do { \ - if (box64_dynarec_strongmem >= STRONGMEM_SIMD_WRITE) \ - SMWRITE(); \ - } while (0) - -// An opcode reads guest memory, this need to be put before the LOAD instruction manually. -#define SMREAD() - -// Similar to SMREAD, but checks lock. -#define SMREADLOCK(lock) \ - do { \ - if (lock) { \ - DMB_ISH(); \ - } else { \ - SMREAD(); \ - } \ - } while (0) - -// An opcode will write memory, this will be put before the STORE instruction automatically. -#define WILLWRITE() \ - do { \ - if (box64_dynarec_strongmem >= dyn->insts[ninst].will_write && dyn->smwrite == 0) { \ - /* Will write but never written, this is the start of a SEQ, put a barrier. */ \ - if (box64_dynarec_weakbarrier) \ - DMB_ISHLD(); \ - else \ - DMB_ISH(); \ - } else if (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE && box64_dynarec_weakbarrier != 2 \ - && dyn->insts[ninst].last_write) { \ - /* Last write, put a barrier */ \ - if (box64_dynarec_weakbarrier) \ - DMB_ISHST(); \ - else \ - DMB_ISH(); \ - } \ - } while (0) - -// Similar to WILLWRITE, but checks lock. -#define WILLWRITELOCK(lock) \ - do { \ - if (lock) { \ - DMB_ISH(); \ - } else { \ - WILLWRITE(); \ - } \ - } while (0) - -// Used to clear the state at the start of a SEQ -#define SMSTART() \ - do { \ - dyn->smwrite = 0; \ - } while (0) - -// Will be put at the end of the SEQ -#define SMEND() \ - do { \ - if (box64_dynarec_strongmem) { \ - /* It's a SEQ, put a barrier here. */ \ - if (dyn->smwrite) { \ - /* Check if the next instruction has a end loop mark */ \ - if (box64_dynarec_weakbarrier) \ - DMB_ISHST(); \ - else \ - DMB_ISH(); \ - } \ - } \ - dyn->smwrite = 0; \ - } while (0) - -// The barrier. -#define SMDMB() DMB_ISH() -#endif - //LOCK_* define #define LOCK_LOCK (int*)1 diff --git a/src/dynarec/dynarec_helper.h b/src/dynarec/dynarec_helper.h index c20c9d74..1f567be2 100644 --- a/src/dynarec/dynarec_helper.h +++ b/src/dynarec/dynarec_helper.h @@ -1,6 +1,189 @@ #ifndef __DYNAREC_HELPER__H_ #define __DYNAREC_HELPER__H_ +/* Box64 Strong Memory Model Emulation + * + * Definition of a SEQ: + * A SEQ is a sequence of opcodes that writes to guest memory, terminated by JMP, RET, CALL, etc. + * + * Memory barriers are added in the following cases to emulate the strong memory model: + * 1. End of a SEQ: + * - Scalar operations (a1) + * - SIMD operations (a2) + * 2. Start of a SEQ: + * - Scalar operations (b1) + * - SIMD operations (b2) + * 3. Right before the last guest memory store in a SEQ: + * - Scalar operations (c1) + * - SIMD operations (c2) + * 4. After every third guest memory store in a SEQ (d) + * + * STRONGMEM levels (coarse-grained): + * 1: Includes a1, b1, c1 + * 2: Includes LEVEL1, plus a2, b2, c2 + * 3: Includes LEVEL2, plus d + * + * WEAKBARRIER levels (fine-grained): + * 1: Use dmb.ishld and dmb.ishst over dmb.ish for more performance + * 2. All 1. Plus disabled the last write barriers (c1, c2) + */ + +#define STRONGMEM_SIMD_WRITE 2 // The level of SIMD memory writes will be tracked +#define STRONGMEM_LAST_WRITE 1 // The level of a barrier before the last guest memory store will be put +#define STRONGMEM_SEQ_WRITE 3 // The level of a barrier at every third memory store will be put + +#if STEP == 1 + +#define SMWRITE() \ + do { \ + /* Mark that current sequence writes to guest memory. */ \ + /* This will be used in SMEND for last_write. */ \ + dyn->smwrite = 1; \ + /* Mark that current opcode writes to guest memory. */ \ + dyn->insts[ninst].will_write = 1; \ + } while (0) + +#define SMWRITELOCK(lock) \ + do { \ + dyn->insts[ninst].lock = lock; \ + SMWRITE(); \ + } while (0) + +#define SMWRITE2() \ + do { \ + if (box64_dynarec_strongmem >= STRONGMEM_SIMD_WRITE) { \ + dyn->smwrite = 1; \ + dyn->insts[ninst].will_write = 2; \ + } \ + } while (0) + +#define SMREAD() +#define SMREADLOCK(lock) +#define WILLWRITE() +#define WILLWRITELOCK(lock) + +#define SMSTART() \ + do { \ + /* Clear current state at the start of a potential SEQ. */ \ + dyn->smwrite = 0; \ + } while (0) + +#define SMEND() \ + do { \ + /* If there is any guest memory write, which is a SEQ, then compute the last_write. */ \ + if (dyn->smwrite && (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE)) { \ + int i = ninst; \ + while (i >= 0 && !dyn->insts[i].will_write) \ + --i; \ + if (i >= 0) { dyn->insts[i].last_write = 1; } \ + } \ + dyn->smwrite = 0; \ + } while (0) + +#define SMDMB() + +#else + +// An opcode writes guest memory, this need to be put after the STORE instruction manually. +#define SMWRITE() \ + do { \ + /* Put a barrier at every third memory write. */ \ + if (box64_dynarec_strongmem >= STRONGMEM_SEQ_WRITE) { \ + if (++dyn->smwrite >= 3 /* Every third memory write */) { \ + DMB_ISH(); \ + dyn->smwrite = 1; \ + } \ + } else { \ + /* Mark that current sequence writes to guest memory. */ \ + dyn->smwrite = 1; \ + } \ + } while (0) + +// Similar to SMWRITE, but checks lock. +#define SMWRITELOCK(lock) \ + do { \ + if (lock) { \ + DMB_ISH(); \ + } else { \ + SMWRITE(); \ + } \ + } while (0) + +// Similar to SMWRITE, but for SIMD instructions. +#define SMWRITE2() \ + do { \ + if (box64_dynarec_strongmem >= STRONGMEM_SIMD_WRITE) \ + SMWRITE(); \ + } while (0) + +// An opcode reads guest memory, this need to be put before the LOAD instruction manually. +#define SMREAD() + +// Similar to SMREAD, but checks lock. +#define SMREADLOCK(lock) \ + do { \ + if (lock) { \ + DMB_ISH(); \ + } else { \ + SMREAD(); \ + } \ + } while (0) + +// An opcode will write memory, this will be put before the STORE instruction automatically. +#define WILLWRITE() \ + do { \ + if (box64_dynarec_strongmem >= dyn->insts[ninst].will_write && dyn->smwrite == 0) { \ + /* Will write but never written, this is the start of a SEQ, put a barrier. */ \ + if (box64_dynarec_weakbarrier) \ + DMB_ISHLD(); \ + else \ + DMB_ISH(); \ + } else if (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE && box64_dynarec_weakbarrier != 2 \ + && dyn->insts[ninst].last_write) { \ + /* Last write, put a barrier */ \ + if (box64_dynarec_weakbarrier) \ + DMB_ISHST(); \ + else \ + DMB_ISH(); \ + } \ + } while (0) + +// Similar to WILLWRITE, but checks lock. +#define WILLWRITELOCK(lock) \ + do { \ + if (lock) { \ + DMB_ISH(); \ + } else { \ + WILLWRITE(); \ + } \ + } while (0) + +// Used to clear the state at the start of a SEQ +#define SMSTART() \ + do { \ + dyn->smwrite = 0; \ + } while (0) + +// Will be put at the end of the SEQ +#define SMEND() \ + do { \ + if (box64_dynarec_strongmem) { \ + /* It's a SEQ, put a barrier here. */ \ + if (dyn->smwrite) { \ + /* Check if the next instruction has a end loop mark */ \ + if (box64_dynarec_weakbarrier) \ + DMB_ISHST(); \ + else \ + DMB_ISH(); \ + } \ + } \ + dyn->smwrite = 0; \ + } while (0) + +// The barrier. +#define SMDMB() DMB_ISH() +#endif + #ifdef ARM64 #include "arm64/dynarec_arm64_helper.h" #elif defined(LA64) @@ -11,4 +194,4 @@ #error Unsupported architecture #endif -#endif //__DYNAREC_HELPER__H_ \ No newline at end of file +#endif //__DYNAREC_HELPER__H_ diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index c0ab6470..fbbad121 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -23,7 +23,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" int isSimpleWrapper(wrapper_t fun); int isRetX87Wrapper(wrapper_t fun); diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index 164f14ef..0bc20158 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -24,7 +24,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/la64/dynarec_la64_64.c b/src/dynarec/la64/dynarec_la64_64.c index a069dd80..fb10e453 100644 --- a/src/dynarec/la64/dynarec_la64_64.c +++ b/src/dynarec/la64/dynarec_la64_64.c @@ -20,7 +20,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_la64_functions.h" uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog) diff --git a/src/dynarec/la64/dynarec_la64_66.c b/src/dynarec/la64/dynarec_la64_66.c index 6ead1b5c..4af61163 100644 --- a/src/dynarec/la64/dynarec_la64_66.c +++ b/src/dynarec/la64/dynarec_la64_66.c @@ -20,7 +20,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_la64_functions.h" diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c index 1cf3b2f9..c348a788 100644 --- a/src/dynarec/la64/dynarec_la64_660f.c +++ b/src/dynarec/la64/dynarec_la64_660f.c @@ -21,7 +21,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/la64/dynarec_la64_6664.c b/src/dynarec/la64/dynarec_la64_6664.c index b6efa1ee..c6928aaa 100644 --- a/src/dynarec/la64/dynarec_la64_6664.c +++ b/src/dynarec/la64/dynarec_la64_6664.c @@ -19,7 +19,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_la64_functions.h" uintptr_t dynarec64_6664(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog) diff --git a/src/dynarec/la64/dynarec_la64_67.c b/src/dynarec/la64/dynarec_la64_67.c index 119778fd..0d69d45a 100644 --- a/src/dynarec/la64/dynarec_la64_67.c +++ b/src/dynarec/la64/dynarec_la64_67.c @@ -20,7 +20,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_la64_functions.h" uintptr_t dynarec64_67(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) diff --git a/src/dynarec/la64/dynarec_la64_emit_logic.c b/src/dynarec/la64/dynarec_la64_emit_logic.c index 08150963..17d232f0 100644 --- a/src/dynarec/la64/dynarec_la64_emit_logic.c +++ b/src/dynarec/la64/dynarec_la64_emit_logic.c @@ -20,7 +20,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" // emit XOR8 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed) void emit_xor8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4) diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index 47cf7ffd..aa8f6a13 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -20,7 +20,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" // emit ADD32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) diff --git a/src/dynarec/la64/dynarec_la64_emit_shift.c b/src/dynarec/la64/dynarec_la64_emit_shift.c index 2b83ccba..9d891bdd 100644 --- a/src/dynarec/la64/dynarec_la64_emit_shift.c +++ b/src/dynarec/la64/dynarec_la64_emit_shift.c @@ -20,7 +20,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" // emit SHL16 instruction, from s1 , shift s2, store result in s1 using s3, s4 and s5 as scratch void emit_shl16(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5) diff --git a/src/dynarec/la64/dynarec_la64_emit_tests.c b/src/dynarec/la64/dynarec_la64_emit_tests.c index 2e65ca0c..55f5ad8e 100644 --- a/src/dynarec/la64/dynarec_la64_emit_tests.c +++ b/src/dynarec/la64/dynarec_la64_emit_tests.c @@ -19,7 +19,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" // emit CMP8 instruction, from cmp s1, s2, using s3, s4, s5 and s6 as scratch diff --git a/src/dynarec/la64/dynarec_la64_f0.c b/src/dynarec/la64/dynarec_la64_f0.c index a6cad8dc..e857999e 100644 --- a/src/dynarec/la64/dynarec_la64_f0.c +++ b/src/dynarec/la64/dynarec_la64_f0.c @@ -19,7 +19,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_la64_functions.h" diff --git a/src/dynarec/la64/dynarec_la64_f20f.c b/src/dynarec/la64/dynarec_la64_f20f.c index 034e33be..fec9879f 100644 --- a/src/dynarec/la64/dynarec_la64_f20f.c +++ b/src/dynarec/la64/dynarec_la64_f20f.c @@ -20,7 +20,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_F20F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c index f0cfaf76..280821d8 100644 --- a/src/dynarec/la64/dynarec_la64_f30f.c +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -21,7 +21,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/la64/dynarec_la64_functions.c b/src/dynarec/la64/dynarec_la64_functions.c index 700cae5a..2d936337 100644 --- a/src/dynarec/la64/dynarec_la64_functions.c +++ b/src/dynarec/la64/dynarec_la64_functions.c @@ -260,7 +260,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r { if (box64_dynarec_dump) { printf_x64_instruction(rex.is32bits ? my_context->dec32 : my_context->dec, &dyn->insts[ninst].x64, name); - dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d/%d", + dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)", (box64_dynarec_dump > 1) ? "\e[32m" : "", (void*)(dyn->native_start + dyn->insts[ninst].address), dyn->insts[ninst].size / 4, @@ -275,7 +275,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r dyn->insts[ninst].x64.use_flags, dyn->insts[ninst].x64.need_before, dyn->insts[ninst].x64.need_after, - dyn->smread, dyn->smwrite); + dyn->smwrite, dyn->insts[ninst].will_write, dyn->insts[ninst].last_write); if (dyn->insts[ninst].pred_sz) { dynarec_log(LOG_NONE, ", pred="); for (int ii = 0; ii < dyn->insts[ninst].pred_sz; ++ii) @@ -384,4 +384,4 @@ void fpu_reset_ninst(dynarec_la64_t* dyn, int ninst) // TODO: x87 and mmx sse_reset(&dyn->insts[ninst].lsx); fpu_reset_reg_lsxcache(&dyn->insts[ninst].lsx); -} \ No newline at end of file +} diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index b33445f3..ab290fc8 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -24,7 +24,7 @@ #include "la64_printer.h" #include "dynarec_la64_private.h" #include "dynarec_la64_functions.h" -#include "dynarec_la64_helper.h" +#include "../dynarec_helper.h" #define SCRATCH 31 diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 686a2a09..b6069c61 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -32,178 +32,6 @@ #define PK64(a) *(uint64_t*)(addr + a) #define PKip(a) *(uint8_t*)(ip + a) -/* Box64 Strong Memory Model Emulation - * - * Definition of a SEQ: - * A SEQ is a sequence of opcodes that writes to guest memory, terminated by JMP, RET, CALL, etc. - * - * Memory barriers are added in the following cases to emulate the strong memory model: - * 1. End of a SEQ: - * - Scalar operations (a1) - * - SIMD operations (a2) - * 2. Start of a SEQ: - * - Scalar operations (b1) - * - SIMD operations (b2) - * 3. Right before the last guest memory store in a SEQ: - * - Scalar operations (c1) - * - SIMD operations (c2) - * 4. After every third guest memory store in a SEQ (d) - * - * STRONGMEM levels: - * LEVEL1: Includes a1, b1 - * LEVEL2: Includes LEVEL1, plus a2, b2, c1, c2 - * LEVEL3: Includes LEVEL2, plus d - */ - -#define STRONGMEM_SIMD_WRITE 2 // The level of SIMD memory writes will be tracked -#define STRONGMEM_LAST_WRITE 2 // The level of a barrier before the last guest memory store will be put -#define STRONGMEM_SEQ_WRITE 3 // The level of a barrier at every third memory store will be put - -#if STEP == 1 - -#define SMWRITE() \ - do { \ - /* Mark that current sequence writes to guest memory. */ \ - /* This will be used in SMEND for last_write. */ \ - dyn->smwrite = 1; \ - /* Mark that current opcode writes to guest memory. */ \ - dyn->insts[ninst].will_write = 1; \ - } while (0) - -#define SMWRITELOCK(lock) \ - do { \ - dyn->insts[ninst].lock = lock; \ - SMWRITE(); \ - } while (0) - -#define SMWRITE2() \ - do { \ - if (box64_dynarec_strongmem >= STRONGMEM_SIMD_WRITE) { \ - dyn->smwrite = 1; \ - dyn->insts[ninst].will_write = 2; \ - } \ - } while (0) - -#define SMREAD() -#define SMREADLOCK(lock) -#define WILLWRITE() -#define WILLWRITELOCK(lock) - -#define SMSTART() \ - do { \ - /* Clear current state at the start of a potential SEQ. */ \ - dyn->smwrite = 0; \ - } while (0) - -#define SMEND() \ - do { \ - /* If there is any guest memory write, which is a SEQ, then compute the last_write. */ \ - if (dyn->smwrite && (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE)) { \ - int i = ninst; \ - while (i >= 0 && !dyn->insts[i].will_write) \ - --i; \ - if (i >= 0) { dyn->insts[i].last_write = 1; } \ - } \ - dyn->smwrite = 0; \ - } while (0) - -#define SMDMB() - -#else - -// An opcode writes guest memory, this need to be put after the STORE instruction manually. -#define SMWRITE() \ - do { \ - /* Put a barrier at every third memory write. */ \ - if (box64_dynarec_strongmem >= STRONGMEM_SEQ_WRITE) { \ - if (++dyn->smwrite >= 3 /* Every third memory write */) { \ - DBAR(0); \ - dyn->smwrite = 1; \ - } \ - } else { \ - /* Mark that current sequence writes to guest memory. */ \ - dyn->smwrite = 1; \ - } \ - } while (0) - -// Similar to SMWRITE, but checks lock. -#define SMWRITELOCK(lock) \ - do { \ - if (lock) { \ - DBAR(0); \ - } else { \ - SMWRITE(); \ - } \ - } while (0) - -// Similar to SMWRITE, but for SIMD instructions. -#define SMWRITE2() \ - do { \ - if (box64_dynarec_strongmem >= STRONGMEM_SIMD_WRITE) \ - SMWRITE(); \ - } while (0) - -// An opcode reads guest memory, this need to be put before the LOAD instruction manually. -#define SMREAD() - -// Similar to SMREAD, but checks lock. -#define SMREADLOCK(lock) \ - do { \ - if (lock) { \ - DBAR(0); \ - } else { \ - SMREAD(); \ - } \ - } while (0) - -// An opcode will write memory, this will be put before the STORE instruction automatically. -#define WILLWRITE() \ - do { \ - if (box64_dynarec_strongmem >= dyn->insts[ninst].will_write && dyn->smwrite == 0) { \ - /* Will write but never written, this is the start of a SEQ, put a barrier. */ \ - DBAR(0); \ - } else if (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE && dyn->insts[ninst].last_write) { \ - /* Last write, put a barrier */ \ - DBAR(0); \ - } \ - } while (0) - -// Similar to WILLWRITE, but checks lock. -#define WILLWRITELOCK(lock) \ - do { \ - if (lock) { \ - DBAR(0); \ - } else { \ - WILLWRITE(); \ - } \ - } while (0) - -// Used to clear the state at the start of a SEQ -#define SMSTART() \ - do { \ - dyn->smwrite = 0; \ - } while (0) - -// Will be put at the end of the SEQ -#define SMEND() \ - do { \ - if (box64_dynarec_strongmem) { \ - /* Check if there is any guest memory write. */ \ - int i = ninst; \ - while (i >= 0 && !dyn->insts[i].will_write) \ - --i; \ - if (i >= 0) { \ - /* It's a SEQ, put a barrier here. */ \ - DBAR(0); \ - } \ - } \ - dyn->smwrite = 0; \ - } while (0) - -// The barrier. -#define SMDMB() DBAR(0) -#endif - // LOCK_* define #define LOCK_LOCK (int*)1 @@ -877,10 +705,7 @@ #define TABLE64(A, V) #endif -#define ARCH_INIT() \ - do { \ - dyn->smread = dyn->smwrite = 0; \ - } while (0) +#define ARCH_INIT() SMSTART() #define ARCH_RESET() diff --git a/src/dynarec/la64/dynarec_la64_private.h b/src/dynarec/la64/dynarec_la64_private.h index 2e64ac55..a9578fc6 100644 --- a/src/dynarec/la64/dynarec_la64_private.h +++ b/src/dynarec/la64/dynarec_la64_private.h @@ -130,7 +130,6 @@ typedef struct dynarec_la64_s { int32_t forward_size; // size at the forward point int forward_ninst; // ninst at the forward point uint16_t ymm_zero; // bitmap of ymm to zero at purge - uint8_t smread; // for strongmem model emulation uint8_t smwrite; // for strongmem model emulation uint8_t always_test; uint8_t abort; diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h index dff89661..4533c568 100644 --- a/src/dynarec/la64/la64_emitter.h +++ b/src/dynarec/la64/la64_emitter.h @@ -266,6 +266,14 @@ f24-f31 fs0-fs7 Static registers Callee // DBAR hint #define DBAR(hint) EMIT(type_hint(0b00111000011100100, hint)) +#define DBAR_RW_RW() DBAR(0b10000) +#define DBAR_R_RW() DBAR(0b10100) +#define DBAR_W_RW() DBAR(0b11000) + +#define DMB_ISH() DBAR_RW_RW() +#define DMB_ISHLD() DBAR_R_RW() +#define DMB_ISHST() DBAR_W_RW() + // GR[rd] = GR[rj] & GR[rk] #define AND(rd, rj, rk) EMIT(type_3R(0b00000000000101001, rk, rj, rd)) // GR[rd] = GR[rj] | GR[rk] diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 5f529fb7..b9c19e58 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -23,7 +23,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_00_0.c b/src/dynarec/rv64/dynarec_rv64_00_0.c index b9a6faf2..a343d892 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_0.c +++ b/src/dynarec/rv64/dynarec_rv64_00_0.c @@ -23,7 +23,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_00_0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_00_1.c b/src/dynarec/rv64/dynarec_rv64_00_1.c index a9c97584..cb938b58 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_1.c +++ b/src/dynarec/rv64/dynarec_rv64_00_1.c @@ -23,7 +23,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" int isSimpleWrapper(wrapper_t fun); diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index c31d760a..c495f935 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -23,7 +23,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 1a7157e8..38ef9148 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -23,7 +23,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" int isSimpleWrapper(wrapper_t fun); int isRetX87Wrapper(wrapper_t fun); diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index fd08d72b..6df08e11 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -23,7 +23,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_0f_vector.c b/src/dynarec/rv64/dynarec_rv64_0f_vector.c index 73c9395d..2239221e 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_0f_vector.c @@ -23,7 +23,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_0F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_64.c b/src/dynarec/rv64/dynarec_rv64_64.c index 6f6deabf..1b8629e3 100644 --- a/src/dynarec/rv64/dynarec_rv64_64.c +++ b/src/dynarec/rv64/dynarec_rv64_64.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_64_vector.c b/src/dynarec/rv64/dynarec_rv64_64_vector.c index 52cb6764..71ea326b 100644 --- a/src/dynarec/rv64/dynarec_rv64_64_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_64_vector.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" uintptr_t dynarec64_64_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int seg, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index f5559843..fcfae274 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -20,7 +20,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 06cf8400..e8bbb1e0 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -20,7 +20,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "emu/x64compstrings.h" uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_660f38.c b/src/dynarec/rv64/dynarec_rv64_660f38.c index 475bf1da..bcee7bd8 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f38.c +++ b/src/dynarec/rv64/dynarec_rv64_660f38.c @@ -20,7 +20,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "emu/x64compstrings.h" uintptr_t dynarec64_660F38(dynarec_rv64_t* dyn, uintptr_t addr, uint8_t opcode, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_660f_vector.c b/src/dynarec/rv64/dynarec_rv64_660f_vector.c index bbdfdf47..ed09b142 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_660f_vector.c @@ -18,7 +18,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_660F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_6664.c b/src/dynarec/rv64/dynarec_rv64_6664.c index a1389aba..bdf2c279 100644 --- a/src/dynarec/rv64/dynarec_rv64_6664.c +++ b/src/dynarec/rv64/dynarec_rv64_6664.c @@ -18,7 +18,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" uintptr_t dynarec64_6664(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_66f0.c b/src/dynarec/rv64/dynarec_rv64_66f0.c index 4317171e..17cd0c00 100644 --- a/src/dynarec/rv64/dynarec_rv64_66f0.c +++ b/src/dynarec/rv64/dynarec_rv64_66f0.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_66f20f.c b/src/dynarec/rv64/dynarec_rv64_66f20f.c index a11dde1c..822855c0 100644 --- a/src/dynarec/rv64/dynarec_rv64_66f20f.c +++ b/src/dynarec/rv64/dynarec_rv64_66f20f.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_66F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_66f30f.c b/src/dynarec/rv64/dynarec_rv64_66f30f.c index 50b4e4a3..851ec625 100644 --- a/src/dynarec/rv64/dynarec_rv64_66f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_66f30f.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_66F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c index bedf6576..e9c54901 100644 --- a/src/dynarec/rv64/dynarec_rv64_67.c +++ b/src/dynarec/rv64/dynarec_rv64_67.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_67_32.c b/src/dynarec/rv64/dynarec_rv64_67_32.c index aa663d34..8d799cee 100644 --- a/src/dynarec/rv64/dynarec_rv64_67_32.c +++ b/src/dynarec/rv64/dynarec_rv64_67_32.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" uintptr_t dynarec64_67_32(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_67_vector.c b/src/dynarec/rv64/dynarec_rv64_67_vector.c index d82df0c9..297893b0 100644 --- a/src/dynarec/rv64/dynarec_rv64_67_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_67_vector.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" uintptr_t dynarec64_67_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_avx.c b/src/dynarec/rv64/dynarec_rv64_avx.c index c9d80f2a..f8b1ce89 100644 --- a/src/dynarec/rv64/dynarec_rv64_avx.c +++ b/src/dynarec/rv64/dynarec_rv64_avx.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" static const char* avx_prefix_string(uint16_t p) { diff --git a/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c b/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c index 443ef949..41a00706 100644 --- a/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_avx_f3_0f.c @@ -22,7 +22,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_AVX_F3_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_d8.c b/src/dynarec/rv64/dynarec_rv64_d8.c index 885eebfd..ee397753 100644 --- a/src/dynarec/rv64/dynarec_rv64_d8.c +++ b/src/dynarec/rv64/dynarec_rv64_d8.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_d9.c b/src/dynarec/rv64/dynarec_rv64_d9.c index f600bb44..fc149371 100644 --- a/src/dynarec/rv64/dynarec_rv64_d9.c +++ b/src/dynarec/rv64/dynarec_rv64_d9.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_da.c b/src/dynarec/rv64/dynarec_rv64_da.c index 648a5f91..b1d2042b 100644 --- a/src/dynarec/rv64/dynarec_rv64_da.c +++ b/src/dynarec/rv64/dynarec_rv64_da.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c index 80e99666..4e10342a 100644 --- a/src/dynarec/rv64/dynarec_rv64_db.c +++ b/src/dynarec/rv64/dynarec_rv64_db.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_dc.c b/src/dynarec/rv64/dynarec_rv64_dc.c index dbf7b314..4255bca0 100644 --- a/src/dynarec/rv64/dynarec_rv64_dc.c +++ b/src/dynarec/rv64/dynarec_rv64_dc.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c index d1255655..1fa37951 100644 --- a/src/dynarec/rv64/dynarec_rv64_dd.c +++ b/src/dynarec/rv64/dynarec_rv64_dd.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_de.c b/src/dynarec/rv64/dynarec_rv64_de.c index f20cc686..370ef7e0 100644 --- a/src/dynarec/rv64/dynarec_rv64_de.c +++ b/src/dynarec/rv64/dynarec_rv64_de.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c index 737f8e85..48cf9ac7 100644 --- a/src/dynarec/rv64/dynarec_rv64_df.c +++ b/src/dynarec/rv64/dynarec_rv64_df.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) diff --git a/src/dynarec/rv64/dynarec_rv64_emit_logic.c b/src/dynarec/rv64/dynarec_rv64_emit_logic.c index 04185f05..86b63a91 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_logic.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_logic.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" // emit XOR8 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch, s4 can be same as s2 (and so s2 destroyed) void emit_xor8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4) diff --git a/src/dynarec/rv64/dynarec_rv64_emit_math.c b/src/dynarec/rv64/dynarec_rv64_emit_math.c index c666497d..6528483d 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_math.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_math.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" // emit ADD32 instruction, from s1, s2, store result in s1 using s3 and s4 as scratch void emit_add32(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5) diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c index 6e61b769..7bf4a7dd 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" // emit SHL8 instruction, from s1 , constant c, store result in s1 using s3, s4 and s5 as scratch void emit_shl8c(dynarec_rv64_t* dyn, int ninst, int s1, uint32_t c, int s3, int s4, int s5) diff --git a/src/dynarec/rv64/dynarec_rv64_emit_tests.c b/src/dynarec/rv64/dynarec_rv64_emit_tests.c index 439951a3..116c602d 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_tests.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_tests.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" // emit CMP8 instruction, from cmp s1, s2, using s3, s4, s5 and s6 as scratch void emit_cmp8(dynarec_rv64_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5, int s6) diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c index fc8c46ad..05242ef3 100644 --- a/src/dynarec/rv64/dynarec_rv64_f0.c +++ b/src/dynarec/rv64/dynarec_rv64_f0.c @@ -18,7 +18,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" #include "dynarec_rv64_functions.h" diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c index 04ca2c06..b2cae02d 100644 --- a/src/dynarec/rv64/dynarec_rv64_f20f.c +++ b/src/dynarec/rv64/dynarec_rv64_f20f.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c index 78c224e7..2fa61ce9 100644 --- a/src/dynarec/rv64/dynarec_rv64_f20f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_f20f_vector.c @@ -19,7 +19,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_F20F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c index 67305342..3cf3e630 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f.c @@ -20,7 +20,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c index ae7c02e2..3288938d 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f_vector.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f_vector.c @@ -20,7 +20,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" uintptr_t dynarec64_F30F_vector(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) { diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c index 5e85e735..2f5839c0 100644 --- a/src/dynarec/rv64/dynarec_rv64_functions.c +++ b/src/dynarec/rv64/dynarec_rv64_functions.c @@ -637,7 +637,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r }; if(box64_dynarec_dump) { printf_x64_instruction(rex.is32bits?my_context->dec32:my_context->dec, &dyn->insts[ninst].x64, name); - dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d/%d, sew@entry=%d, sew@exit=%d", + dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d), sew@entry=%d, sew@exit=%d", (box64_dynarec_dump > 1) ? "\e[32m" : "", (void*)(dyn->native_start + dyn->insts[ninst].address), dyn->insts[ninst].size / 4, @@ -652,7 +652,8 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r dyn->insts[ninst].x64.use_flags, dyn->insts[ninst].x64.need_before, dyn->insts[ninst].x64.need_after, - dyn->smread, dyn->smwrite, dyn->insts[ninst].vector_sew_entry, dyn->insts[ninst].vector_sew_exit); + dyn->smwrite, dyn->insts[ninst].will_write, dyn->insts[ninst].last_write, + dyn->insts[ninst].vector_sew_entry, dyn->insts[ninst].vector_sew_exit); if(dyn->insts[ninst].pred_sz) { dynarec_log(LOG_NONE, ", pred="); for(int ii=0; ii<dyn->insts[ninst].pred_sz; ++ii) diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 5081a653..a8d14669 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -25,7 +25,7 @@ #include "rv64_printer.h" #include "dynarec_rv64_private.h" #include "dynarec_rv64_functions.h" -#include "dynarec_rv64_helper.h" +#include "../dynarec_helper.h" static uintptr_t geted_32(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, uint8_t* ed, uint8_t hint, uint8_t scratch, int64_t* fixaddress, int *l, int i12); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 7903ca06..33143127 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -32,178 +32,6 @@ #define PK64(a) *(uint64_t*)(addr + a) #define PKip(a) *(uint8_t*)(ip + a) -/* Box64 Strong Memory Model Emulation - * - * Definition of a SEQ: - * A SEQ is a sequence of opcodes that writes to guest memory, terminated by JMP, RET, CALL, etc. - * - * Memory barriers are added in the following cases to emulate the strong memory model: - * 1. End of a SEQ: - * - Scalar operations (a1) - * - SIMD operations (a2) - * 2. Start of a SEQ: - * - Scalar operations (b1) - * - SIMD operations (b2) - * 3. Right before the last guest memory store in a SEQ: - * - Scalar operations (c1) - * - SIMD operations (c2) - * 4. After every third guest memory store in a SEQ (d) - * - * STRONGMEM levels: - * LEVEL1: Includes a1, b1 - * LEVEL2: Includes LEVEL1, plus a2, b2, c1, c2 - * LEVEL3: Includes LEVEL2, plus d - */ - -#define STRONGMEM_SIMD_WRITE 2 // The level of SIMD memory writes will be tracked -#define STRONGMEM_LAST_WRITE 2 // The level of a barrier before the last guest memory store will be put -#define STRONGMEM_SEQ_WRITE 3 // The level of a barrier at every third memory store will be put - -#if STEP == 1 - -#define SMWRITE() \ - do { \ - /* Mark that current sequence writes to guest memory. */ \ - /* This will be used in SMEND for last_write. */ \ - dyn->smwrite = 1; \ - /* Mark that current opcode writes to guest memory. */ \ - dyn->insts[ninst].will_write = 1; \ - } while (0) - -#define SMWRITELOCK(lock) \ - do { \ - dyn->insts[ninst].lock = lock; \ - SMWRITE(); \ - } while (0) - -#define SMWRITE2() \ - do { \ - if (box64_dynarec_strongmem >= STRONGMEM_SIMD_WRITE) { \ - dyn->smwrite = 1; \ - dyn->insts[ninst].will_write = 2; \ - } \ - } while (0) - -#define SMREAD() -#define SMREADLOCK(lock) -#define WILLWRITE() -#define WILLWRITELOCK(lock) - -#define SMSTART() \ - do { \ - /* Clear current state at the start of a potential SEQ. */ \ - dyn->smwrite = 0; \ - } while (0) - -#define SMEND() \ - do { \ - /* If there is any guest memory write, which is a SEQ, then compute the last_write. */ \ - if (dyn->smwrite && (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE)) { \ - int i = ninst; \ - while (i >= 0 && !dyn->insts[i].will_write) \ - --i; \ - if (i >= 0) { dyn->insts[i].last_write = 1; } \ - } \ - dyn->smwrite = 0; \ - } while (0) - -#define SMDMB() - -#else - -// An opcode writes guest memory, this need to be put after the STORE instruction manually. -#define SMWRITE() \ - do { \ - /* Put a barrier at every third memory write. */ \ - if (box64_dynarec_strongmem >= STRONGMEM_SEQ_WRITE) { \ - if (++dyn->smwrite >= 3 /* Every third memory write */) { \ - FENCE_RW_RW(); \ - dyn->smwrite = 1; \ - } \ - } else { \ - /* Mark that current sequence writes to guest memory. */ \ - dyn->smwrite = 1; \ - } \ - } while (0) - -// Similar to SMWRITE, but checks lock. -#define SMWRITELOCK(lock) \ - do { \ - if (lock) { \ - FENCE_RW_RW(); \ - } else { \ - SMWRITE(); \ - } \ - } while (0) - -// Similar to SMWRITE, but for SIMD instructions. -#define SMWRITE2() \ - do { \ - if (box64_dynarec_strongmem >= STRONGMEM_SIMD_WRITE) \ - SMWRITE(); \ - } while (0) - -// An opcode reads guest memory, this need to be put before the LOAD instruction manually. -#define SMREAD() - -// Similar to SMREAD, but checks lock. -#define SMREADLOCK(lock) \ - do { \ - if (lock) { \ - FENCE_RW_RW(); \ - } else { \ - SMREAD(); \ - } \ - } while (0) - -// An opcode will write memory, this will be put before the STORE instruction automatically. -#define WILLWRITE() \ - do { \ - if (box64_dynarec_strongmem >= dyn->insts[ninst].will_write && dyn->smwrite == 0) { \ - /* Will write but never written, this is the start of a SEQ, put a barrier. */ \ - FENCE_RW_RW(); \ - } else if (box64_dynarec_strongmem >= STRONGMEM_LAST_WRITE && dyn->insts[ninst].last_write) { \ - /* Last write, put a barrier */ \ - FENCE_RW_RW(); \ - } \ - } while (0) - -// Similar to WILLWRITE, but checks lock. -#define WILLWRITELOCK(lock) \ - do { \ - if (lock) { \ - FENCE_RW_RW(); \ - } else { \ - WILLWRITE(); \ - } \ - } while (0) - -// Used to clear the state at the start of a SEQ -#define SMSTART() \ - do { \ - dyn->smwrite = 0; \ - } while (0) - -// Will be put at the end of the SEQ -#define SMEND() \ - do { \ - if (box64_dynarec_strongmem) { \ - /* Check if there is any guest memory write. */ \ - int i = ninst; \ - while (i >= 0 && !dyn->insts[i].will_write) \ - --i; \ - if (i >= 0) { \ - /* It's a SEQ, put a barrier here. */ \ - FENCE_RW_RW(); \ - } \ - } \ - dyn->smwrite = 0; \ - } while (0) - -// The barrier. -#define SMDMB() FENCE_RW_RW() -#endif - // LOCK_* define #define LOCK_LOCK (int*)1 @@ -1243,8 +1071,8 @@ #define FTABLE64(A, V) #endif -#define ARCH_INIT() \ - dyn->smread = dyn->smwrite = 0; \ +#define ARCH_INIT() \ + SMSTART(); \ dyn->vector_sew = VECTOR_SEWNA; #define ARCH_RESET() \ diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h index 3de4b465..4600dfc7 100644 --- a/src/dynarec/rv64/dynarec_rv64_private.h +++ b/src/dynarec/rv64/dynarec_rv64_private.h @@ -160,7 +160,6 @@ typedef struct dynarec_rv64_s { dynablock_t* dynablock; instsize_t* instsize; size_t insts_size; // size of the instruction size array (calculated) - uint8_t smread; // for strongmem model emulation uint8_t smwrite; // for strongmem model emulation uintptr_t forward; // address of the last end of code while testing forward uintptr_t forward_to; // address of the next jump to (to check if everything is ok) diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index 99fcf0e5..fab9aad5 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -399,8 +399,14 @@ f28–31 ft8–11 FP temporaries Caller } while (0) #define FENCE_gen(pred, succ) (((pred) << 24) | ((succ) << 20) | 0b0001111) +#define FENCE_R_RW() EMIT(FENCE_gen(2, 3)) +#define FENCE_W_W() EMIT(FENCE_gen(1, 1)) #define FENCE_RW_RW() EMIT(FENCE_gen(3, 3)) +#define DMB_ISH() FENCE_RW_RW() +#define DMB_ISHLD() FENCE_R_RW() +#define DMB_ISHST() FENCE_W_W() + #define FENCE_I_gen() ((0b001 << 12) | 0b0001111) #define FENCE_I() EMIT(FENCE_I_gen()) |