mirror of
https://github.com/ptitSeb/box64.git
synced 2024-11-27 00:30:32 +00:00
[DYNAREC] Reuse strongmem infra for all backends (#2052)
This commit is contained in:
parent
6aa57f5c73
commit
d1a253f469
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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.};
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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_
|
||||
#endif //__DYNAREC_HELPER__H_
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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]
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user