Revert "more wasm, deley slot issue"

This reverts commit 40c352e5ed.
This commit is contained in:
Joseph Mattiello 2025-07-06 14:46:19 -04:00
parent 40c352e5ed
commit a2865a95ba
1 changed files with 11 additions and 366 deletions

View File

@ -57,7 +57,6 @@ struct WasmBlockStats {
// WASM JIT: Global state
static std::unordered_map<u32, WasmBlockStats> wasm_block_stats;
static std::mutex wasm_compilation_mutex;
static bool wasm_jit_enabled = true; // Global flag to disable WASM JIT on failures
// WASM JIT: Ultra-fast register cache
struct WasmRegisterCache {
@ -125,109 +124,43 @@ private:
WasmStack stack;
public:
// Complete WASM bytecode opcodes for maximum performance
// WASM bytecode opcodes (simplified subset)
enum WasmOp : u8 {
// Stack operations
WASM_I32_CONST = 0x41,
WASM_F32_CONST = 0x43,
WASM_LOCAL_GET = 0x20,
WASM_LOCAL_SET = 0x21,
// Integer arithmetic
// Arithmetic
WASM_I32_ADD = 0x6A,
WASM_I32_SUB = 0x6B,
WASM_I32_MUL = 0x6C,
WASM_I32_DIV_S = 0x6D,
WASM_I32_DIV_U = 0x6E,
WASM_I32_REM_S = 0x6F,
WASM_I32_REM_U = 0x70,
// Integer bitwise
WASM_I32_AND = 0x71,
WASM_I32_OR = 0x72,
WASM_I32_XOR = 0x73,
WASM_I32_SHL = 0x74,
WASM_I32_SHR_S = 0x75,
WASM_I32_SHR_U = 0x76,
WASM_I32_ROTL = 0x77,
WASM_I32_ROTR = 0x78,
WASM_I32_SHR_S = 0x75,
// Integer comparison
WASM_I32_EQ = 0x46,
WASM_I32_NE = 0x47,
WASM_I32_LT_S = 0x48,
WASM_I32_LT_U = 0x49,
WASM_I32_GT_S = 0x4A,
WASM_I32_GT_U = 0x4B,
WASM_I32_LE_S = 0x4C,
WASM_I32_LE_U = 0x4D,
WASM_I32_GE_S = 0x4E,
WASM_I32_GE_U = 0x4F,
// Memory
WASM_I32_LOAD = 0x28,
WASM_I32_STORE = 0x36,
// Float arithmetic
WASM_F32_ADD = 0x92,
WASM_F32_SUB = 0x93,
WASM_F32_MUL = 0x94,
WASM_F32_DIV = 0x95,
WASM_F32_ABS = 0x8B,
WASM_F32_NEG = 0x8C,
WASM_F32_SQRT = 0x91,
// Type conversions
WASM_I32_TRUNC_F32_S = 0xA8,
WASM_F32_CONVERT_I32_S = 0xB2,
// Memory operations
WASM_LOAD = 0x28,
WASM_STORE = 0x36,
// Control flow
WASM_BR = 0x0C,
WASM_BR_IF = 0x0D,
// Control
WASM_RETURN = 0x0F,
WASM_END = 0x0B,
// Custom SH4 operations (high-performance)
// Custom: Register access
WASM_REG_LOAD = 0xF0,
WASM_REG_STORE = 0xF1,
WASM_MEM_FAST = 0xF2,
WASM_BYTE_SWAP = 0xF3,
WASM_ROTL_CARRY = 0xF4,
WASM_ROTR_CARRY = 0xF5,
WASM_ADD_CARRY = 0xF6,
WASM_SUB_CARRY = 0xF7,
WASM_SHIFT_DYNAMIC = 0xF8,
WASM_SHIFT_ARITH_DYNAMIC = 0xF9,
WASM_CHECK_INT = 0xFA,
WASM_SYNC_SR = 0xFB,
WASM_SYNC_FPSCR = 0xFC,
WASM_FALLBACK = 0xFF
WASM_MEM_FAST = 0xF2
};
// Ultra-fast WASM execution (no validation, maximum speed)
void execute_wasm_block(const std::vector<u8>& bytecode) __attribute__((hot)) {
// Safety checks for WASM execution
if (bytecode.empty()) {
WARN_LOG(DYNAREC, "WASM: Empty bytecode - fallback to interpreter");
return;
}
const u8* pc = bytecode.data();
const u8* end = pc + bytecode.size();
// Validate bytecode bounds
if (pc >= end) {
WARN_LOG(DYNAREC, "WASM: Invalid bytecode bounds - fallback to interpreter");
return;
}
while (pc < end) {
// Safety check before reading opcode
if (pc >= end) {
WARN_LOG(DYNAREC, "WASM: PC exceeded bounds during execution");
break;
}
u8 opcode = *pc++;
switch (opcode) {
@ -306,277 +239,6 @@ public:
break;
}
case WASM_I32_MUL: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push(a * b);
break;
}
case WASM_I32_DIV_S: {
u32 b = stack.pop();
u32 a = stack.pop();
if (b != 0) stack.push((s32)a / (s32)b);
else stack.push(0);
break;
}
case WASM_I32_DIV_U: {
u32 b = stack.pop();
u32 a = stack.pop();
if (b != 0) stack.push(a / b);
else stack.push(0);
break;
}
// ===== COMPARISON OPERATIONS =====
case WASM_I32_EQ: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push(a == b ? 1 : 0);
break;
}
case WASM_I32_NE: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push(a != b ? 1 : 0);
break;
}
case WASM_I32_LT_S: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push((s32)a < (s32)b ? 1 : 0);
break;
}
case WASM_I32_LT_U: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push(a < b ? 1 : 0);
break;
}
case WASM_I32_GT_S: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push((s32)a > (s32)b ? 1 : 0);
break;
}
case WASM_I32_GT_U: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push(a > b ? 1 : 0);
break;
}
case WASM_I32_GE_S: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push((s32)a >= (s32)b ? 1 : 0);
break;
}
case WASM_I32_GE_U: {
u32 b = stack.pop();
u32 a = stack.pop();
stack.push(a >= b ? 1 : 0);
break;
}
// ===== FLOATING POINT OPERATIONS =====
case WASM_F32_ADD: {
u32 b_bits = stack.pop();
u32 a_bits = stack.pop();
f32 b = *(f32*)&b_bits;
f32 a = *(f32*)&a_bits;
f32 result = a + b;
stack.push(*(u32*)&result);
break;
}
case WASM_F32_SUB: {
u32 b_bits = stack.pop();
u32 a_bits = stack.pop();
f32 b = *(f32*)&b_bits;
f32 a = *(f32*)&a_bits;
f32 result = a - b;
stack.push(*(u32*)&result);
break;
}
case WASM_F32_MUL: {
u32 b_bits = stack.pop();
u32 a_bits = stack.pop();
f32 b = *(f32*)&b_bits;
f32 a = *(f32*)&a_bits;
f32 result = a * b;
stack.push(*(u32*)&result);
break;
}
case WASM_F32_DIV: {
u32 b_bits = stack.pop();
u32 a_bits = stack.pop();
f32 b = *(f32*)&b_bits;
f32 a = *(f32*)&a_bits;
f32 result = a / b;
stack.push(*(u32*)&result);
break;
}
case WASM_F32_ABS: {
u32 a_bits = stack.pop();
f32 a = *(f32*)&a_bits;
f32 result = fabsf(a);
stack.push(*(u32*)&result);
break;
}
case WASM_F32_NEG: {
u32 a_bits = stack.pop();
f32 a = *(f32*)&a_bits;
f32 result = -a;
stack.push(*(u32*)&result);
break;
}
case WASM_F32_SQRT: {
u32 a_bits = stack.pop();
f32 a = *(f32*)&a_bits;
f32 result = sqrtf(a);
stack.push(*(u32*)&result);
break;
}
// ===== TYPE CONVERSIONS =====
case WASM_I32_TRUNC_F32_S: {
u32 a_bits = stack.pop();
f32 a = *(f32*)&a_bits;
s32 result = (s32)a;
stack.push((u32)result);
break;
}
case WASM_F32_CONVERT_I32_S: {
s32 a = (s32)stack.pop();
f32 result = (f32)a;
stack.push(*(u32*)&result);
break;
}
// ===== CUSTOM SH4 OPERATIONS =====
case WASM_BYTE_SWAP: {
u32 a = stack.pop();
u32 result = ((a & 0xFF) << 8) | ((a >> 8) & 0xFF) | (a & 0xFFFF0000);
stack.push(result);
break;
}
case WASM_ROTL_CARRY: {
u32 carry = stack.pop(); // T flag
u32 a = stack.pop();
u32 result = (a << 1) | (carry & 1);
u32 new_carry = (a >> 31) & 1;
stack.push(result);
g_wasm_cache.sr_t = new_carry;
break;
}
case WASM_ROTR_CARRY: {
u32 carry = stack.pop(); // T flag
u32 a = stack.pop();
u32 result = (a >> 1) | ((carry & 1) << 31);
u32 new_carry = a & 1;
stack.push(result);
g_wasm_cache.sr_t = new_carry;
break;
}
case WASM_ADD_CARRY: {
u32 carry = stack.pop(); // T flag
u32 b = stack.pop();
u32 a = stack.pop();
u64 result64 = (u64)a + (u64)b + (carry & 1);
u32 result = (u32)result64;
u32 new_carry = (result64 >> 32) & 1;
stack.push(result);
g_wasm_cache.sr_t = new_carry;
break;
}
case WASM_SUB_CARRY: {
u32 carry = stack.pop(); // T flag
u32 b = stack.pop();
u32 a = stack.pop();
u64 result64 = (u64)a - (u64)b - (carry & 1);
u32 result = (u32)result64;
u32 new_carry = (result64 >> 32) & 1;
stack.push(result);
g_wasm_cache.sr_t = new_carry;
break;
}
case WASM_SHIFT_DYNAMIC: {
u32 shift_amount = stack.pop();
u32 a = stack.pop();
u32 result;
if ((s32)shift_amount >= 0) {
result = a << (shift_amount & 0x1F);
} else {
result = a >> ((-shift_amount) & 0x1F);
}
stack.push(result);
break;
}
case WASM_SHIFT_ARITH_DYNAMIC: {
u32 shift_amount = stack.pop();
u32 a = stack.pop();
u32 result;
if ((s32)shift_amount >= 0) {
result = a << (shift_amount & 0x1F);
} else {
result = (s32)a >> ((-shift_amount) & 0x1F);
}
stack.push(result);
break;
}
case WASM_CHECK_INT: {
// Interrupt/exception check - inline fast path
if (__builtin_expect(UpdateSystem_INTC(), 0)) {
// Handle interrupt - this is rare
g_wasm_cache.store_all();
return;
}
break;
}
case WASM_SYNC_SR: {
// Synchronize status register - mostly no-op in fast path
break;
}
case WASM_SYNC_FPSCR: {
// Synchronize FPU control register - mostly no-op in fast path
break;
}
case WASM_FALLBACK: {
u8 shil_op = *pc++;
// This should be very rare now - fallback to legacy interpreter
g_wasm_cache.store_all();
// Create a dummy shil_opcode for fallback (simplified)
shil_opcode dummy_op;
dummy_op.op = (shilop)shil_op;
ShilInterpreter::executeOpcode(dummy_op);
g_wasm_cache.load_all();
break;
}
case WASM_REG_LOAD: {
u8 reg_idx = *pc++;
if (reg_idx < 16) {
@ -599,13 +261,6 @@ public:
}
case WASM_MEM_FAST: {
// Safety check for parameter bytes
if (pc + 2 > end) {
WARN_LOG(DYNAREC, "WASM: Not enough bytes for MEM_FAST parameters");
g_wasm_cache.store_all();
return;
}
u8 op_type = *pc++; // 0=read, 1=write
u8 size = *pc++; // 1, 2, 4 bytes
@ -659,12 +314,8 @@ public:
return;
default:
// Unknown opcode detected - this indicates corrupted WASM bytecode
WARN_LOG(DYNAREC, "WASM: Unknown opcode 0x%02X at PC offset %zu - disabling WASM JIT",
opcode, (size_t)(pc - bytecode.data() - 1));
wasm_jit_enabled = false; // Disable WASM JIT to prevent further crashes
g_wasm_cache.store_all();
return;
// Skip unknown opcodes
break;
}
}
}
@ -840,12 +491,6 @@ public:
static void execute_block(RuntimeBlockInfo* block) __attribute__((hot)) {
u32 addr = block->addr;
// Check if WASM JIT is disabled due to errors
if (!wasm_jit_enabled) {
execute_block_interpreter_fast(block);
return;
}
// Update execution statistics
wasm_block_stats[addr].execution_count++;
wasm_block_stats[addr].last_execution = std::chrono::steady_clock::now();