From 24d5f92b766cb88c1d5b3f0ad630e27975879506 Mon Sep 17 00:00:00 2001 From: Mphatso Raymond Mataka <45720369+HorseTrain@users.noreply.github.com> Date: Thu, 27 Feb 2025 01:03:19 -0800 Subject: [PATCH] Introduced even more aggressive optimizations. --- src/assembly/aarch64/aarch64_assembler.cpp | 24 + src/assembly/aarch64/aarch64_assembler.h | 7 + src/assembly/aarch64/rarma.h | 322 + src/assembly/x86/x86_assembler.cpp | 9 + src/emulator/aarch64/aarch64_impl.cpp | 14914 +++++++++---------- src/emulator/aarch64/aarch64_impl.h | 496 +- src/ir/ssa.cpp | 254 +- src/jit/jit_memory.cpp | 6 +- src/jit/rem_tester_arm.code-workspace | 11 + 9 files changed, 8276 insertions(+), 7767 deletions(-) create mode 100644 src/assembly/aarch64/rarma.h create mode 100644 src/jit/rem_tester_arm.code-workspace diff --git a/src/assembly/aarch64/aarch64_assembler.cpp b/src/assembly/aarch64/aarch64_assembler.cpp index e69de29..fb4653c 100644 --- a/src/assembly/aarch64/aarch64_assembler.cpp +++ b/src/assembly/aarch64/aarch64_assembler.cpp @@ -0,0 +1,24 @@ +#include "aarch64_assembler.h" +#include + +#define ONE_MB 1 * 1024 * 1024 + +#define X(reg) rarma_context::X(reg) +#define SP rarma_context::SP() +#define WSP rarma_context::SP() + +void assemble_aarch64_abi_caller_code(void* result_code, uint64_t* result_code_size, abi abi_information) +{ + rarma_context c; + + rarma_context::create(&c, ONE_MB); + + rarma_context::sub_imm12(&c, SP, SP, 8); + + rarma_context::add_imm12(&c, SP, SP, 8); + + *result_code_size = c.memory_location; + memcpy(result_code, c.memory_block, *result_code_size); + + rarma_context::destroy(&c); +} \ No newline at end of file diff --git a/src/assembly/aarch64/aarch64_assembler.h b/src/assembly/aarch64/aarch64_assembler.h index 00e73b3..c404ece 100644 --- a/src/assembly/aarch64/aarch64_assembler.h +++ b/src/assembly/aarch64/aarch64_assembler.h @@ -1,4 +1,11 @@ +#include +#include "abi_information.h" + #ifndef AARCH64_ASSEMBLER_H #define AARCH64_ASSEMBLER_H +#include "rarma.h" + +void assemble_aarch64_abi_caller_code(void* result_code, uint64_t* result_code_size, abi abi_information); + #endif \ No newline at end of file diff --git a/src/assembly/aarch64/rarma.h b/src/assembly/aarch64/rarma.h new file mode 100644 index 0000000..986ee10 --- /dev/null +++ b/src/assembly/aarch64/rarma.h @@ -0,0 +1,322 @@ +#ifndef RARMA_H +#define RARMA_H + +#include +#include +#include +#include + +struct rarma_context +{ + void* memory_block; + + uint64_t memory_block_size; + uint64_t memory_location; + + enum operand_type + { + zr, + sp, + gp, + vec + }; + + enum shift_type + { + lsl, + lsr, + ror, + asr + }; + + struct operand + { + int operand_size; + int operand_register_index; + + operand_type type; + }; + + static uint64_t get_code_size(rarma_context* context) + { + return context->memory_location; + } + + static operand gp_size(int index, int size, operand_type type) + { + operand result; + + result.operand_size = size; + result.operand_register_index = index; + result.type = type; + + assert_in_mask(index, 5); + + switch (type) + { + case sp: + case zr: + { + assert(index == 31); + + assert(size >= 2 && size <= 3); + }; break; + } + + return result; + } + + static operand X(int index) + { + return gp_size(index, 3, operand_type::gp); + } + + static operand SP() + { + return gp_size(31, 3, operand_type::sp); + } + + static operand W(int index) + { + return gp_size(index, 2, operand_type::gp); + } + + static operand WSP() + { + return gp_size(31, 2, operand_type::sp); + } + + static operand H(int index) + { + return gp_size(index, 1, operand_type::gp); + } + + static operand B(int index) + { + return gp_size(index, 0, operand_type::gp); + } + + static void assert_is_gp_sp(operand test) + { + if (test.operand_register_index == 31) + { + assert(test.type == sp); + } + else + { + assert(test.type == gp); + } + } + + static void assert_is_gp_zr(operand test) + { + if (test.operand_register_index == 31) + { + assert(test.type == zr); + } + else + { + assert(test.type == gp); + } + } + + static void assert_same_size(operand left, operand right) + { + assert(left.operand_size == right.operand_size); + } + + static bool is_vector(operand test) + { + return test.operand_size == 4; + } + + static void assert_not_vector(operand test) + { + assert(!is_vector(test)); + } + + static void assert_w_or_x(operand test) + { + assert(test.operand_size == 2 || test.operand_size == 3); + } + + static void assert_in_mask(int imm, int bit_count) + { + assert((imm & ~create_mask(bit_count)) == 0); + } + + static void create(rarma_context* result, uint64_t memory_block_size = 1024) + { + result->memory_block = malloc(memory_block_size); + + result->memory_location = 0; + result->memory_block_size = memory_block_size; + } + + static void destroy(rarma_context* to_destroy) + { + free(to_destroy->memory_block); + } + + static uint32_t write_instruction(rarma_context* context,uint32_t instruction) + { + if (context->memory_location >= context->memory_block_size) + { + std::cout << "RARM OUT OF SPACE" << std::endl; + + throw 0; + } + + *(uint32_t*)((uint64_t)context->memory_block + context->memory_location) = instruction; + + context->memory_location += 4; + + return instruction; + } + + static int create_mask(int size) + { + return (1 << size) - 1; + } + + static uint32_t add_subtract_shifted(rarma_context* context, bool is_add, bool set_flags, operand d, operand n, operand m, shift_type shift, int imm6) + { + int sf = d.operand_size == 3; + int op = !is_add; + int S = set_flags; + + assert_in_mask(imm6, 6); + assert_in_mask(shift, 2); + + assert_is_gp_zr(d); + assert_is_gp_zr(n); + assert_is_gp_zr(m); + + uint32_t result = 0b01011 << 24; + + result |= sf << 31; + result |= op << 30; + result |= S << 28; + result |= shift << 22; + result |= m.operand_register_index << 16; + result |= imm6 << 10; + result |= n.operand_register_index << 5; + result |= d.operand_register_index; + + write_instruction(context, result); + + return result; + } + + static uint32_t add_subtract_imm12(rarma_context* context, bool is_add, bool set_flags, operand d, operand n, int imm12) + { + int sf = d.operand_size == 3; + int op = !is_add; + int S = set_flags; + int sh; + + if (imm12 == 0) + { + sh = 0; + } + else if (imm12 & create_mask(12)) + { + assert_in_mask(imm12, 12); + + sh = 0; + } + else if (imm12 >> 12) + { + imm12 >>= 12; + + assert((imm12 & ~create_mask(12)) == 0); + + sh = 1; + } + + uint32_t result = 0b100010 << 23; + + assert_same_size(d, n); + assert_not_vector(d); + assert_w_or_x(d); + + assert_is_gp_sp(n); + + if (set_flags) + { + assert_is_gp_zr(d); + } + else + { + assert_is_gp_sp(d); + } + + result |= (sf << 31); + result |= (op << 30); + result |= (S << 29); + result |= (sh << 22); + + result |= d.operand_register_index; + result |= n.operand_register_index << 5; + result |= imm12 << 10; + + write_instruction(context, result); + + return result; + } + + static uint32_t add_imm12(rarma_context* context, operand d, operand n, int imm12) + { + return add_subtract_imm12(context, true, false, d, n, imm12); + } + + static uint32_t sub_imm12(rarma_context* context, operand d, operand n, int imm12) + { + return add_subtract_imm12(context, false, false, d, n, imm12); + } + + static uint32_t adds_imm12(rarma_context* context, operand d, operand n, int imm12) + { + return add_subtract_imm12(context, true, true, d, n, imm12); + } + + static uint32_t subs_imm12(rarma_context* context, operand d, operand n, int imm12) + { + return add_subtract_imm12(context, false, true, d, n, imm12); + } + + static uint32_t add_shifted(rarma_context* context, operand d, operand n, operand m, shift_type shift = shift_type::lsl, int imm6 = 0) + { + return add_subtract_shifted(context, true, false, d, n, m, shift, imm6); + } + + static uint32_t sub_shifted(rarma_context* context, operand d, operand n, operand m, shift_type shift = shift_type::lsl, int imm6 = 0) + { + return add_subtract_shifted(context, false, false, d, n, m, shift, imm6); + } + + static uint32_t adds_shifted(rarma_context* context, operand d, operand n, operand m, shift_type shift = shift_type::lsl, int imm6 = 0) + { + return add_subtract_shifted(context, true, true, d, n, m, shift, imm6); + } + + static uint32_t subs_shifted(rarma_context* context, operand d, operand n, operand m, shift_type shift = shift_type::lsl, int imm6 = 0) + { + return add_subtract_shifted(context, false, true, d, n, m, shift, imm6); + } + + static uint32_t ret(rarma_context* context, operand n) + { + uint32_t result = 0b1101011001011111000000 << 10; + + assert_is_gp_zr(n); + + result |= n.operand_register_index << 5; + + write_instruction(context, result); + + return result; + } +}; + +#endif \ No newline at end of file diff --git a/src/assembly/x86/x86_assembler.cpp b/src/assembly/x86/x86_assembler.cpp index 42db895..3fede6c 100755 --- a/src/assembly/x86/x86_assembler.cpp +++ b/src/assembly/x86/x86_assembler.cpp @@ -233,6 +233,15 @@ void assemble_x86_64_code(void** result_code, uint64_t* result_code_size, ir_ope case ir_jump_if_equal: case ir_jump_if_not_equal: + + case ir_jump_if_greater_equal_signed: + case ir_jump_if_greater_equal_unsigned: + case ir_jump_if_greater_signed: + case ir_jump_if_greater_unsigned: + case ir_jump_if_less_equal_signed: + case ir_jump_if_less_equal_unsigned: + case ir_jump_if_less_signed: + case ir_jump_if_less_unsigned: { ir_operand label_operand = working_operation.sources[0]; ir_operand left = working_operation.sources[1]; diff --git a/src/emulator/aarch64/aarch64_impl.cpp b/src/emulator/aarch64/aarch64_impl.cpp index c2f3a57..5e6c7ad 100755 --- a/src/emulator/aarch64/aarch64_impl.cpp +++ b/src/emulator/aarch64/aarch64_impl.cpp @@ -966,950 +966,6 @@ static void emit_load_store_exclusive_ordered_jit(ssa_emit_context* ctx, uint32_ load_store_exclusive_ordered_jit(ctx, size, ordered, L, Rs, o0, Rn, Rt); } -static void call_conversion_between_floating_point_and_fixed_point_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int S = (instruction >> 29) & 1; - int ftype = (instruction >> 22) & 3; - int rmode = (instruction >> 19) & 3; - int opcode = (instruction >> 16) & 7; - int scale = (instruction >> 10) & 63; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - conversion_between_floating_point_and_fixed_point_interpreter(ctx, sf, S, ftype, rmode, opcode, scale, Rn, Rd); -} - -static void emit_conversion_between_floating_point_and_fixed_point_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int S = (instruction >> 29) & 1; - int ftype = (instruction >> 22) & 3; - int rmode = (instruction >> 19) & 3; - int opcode = (instruction >> 16) & 7; - int scale = (instruction >> 10) & 63; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - conversion_between_floating_point_and_fixed_point_jit(ctx, sf, S, ftype, rmode, opcode, scale, Rn, Rd); -} - -static void call_fcvt_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int opc = (instruction >> 15) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvt_interpreter(ctx, ftype, opc, Rn, Rd); -} - -static void emit_fcvt_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int opc = (instruction >> 15) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvt_jit(ctx, ftype, opc, Rn, Rd); -} - -static void call_fcvtz_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvtz_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); -} - -static void emit_fcvtz_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvtz_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); -} - -static void call_fcvtn_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvtn_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); -} - -static void emit_fcvtn_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvtn_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); -} - -static void call_fcvta_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvta_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); -} - -static void emit_fcvta_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvta_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); -} - -static void call_fcvtm_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvtm_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); -} - -static void emit_fcvtm_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvtm_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); -} - -static void call_frintp_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frintp_scalar_interpreter(ctx, ftype, Rn, Rd); -} - -static void emit_frintp_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frintp_scalar_jit(ctx, ftype, Rn, Rd); -} - -static void call_frintm_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frintm_scalar_interpreter(ctx, ftype, Rn, Rd); -} - -static void emit_frintm_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frintm_scalar_jit(ctx, ftype, Rn, Rd); -} - -static void call_fcvtp_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvtp_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); -} - -static void emit_fcvtp_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sf = (instruction >> 31) & 1; - int ftype = (instruction >> 22) & 3; - int U = (instruction >> 16) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcvtp_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); -} - -static void call_fadd_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fadd_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fadd_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fadd_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fmul_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fmul_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fsub_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fsub_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fsub_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fsub_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fdiv_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fdiv_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fdiv_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fdiv_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fmin_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmin_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fmin_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmin_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fmax_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmax_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fmax_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmax_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fmul_accumulate_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int neg = (instruction >> 23) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_accumulate_vector_interpreter(ctx, Q, neg, sz, Rm, Rn, Rd); -} - -static void emit_fmul_accumulate_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int neg = (instruction >> 23) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_accumulate_vector_jit(ctx, Q, neg, sz, Rm, Rn, Rd); -} - -static void call_faddp_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - faddp_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_faddp_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - faddp_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_frsqrte_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frsqrte_vector_interpreter(ctx, Q, sz, Rn, Rd); -} - -static void emit_frsqrte_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frsqrte_vector_jit(ctx, Q, sz, Rn, Rd); -} - -static void call_frsqrts_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frsqrts_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_frsqrts_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frsqrts_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_frecps_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frecps_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_frecps_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frecps_vector_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fmul_scalar_by_element_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sz = (instruction >> 22) & 1; - int L = (instruction >> 21) & 1; - int M = (instruction >> 20) & 1; - int Rm = (instruction >> 16) & 15; - int H = (instruction >> 11) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_scalar_by_element_interpreter(ctx, sz, L, M, Rm, H, Rn, Rd); -} - -static void emit_fmul_scalar_by_element_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sz = (instruction >> 22) & 1; - int L = (instruction >> 21) & 1; - int M = (instruction >> 20) & 1; - int Rm = (instruction >> 16) & 15; - int H = (instruction >> 11) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_scalar_by_element_jit(ctx, sz, L, M, Rm, H, Rn, Rd); -} - -static void call_fmul_vector_by_element_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int L = (instruction >> 21) & 1; - int M = (instruction >> 20) & 1; - int Rm = (instruction >> 16) & 15; - int H = (instruction >> 11) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_vector_by_element_interpreter(ctx, Q, sz, L, M, Rm, H, Rn, Rd); -} - -static void emit_fmul_vector_by_element_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int L = (instruction >> 21) & 1; - int M = (instruction >> 20) & 1; - int Rm = (instruction >> 16) & 15; - int H = (instruction >> 11) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_vector_by_element_jit(ctx, Q, sz, L, M, Rm, H, Rn, Rd); -} - -static void call_fmul_accumulate_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sz = (instruction >> 22) & 1; - int L = (instruction >> 21) & 1; - int M = (instruction >> 20) & 1; - int Rm = (instruction >> 16) & 15; - int neg = (instruction >> 14) & 1; - int H = (instruction >> 11) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_accumulate_scalar_interpreter(ctx, sz, L, M, Rm, neg, H, Rn, Rd); -} - -static void emit_fmul_accumulate_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sz = (instruction >> 22) & 1; - int L = (instruction >> 21) & 1; - int M = (instruction >> 20) & 1; - int Rm = (instruction >> 16) & 15; - int neg = (instruction >> 14) & 1; - int H = (instruction >> 11) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_accumulate_scalar_jit(ctx, sz, L, M, Rm, neg, H, Rn, Rd); -} - -static void call_fmul_accumulate_element_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int L = (instruction >> 21) & 1; - int M = (instruction >> 20) & 1; - int Rm = (instruction >> 16) & 15; - int neg = (instruction >> 14) & 1; - int H = (instruction >> 11) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_accumulate_element_interpreter(ctx, Q, sz, L, M, Rm, neg, H, Rn, Rd); -} - -static void emit_fmul_accumulate_element_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int L = (instruction >> 21) & 1; - int M = (instruction >> 20) & 1; - int Rm = (instruction >> 16) & 15; - int neg = (instruction >> 14) & 1; - int H = (instruction >> 11) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_accumulate_element_jit(ctx, Q, sz, L, M, Rm, neg, H, Rn, Rd); -} - -static void call_faddp_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - faddp_scalar_interpreter(ctx, sz, Rn, Rd); -} - -static void emit_faddp_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - faddp_scalar_jit(ctx, sz, Rn, Rd); -} - -static void call_fcmeq_vector_zero_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmeq_vector_zero_interpreter(ctx, Q, sz, Rn, Rd); -} - -static void emit_fcmeq_vector_zero_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmeq_vector_zero_jit(ctx, Q, sz, Rn, Rd); -} - -static void call_fcmgt_vector_zero_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmgt_vector_zero_interpreter(ctx, Q, sz, Rn, Rd); -} - -static void emit_fcmgt_vector_zero_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmgt_vector_zero_jit(ctx, Q, sz, Rn, Rd); -} - -static void call_fcmge_vector_zero_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmge_vector_zero_interpreter(ctx, Q, sz, Rn, Rd); -} - -static void emit_fcmge_vector_zero_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmge_vector_zero_jit(ctx, Q, sz, Rn, Rd); -} - -static void call_fcmeq_vector_register_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmeq_vector_register_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fcmeq_vector_register_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmeq_vector_register_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fcmgt_vector_register_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmgt_vector_register_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fcmgt_vector_register_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmgt_vector_register_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fcmge_vector_register_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmge_vector_register_interpreter(ctx, Q, sz, Rm, Rn, Rd); -} - -static void emit_fcmge_vector_register_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmge_vector_register_jit(ctx, Q, sz, Rm, Rn, Rd); -} - -static void call_fcmle_zero_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmle_zero_vector_interpreter(ctx, Q, sz, Rn, Rd); -} - -static void emit_fcmle_zero_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fcmle_zero_vector_jit(ctx, Q, sz, Rn, Rd); -} - -static void call_fadd_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fadd_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fadd_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fadd_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fsub_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fsub_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fsub_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fsub_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fmul_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fmul_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmul_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fdiv_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fdiv_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fdiv_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fdiv_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fmax_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmax_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fmax_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmax_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fmin_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmin_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fmin_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmin_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fmaxnm_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmaxnm_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fmaxnm_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fmaxnm_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fminnm_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fminnm_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fminnm_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fminnm_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fnmul_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fnmul_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); -} - -static void emit_fnmul_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rm = (instruction >> 16) & 31; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fnmul_scalar_jit(ctx, ftype, Rm, Rn, Rd); -} - -static void call_fabs_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fabs_scalar_interpreter(ctx, ftype, Rn, Rd); -} - -static void emit_fabs_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fabs_scalar_jit(ctx, ftype, Rn, Rd); -} - -static void call_fneg_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fneg_scalar_interpreter(ctx, ftype, Rn, Rd); -} - -static void emit_fneg_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fneg_scalar_jit(ctx, ftype, Rn, Rd); -} - -static void call_fneg_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fneg_vector_interpreter(ctx, Q, sz, Rn, Rd); -} - -static void emit_fneg_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fneg_vector_jit(ctx, Q, sz, Rn, Rd); -} - -static void call_fsqrt_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fsqrt_scalar_interpreter(ctx, ftype, Rn, Rd); -} - -static void emit_fsqrt_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fsqrt_scalar_jit(ctx, ftype, Rn, Rd); -} - -static void call_fsqrt_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fsqrt_vector_interpreter(ctx, Q, sz, Rn, Rd); -} - -static void emit_fsqrt_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - fsqrt_vector_jit(ctx, Q, sz, Rn, Rd); -} - -static void call_frecpe_vector_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frecpe_vector_interpreter(ctx, Q, sz, Rn, Rd); -} - -static void emit_frecpe_vector_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int Q = (instruction >> 30) & 1; - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frecpe_vector_jit(ctx, Q, sz, Rn, Rd); -} - -static void call_frsqrte_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frsqrte_scalar_interpreter(ctx, sz, Rn, Rd); -} - -static void emit_frsqrte_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int sz = (instruction >> 22) & 1; - int Rn = (instruction >> 5) & 31; - int Rd = (instruction >> 0) & 31; - frsqrte_scalar_jit(ctx, sz, Rn, Rd); -} - -static void call_fmov_scalar_immediate_interpreter(interpreter_data* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int imm8 = (instruction >> 13) & 255; - int Rd = (instruction >> 0) & 31; - fmov_scalar_immediate_interpreter(ctx, ftype, imm8, Rd); -} - -static void emit_fmov_scalar_immediate_jit(ssa_emit_context* ctx, uint32_t instruction) -{ - int ftype = (instruction >> 22) & 3; - int imm8 = (instruction >> 13) & 255; - int Rd = (instruction >> 0) & 31; - fmov_scalar_immediate_jit(ctx, ftype, imm8, Rd); -} - static void call_dup_general_interpreter(interpreter_data* ctx, uint32_t instruction) { int Q = (instruction >> 30) & 1; @@ -2946,6 +2002,950 @@ static void emit_fccmp_jit(ssa_emit_context* ctx, uint32_t instruction) fccmp_jit(ctx, ftype, Rm, cond, Rn, nzcv); } +static void call_conversion_between_floating_point_and_fixed_point_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int S = (instruction >> 29) & 1; + int ftype = (instruction >> 22) & 3; + int rmode = (instruction >> 19) & 3; + int opcode = (instruction >> 16) & 7; + int scale = (instruction >> 10) & 63; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + conversion_between_floating_point_and_fixed_point_interpreter(ctx, sf, S, ftype, rmode, opcode, scale, Rn, Rd); +} + +static void emit_conversion_between_floating_point_and_fixed_point_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int S = (instruction >> 29) & 1; + int ftype = (instruction >> 22) & 3; + int rmode = (instruction >> 19) & 3; + int opcode = (instruction >> 16) & 7; + int scale = (instruction >> 10) & 63; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + conversion_between_floating_point_and_fixed_point_jit(ctx, sf, S, ftype, rmode, opcode, scale, Rn, Rd); +} + +static void call_fcvt_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int opc = (instruction >> 15) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvt_interpreter(ctx, ftype, opc, Rn, Rd); +} + +static void emit_fcvt_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int opc = (instruction >> 15) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvt_jit(ctx, ftype, opc, Rn, Rd); +} + +static void call_fcvtz_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvtz_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); +} + +static void emit_fcvtz_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvtz_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); +} + +static void call_fcvtn_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvtn_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); +} + +static void emit_fcvtn_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvtn_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); +} + +static void call_fcvta_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvta_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); +} + +static void emit_fcvta_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvta_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); +} + +static void call_fcvtm_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvtm_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); +} + +static void emit_fcvtm_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvtm_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); +} + +static void call_frintp_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frintp_scalar_interpreter(ctx, ftype, Rn, Rd); +} + +static void emit_frintp_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frintp_scalar_jit(ctx, ftype, Rn, Rd); +} + +static void call_frintm_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frintm_scalar_interpreter(ctx, ftype, Rn, Rd); +} + +static void emit_frintm_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frintm_scalar_jit(ctx, ftype, Rn, Rd); +} + +static void call_fcvtp_scalar_integer_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvtp_scalar_integer_interpreter(ctx, sf, ftype, U, Rn, Rd); +} + +static void emit_fcvtp_scalar_integer_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sf = (instruction >> 31) & 1; + int ftype = (instruction >> 22) & 3; + int U = (instruction >> 16) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcvtp_scalar_integer_jit(ctx, sf, ftype, U, Rn, Rd); +} + +static void call_fadd_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fadd_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fadd_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fadd_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fsub_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fsub_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fsub_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fsub_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fmul_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fmul_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fdiv_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fdiv_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fdiv_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fdiv_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fmax_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmax_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fmax_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmax_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fmin_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmin_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fmin_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmin_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fmaxnm_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmaxnm_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fmaxnm_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmaxnm_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fminnm_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fminnm_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fminnm_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fminnm_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fnmul_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fnmul_scalar_interpreter(ctx, ftype, Rm, Rn, Rd); +} + +static void emit_fnmul_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fnmul_scalar_jit(ctx, ftype, Rm, Rn, Rd); +} + +static void call_fabs_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fabs_scalar_interpreter(ctx, ftype, Rn, Rd); +} + +static void emit_fabs_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fabs_scalar_jit(ctx, ftype, Rn, Rd); +} + +static void call_fneg_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fneg_scalar_interpreter(ctx, ftype, Rn, Rd); +} + +static void emit_fneg_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fneg_scalar_jit(ctx, ftype, Rn, Rd); +} + +static void call_fneg_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fneg_vector_interpreter(ctx, Q, sz, Rn, Rd); +} + +static void emit_fneg_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fneg_vector_jit(ctx, Q, sz, Rn, Rd); +} + +static void call_fsqrt_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fsqrt_scalar_interpreter(ctx, ftype, Rn, Rd); +} + +static void emit_fsqrt_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fsqrt_scalar_jit(ctx, ftype, Rn, Rd); +} + +static void call_fsqrt_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fsqrt_vector_interpreter(ctx, Q, sz, Rn, Rd); +} + +static void emit_fsqrt_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fsqrt_vector_jit(ctx, Q, sz, Rn, Rd); +} + +static void call_frecpe_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frecpe_vector_interpreter(ctx, Q, sz, Rn, Rd); +} + +static void emit_frecpe_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frecpe_vector_jit(ctx, Q, sz, Rn, Rd); +} + +static void call_frsqrte_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frsqrte_scalar_interpreter(ctx, sz, Rn, Rd); +} + +static void emit_frsqrte_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frsqrte_scalar_jit(ctx, sz, Rn, Rd); +} + +static void call_fmov_scalar_immediate_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int imm8 = (instruction >> 13) & 255; + int Rd = (instruction >> 0) & 31; + fmov_scalar_immediate_interpreter(ctx, ftype, imm8, Rd); +} + +static void emit_fmov_scalar_immediate_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int ftype = (instruction >> 22) & 3; + int imm8 = (instruction >> 13) & 255; + int Rd = (instruction >> 0) & 31; + fmov_scalar_immediate_jit(ctx, ftype, imm8, Rd); +} + +static void call_fadd_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fadd_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fadd_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fadd_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fmul_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fmul_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fsub_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fsub_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fsub_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fsub_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fdiv_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fdiv_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fdiv_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fdiv_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fmin_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmin_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fmin_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmin_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fmax_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmax_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fmax_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmax_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fmul_accumulate_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int neg = (instruction >> 23) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_accumulate_vector_interpreter(ctx, Q, neg, sz, Rm, Rn, Rd); +} + +static void emit_fmul_accumulate_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int neg = (instruction >> 23) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_accumulate_vector_jit(ctx, Q, neg, sz, Rm, Rn, Rd); +} + +static void call_faddp_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + faddp_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_faddp_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + faddp_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_frsqrte_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frsqrte_vector_interpreter(ctx, Q, sz, Rn, Rd); +} + +static void emit_frsqrte_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frsqrte_vector_jit(ctx, Q, sz, Rn, Rd); +} + +static void call_frsqrts_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frsqrts_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_frsqrts_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frsqrts_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_frecps_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frecps_vector_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_frecps_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + frecps_vector_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fmul_scalar_by_element_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sz = (instruction >> 22) & 1; + int L = (instruction >> 21) & 1; + int M = (instruction >> 20) & 1; + int Rm = (instruction >> 16) & 15; + int H = (instruction >> 11) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_scalar_by_element_interpreter(ctx, sz, L, M, Rm, H, Rn, Rd); +} + +static void emit_fmul_scalar_by_element_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sz = (instruction >> 22) & 1; + int L = (instruction >> 21) & 1; + int M = (instruction >> 20) & 1; + int Rm = (instruction >> 16) & 15; + int H = (instruction >> 11) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_scalar_by_element_jit(ctx, sz, L, M, Rm, H, Rn, Rd); +} + +static void call_fmul_vector_by_element_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int L = (instruction >> 21) & 1; + int M = (instruction >> 20) & 1; + int Rm = (instruction >> 16) & 15; + int H = (instruction >> 11) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_vector_by_element_interpreter(ctx, Q, sz, L, M, Rm, H, Rn, Rd); +} + +static void emit_fmul_vector_by_element_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int L = (instruction >> 21) & 1; + int M = (instruction >> 20) & 1; + int Rm = (instruction >> 16) & 15; + int H = (instruction >> 11) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_vector_by_element_jit(ctx, Q, sz, L, M, Rm, H, Rn, Rd); +} + +static void call_fmul_accumulate_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sz = (instruction >> 22) & 1; + int L = (instruction >> 21) & 1; + int M = (instruction >> 20) & 1; + int Rm = (instruction >> 16) & 15; + int neg = (instruction >> 14) & 1; + int H = (instruction >> 11) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_accumulate_scalar_interpreter(ctx, sz, L, M, Rm, neg, H, Rn, Rd); +} + +static void emit_fmul_accumulate_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sz = (instruction >> 22) & 1; + int L = (instruction >> 21) & 1; + int M = (instruction >> 20) & 1; + int Rm = (instruction >> 16) & 15; + int neg = (instruction >> 14) & 1; + int H = (instruction >> 11) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_accumulate_scalar_jit(ctx, sz, L, M, Rm, neg, H, Rn, Rd); +} + +static void call_fmul_accumulate_element_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int L = (instruction >> 21) & 1; + int M = (instruction >> 20) & 1; + int Rm = (instruction >> 16) & 15; + int neg = (instruction >> 14) & 1; + int H = (instruction >> 11) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_accumulate_element_interpreter(ctx, Q, sz, L, M, Rm, neg, H, Rn, Rd); +} + +static void emit_fmul_accumulate_element_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int L = (instruction >> 21) & 1; + int M = (instruction >> 20) & 1; + int Rm = (instruction >> 16) & 15; + int neg = (instruction >> 14) & 1; + int H = (instruction >> 11) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fmul_accumulate_element_jit(ctx, Q, sz, L, M, Rm, neg, H, Rn, Rd); +} + +static void call_faddp_scalar_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + faddp_scalar_interpreter(ctx, sz, Rn, Rd); +} + +static void emit_faddp_scalar_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + faddp_scalar_jit(ctx, sz, Rn, Rd); +} + +static void call_fcmeq_vector_zero_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmeq_vector_zero_interpreter(ctx, Q, sz, Rn, Rd); +} + +static void emit_fcmeq_vector_zero_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmeq_vector_zero_jit(ctx, Q, sz, Rn, Rd); +} + +static void call_fcmgt_vector_zero_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmgt_vector_zero_interpreter(ctx, Q, sz, Rn, Rd); +} + +static void emit_fcmgt_vector_zero_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmgt_vector_zero_jit(ctx, Q, sz, Rn, Rd); +} + +static void call_fcmge_vector_zero_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmge_vector_zero_interpreter(ctx, Q, sz, Rn, Rd); +} + +static void emit_fcmge_vector_zero_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmge_vector_zero_jit(ctx, Q, sz, Rn, Rd); +} + +static void call_fcmeq_vector_register_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmeq_vector_register_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fcmeq_vector_register_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmeq_vector_register_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fcmgt_vector_register_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmgt_vector_register_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fcmgt_vector_register_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmgt_vector_register_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fcmge_vector_register_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmge_vector_register_interpreter(ctx, Q, sz, Rm, Rn, Rd); +} + +static void emit_fcmge_vector_register_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rm = (instruction >> 16) & 31; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmge_vector_register_jit(ctx, Q, sz, Rm, Rn, Rd); +} + +static void call_fcmle_zero_vector_interpreter(interpreter_data* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmle_zero_vector_interpreter(ctx, Q, sz, Rn, Rd); +} + +static void emit_fcmle_zero_vector_jit(ssa_emit_context* ctx, uint32_t instruction) +{ + int Q = (instruction >> 30) & 1; + int sz = (instruction >> 22) & 1; + int Rn = (instruction >> 5) & 31; + int Rd = (instruction >> 0) & 31; + fcmle_zero_vector_jit(ctx, Q, sz, Rn, Rd); +} + void init_aarch64_decoder(guest_process* process) { append_table(process, "---100010-----------------------", (void*)emit_add_subtract_imm12_jit, (void*)call_add_subtract_imm12_interpreter,nullptr, "add_subtract_imm12"); @@ -2990,55 +2990,6 @@ void init_aarch64_decoder(guest_process* process) append_table(process, "--111-01------------------------", (void*)emit_load_store_register_imm_unsigned_jit, (void*)call_load_store_register_imm_unsigned_interpreter,nullptr, "load_store_register_imm_unsigned"); append_table(process, "--111-00--1---------10----------", (void*)emit_load_store_register_offset_jit, (void*)call_load_store_register_offset_interpreter,nullptr, "load_store_register_offset"); append_table(process, "--001000--0------11111----------", (void*)emit_load_store_exclusive_ordered_jit, (void*)call_load_store_exclusive_ordered_interpreter,nullptr, "load_store_exclusive_ordered"); - append_table(process, "-0-11110--0---------------------", (void*)emit_conversion_between_floating_point_and_fixed_point_jit, (void*)call_conversion_between_floating_point_and_fixed_point_interpreter,nullptr, "conversion_between_floating_point_and_fixed_point"); - append_table(process, "00011110--10001--10000----------", (void*)emit_fcvt_jit, (void*)call_fcvt_interpreter,nullptr, "fcvt"); - append_table(process, "-0011110--11100-000000----------", (void*)emit_fcvtz_scalar_integer_jit, (void*)call_fcvtz_scalar_integer_interpreter,nullptr, "fcvtz_scalar_integer"); - append_table(process, "-0011110--10000-000000----------", (void*)emit_fcvtn_scalar_integer_jit, (void*)call_fcvtn_scalar_integer_interpreter,nullptr, "fcvtn_scalar_integer"); - append_table(process, "-0011110--10010-000000----------", (void*)emit_fcvta_scalar_integer_jit, (void*)call_fcvta_scalar_integer_interpreter,nullptr, "fcvta_scalar_integer"); - append_table(process, "-0011110--11000-000000----------", (void*)emit_fcvtm_scalar_integer_jit, (void*)call_fcvtm_scalar_integer_interpreter,nullptr, "fcvtm_scalar_integer"); - append_table(process, "00011110--100100110000----------", (void*)emit_frintp_scalar_jit, (void*)call_frintp_scalar_interpreter,nullptr, "frintp_scalar"); - append_table(process, "00011110--100101010000----------", (void*)emit_frintm_scalar_jit, (void*)call_frintm_scalar_interpreter,nullptr, "frintm_scalar"); - append_table(process, "-0011110--10100-000000----------", (void*)emit_fcvtp_scalar_integer_jit, (void*)call_fcvtp_scalar_integer_interpreter,nullptr, "fcvtp_scalar_integer"); - append_table(process, "0-0011100-1-----110101----------", (void*)emit_fadd_vector_jit, (void*)call_fadd_vector_interpreter,nullptr, "fadd_vector"); - append_table(process, "0-1011100-1-----110111----------", (void*)emit_fmul_vector_jit, (void*)call_fmul_vector_interpreter,nullptr, "fmul_vector"); - append_table(process, "0-0011101-1-----110101----------", (void*)emit_fsub_vector_jit, (void*)call_fsub_vector_interpreter,nullptr, "fsub_vector"); - append_table(process, "0-1011100-1-----111111----------", (void*)emit_fdiv_vector_jit, (void*)call_fdiv_vector_interpreter,nullptr, "fdiv_vector"); - append_table(process, "0-0011101-1-----111101----------", (void*)emit_fmin_vector_jit, (void*)call_fmin_vector_interpreter,nullptr, "fmin_vector"); - append_table(process, "0-0011100-1-----111101----------", (void*)emit_fmax_vector_jit, (void*)call_fmax_vector_interpreter,nullptr, "fmax_vector"); - append_table(process, "0-001110--1-----110011----------", (void*)emit_fmul_accumulate_vector_jit, (void*)call_fmul_accumulate_vector_interpreter,nullptr, "fmul_accumulate_vector"); - append_table(process, "0-1011100-1-----110101----------", (void*)emit_faddp_vector_jit, (void*)call_faddp_vector_interpreter,nullptr, "faddp_vector"); - append_table(process, "0-1011101-100001110110----------", (void*)emit_frsqrte_vector_jit, (void*)call_frsqrte_vector_interpreter,nullptr, "frsqrte_vector"); - append_table(process, "0-0011101-1-----111111----------", (void*)emit_frsqrts_vector_jit, (void*)call_frsqrts_vector_interpreter,nullptr, "frsqrts_vector"); - append_table(process, "0-0011100-1-----111111----------", (void*)emit_frecps_vector_jit, (void*)call_frecps_vector_interpreter,nullptr, "frecps_vector"); - append_table(process, "010111111-------1001-0----------", (void*)emit_fmul_scalar_by_element_jit, (void*)call_fmul_scalar_by_element_interpreter,nullptr, "fmul_scalar_by_element"); - append_table(process, "0-0011111-------1001-0----------", (void*)emit_fmul_vector_by_element_jit, (void*)call_fmul_vector_by_element_interpreter,nullptr, "fmul_vector_by_element"); - append_table(process, "010111111-------0-01-0----------", (void*)emit_fmul_accumulate_scalar_jit, (void*)call_fmul_accumulate_scalar_interpreter,nullptr, "fmul_accumulate_scalar"); - append_table(process, "0-0011111-------0-01-0----------", (void*)emit_fmul_accumulate_element_jit, (void*)call_fmul_accumulate_element_interpreter,nullptr, "fmul_accumulate_element"); - append_table(process, "011111100-110000110110----------", (void*)emit_faddp_scalar_jit, (void*)call_faddp_scalar_interpreter,nullptr, "faddp_scalar"); - append_table(process, "0-0011101-100000110110----------", (void*)emit_fcmeq_vector_zero_jit, (void*)call_fcmeq_vector_zero_interpreter,nullptr, "fcmeq_vector_zero"); - append_table(process, "0-0011101-100000110010----------", (void*)emit_fcmgt_vector_zero_jit, (void*)call_fcmgt_vector_zero_interpreter,nullptr, "fcmgt_vector_zero"); - append_table(process, "0-1011101-100000110010----------", (void*)emit_fcmge_vector_zero_jit, (void*)call_fcmge_vector_zero_interpreter,nullptr, "fcmge_vector_zero"); - append_table(process, "0-0011100-1-----111001----------", (void*)emit_fcmeq_vector_register_jit, (void*)call_fcmeq_vector_register_interpreter,nullptr, "fcmeq_vector_register"); - append_table(process, "0-1011101-1-----111001----------", (void*)emit_fcmgt_vector_register_jit, (void*)call_fcmgt_vector_register_interpreter,nullptr, "fcmgt_vector_register"); - append_table(process, "0-1011100-1-----111001----------", (void*)emit_fcmge_vector_register_jit, (void*)call_fcmge_vector_register_interpreter,nullptr, "fcmge_vector_register"); - append_table(process, "0-1011101-100000110110----------", (void*)emit_fcmle_zero_vector_jit, (void*)call_fcmle_zero_vector_interpreter,nullptr, "fcmle_zero_vector"); - append_table(process, "00011110--1-----001010----------", (void*)emit_fadd_scalar_jit, (void*)call_fadd_scalar_interpreter,nullptr, "fadd_scalar"); - append_table(process, "00011110--1-----001110----------", (void*)emit_fsub_scalar_jit, (void*)call_fsub_scalar_interpreter,nullptr, "fsub_scalar"); - append_table(process, "00011110--1-----000010----------", (void*)emit_fmul_scalar_jit, (void*)call_fmul_scalar_interpreter,nullptr, "fmul_scalar"); - append_table(process, "00011110--1-----000110----------", (void*)emit_fdiv_scalar_jit, (void*)call_fdiv_scalar_interpreter,nullptr, "fdiv_scalar"); - append_table(process, "00011110--1-----010010----------", (void*)emit_fmax_scalar_jit, (void*)call_fmax_scalar_interpreter,nullptr, "fmax_scalar"); - append_table(process, "00011110--1-----010110----------", (void*)emit_fmin_scalar_jit, (void*)call_fmin_scalar_interpreter,nullptr, "fmin_scalar"); - append_table(process, "00011110--1-----011010----------", (void*)emit_fmaxnm_scalar_jit, (void*)call_fmaxnm_scalar_interpreter,nullptr, "fmaxnm_scalar"); - append_table(process, "00011110--1-----011110----------", (void*)emit_fminnm_scalar_jit, (void*)call_fminnm_scalar_interpreter,nullptr, "fminnm_scalar"); - append_table(process, "00011110--1-----100010----------", (void*)emit_fnmul_scalar_jit, (void*)call_fnmul_scalar_interpreter,nullptr, "fnmul_scalar"); - append_table(process, "00011110--100000110000----------", (void*)emit_fabs_scalar_jit, (void*)call_fabs_scalar_interpreter,nullptr, "fabs_scalar"); - append_table(process, "00011110--100001010000----------", (void*)emit_fneg_scalar_jit, (void*)call_fneg_scalar_interpreter,nullptr, "fneg_scalar"); - append_table(process, "0-1011101-100000111110----------", (void*)emit_fneg_vector_jit, (void*)call_fneg_vector_interpreter,nullptr, "fneg_vector"); - append_table(process, "00011110--100001110000----------", (void*)emit_fsqrt_scalar_jit, (void*)call_fsqrt_scalar_interpreter,nullptr, "fsqrt_scalar"); - append_table(process, "0-1011101-100001111110----------", (void*)emit_fsqrt_vector_jit, (void*)call_fsqrt_vector_interpreter,nullptr, "fsqrt_vector"); - append_table(process, "0-0011101-100001110110----------", (void*)emit_frecpe_vector_jit, (void*)call_frecpe_vector_interpreter,nullptr, "frecpe_vector"); - append_table(process, "011111101-100001110110----------", (void*)emit_frsqrte_scalar_jit, (void*)call_frsqrte_scalar_interpreter,nullptr, "frsqrte_scalar"); - append_table(process, "00011110--1--------10000000-----", (void*)emit_fmov_scalar_immediate_jit, (void*)call_fmov_scalar_immediate_interpreter,nullptr, "fmov_scalar_immediate"); append_table(process, "0-001110000-----000011----------", (void*)emit_dup_general_jit, (void*)call_dup_general_interpreter,nullptr, "dup_general"); append_table(process, "01011110000-----000001----------", (void*)emit_dup_element_scalar_jit, (void*)call_dup_element_scalar_interpreter,nullptr, "dup_element_scalar"); append_table(process, "0-001110000-----000001----------", (void*)emit_dup_element_vector_jit, (void*)call_dup_element_vector_interpreter,nullptr, "dup_element_vector"); @@ -3089,6 +3040,2489 @@ void init_aarch64_decoder(guest_process* process) append_table(process, "00011110--1---------11----------", (void*)emit_floating_point_conditional_select_jit, (void*)call_floating_point_conditional_select_interpreter,nullptr, "floating_point_conditional_select"); append_table(process, "00011110--1-----001000-----0-000", (void*)emit_fcmp_jit, (void*)call_fcmp_interpreter,nullptr, "fcmp"); append_table(process, "00011110--1---------01-----0----", (void*)emit_fccmp_jit, (void*)call_fccmp_interpreter,nullptr, "fccmp"); + append_table(process, "-0-11110--0---------------------", (void*)emit_conversion_between_floating_point_and_fixed_point_jit, (void*)call_conversion_between_floating_point_and_fixed_point_interpreter,nullptr, "conversion_between_floating_point_and_fixed_point"); + append_table(process, "00011110--10001--10000----------", (void*)emit_fcvt_jit, (void*)call_fcvt_interpreter,nullptr, "fcvt"); + append_table(process, "-0011110--11100-000000----------", (void*)emit_fcvtz_scalar_integer_jit, (void*)call_fcvtz_scalar_integer_interpreter,nullptr, "fcvtz_scalar_integer"); + append_table(process, "-0011110--10000-000000----------", (void*)emit_fcvtn_scalar_integer_jit, (void*)call_fcvtn_scalar_integer_interpreter,nullptr, "fcvtn_scalar_integer"); + append_table(process, "-0011110--10010-000000----------", (void*)emit_fcvta_scalar_integer_jit, (void*)call_fcvta_scalar_integer_interpreter,nullptr, "fcvta_scalar_integer"); + append_table(process, "-0011110--11000-000000----------", (void*)emit_fcvtm_scalar_integer_jit, (void*)call_fcvtm_scalar_integer_interpreter,nullptr, "fcvtm_scalar_integer"); + append_table(process, "00011110--100100110000----------", (void*)emit_frintp_scalar_jit, (void*)call_frintp_scalar_interpreter,nullptr, "frintp_scalar"); + append_table(process, "00011110--100101010000----------", (void*)emit_frintm_scalar_jit, (void*)call_frintm_scalar_interpreter,nullptr, "frintm_scalar"); + append_table(process, "-0011110--10100-000000----------", (void*)emit_fcvtp_scalar_integer_jit, (void*)call_fcvtp_scalar_integer_interpreter,nullptr, "fcvtp_scalar_integer"); + append_table(process, "00011110--1-----001010----------", (void*)emit_fadd_scalar_jit, (void*)call_fadd_scalar_interpreter,nullptr, "fadd_scalar"); + append_table(process, "00011110--1-----001110----------", (void*)emit_fsub_scalar_jit, (void*)call_fsub_scalar_interpreter,nullptr, "fsub_scalar"); + append_table(process, "00011110--1-----000010----------", (void*)emit_fmul_scalar_jit, (void*)call_fmul_scalar_interpreter,nullptr, "fmul_scalar"); + append_table(process, "00011110--1-----000110----------", (void*)emit_fdiv_scalar_jit, (void*)call_fdiv_scalar_interpreter,nullptr, "fdiv_scalar"); + append_table(process, "00011110--1-----010010----------", (void*)emit_fmax_scalar_jit, (void*)call_fmax_scalar_interpreter,nullptr, "fmax_scalar"); + append_table(process, "00011110--1-----010110----------", (void*)emit_fmin_scalar_jit, (void*)call_fmin_scalar_interpreter,nullptr, "fmin_scalar"); + append_table(process, "00011110--1-----011010----------", (void*)emit_fmaxnm_scalar_jit, (void*)call_fmaxnm_scalar_interpreter,nullptr, "fmaxnm_scalar"); + append_table(process, "00011110--1-----011110----------", (void*)emit_fminnm_scalar_jit, (void*)call_fminnm_scalar_interpreter,nullptr, "fminnm_scalar"); + append_table(process, "00011110--1-----100010----------", (void*)emit_fnmul_scalar_jit, (void*)call_fnmul_scalar_interpreter,nullptr, "fnmul_scalar"); + append_table(process, "00011110--100000110000----------", (void*)emit_fabs_scalar_jit, (void*)call_fabs_scalar_interpreter,nullptr, "fabs_scalar"); + append_table(process, "00011110--100001010000----------", (void*)emit_fneg_scalar_jit, (void*)call_fneg_scalar_interpreter,nullptr, "fneg_scalar"); + append_table(process, "0-1011101-100000111110----------", (void*)emit_fneg_vector_jit, (void*)call_fneg_vector_interpreter,nullptr, "fneg_vector"); + append_table(process, "00011110--100001110000----------", (void*)emit_fsqrt_scalar_jit, (void*)call_fsqrt_scalar_interpreter,nullptr, "fsqrt_scalar"); + append_table(process, "0-1011101-100001111110----------", (void*)emit_fsqrt_vector_jit, (void*)call_fsqrt_vector_interpreter,nullptr, "fsqrt_vector"); + append_table(process, "0-0011101-100001110110----------", (void*)emit_frecpe_vector_jit, (void*)call_frecpe_vector_interpreter,nullptr, "frecpe_vector"); + append_table(process, "011111101-100001110110----------", (void*)emit_frsqrte_scalar_jit, (void*)call_frsqrte_scalar_interpreter,nullptr, "frsqrte_scalar"); + append_table(process, "00011110--1--------10000000-----", (void*)emit_fmov_scalar_immediate_jit, (void*)call_fmov_scalar_immediate_interpreter,nullptr, "fmov_scalar_immediate"); + append_table(process, "0-0011100-1-----110101----------", (void*)emit_fadd_vector_jit, (void*)call_fadd_vector_interpreter,nullptr, "fadd_vector"); + append_table(process, "0-1011100-1-----110111----------", (void*)emit_fmul_vector_jit, (void*)call_fmul_vector_interpreter,nullptr, "fmul_vector"); + append_table(process, "0-0011101-1-----110101----------", (void*)emit_fsub_vector_jit, (void*)call_fsub_vector_interpreter,nullptr, "fsub_vector"); + append_table(process, "0-1011100-1-----111111----------", (void*)emit_fdiv_vector_jit, (void*)call_fdiv_vector_interpreter,nullptr, "fdiv_vector"); + append_table(process, "0-0011101-1-----111101----------", (void*)emit_fmin_vector_jit, (void*)call_fmin_vector_interpreter,nullptr, "fmin_vector"); + append_table(process, "0-0011100-1-----111101----------", (void*)emit_fmax_vector_jit, (void*)call_fmax_vector_interpreter,nullptr, "fmax_vector"); + append_table(process, "0-001110--1-----110011----------", (void*)emit_fmul_accumulate_vector_jit, (void*)call_fmul_accumulate_vector_interpreter,nullptr, "fmul_accumulate_vector"); + append_table(process, "0-1011100-1-----110101----------", (void*)emit_faddp_vector_jit, (void*)call_faddp_vector_interpreter,nullptr, "faddp_vector"); + append_table(process, "0-1011101-100001110110----------", (void*)emit_frsqrte_vector_jit, (void*)call_frsqrte_vector_interpreter,nullptr, "frsqrte_vector"); + append_table(process, "0-0011101-1-----111111----------", (void*)emit_frsqrts_vector_jit, (void*)call_frsqrts_vector_interpreter,nullptr, "frsqrts_vector"); + append_table(process, "0-0011100-1-----111111----------", (void*)emit_frecps_vector_jit, (void*)call_frecps_vector_interpreter,nullptr, "frecps_vector"); + append_table(process, "010111111-------1001-0----------", (void*)emit_fmul_scalar_by_element_jit, (void*)call_fmul_scalar_by_element_interpreter,nullptr, "fmul_scalar_by_element"); + append_table(process, "0-0011111-------1001-0----------", (void*)emit_fmul_vector_by_element_jit, (void*)call_fmul_vector_by_element_interpreter,nullptr, "fmul_vector_by_element"); + append_table(process, "010111111-------0-01-0----------", (void*)emit_fmul_accumulate_scalar_jit, (void*)call_fmul_accumulate_scalar_interpreter,nullptr, "fmul_accumulate_scalar"); + append_table(process, "0-0011111-------0-01-0----------", (void*)emit_fmul_accumulate_element_jit, (void*)call_fmul_accumulate_element_interpreter,nullptr, "fmul_accumulate_element"); + append_table(process, "011111100-110000110110----------", (void*)emit_faddp_scalar_jit, (void*)call_faddp_scalar_interpreter,nullptr, "faddp_scalar"); + append_table(process, "0-0011101-100000110110----------", (void*)emit_fcmeq_vector_zero_jit, (void*)call_fcmeq_vector_zero_interpreter,nullptr, "fcmeq_vector_zero"); + append_table(process, "0-0011101-100000110010----------", (void*)emit_fcmgt_vector_zero_jit, (void*)call_fcmgt_vector_zero_interpreter,nullptr, "fcmgt_vector_zero"); + append_table(process, "0-1011101-100000110010----------", (void*)emit_fcmge_vector_zero_jit, (void*)call_fcmge_vector_zero_interpreter,nullptr, "fcmge_vector_zero"); + append_table(process, "0-0011100-1-----111001----------", (void*)emit_fcmeq_vector_register_jit, (void*)call_fcmeq_vector_register_interpreter,nullptr, "fcmeq_vector_register"); + append_table(process, "0-1011101-1-----111001----------", (void*)emit_fcmgt_vector_register_jit, (void*)call_fcmgt_vector_register_interpreter,nullptr, "fcmgt_vector_register"); + append_table(process, "0-1011100-1-----111001----------", (void*)emit_fcmge_vector_register_jit, (void*)call_fcmge_vector_register_interpreter,nullptr, "fcmge_vector_register"); + append_table(process, "0-1011101-100000110110----------", (void*)emit_fcmle_zero_vector_jit, (void*)call_fcmle_zero_vector_interpreter,nullptr, "fcmle_zero_vector"); +} + +void add_subtract_imm12_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t sh, uint64_t imm12, uint64_t Rn, uint64_t Rd) +{ + if (sf == 0ULL) + { + uint32_t operand1 = XSP_interpreter(ctx,Rn); + uint32_t operand2 = decode_add_subtract_imm_12_interpreter(ctx,imm12,sh); + uint32_t d = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); + if ((S)) + { + X_interpreter(ctx,Rd,(uint64_t)d); + } + else + { + XSP_interpreter(ctx,Rd,(uint64_t)d); + } + } + if (sf == 1ULL) + { + uint64_t operand1 = XSP_interpreter(ctx,Rn); + uint64_t operand2 = decode_add_subtract_imm_12_interpreter(ctx,imm12,sh); + uint64_t d = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); + if ((S)) + { + X_interpreter(ctx,Rd,(uint64_t)d); + } + else + { + XSP_interpreter(ctx,Rd,(uint64_t)d); + } + } + +} + +void add_subtract_shifted_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t shift, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd) +{ + uint64_t shift_ammount = imm6; + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = a_shift_reg_interpreter(ctx,Rm,shift,shift_ammount); + uint32_t result = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = a_shift_reg_interpreter(ctx,Rm,shift,shift_ammount); + uint64_t result = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void add_subtract_extended_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t option, uint64_t imm3, uint64_t Rn, uint64_t Rd) +{ + if (sf == 0ULL) + { + uint64_t shift = imm3; + uint64_t extend_type = option; + uint32_t operand1 = XSP_interpreter(ctx,Rn); + uint32_t operand2 = a_extend_reg_interpreter(ctx,Rm,extend_type,shift); + uint32_t result = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); + if ((S)) + { + X_interpreter(ctx,Rd,(uint64_t)result); + } + else + { + XSP_interpreter(ctx,Rd,(uint64_t)result); + } + } + if (sf == 1ULL) + { + uint64_t shift = imm3; + uint64_t extend_type = option; + uint64_t operand1 = XSP_interpreter(ctx,Rn); + uint64_t operand2 = a_extend_reg_interpreter(ctx,Rm,extend_type,shift); + uint64_t result = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); + if ((S)) + { + X_interpreter(ctx,Rd,(uint64_t)result); + } + else + { + XSP_interpreter(ctx,Rd,(uint64_t)result); + } + } + +} + +void add_subtract_carry_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = X_interpreter(ctx,Rm); + uint32_t result = add_subtract_carry_impl_interpreter(ctx,operand1,operand2,((uint64_t)S == (uint64_t)1ULL),((uint64_t)op == (uint64_t)0ULL),(uint32_t)_sys_interpreter(ctx,(uint64_t)nzcv_c)); + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = X_interpreter(ctx,Rm); + uint64_t result = add_subtract_carry_impl_interpreter(ctx,operand1,operand2,((uint64_t)S == (uint64_t)1ULL),((uint64_t)op == (uint64_t)0ULL),(uint64_t)_sys_interpreter(ctx,(uint64_t)nzcv_c)); + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void shift_variable_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t op2, uint64_t Rn, uint64_t Rd) +{ + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = X_interpreter(ctx,Rm); + uint64_t mask = ((uint64_t)(((uint64_t)32ULL << (uint64_t)sf)) - (uint64_t)1ULL); + uint32_t result; + operand2 = ((uint32_t)operand2 & (uint32_t)mask); + if ((((uint64_t)op2 == (uint64_t)0ULL))) + { + result = ((uint32_t)operand1 << (uint32_t)operand2); + } + else if ((((uint64_t)op2 == (uint64_t)1ULL))) + { + result = ((uint32_t)operand1 >> (uint32_t)operand2); + } + else if ((((uint64_t)op2 == (uint64_t)2ULL))) + { + result = ((uint32_t)(sign_extend((uint32_t)operand1) >> sign_extend((uint32_t)operand2))); + } + else + { + result = (rotate_right((uint32_t)operand1,(uint32_t)operand2)); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = X_interpreter(ctx,Rm); + uint64_t mask = ((uint64_t)(((uint64_t)32ULL << (uint64_t)sf)) - (uint64_t)1ULL); + uint64_t result; + operand2 = ((uint64_t)operand2 & (uint64_t)mask); + if ((((uint64_t)op2 == (uint64_t)0ULL))) + { + result = ((uint64_t)operand1 << (uint64_t)operand2); + } + else if ((((uint64_t)op2 == (uint64_t)1ULL))) + { + result = ((uint64_t)operand1 >> (uint64_t)operand2); + } + else if ((((uint64_t)op2 == (uint64_t)2ULL))) + { + result = ((uint64_t)(sign_extend((uint64_t)operand1) >> sign_extend((uint64_t)operand2))); + } + else + { + result = (rotate_right((uint64_t)operand1,(uint64_t)operand2)); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void multiply_with_32_interpreter(interpreter_data* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd) +{ + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = X_interpreter(ctx,Rm); + uint64_t operand3 = X_interpreter(ctx,Ra); + uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); + uint64_t is_signed = ((uint64_t)U == (uint64_t)0ULL); + if ((is_signed)) + { + operand1 = (uint64_t)sign_extend((uint32_t)operand1); + operand2 = (uint64_t)sign_extend((uint32_t)operand2); + } + else + { + operand1 = ((uint64_t)operand1 & (uint64_t)4294967295ULL); + operand2 = ((uint64_t)operand2 & (uint64_t)4294967295ULL); + } + uint64_t result; + if ((is_add)) + { + result = ((uint64_t)operand3 + (uint64_t)(((uint64_t)operand1 * (uint64_t)operand2))); + } + else + { + result = ((uint64_t)operand3 - (uint64_t)(((uint64_t)operand1 * (uint64_t)operand2))); + } + X_interpreter(ctx,Rd,result); +} + +void multiply_hi_interpreter(interpreter_data* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Rn, uint64_t Rd) +{ + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = X_interpreter(ctx,Rm); + uint64_t is_signed = ((uint64_t)U == (uint64_t)0ULL); + uint64_t result; + if ((is_signed)) + { + result = (multiply_hi((uint64_t)operand1,(uint64_t)operand2, true)); + } + else + { + result = (multiply_hi((uint64_t)operand1,(uint64_t)operand2, false)); + } + X_interpreter(ctx,Rd,result); +} + +void multiply_additive_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd) +{ + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = X_interpreter(ctx,Rm); + uint32_t operand3 = X_interpreter(ctx,Ra); + uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); + uint32_t result; + if ((is_add)) + { + result = ((uint32_t)operand3 + (uint32_t)(((uint32_t)operand1 * (uint32_t)operand2))); + } + else + { + result = ((uint32_t)operand3 - (uint32_t)(((uint32_t)operand1 * (uint32_t)operand2))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = X_interpreter(ctx,Rm); + uint64_t operand3 = X_interpreter(ctx,Ra); + uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); + uint64_t result; + if ((is_add)) + { + result = ((uint64_t)operand3 + (uint64_t)(((uint64_t)operand1 * (uint64_t)operand2))); + } + else + { + result = ((uint64_t)operand3 - (uint64_t)(((uint64_t)operand1 * (uint64_t)operand2))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void divide_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t o1, uint64_t Rn, uint64_t Rd) +{ + uint64_t is_signed = ((uint64_t)o1 == (uint64_t)1ULL); + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = X_interpreter(ctx,Rm); + uint32_t result; + if ((((uint32_t)operand2 == (uint32_t)0ULL))) + { + X_interpreter(ctx,Rd,(uint64_t)0ULL); + } + else + { + if ((is_signed)) + { + uint64_t min = 9223372036854775808ULL; + if ((!sf)) + { + min = ((uint64_t)min >> (uint64_t)32ULL); + } + if ((((uint32_t)((uint32_t)operand1 == (uint32_t)min) && (uint32_t)((uint32_t)operand2 == (uint32_t)-1ULL)))) + { + X_interpreter(ctx,Rd,(uint64_t)min); + } + else + { + X_interpreter(ctx,Rd,(uint64_t)((uint32_t)(sign_extend((uint32_t)operand1) / sign_extend((uint32_t)operand2)))); + } + } + else + { + X_interpreter(ctx,Rd,(uint64_t)((uint32_t)operand1 / (uint32_t)operand2)); + } + } + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = X_interpreter(ctx,Rm); + uint64_t result; + if ((((uint64_t)operand2 == (uint64_t)0ULL))) + { + X_interpreter(ctx,Rd,(uint64_t)0ULL); + } + else + { + if ((is_signed)) + { + uint64_t min = 9223372036854775808ULL; + if ((!sf)) + { + min = ((uint64_t)min >> (uint64_t)32ULL); + } + if ((((uint64_t)((uint64_t)operand1 == (uint64_t)min) && (uint64_t)((uint64_t)operand2 == (uint64_t)-1ULL)))) + { + X_interpreter(ctx,Rd,(uint64_t)min); + } + else + { + X_interpreter(ctx,Rd,(uint64_t)((uint64_t)(sign_extend((uint64_t)operand1) / sign_extend((uint64_t)operand2)))); + } + } + else + { + X_interpreter(ctx,Rd,(uint64_t)((uint64_t)operand1 / (uint64_t)operand2)); + } + } + } + +} + +uint64_t create_rbit_mask_interpreter(interpreter_data* ctx, uint64_t index) +{ + index = ((uint64_t)1ULL << (uint64_t)index); + uint64_t mask = ((uint64_t)(((uint64_t)(((uint64_t)1ULL << (uint64_t)index)) - (uint64_t)1ULL)) << (uint64_t)index); + mask = replicate_c_interpreter(ctx,mask,((uint64_t)index * (uint64_t)2ULL),((uint64_t)((uint64_t)64ULL / (uint64_t)index) / (uint64_t)2ULL)); + return mask; +} + +void rbit_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + if (sf == 0ULL) + { + uint32_t operand = X_interpreter(ctx,Rn); + uint32_t result = operand; + uint64_t max = ((uint64_t)5ULL + (uint64_t)sf); + for (uint64_t i = 0; i < (max); i++) + { + uint64_t n_mask = create_rbit_mask_interpreter(ctx,i); + uint64_t i_mask = ~n_mask; + uint64_t shift = ((uint64_t)1ULL << (uint64_t)i); + result = ((uint32_t)(((uint32_t)(((uint32_t)result & (uint32_t)n_mask)) >> (uint32_t)shift)) | (uint32_t)(((uint32_t)(((uint32_t)result & (uint32_t)i_mask)) << (uint32_t)shift))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand = X_interpreter(ctx,Rn); + uint64_t result = operand; + uint64_t max = ((uint64_t)5ULL + (uint64_t)sf); + for (uint64_t i = 0; i < (max); i++) + { + uint64_t n_mask = create_rbit_mask_interpreter(ctx,i); + uint64_t i_mask = ~n_mask; + uint64_t shift = ((uint64_t)1ULL << (uint64_t)i); + result = ((uint64_t)(((uint64_t)(((uint64_t)result & (uint64_t)n_mask)) >> (uint64_t)shift)) | (uint64_t)(((uint64_t)(((uint64_t)result & (uint64_t)i_mask)) << (uint64_t)shift))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void rev16_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd) +{ + if (sf == 0ULL) + { + uint64_t count = ((uint64_t)2ULL << (uint64_t)sf); + uint32_t working = X_interpreter(ctx,Rn); + uint32_t result = 0ULL; + for (uint64_t i = 0; i < (count); i++) + { + uint32_t part = ((uint32_t)(((uint32_t)working >> (uint32_t)(((uint64_t)i * (uint64_t)16ULL)))) & (uint32_t)65535ULL); + part = reverse_bytes_interpreter(ctx,part,2ULL); + result = ((uint32_t)result | (uint32_t)(((uint32_t)part << (uint32_t)(((uint64_t)i * (uint64_t)16ULL))))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t count = ((uint64_t)2ULL << (uint64_t)sf); + uint64_t working = X_interpreter(ctx,Rn); + uint64_t result = 0ULL; + for (uint64_t i = 0; i < (count); i++) + { + uint64_t part = ((uint64_t)(((uint64_t)working >> (uint64_t)(((uint64_t)i * (uint64_t)16ULL)))) & (uint64_t)65535ULL); + part = reverse_bytes_interpreter(ctx,part,2ULL); + result = ((uint64_t)result | (uint64_t)(((uint64_t)part << (uint64_t)(((uint64_t)i * (uint64_t)16ULL))))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void reverse_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + if (sf == 0ULL) + { + uint32_t working = X_interpreter(ctx,Rn); + uint32_t result; + if ((((uint64_t)sf == (uint64_t)opc))) + { + result = reverse_bytes_interpreter(ctx,working,((uint64_t)4ULL << (uint64_t)sf)); + } + else + { + result = ((uint32_t)reverse_bytes_interpreter(ctx,working,4ULL) | (uint32_t)(((uint32_t)reverse_bytes_interpreter(ctx,((uint32_t)working >> (uint32_t)32ULL),4ULL) << (uint32_t)32ULL))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t working = X_interpreter(ctx,Rn); + uint64_t result; + if ((((uint64_t)sf == (uint64_t)opc))) + { + result = reverse_bytes_interpreter(ctx,working,((uint64_t)4ULL << (uint64_t)sf)); + } + else + { + result = ((uint64_t)reverse_bytes_interpreter(ctx,working,4ULL) | (uint64_t)(((uint64_t)reverse_bytes_interpreter(ctx,((uint64_t)working >> (uint64_t)32ULL),4ULL) << (uint64_t)32ULL))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void count_leading_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t s, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + if (sf == 0ULL) + { + uint32_t operand = X_interpreter(ctx,Rn); + uint32_t result = 0ULL; + uint32_t done = 0ULL; + uint32_t sig_bit; + if ((s)) + { + sig_bit = ((uint32_t)(((uint32_t)operand >> (uint32_t)(((uint64_t)datasize - (uint64_t)1ULL)))) & (uint32_t)1ULL); + datasize = ((uint64_t)datasize - (uint64_t)1ULL); + } + if ((use_x86_lzcnt_interpreter(ctx))) + { + if ((s)) + { + uint32_t nhigh = ((uint32_t)operand >> (uint32_t)1ULL); + uint32_t mask = -1ULL; + mask = ((uint32_t)mask >> (uint32_t)1ULL); + uint32_t nlow = ((uint32_t)operand & (uint32_t)mask); + result = intrinsic_unary_interpreter(ctx,(uint64_t)x86_lzcnt,(((uint32_t)nhigh ^ (uint32_t)nlow))); + result = ((uint32_t)result - (uint32_t)1ULL); + } + else + { + result = intrinsic_unary_interpreter(ctx,(uint64_t)x86_lzcnt,operand); + } + } + else + { + for (uint64_t i = 0; i < (datasize); i++) + { + uint32_t working = ((uint32_t)(((uint32_t)operand >> (uint32_t)(((uint64_t)((uint64_t)datasize - (uint64_t)i) - (uint64_t)1ULL)))) & (uint32_t)1ULL); + if ((s)) + { + if ((((uint32_t)working != (uint32_t)sig_bit))) + { + done = 1ULL; + } + } + else if ((working)) + { + done = 1ULL; + } + if ((!done)) + { + result = ((uint32_t)result + (uint32_t)1ULL); + } + } + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand = X_interpreter(ctx,Rn); + uint64_t result = 0ULL; + uint64_t done = 0ULL; + uint64_t sig_bit; + if ((s)) + { + sig_bit = ((uint64_t)(((uint64_t)operand >> (uint64_t)(((uint64_t)datasize - (uint64_t)1ULL)))) & (uint64_t)1ULL); + datasize = ((uint64_t)datasize - (uint64_t)1ULL); + } + if ((use_x86_lzcnt_interpreter(ctx))) + { + if ((s)) + { + uint64_t nhigh = ((uint64_t)operand >> (uint64_t)1ULL); + uint64_t mask = -1ULL; + mask = ((uint64_t)mask >> (uint64_t)1ULL); + uint64_t nlow = ((uint64_t)operand & (uint64_t)mask); + result = intrinsic_unary_interpreter(ctx,(uint64_t)x86_lzcnt,(((uint64_t)nhigh ^ (uint64_t)nlow))); + result = ((uint64_t)result - (uint64_t)1ULL); + } + else + { + result = intrinsic_unary_interpreter(ctx,(uint64_t)x86_lzcnt,operand); + } + } + else + { + for (uint64_t i = 0; i < (datasize); i++) + { + uint64_t working = ((uint64_t)(((uint64_t)operand >> (uint64_t)(((uint64_t)((uint64_t)datasize - (uint64_t)i) - (uint64_t)1ULL)))) & (uint64_t)1ULL); + if ((s)) + { + if ((((uint64_t)working != (uint64_t)sig_bit))) + { + done = 1ULL; + } + } + else if ((working)) + { + done = 1ULL; + } + if ((!done)) + { + result = ((uint64_t)result + (uint64_t)1ULL); + } + } + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void extr_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t N, uint64_t Rm, uint64_t imms, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = X_interpreter(ctx,Rm); + uint64_t lsb = imms; + uint32_t result; + if ((((uint64_t)lsb == (uint64_t)0ULL))) + { + result = operand2; + } + else if ((((uint64_t)Rn == (uint64_t)Rm))) + { + result = (rotate_right((uint32_t)operand1,(uint32_t)lsb)); + } + else + { + result = ((uint32_t)(((uint32_t)operand2 >> (uint32_t)lsb)) | (uint32_t)(((uint32_t)operand1 << (uint32_t)(((uint64_t)datasize - (uint64_t)lsb))))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = X_interpreter(ctx,Rm); + uint64_t lsb = imms; + uint64_t result; + if ((((uint64_t)lsb == (uint64_t)0ULL))) + { + result = operand2; + } + else if ((((uint64_t)Rn == (uint64_t)Rm))) + { + result = (rotate_right((uint64_t)operand1,(uint64_t)lsb)); + } + else + { + result = ((uint64_t)(((uint64_t)operand2 >> (uint64_t)lsb)) | (uint64_t)(((uint64_t)operand1 << (uint64_t)(((uint64_t)datasize - (uint64_t)lsb))))); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void bitfield_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t tmask = decode_bitmask_tmask_interpreter(ctx,N,imms,immr,0ULL,datasize,1ULL); + uint64_t wmask = decode_bitmask_tmask_interpreter(ctx,N,imms,immr,0ULL,datasize,0ULL); + uint64_t inzero; + uint64_t _extend; + if ((((uint64_t)opc == (uint64_t)0ULL))) + { + inzero = 1ULL; + _extend = 1ULL; + } + else if ((((uint64_t)opc == (uint64_t)1ULL))) + { + inzero = 0ULL; + _extend = 0ULL; + } + else if ((((uint64_t)opc == (uint64_t)2ULL))) + { + inzero = 1ULL; + _extend = 0ULL; + } + else + { + undefined_interpreter(ctx); + } + if (sf == 0ULL) + { + uint32_t dst; + uint32_t src = X_interpreter(ctx,Rn); + if ((inzero)) + { + dst = 0ULL; + } + else + { + dst = X_interpreter(ctx,Rd); + } + uint32_t bot = ((uint32_t)(((uint32_t)dst & (uint32_t)~wmask)) | (uint32_t)(((uint32_t)((rotate_right((uint32_t)src,(uint32_t)immr))) & (uint32_t)wmask))); + uint32_t top; + if ((_extend)) + { + top = ((uint32_t)0ULL - (uint32_t)(((uint32_t)(((uint32_t)src >> (uint32_t)imms)) & (uint32_t)1ULL))); + } + else + { + top = dst; + } + X_interpreter(ctx,Rd,(uint64_t)((uint32_t)(((uint32_t)top & (uint32_t)~tmask)) | (uint32_t)(((uint32_t)bot & (uint32_t)tmask)))); + } + if (sf == 1ULL) + { + uint64_t dst; + uint64_t src = X_interpreter(ctx,Rn); + if ((inzero)) + { + dst = 0ULL; + } + else + { + dst = X_interpreter(ctx,Rd); + } + uint64_t bot = ((uint64_t)(((uint64_t)dst & (uint64_t)~wmask)) | (uint64_t)(((uint64_t)((rotate_right((uint64_t)src,(uint64_t)immr))) & (uint64_t)wmask))); + uint64_t top; + if ((_extend)) + { + top = ((uint64_t)0ULL - (uint64_t)(((uint64_t)(((uint64_t)src >> (uint64_t)imms)) & (uint64_t)1ULL))); + } + else + { + top = dst; + } + X_interpreter(ctx,Rd,(uint64_t)((uint64_t)(((uint64_t)top & (uint64_t)~tmask)) | (uint64_t)(((uint64_t)bot & (uint64_t)tmask)))); + } + +} + +void logical_immediate_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = decode_bitmask_tmask_interpreter(ctx,N,imms,immr,1ULL,datasize,0ULL); + uint32_t result; + if ((((uint64_t)opc == (uint64_t)0ULL))) + { + result = ((uint32_t)operand1 & (uint32_t)operand2); + } + else if ((((uint64_t)opc == (uint64_t)1ULL))) + { + result = ((uint32_t)operand1 | (uint32_t)operand2); + } + else if ((((uint64_t)opc == (uint64_t)2ULL))) + { + result = ((uint32_t)operand1 ^ (uint32_t)operand2); + } + else if ((((uint64_t)opc == (uint64_t)3ULL))) + { + result = ((uint32_t)operand1 & (uint32_t)operand2); + X_interpreter(ctx,Rd,(uint64_t)result); + _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint32_t)(sign_extend((uint32_t)result) < sign_extend((uint32_t)0ULL)))); + _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint32_t)result == (uint32_t)0ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)0ULL); + _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)0ULL); + return; + } + XSP_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = decode_bitmask_tmask_interpreter(ctx,N,imms,immr,1ULL,datasize,0ULL); + uint64_t result; + if ((((uint64_t)opc == (uint64_t)0ULL))) + { + result = ((uint64_t)operand1 & (uint64_t)operand2); + } + else if ((((uint64_t)opc == (uint64_t)1ULL))) + { + result = ((uint64_t)operand1 | (uint64_t)operand2); + } + else if ((((uint64_t)opc == (uint64_t)2ULL))) + { + result = ((uint64_t)operand1 ^ (uint64_t)operand2); + } + else if ((((uint64_t)opc == (uint64_t)3ULL))) + { + result = ((uint64_t)operand1 & (uint64_t)operand2); + X_interpreter(ctx,Rd,(uint64_t)result); + _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(sign_extend((uint64_t)result) < sign_extend((uint64_t)0ULL)))); + _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)result == (uint64_t)0ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)0ULL); + _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)0ULL); + return; + } + XSP_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void logical_shifted_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t shift, uint64_t N, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd) +{ + uint64_t shift_type = shift; + uint64_t shift_ammount = imm6; + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = a_shift_reg_interpreter(ctx,Rm,shift_type,shift_ammount); + if ((N)) + { + operand2 = ~operand2; + } + uint32_t result; + if ((((uint64_t)((uint64_t)opc == (uint64_t)0ULL) || (uint64_t)((uint64_t)opc == (uint64_t)3ULL)))) + { + result = ((uint32_t)operand1 & (uint32_t)operand2); + if ((((uint64_t)opc == (uint64_t)3ULL))) + { + _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint32_t)(sign_extend((uint32_t)result) < sign_extend((uint32_t)0ULL)))); + _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint32_t)result == (uint32_t)0ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)0ULL); + _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)0ULL); + } + } + else if ((((uint64_t)opc == (uint64_t)1ULL))) + { + result = ((uint32_t)operand1 | (uint32_t)operand2); + } + else if ((((uint64_t)opc == (uint64_t)2ULL))) + { + result = ((uint32_t)operand1 ^ (uint32_t)operand2); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = a_shift_reg_interpreter(ctx,Rm,shift_type,shift_ammount); + if ((N)) + { + operand2 = ~operand2; + } + uint64_t result; + if ((((uint64_t)((uint64_t)opc == (uint64_t)0ULL) || (uint64_t)((uint64_t)opc == (uint64_t)3ULL)))) + { + result = ((uint64_t)operand1 & (uint64_t)operand2); + if ((((uint64_t)opc == (uint64_t)3ULL))) + { + _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(sign_extend((uint64_t)result) < sign_extend((uint64_t)0ULL)))); + _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)result == (uint64_t)0ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)0ULL); + _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)0ULL); + } + } + else if ((((uint64_t)opc == (uint64_t)1ULL))) + { + result = ((uint64_t)operand1 | (uint64_t)operand2); + } + else if ((((uint64_t)opc == (uint64_t)2ULL))) + { + result = ((uint64_t)operand1 ^ (uint64_t)operand2); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void conditional_select_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t cond, uint64_t op2, uint64_t Rn, uint64_t Rd) +{ + uint64_t incrament = op2; + uint64_t invert = op; + if (sf == 0ULL) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2 = X_interpreter(ctx,Rm); + uint32_t condition_pass = condition_holds_interpreter(ctx,cond); + if ((condition_pass)) + { + X_interpreter(ctx,Rd,(uint64_t)operand1); + } + else + { + if ((invert)) + { + operand2 = ~operand2; + } + if ((incrament)) + { + operand2 = ((uint32_t)operand2 + (uint32_t)1ULL); + } + X_interpreter(ctx,Rd,(uint64_t)operand2); + } + } + if (sf == 1ULL) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2 = X_interpreter(ctx,Rm); + uint64_t condition_pass = condition_holds_interpreter(ctx,cond); + if ((condition_pass)) + { + X_interpreter(ctx,Rd,(uint64_t)operand1); + } + else + { + if ((invert)) + { + operand2 = ~operand2; + } + if ((incrament)) + { + operand2 = ((uint64_t)operand2 + (uint64_t)1ULL); + } + X_interpreter(ctx,Rd,(uint64_t)operand2); + } + } + +} + +void conditional_compare_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t Rm, uint64_t cond, uint64_t mode, uint64_t Rn, uint64_t nzcv) +{ + if (sf == 0ULL) + { + if ((condition_holds_interpreter(ctx,cond))) + { + uint32_t operand1 = X_interpreter(ctx,Rn); + uint32_t operand2; + if ((mode)) + { + operand2 = Rm; + } + else + { + operand2 = X_interpreter(ctx,Rm); + } + add_subtract_impl_interpreter(ctx,operand1,operand2,1ULL,((uint64_t)op == (uint64_t)0ULL)); + } + else + { + _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); + } + } + if (sf == 1ULL) + { + if ((condition_holds_interpreter(ctx,cond))) + { + uint64_t operand1 = X_interpreter(ctx,Rn); + uint64_t operand2; + if ((mode)) + { + operand2 = Rm; + } + else + { + operand2 = X_interpreter(ctx,Rm); + } + add_subtract_impl_interpreter(ctx,operand1,operand2,1ULL,((uint64_t)op == (uint64_t)0ULL)); + } + else + { + _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); + } + } + +} + +void move_wide_immediate_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t hw, uint64_t imm16, uint64_t Rd) +{ + uint64_t shift = ((uint64_t)hw * (uint64_t)16ULL); + uint64_t immediate = ((uint64_t)imm16 << (uint64_t)shift); + if (sf == 0ULL) + { + uint32_t result; + if ((((uint64_t)opc == (uint64_t)0ULL))) + { + result = ~immediate; + } + else if ((((uint64_t)opc == (uint64_t)3ULL))) + { + result = X_interpreter(ctx,Rd); + result = ((uint32_t)result & (uint32_t)~(((uint64_t)65535ULL << (uint64_t)shift))); + result = ((uint32_t)result | (uint32_t)immediate); + } + else + { + result = immediate; + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (sf == 1ULL) + { + uint64_t result; + if ((((uint64_t)opc == (uint64_t)0ULL))) + { + result = ~immediate; + } + else if ((((uint64_t)opc == (uint64_t)3ULL))) + { + result = X_interpreter(ctx,Rd); + result = ((uint64_t)result & (uint64_t)~(((uint64_t)65535ULL << (uint64_t)shift))); + result = ((uint64_t)result | (uint64_t)immediate); + } + else + { + result = immediate; + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + +} + +void pc_rel_addressing_interpreter(interpreter_data* ctx, uint64_t op, uint64_t immlo, uint64_t immhi, uint64_t Rd) +{ + uint64_t offset = sign_extend_interpreter(ctx,((uint64_t)(((uint64_t)immhi << (uint64_t)2ULL)) | (uint64_t)immlo),21ULL); + uint64_t instruction_pc = _get_pc_interpreter(ctx); + if ((op)) + { + offset = ((uint64_t)offset << (uint64_t)12ULL); + instruction_pc = ((uint64_t)instruction_pc & (uint64_t)~4095ULL); + } + X_interpreter(ctx,Rd,(uint64_t)((uint64_t)instruction_pc + (uint64_t)offset)); +} + +void branch_register_interpreter(interpreter_data* ctx, uint64_t l, uint64_t Rn) +{ + branch_long_universal_interpreter(ctx,Rn,l); +} + +void return_register_interpreter(interpreter_data* ctx, uint64_t Rn) +{ + _return_from_call_interpreter(ctx,X_interpreter(ctx,Rn)); +} + +void test_bit_branch_interpreter(interpreter_data* ctx, uint64_t b5, uint64_t op, uint64_t b40, uint64_t imm14, uint64_t Rt) +{ + uint64_t bit_pos = ((uint64_t)b40 + (uint64_t)(((uint64_t)b5 << (uint64_t)5ULL))); + uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm14,14ULL) << (uint64_t)2ULL))); + uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); + uint64_t src = X_interpreter(ctx,Rt); + uint8_t branch_pass = ((uint64_t)(((uint64_t)(((uint64_t)src >> (uint64_t)bit_pos)) & (uint64_t)1ULL)) == (uint64_t)op); + _branch_conditional_interpreter(ctx,new_location,next_location,(uint64_t)branch_pass); +} + +void compare_and_branch_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t imm19, uint64_t Rt) +{ + if (sf == 0ULL) + { + uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm19,19ULL) << (uint64_t)2ULL))); + uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); + uint32_t operand = X_interpreter(ctx,Rt); + uint8_t branch_pass; + if ((!op)) + { + branch_pass = ((uint32_t)operand == (uint32_t)0ULL); + } + else + { + branch_pass = ((uint32_t)operand != (uint32_t)0ULL); + } + _branch_conditional_interpreter(ctx,new_location,next_location,(uint64_t)branch_pass); + } + if (sf == 1ULL) + { + uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm19,19ULL) << (uint64_t)2ULL))); + uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); + uint64_t operand = X_interpreter(ctx,Rt); + uint8_t branch_pass; + if ((!op)) + { + branch_pass = ((uint64_t)operand == (uint64_t)0ULL); + } + else + { + branch_pass = ((uint64_t)operand != (uint64_t)0ULL); + } + _branch_conditional_interpreter(ctx,new_location,next_location,(uint64_t)branch_pass); + } + +} + +void b_unconditional_interpreter(interpreter_data* ctx, uint64_t op, uint64_t imm26) +{ + uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm26,26ULL) << (uint64_t)2ULL))); + if ((op)) + { + uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); + X_interpreter(ctx,30ULL,(uint64_t)next_location); + _branch_call_interpreter(ctx,(uint64_t)new_location); + } + else + { + _branch_short_interpreter(ctx,new_location); + } +} + +void b_conditional_interpreter(interpreter_data* ctx, uint64_t imm19, uint64_t cond) +{ + uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm19,19ULL) << (uint64_t)2ULL))); + uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); + _branch_conditional_interpreter(ctx,new_location,next_location,(uint64_t)condition_holds_interpreter(ctx,cond)); +} + +void svc_interpreter(interpreter_data* ctx, uint64_t imm16) +{ + call_supervisor_interpreter(ctx,imm16); +} + +void msr_register_interpreter(interpreter_data* ctx, uint64_t imm15, uint64_t Rt) +{ + uint64_t operand = X_interpreter(ctx,Rt); + if ((((uint64_t)imm15 == (uint64_t)23072ULL))) + { + _sys_interpreter(ctx,(uint64_t)fpcr,operand); + } + else if ((((uint64_t)imm15 == (uint64_t)23073ULL))) + { + _sys_interpreter(ctx,(uint64_t)fpsr,operand); + } + else if ((((uint64_t)imm15 == (uint64_t)24194ULL))) + { + _sys_interpreter(ctx,(uint64_t)thread_local_1,operand); + } + else if ((((uint64_t)imm15 == (uint64_t)24195ULL))) + { + _sys_interpreter(ctx,(uint64_t)thread_local_0,operand); + } + else + { + undefined_with_interpreter(ctx,imm15); + } +} + +void mrs_register_interpreter(interpreter_data* ctx, uint64_t imm15, uint64_t Rt) +{ + uint64_t operand; + if ((((uint64_t)imm15 == (uint64_t)23072ULL))) + { + operand = _sys_interpreter(ctx,(uint64_t)fpcr); + } + else if ((((uint64_t)imm15 == (uint64_t)23073ULL))) + { + operand = _sys_interpreter(ctx,(uint64_t)fpsr); + } + else if ((((uint64_t)imm15 == (uint64_t)24194ULL))) + { + operand = _sys_interpreter(ctx,(uint64_t)thread_local_1); + } + else if ((((uint64_t)imm15 == (uint64_t)24195ULL))) + { + operand = _sys_interpreter(ctx,(uint64_t)thread_local_0); + } + else if ((((uint64_t)imm15 == (uint64_t)24321ULL))) + { + operand = call_counter_interpreter(ctx); + } + else if ((((uint64_t)imm15 == (uint64_t)22529ULL))) + { + operand = 2219098116ULL; + } + else + { + undefined_with_interpreter(ctx,imm15); + } + X_interpreter(ctx,Rt,operand); +} + +void hints_interpreter(interpreter_data* ctx, uint64_t imm7) +{ +} + +void sys_interpreter(interpreter_data* ctx, uint64_t L, uint64_t imm19) +{ +} + +void barriers_interpreter(interpreter_data* ctx, uint64_t CRm, uint64_t op2, uint64_t Rt) +{ + if ((((uint64_t)((uint64_t)op2 == (uint64_t)2ULL) && (uint64_t)((uint64_t)Rt == (uint64_t)31ULL)))) + { + _sys_interpreter(ctx,(uint64_t)exclusive_address,(uint64_t)-1ULL); + _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)-1ULL); + } +} + +void load_store_register_post_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) +{ + load_store_register_imm_unscaled_interpreter(ctx,size,VR,opc,imm9,1ULL,Rn,Rt); +} + +void load_store_register_pre_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) +{ + load_store_register_imm_unscaled_interpreter(ctx,size,VR,opc,imm9,3ULL,Rn,Rt); +} + +void load_store_register_unscaled_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) +{ + load_store_register_imm_unscaled_interpreter(ctx,size,VR,opc,imm9,0ULL,Rn,Rt); +} + +void load_store_register_pair_imm_offset_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) +{ + load_store_register_pair_imm_interpreter(ctx,opc,VR,2ULL,L,imm7,Rt2,Rn,Rt); +} + +void load_store_register_pair_imm_post_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) +{ + load_store_register_pair_imm_interpreter(ctx,opc,VR,1ULL,L,imm7,Rt2,Rn,Rt); +} + +void load_store_register_pair_imm_pre_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) +{ + load_store_register_pair_imm_interpreter(ctx,opc,VR,3ULL,L,imm7,Rt2,Rn,Rt); +} + +void load_store_register_pair_imm_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t wb, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) +{ + uint64_t wback = ((uint64_t)wb != (uint64_t)2ULL); + uint64_t postindex = ((uint64_t)wb == (uint64_t)1ULL); + uint64_t memop = !L; + uint64_t is_signed = (((uint64_t)opc & (uint64_t)1ULL)); + uint64_t scale; + if ((VR)) + { + scale = ((uint64_t)2ULL + (uint64_t)opc); + } + else + { + scale = ((uint64_t)2ULL + (uint64_t)(((uint64_t)(((uint64_t)opc >> (uint64_t)1ULL)) & (uint64_t)1ULL))); + } + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + uint64_t offset = ((uint64_t)sign_extend_interpreter(ctx,imm7,7ULL) << (uint64_t)scale); + uint64_t dbytes = ((uint64_t)datasize / (uint64_t)8ULL); + uint64_t address = XSP_interpreter(ctx,Rn); + if ((!postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + { + if (datasize == 8ULL) + { + if ((VR)) + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint8_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint8_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + V_interpreter(ctx,Rt,(uint128_t)d0); + V_interpreter(ctx,Rt2,(uint128_t)d1); + } + else + { + mem_interpreter(ctx,address,(uint8_t)V_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint8_t)V_interpreter(ctx,Rt2)); + } + } + else + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + if ((is_signed)) + { + d0 = (uint64_t)sign_extend((uint32_t)d0); + d1 = (uint64_t)sign_extend((uint32_t)d1); + } + X_interpreter(ctx,Rt,d0); + X_interpreter(ctx,Rt2,d1); + } + else + { + mem_interpreter(ctx,address,(uint8_t)X_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint8_t)X_interpreter(ctx,Rt2)); + } + } + } + if (datasize == 16ULL) + { + if ((VR)) + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint16_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint16_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + V_interpreter(ctx,Rt,(uint128_t)d0); + V_interpreter(ctx,Rt2,(uint128_t)d1); + } + else + { + mem_interpreter(ctx,address,(uint16_t)V_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint16_t)V_interpreter(ctx,Rt2)); + } + } + else + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + if ((is_signed)) + { + d0 = (uint64_t)sign_extend((uint32_t)d0); + d1 = (uint64_t)sign_extend((uint32_t)d1); + } + X_interpreter(ctx,Rt,d0); + X_interpreter(ctx,Rt2,d1); + } + else + { + mem_interpreter(ctx,address,(uint16_t)X_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint16_t)X_interpreter(ctx,Rt2)); + } + } + } + if (datasize == 32ULL) + { + if ((VR)) + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint32_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint32_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + V_interpreter(ctx,Rt,(uint128_t)d0); + V_interpreter(ctx,Rt2,(uint128_t)d1); + } + else + { + mem_interpreter(ctx,address,(uint32_t)V_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint32_t)V_interpreter(ctx,Rt2)); + } + } + else + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + if ((is_signed)) + { + d0 = (uint64_t)sign_extend((uint32_t)d0); + d1 = (uint64_t)sign_extend((uint32_t)d1); + } + X_interpreter(ctx,Rt,d0); + X_interpreter(ctx,Rt2,d1); + } + else + { + mem_interpreter(ctx,address,(uint32_t)X_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint32_t)X_interpreter(ctx,Rt2)); + } + } + } + if (datasize == 64ULL) + { + if ((VR)) + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + V_interpreter(ctx,Rt,(uint128_t)d0); + V_interpreter(ctx,Rt2,(uint128_t)d1); + } + else + { + mem_interpreter(ctx,address,(uint64_t)V_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint64_t)V_interpreter(ctx,Rt2)); + } + } + else + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + if ((is_signed)) + { + d0 = (uint64_t)sign_extend((uint32_t)d0); + d1 = (uint64_t)sign_extend((uint32_t)d1); + } + X_interpreter(ctx,Rt,d0); + X_interpreter(ctx,Rt2,d1); + } + else + { + mem_interpreter(ctx,address,(uint64_t)X_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint64_t)X_interpreter(ctx,Rt2)); + } + } + } + if (datasize == 128ULL) + { + if ((VR)) + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint128_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint128_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + V_interpreter(ctx,Rt,(uint128_t)d0); + V_interpreter(ctx,Rt2,(uint128_t)d1); + } + else + { + mem_interpreter(ctx,address,(uint128_t)V_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint128_t)V_interpreter(ctx,Rt2)); + } + } + else + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); + uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); + if ((is_signed)) + { + d0 = (uint64_t)sign_extend((uint32_t)d0); + d1 = (uint64_t)sign_extend((uint32_t)d1); + } + X_interpreter(ctx,Rt,d0); + X_interpreter(ctx,Rt2,d1); + } + else + { + mem_interpreter(ctx,address,(uint128_t)X_interpreter(ctx,Rt)); + mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint128_t)X_interpreter(ctx,Rt2)); + } + } + } + + } + if ((wback)) + { + if ((postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + XSP_interpreter(ctx,Rn,address); + } +} + +void load_store_register_imm_unsigned_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm12, uint64_t Rn, uint64_t Rt) +{ + if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) + { + return; + } + uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); + uint64_t wback = 0ULL; + uint64_t postindex = 0ULL; + if ((is_vector)) + { + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = ((uint64_t)(((uint64_t)bit_c_interpreter(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); + uint64_t offset = ((uint64_t)imm12 << (uint64_t)scale); + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + uint64_t address = XSP_interpreter(ctx,Rn); + if ((!postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + { + if (datasize == 8ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint8_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint8_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 16ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint16_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint16_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint32_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint32_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint64_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 128ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint128_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint128_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + + } + if ((wback)) + { + if ((postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + XSP_interpreter(ctx,Rn,address); + } + } + else + { + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = size; + uint64_t offset = ((uint64_t)imm12 << (uint64_t)scale); + if ((((uint64_t)bit_c_interpreter(ctx,opc,1ULL) == (uint64_t)0ULL))) + { + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + if ((((uint64_t)size == (uint64_t)3ULL))) + regsize = 64ULL; + else + regsize = 32ULL; + _signed = 0ULL; + } + else + { + if ((((uint64_t)size == (uint64_t)3ULL))) + { + undefined_interpreter(ctx); + } + else + { + memop = 0ULL; + if ((((uint64_t)opc & (uint64_t)1ULL))) + regsize = 32ULL; + else + regsize = 64ULL; + _signed = 1ULL; + } + } + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + uint64_t address = XSP_interpreter(ctx,Rn); + if ((!postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + { + if (datasize == 8ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint8_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint8_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint8_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint8_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 16ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint16_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint16_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint16_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint16_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 32ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint32_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint32_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint32_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint32_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 64ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint64_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint64_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint64_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint64_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + + } + if ((wback)) + { + if ((postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + XSP_interpreter(ctx,Rn,address); + } + } +} + +void load_store_register_imm_unscaled_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t wb, uint64_t Rn, uint64_t Rt) +{ + if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) + { + return; + } + uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); + uint64_t wback = ((uint64_t)wb != (uint64_t)0ULL); + uint64_t postindex = ((uint64_t)wb == (uint64_t)1ULL); + uint64_t offset = sign_extend_interpreter(ctx,imm9,9ULL); + if ((is_vector)) + { + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = ((uint64_t)(((uint64_t)bit_c_interpreter(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + uint64_t address = XSP_interpreter(ctx,Rn); + if ((!postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + { + if (datasize == 8ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint8_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint8_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 16ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint16_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint16_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint32_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint32_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint64_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 128ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint128_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint128_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + + } + if ((wback)) + { + if ((postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + XSP_interpreter(ctx,Rn,address); + } + } + else + { + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = size; + if ((((uint64_t)bit_c_interpreter(ctx,opc,1ULL) == (uint64_t)0ULL))) + { + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + if ((((uint64_t)size == (uint64_t)3ULL))) + regsize = 64ULL; + else + regsize = 32ULL; + _signed = 0ULL; + } + else + { + if ((((uint64_t)size == (uint64_t)3ULL))) + { + undefined_interpreter(ctx); + } + else + { + memop = 0ULL; + if ((((uint64_t)opc & (uint64_t)1ULL))) + regsize = 32ULL; + else + regsize = 64ULL; + _signed = 1ULL; + } + } + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + uint64_t address = XSP_interpreter(ctx,Rn); + if ((!postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + { + if (datasize == 8ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint8_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint8_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint8_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint8_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 16ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint16_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint16_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint16_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint16_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 32ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint32_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint32_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint32_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint32_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 64ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint64_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint64_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint64_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint64_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + + } + if ((wback)) + { + if ((postindex)) + { + address = ((uint64_t)address + (uint64_t)offset); + } + XSP_interpreter(ctx,Rn,address); + } + } +} + +void load_store_register_offset_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t Rm, uint64_t option, uint64_t S, uint64_t Rn, uint64_t Rt) +{ + if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) + { + return; + } + uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); + uint64_t wback = 0ULL; + uint64_t postindex = 0ULL; + if ((is_vector)) + { + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = ((uint64_t)(((uint64_t)bit_c_interpreter(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); + uint64_t shift = ((uint64_t)scale * (uint64_t)S); + uint64_t offset = a_extend_reg_64_interpreter(ctx,Rm,option,shift); + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + uint64_t address = ((uint64_t)XSP_interpreter(ctx,Rn) + (uint64_t)offset); + if (datasize == 8ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint8_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint8_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 16ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint16_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint16_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint32_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint32_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint64_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + if (datasize == 128ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint128_t data = V_interpreter(ctx,Rt); + mem_interpreter(ctx,address,data); + } + else + { + uint128_t data = mem_interpreter(ctx,address); + V_interpreter(ctx,Rt,(uint128_t)data); + } + } + + } + else + { + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = size; + uint64_t shift = ((uint64_t)scale * (uint64_t)S); + uint64_t offset = a_extend_reg_64_interpreter(ctx,Rm,option,shift); + if ((((uint64_t)bit_c_interpreter(ctx,opc,1ULL) == (uint64_t)0ULL))) + { + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + if ((((uint64_t)size == (uint64_t)3ULL))) + regsize = 64ULL; + else + regsize = 32ULL; + _signed = 0ULL; + } + else + { + if ((((uint64_t)size == (uint64_t)3ULL))) + { + undefined_interpreter(ctx); + } + else + { + memop = 0ULL; + if ((((uint64_t)opc & (uint64_t)1ULL))) + regsize = 32ULL; + else + regsize = 64ULL; + _signed = 1ULL; + } + } + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + uint64_t address = ((uint64_t)XSP_interpreter(ctx,Rn) + (uint64_t)offset); + if (datasize == 8ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint8_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint8_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint8_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint8_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 16ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint16_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint16_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint16_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint16_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 32ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint32_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint32_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint32_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint32_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + if (datasize == 64ULL) + { + if (regsize == 32ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint64_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint32_t)sign_extend((uint64_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + if (regsize == 64ULL) + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + uint64_t data = X_interpreter(ctx,Rt); + mem_interpreter(ctx,address,(uint64_t)data); + } + else + { + uint64_t n = mem_interpreter(ctx,address); + if ((_signed)) + { + n = (uint64_t)sign_extend((uint64_t)n); + } + X_interpreter(ctx,Rt,n); + } + } + + } + + } +} + +void load_store_exclusive_ordered_interpreter(interpreter_data* ctx, uint64_t size, uint64_t ordered, uint64_t L, uint64_t Rs, uint64_t o0, uint64_t Rn, uint64_t Rt) +{ + uint64_t is_exclusive = ((uint64_t)ordered == (uint64_t)0ULL); + if ((L)) + { + load_exclusive_interpreter(ctx,is_exclusive,size,Rn,Rt); + } + else + { + store_exclusive_interpreter(ctx,is_exclusive,size,Rn,Rt,Rs); + } +} + +uint64_t exclusive_address_mask_interpreter(interpreter_data* ctx) +{ + return ~(((uint64_t)(((uint64_t)4ULL << (uint64_t)4ULL)) - (uint64_t)1ULL)); +} + +void load_exclusive_interpreter(interpreter_data* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t address = XSP_interpreter(ctx,Rn); + if (datasize == 8ULL) + { + uint8_t value = mem_interpreter(ctx,address); + if ((is_exclusive)) + { + _sys_interpreter(ctx,(uint64_t)exclusive_address,((uint64_t)address & (uint64_t)exclusive_address_mask_interpreter(ctx))); + _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)value); + } + X_interpreter(ctx,Rt,(uint64_t)value); + } + if (datasize == 16ULL) + { + uint16_t value = mem_interpreter(ctx,address); + if ((is_exclusive)) + { + _sys_interpreter(ctx,(uint64_t)exclusive_address,((uint64_t)address & (uint64_t)exclusive_address_mask_interpreter(ctx))); + _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)value); + } + X_interpreter(ctx,Rt,(uint64_t)value); + } + if (datasize == 32ULL) + { + uint32_t value = mem_interpreter(ctx,address); + if ((is_exclusive)) + { + _sys_interpreter(ctx,(uint64_t)exclusive_address,((uint64_t)address & (uint64_t)exclusive_address_mask_interpreter(ctx))); + _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)value); + } + X_interpreter(ctx,Rt,(uint64_t)value); + } + if (datasize == 64ULL) + { + uint64_t value = mem_interpreter(ctx,address); + if ((is_exclusive)) + { + _sys_interpreter(ctx,(uint64_t)exclusive_address,((uint64_t)address & (uint64_t)exclusive_address_mask_interpreter(ctx))); + _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)value); + } + X_interpreter(ctx,Rt,(uint64_t)value); + } + +} + +void store_exclusive_interpreter(interpreter_data* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t Rs) +{ + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t address = XSP_interpreter(ctx,Rn); + if (datasize == 8ULL) + { + if ((is_exclusive)) + { + uint64_t mask = exclusive_address_mask_interpreter(ctx); + uint64_t _exclusive_address = _sys_interpreter(ctx,(uint64_t)exclusive_address); + if ((((uint64_t)_exclusive_address == (uint64_t)(((uint64_t)address & (uint64_t)mask))))) + { + uint8_t to_swap = X_interpreter(ctx,Rt); + uint8_t expecting = _sys_interpreter(ctx,(uint64_t)exclusive_value); + uint8_t cas_success = compare_and_swap_interpreter(ctx,address,(uint64_t)expecting,(uint64_t)to_swap,datasize); + X_interpreter(ctx,Rs,(uint64_t)((uint8_t)(((uint8_t)cas_success ^ (uint8_t)1ULL)) & (uint8_t)1ULL)); + } + else + { + X_interpreter(ctx,Rs,(uint64_t)1ULL); + } + } + else + { + mem_interpreter(ctx,address,(uint8_t)X_interpreter(ctx,Rt)); + } + } + if (datasize == 16ULL) + { + if ((is_exclusive)) + { + uint64_t mask = exclusive_address_mask_interpreter(ctx); + uint64_t _exclusive_address = _sys_interpreter(ctx,(uint64_t)exclusive_address); + if ((((uint64_t)_exclusive_address == (uint64_t)(((uint64_t)address & (uint64_t)mask))))) + { + uint16_t to_swap = X_interpreter(ctx,Rt); + uint16_t expecting = _sys_interpreter(ctx,(uint64_t)exclusive_value); + uint16_t cas_success = compare_and_swap_interpreter(ctx,address,(uint64_t)expecting,(uint64_t)to_swap,datasize); + X_interpreter(ctx,Rs,(uint64_t)((uint16_t)(((uint16_t)cas_success ^ (uint16_t)1ULL)) & (uint16_t)1ULL)); + } + else + { + X_interpreter(ctx,Rs,(uint64_t)1ULL); + } + } + else + { + mem_interpreter(ctx,address,(uint16_t)X_interpreter(ctx,Rt)); + } + } + if (datasize == 32ULL) + { + if ((is_exclusive)) + { + uint64_t mask = exclusive_address_mask_interpreter(ctx); + uint64_t _exclusive_address = _sys_interpreter(ctx,(uint64_t)exclusive_address); + if ((((uint64_t)_exclusive_address == (uint64_t)(((uint64_t)address & (uint64_t)mask))))) + { + uint32_t to_swap = X_interpreter(ctx,Rt); + uint32_t expecting = _sys_interpreter(ctx,(uint64_t)exclusive_value); + uint32_t cas_success = compare_and_swap_interpreter(ctx,address,(uint64_t)expecting,(uint64_t)to_swap,datasize); + X_interpreter(ctx,Rs,(uint64_t)((uint32_t)(((uint32_t)cas_success ^ (uint32_t)1ULL)) & (uint32_t)1ULL)); + } + else + { + X_interpreter(ctx,Rs,(uint64_t)1ULL); + } + } + else + { + mem_interpreter(ctx,address,(uint32_t)X_interpreter(ctx,Rt)); + } + } + if (datasize == 64ULL) + { + if ((is_exclusive)) + { + uint64_t mask = exclusive_address_mask_interpreter(ctx); + uint64_t _exclusive_address = _sys_interpreter(ctx,(uint64_t)exclusive_address); + if ((((uint64_t)_exclusive_address == (uint64_t)(((uint64_t)address & (uint64_t)mask))))) + { + uint64_t to_swap = X_interpreter(ctx,Rt); + uint64_t expecting = _sys_interpreter(ctx,(uint64_t)exclusive_value); + uint64_t cas_success = compare_and_swap_interpreter(ctx,address,(uint64_t)expecting,(uint64_t)to_swap,datasize); + X_interpreter(ctx,Rs,(uint64_t)((uint64_t)(((uint64_t)cas_success ^ (uint64_t)1ULL)) & (uint64_t)1ULL)); + } + else + { + X_interpreter(ctx,Rs,(uint64_t)1ULL); + } + } + else + { + mem_interpreter(ctx,address,(uint64_t)X_interpreter(ctx,Rt)); + } + } + } uint64_t sign_extend_interpreter(interpreter_data* ctx, uint64_t source, uint64_t count) @@ -3421,6 +5855,1224 @@ uint64_t select_interpreter(interpreter_data* ctx, uint64_t condition, uint64_t return no; } +void dup_general_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t element = X_interpreter(ctx,Rn); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t result; + if ((use_x86_sse_interpreter(ctx))) + { + result = sse_coppy_gp_across_lanes_interpreter(ctx,element,esize); + if ((!Q)) + { + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + } + } + else + { + result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint128_t::insert(&result, e, esize, element); + } + } + V_interpreter(ctx,Rd,result); +} + +void dup_element_scalar_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); + uint64_t index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)bit_c_interpreter(ctx,imm5,4ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = esize; + uint64_t elements = 1ULL; + dup_element_interpreter(ctx,index,esize,elements,Rn,Rd); +} + +void dup_element_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); + uint64_t index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)bit_c_interpreter(ctx,imm5,4ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + dup_element_interpreter(ctx,index,esize,elements,Rn,Rd); +} + +void move_to_gp_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t U, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)Q); + uint64_t index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint128_t operand = V_interpreter(ctx,Rn); + if (esize == 8ULL) + { + if (datasize == 32ULL) + { + uint32_t result = uint128_t::extract(operand, index, esize); + if ((!U)) + { + result = (uint32_t)sign_extend((uint8_t)result); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (datasize == 64ULL) + { + uint64_t result = uint128_t::extract(operand, index, esize); + if ((!U)) + { + result = (uint64_t)sign_extend((uint8_t)result); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + + } + if (esize == 16ULL) + { + if (datasize == 32ULL) + { + uint32_t result = uint128_t::extract(operand, index, esize); + if ((!U)) + { + result = (uint32_t)sign_extend((uint16_t)result); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (datasize == 64ULL) + { + uint64_t result = uint128_t::extract(operand, index, esize); + if ((!U)) + { + result = (uint64_t)sign_extend((uint16_t)result); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + + } + if (esize == 32ULL) + { + if (datasize == 32ULL) + { + uint32_t result = uint128_t::extract(operand, index, esize); + if ((!U)) + { + result = (uint32_t)sign_extend((uint32_t)result); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (datasize == 64ULL) + { + uint64_t result = uint128_t::extract(operand, index, esize); + if ((!U)) + { + result = (uint64_t)sign_extend((uint32_t)result); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + + } + if (esize == 64ULL) + { + if (datasize == 32ULL) + { + uint32_t result = uint128_t::extract(operand, index, esize); + if ((!U)) + { + result = (uint32_t)sign_extend((uint64_t)result); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + if (datasize == 64ULL) + { + uint64_t result = uint128_t::extract(operand, index, esize); + if ((!U)) + { + result = (uint64_t)sign_extend((uint64_t)result); + } + X_interpreter(ctx,Rd,(uint64_t)result); + } + + } + +} + +void ins_general_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); + uint64_t index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t element = X_interpreter(ctx,Rn); + uint128_t result = V_interpreter(ctx,Rd); + uint128_t::insert(&result, index, esize, element); + V_interpreter(ctx,Rd,result); +} + +void ins_element_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t imm4, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); + uint64_t dst_index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint64_t src_index = bits_c_interpreter(ctx,imm4,3ULL,size); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t result = V_interpreter(ctx,Rd); + uint128_t::insert(&result, dst_index, esize, (uint128_t::extract(operand, src_index, esize))); + V_interpreter(ctx,Rd,result); +} + +void movi_immediate_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t op, uint64_t immhi, uint64_t cmode, uint64_t immlo, uint64_t Rd) +{ + uint64_t d = Rd; + uint64_t imm8 = ((uint64_t)(((uint64_t)immhi << (uint64_t)5ULL)) | (uint64_t)immlo); + uint64_t cmode_helper = ((uint64_t)(((uint64_t)cmode << (uint64_t)1ULL)) | (uint64_t)op); + uint64_t mode = 0ULL; + if ((((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)2ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)18ULL))))) + { + mode = 0ULL; + } + else if ((((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)3ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)19ULL))))) + { + mode = 1ULL; + } + else if ((((uint64_t)((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)1ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)17ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)29ULL)) == (uint64_t)25ULL))))) + { + mode = 2ULL; + } + else if ((((uint64_t)((uint64_t)((uint64_t)((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)0ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)16ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)29ULL)) == (uint64_t)24ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)30ULL)) == (uint64_t)28ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)31ULL)) == (uint64_t)30ULL))))) + { + mode = 3ULL; + } + else if ((((uint64_t)cmode_helper == (uint64_t)31ULL))) + { + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + undefined_interpreter(ctx); + } + mode = 3ULL; + } + else + { + undefined_interpreter(ctx); + } + uint64_t imm64 = expand_imm_interpreter(ctx,op,cmode,imm8); + uint128_t imm = imm64; + if ((Q)) + { + uint128_t::insert(&imm, 1ULL, 64ULL, imm64); + } + uint128_t operand = 0; + uint128_t result = 0; + if ((((uint64_t)mode == (uint64_t)3ULL))) + { + result = imm; + } + else if ((((uint64_t)mode == (uint64_t)2ULL))) + { + for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) + { + uint128_t::insert(&result, e, 64ULL, ~(uint128_t::extract(imm, e, 64ULL))); + } + } + else if ((((uint64_t)mode == (uint64_t)0ULL))) + { + operand = V_interpreter(ctx,Rd); + for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) + { + uint128_t::insert(&result, e, 64ULL, (((uint64_t)(uint128_t::extract(operand, e, 64ULL)) | (uint64_t)(uint128_t::extract(imm, e, 64ULL))))); + } + } + else if ((((uint64_t)mode == (uint64_t)1ULL))) + { + operand = V_interpreter(ctx,Rd); + for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) + { + uint128_t::insert(&result, e, 64ULL, (((uint64_t)(uint128_t::extract(operand, e, 64ULL)) & (uint64_t)~(uint128_t::extract(imm, e, 64ULL))))); + } + } + else + { + undefined_interpreter(ctx); + } + V_interpreter(ctx,Rd,result); +} + +void fmov_general_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t Rn, uint64_t Rd) +{ + uint64_t intsize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t fltsize = get_flt_size_interpreter(ctx,ftype); + if ((((uint64_t)intsize != (uint64_t)fltsize))) + { + undefined_interpreter(ctx); + } + uint64_t size = intsize; + uint64_t part = rmode; + uint64_t int_to_float = opcode; + if ((int_to_float)) + { + uint64_t result = X_interpreter(ctx,Rn); + if (size == 32ULL) + { + VPart_interpreter(ctx,Rd,part,size,(uint64_t)(uint32_t)result); + } + if (size == 64ULL) + { + VPart_interpreter(ctx,Rd,part,size,(uint64_t)(uint64_t)result); + } + + } + else + { + uint128_t v = V_interpreter(ctx,Rn); + uint64_t result = uint128_t::extract(v, part, size); + X_interpreter(ctx,Rd,result); + } +} + +void convert_to_float_gp_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd) +{ + convert_to_float_interpreter(ctx,sf,ftype,U,Rn,Rd,0ULL); +} + +void convert_to_float_vector_scalar_interpreter(interpreter_data* ctx, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + convert_to_float_interpreter(ctx,sz,sz,U,Rn,Rd,1ULL); +} + +void convert_to_float_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t result = 0; + if (esize == 16ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, esize); + uint64_t working; + if ((U)) + { + working = convert_to_float((uint16_t)element, 0); + } + else + { + working = convert_to_float((uint16_t)element, 1); + } + uint128_t::insert(&result, e, esize, working); + } + V_interpreter(ctx,Rd,result); + } + if (esize == 32ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, esize); + uint64_t working; + if ((U)) + { + working = convert_to_float((uint32_t)element, 0); + } + else + { + working = convert_to_float((uint32_t)element, 1); + } + uint128_t::insert(&result, e, esize, working); + } + V_interpreter(ctx,Rd,result); + } + if (esize == 64ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, esize); + uint64_t working; + if ((U)) + { + working = convert_to_float((uint64_t)element, 0); + } + else + { + working = convert_to_float((uint64_t)element, 1); + } + uint128_t::insert(&result, e, esize, working); + } + V_interpreter(ctx,Rd,result); + } + +} + +void shl_immedaite_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_interpreter(ctx,immh,32ULL)); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t shift = ((uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb)) - (uint64_t)esize); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, esize); + element = ((uint64_t)element << (uint64_t)shift); + uint128_t::insert(&result, e, esize, element); + } + V_interpreter(ctx,Rd,result); +} + +void sshr_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_interpreter(ctx,immh,32ULL)); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t shift = ((uint64_t)(((uint64_t)esize * (uint64_t)2ULL)) - (uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb))); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t result = 0; + if (esize == 8ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, esize); + element = shift_right_check_interpreter(ctx,(uint64_t)sign_extend((uint8_t)element),(uint64_t)shift,esize,0ULL); + uint128_t::insert(&result, e, esize, element); + } + V_interpreter(ctx,Rd,result); + } + if (esize == 16ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, esize); + element = shift_right_check_interpreter(ctx,(uint64_t)sign_extend((uint16_t)element),(uint64_t)shift,esize,0ULL); + uint128_t::insert(&result, e, esize, element); + } + V_interpreter(ctx,Rd,result); + } + if (esize == 32ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, esize); + element = shift_right_check_interpreter(ctx,(uint64_t)sign_extend((uint32_t)element),(uint64_t)shift,esize,0ULL); + uint128_t::insert(&result, e, esize, element); + } + V_interpreter(ctx,Rd,result); + } + if (esize == 64ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, esize); + element = shift_right_check_interpreter(ctx,(uint64_t)sign_extend((uint64_t)element),(uint64_t)shift,esize,0ULL); + uint128_t::insert(&result, e, esize, element); + } + V_interpreter(ctx,Rd,result); + } + +} + +void shll_shll2_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,immh,2ULL,0ULL),32ULL)); + uint64_t datasize = 64ULL; + uint64_t part = Q; + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t shift = ((uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb)) - (uint64_t)esize); + uint64_t operand = VPart_interpreter(ctx,Rn,part,datasize); + uint128_t result = 0; + uint128_t working_vector = 0; + uint128_t::insert(&working_vector, 0ULL, datasize, operand); + if (esize == 8ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(working_vector, e, esize); + if ((!U)) + { + element = (uint64_t)sign_extend((uint8_t)element); + } + element = ((uint64_t)element << (uint64_t)shift); + uint128_t::insert(&result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); + } + V_interpreter(ctx,Rd,result); + } + if (esize == 16ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(working_vector, e, esize); + if ((!U)) + { + element = (uint64_t)sign_extend((uint16_t)element); + } + element = ((uint64_t)element << (uint64_t)shift); + uint128_t::insert(&result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); + } + V_interpreter(ctx,Rd,result); + } + if (esize == 32ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(working_vector, e, esize); + if ((!U)) + { + element = (uint64_t)sign_extend((uint32_t)element); + } + element = ((uint64_t)element << (uint64_t)shift); + uint128_t::insert(&result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); + } + V_interpreter(ctx,Rd,result); + } + if (esize == 64ULL) + { + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(working_vector, e, esize); + if ((!U)) + { + element = (uint64_t)sign_extend((uint64_t)element); + } + element = ((uint64_t)element << (uint64_t)shift); + uint128_t::insert(&result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); + } + V_interpreter(ctx,Rd,result); + } + +} + +void shrn_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,immh,2ULL,0ULL),32ULL)); + uint64_t datasize = 64ULL; + uint64_t part = Q; + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t shift = ((uint64_t)(((uint64_t)2ULL * (uint64_t)esize)) - (uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb))); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = shift_right_check_interpreter(ctx,uint128_t::extract(operand, e, (((uint64_t)2ULL * (uint64_t)esize))),(uint64_t)shift,((uint64_t)2ULL * (uint64_t)esize),1ULL); + uint128_t::insert(&result, e, esize, element); + } + VPart_interpreter(ctx,Rd,part,datasize,(uint64_t)result); +} + +void rev64_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint64_t csize = 64ULL; + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t containers = ((uint64_t)datasize / (uint64_t)csize); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t result = 0; + for (uint64_t c = 0; c < (containers); c++) + { + uint64_t container = uint128_t::extract(operand, c, csize); + uint128_t::insert(&result, c, csize, reverse_interpreter(ctx,(uint128_t)container,esize,csize)); + } + V_interpreter(ctx,Rd,result); +} + +void neg_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint128_t operand = V_interpreter(ctx,Rn); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint128_t::insert(&result, e, esize, -(uint128_t::extract(operand, e, esize))); + } + V_interpreter(ctx,Rd,result); +} + +void not_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rn, uint64_t Rd) +{ + uint128_t operand = V_interpreter(ctx,Rn); + uint64_t esize = 8ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint128_t::insert(&result, e, esize, ~(uint128_t::extract(operand, e, esize))); + } + V_interpreter(ctx,Rd,result); +} + +void abs_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint128_t operand = V_interpreter(ctx,Rn); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + if (esize == 8ULL) + { + uint8_t working = (uint128_t::extract(operand, e, esize)); + if ((((uint8_t)(sign_extend((uint8_t)working) < sign_extend((uint8_t)0ULL))))) + { + working = -working; + } + uint128_t::insert(&result, e, esize, working); + } + if (esize == 16ULL) + { + uint16_t working = (uint128_t::extract(operand, e, esize)); + if ((((uint16_t)(sign_extend((uint16_t)working) < sign_extend((uint16_t)0ULL))))) + { + working = -working; + } + uint128_t::insert(&result, e, esize, working); + } + if (esize == 32ULL) + { + uint32_t working = (uint128_t::extract(operand, e, esize)); + if ((((uint32_t)(sign_extend((uint32_t)working) < sign_extend((uint32_t)0ULL))))) + { + working = -working; + } + uint128_t::insert(&result, e, esize, working); + } + if (esize == 64ULL) + { + uint64_t working = (uint128_t::extract(operand, e, esize)); + if ((((uint64_t)(sign_extend((uint64_t)working) < sign_extend((uint64_t)0ULL))))) + { + working = -working; + } + uint128_t::insert(&result, e, esize, working); + } + + } + V_interpreter(ctx,Rd,result); +} + +void mul_vector_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd) +{ + uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)H); + uint64_t index; + uint64_t rm_hi; + if ((((uint64_t)size == (uint64_t)1ULL))) + { + index = H; + index = ((uint64_t)L | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); + index = ((uint64_t)M | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); + rm_hi = 0ULL; + } + else if ((((uint64_t)size == (uint64_t)2ULL))) + { + index = H; + index = ((uint64_t)L | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); + rm_hi = M; + } + else + { + undefined_interpreter(ctx); + } + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,((uint64_t)Rm | (uint64_t)(((uint64_t)rm_hi << (uint64_t)4ULL)))); + uint128_t result = 0; + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t element2 = uint128_t::extract(operand2, index, esize); + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element1 = uint128_t::extract(operand1, e, esize); + uint64_t product = ((uint64_t)element1 * (uint64_t)element2); + uint128_t::insert(&result, e, esize, product); + } + V_interpreter(ctx,Rd,result); +} + +void mul_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element1 = uint128_t::extract(operand1, e, esize); + uint64_t element2 = uint128_t::extract(operand2, e, esize); + uint64_t working = ((uint64_t)element1 * (uint64_t)element2); + uint128_t::insert(&result, e, esize, working); + } + V_interpreter(ctx,Rd,result); +} + +void ext_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t imm4, uint64_t Rn, uint64_t Rd) +{ + uint128_t lo = V_interpreter(ctx,Rn); + uint128_t hi = V_interpreter(ctx,Rm); + uint64_t vector_size = ((uint64_t)8ULL << (uint64_t)Q); + uint64_t start = imm4; + uint128_t result = 0; + for (uint64_t e = 0; e < (vector_size); e++) + { + uint8_t working = get_from_concacted_vector_interpreter(ctx,hi,lo,((uint64_t)start + (uint64_t)e),vector_size,8ULL); + uint128_t::insert(&result, e, 8ULL, working); + } + V_interpreter(ctx,Rd,result); +} + +void compare_above_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + if (esize == 8ULL) + { + uint8_t element1 = uint128_t::extract(operand1, e, esize); + uint8_t element2 = uint128_t::extract(operand2, e, esize); + uint8_t working; + if ((U)) + { + working = ((uint8_t)element1 > (uint8_t)element2); + } + else + { + working = ((uint8_t)(sign_extend((uint8_t)element1) > sign_extend((uint8_t)element2))); + } + uint128_t::insert(&result, e, esize, (((uint8_t)0ULL - (uint8_t)working))); + } + if (esize == 16ULL) + { + uint16_t element1 = uint128_t::extract(operand1, e, esize); + uint16_t element2 = uint128_t::extract(operand2, e, esize); + uint16_t working; + if ((U)) + { + working = ((uint16_t)element1 > (uint16_t)element2); + } + else + { + working = ((uint16_t)(sign_extend((uint16_t)element1) > sign_extend((uint16_t)element2))); + } + uint128_t::insert(&result, e, esize, (((uint16_t)0ULL - (uint16_t)working))); + } + if (esize == 32ULL) + { + uint32_t element1 = uint128_t::extract(operand1, e, esize); + uint32_t element2 = uint128_t::extract(operand2, e, esize); + uint32_t working; + if ((U)) + { + working = ((uint32_t)element1 > (uint32_t)element2); + } + else + { + working = ((uint32_t)(sign_extend((uint32_t)element1) > sign_extend((uint32_t)element2))); + } + uint128_t::insert(&result, e, esize, (((uint32_t)0ULL - (uint32_t)working))); + } + if (esize == 64ULL) + { + uint64_t element1 = uint128_t::extract(operand1, e, esize); + uint64_t element2 = uint128_t::extract(operand2, e, esize); + uint64_t working; + if ((U)) + { + working = ((uint64_t)element1 > (uint64_t)element2); + } + else + { + working = ((uint64_t)(sign_extend((uint64_t)element1) > sign_extend((uint64_t)element2))); + } + uint128_t::insert(&result, e, esize, (((uint64_t)0ULL - (uint64_t)working))); + } + + } + V_interpreter(ctx,Rd,result); +} + +void shl_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand1, e, esize); + uint64_t shift = (uint64_t)sign_extend((uint8_t)(uint128_t::extract(operand2, e, esize))); + if ((!U)) + { + if (esize == 8ULL) + { + element = (uint64_t)sign_extend((uint8_t)element); + } + if (esize == 16ULL) + { + element = (uint64_t)sign_extend((uint16_t)element); + } + if (esize == 32ULL) + { + element = (uint64_t)sign_extend((uint32_t)element); + } + if (esize == 64ULL) + { + element = (uint64_t)sign_extend((uint64_t)element); + } + + } + if ((((uint64_t)(sign_extend((uint64_t)shift) >= sign_extend((uint64_t)0ULL))))) + { + element = shift_left_check_interpreter(ctx,element,shift,esize); + } + else + { + shift = -shift; + element = shift_right_check_interpreter(ctx,element,shift,esize,U); + } + uint128_t::insert(&result, e, esize, element); + } + V_interpreter(ctx,Rd,result); +} + +void add_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result; + if ((use_x86_sse2_interpreter(ctx))) + { + uint64_t add_instruction; + if ((((uint64_t)esize == (uint64_t)8ULL))) + add_instruction = (uint64_t)x86_paddb; + else if ((((uint64_t)esize == (uint64_t)16ULL))) + add_instruction = (uint64_t)x86_paddw; + else if ((((uint64_t)esize == (uint64_t)32ULL))) + add_instruction = (uint64_t)x86_paddd; + else if ((((uint64_t)esize == (uint64_t)64ULL))) + add_instruction = (uint64_t)x86_paddq; + else + undefined_interpreter(ctx); + result = intrinsic_binary_interpreter(ctx,add_instruction,operand1,operand2); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + } + } + else + { + result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element1 = uint128_t::extract(operand1, e, esize); + uint64_t element2 = uint128_t::extract(operand2, e, esize); + uint128_t::insert(&result, e, esize, (((uint64_t)element1 + (uint64_t)element2))); + } + } + V_interpreter(ctx,Rd,result); +} + +void addlv_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t is_unsigned = U; + uint128_t source = V_interpreter(ctx,Rn); + uint128_t operand = V_interpreter(ctx,Rn); + uint64_t sum = 0ULL; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t working = (uint128_t::extract(operand, e, esize)); + if ((!is_unsigned)) + { + if (esize == 8ULL) + { + working = (uint64_t)sign_extend((uint8_t)working); + } + if (esize == 16ULL) + { + working = (uint64_t)sign_extend((uint16_t)working); + } + if (esize == 32ULL) + { + working = (uint64_t)sign_extend((uint32_t)working); + } + if (esize == 64ULL) + { + working = (uint64_t)sign_extend((uint64_t)working); + } + + } + sum = ((uint64_t)sum + (uint64_t)working); + } + uint128_t final = 0; + uint128_t::insert(&final, 0ULL, (((uint64_t)2ULL * (uint64_t)esize)), sum); + V_interpreter(ctx,Rd,final); +} + +void cnt_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = 8ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)8ULL); + uint128_t source = V_interpreter(ctx,Rn); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint8_t working = uint128_t::extract(source, e, esize); + uint8_t count = 0ULL; + if ((use_x86_interpreter(ctx))) + { + count = intrinsic_unary_interpreter(ctx,(uint64_t)x86_popcnt,(uint16_t)working); + } + else + { + for (uint64_t b = 0; b < (esize); b++) + { + uint8_t bit = ((uint8_t)(((uint8_t)working >> (uint8_t)b)) & (uint8_t)1ULL); + if ((bit)) + { + count = (((uint8_t)count + (uint8_t)1ULL)); + } + } + } + uint128_t::insert(&result, e, esize, count); + } + V_interpreter(ctx,Rd,result); +} + +void orr_orn_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((use_x86_sse_interpreter(ctx))) + { + x86_sse_logic_vector_interpreter(ctx,Rd,Rn,Rm,Q,invert,(uint64_t)x86_orps); + } + else + { + uint64_t esize = 64ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element1 = uint128_t::extract(operand1, e, esize); + uint64_t element2 = uint128_t::extract(operand2, e, esize); + if ((invert)) + { + element2 = ~element2; + } + uint128_t::insert(&result, e, esize, (((uint64_t)element1 | (uint64_t)element2))); + } + V_interpreter(ctx,Rd,result); + } +} + +void bsl_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = 64ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand1 = V_interpreter(ctx,Rm); + uint128_t operand2 = V_interpreter(ctx,Rd); + uint128_t operand3 = V_interpreter(ctx,Rn); + if ((use_x86_sse_interpreter(ctx))) + { + uint128_t xor_result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand1,operand3); + uint128_t and_result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_pand,xor_result,operand2); + uint128_t final_result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand1,and_result); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + uint128_t::insert(&final_result, 1ULL, 64ULL, (uint64_t)0ULL); + } + V_interpreter(ctx,Rd,final_result); + } + else + { + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element1 = uint128_t::extract(operand1, e, esize); + uint64_t element2 = uint128_t::extract(operand2, e, esize); + uint64_t element3 = uint128_t::extract(operand3, e, esize); + uint128_t::insert(&result, e, esize, (((uint64_t)element1 ^ (uint64_t)(((uint64_t)(((uint64_t)element1 ^ (uint64_t)element3)) & (uint64_t)element2))))); + } + V_interpreter(ctx,Rd,result); + } +} + +void and_bic_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((use_x86_sse2_interpreter(ctx))) + { + if ((invert)) + { + x86_sse_logic_vector_interpreter(ctx,Rd,Rm,Rn,Q,0ULL,(uint64_t)x86_pandn); + } + else + { + x86_sse_logic_vector_interpreter(ctx,Rd,Rn,Rm,Q,0ULL,(uint64_t)x86_pand); + } + } + else + { + uint64_t esize = 64ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element1 = uint128_t::extract(operand1, e, esize); + uint64_t element2 = uint128_t::extract(operand2, e, esize); + if ((invert)) + { + element2 = ~element2; + } + uint128_t::insert(&result, e, esize, (((uint64_t)element1 & (uint64_t)element2))); + } + V_interpreter(ctx,Rd,result); + } +} + +void eor_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((use_x86_sse_interpreter(ctx))) + { + x86_sse_logic_vector_interpreter(ctx,Rd,Rn,Rm,Q,0ULL,(uint64_t)x86_xorps); + } + else + { + uint64_t esize = 64ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element1 = uint128_t::extract(operand1, e, esize); + uint64_t element2 = uint128_t::extract(operand2, e, esize); + uint128_t::insert(&result, e, esize, (((uint64_t)element1 ^ (uint64_t)element2))); + } + V_interpreter(ctx,Rd,result); + } +} + +void xnt_xnt2_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = 64ULL; + uint64_t part = Q; + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t result = 0; + uint64_t mask = -1ULL; + if ((((uint64_t)esize != (uint64_t)64ULL))) + { + mask = ((uint64_t)(((uint64_t)1ULL << (uint64_t)esize)) - (uint64_t)1ULL); + } + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t element = uint128_t::extract(operand, e, (((uint64_t)2ULL * (uint64_t)esize))); + uint128_t::insert(&result, e, esize, (((uint64_t)element & (uint64_t)mask))); + } + VPart_interpreter(ctx,Rd,part,datasize,(uint64_t)result); +} + +void zip_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t part = op; + uint64_t pairs = ((uint64_t)elements / (uint64_t)2ULL); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + uint64_t base = ((uint64_t)part * (uint64_t)pairs); + for (uint64_t p = 0; p < (pairs); p++) + { + uint128_t::insert(&result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)0ULL)), esize, (uint128_t::extract(operand1, (((uint64_t)base + (uint64_t)p)), esize))); + uint128_t::insert(&result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)1ULL)), esize, (uint128_t::extract(operand2, (((uint64_t)base + (uint64_t)p)), esize))); + } + V_interpreter(ctx,Rd,result); +} + +void trn_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t part = op; + uint64_t pairs = ((uint64_t)elements / (uint64_t)2ULL); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + for (uint64_t p = 0; p < (pairs); p++) + { + uint128_t::insert(&result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)0ULL)), esize, (uint128_t::extract(operand1, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)part)), esize))); + uint128_t::insert(&result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)1ULL)), esize, (uint128_t::extract(operand2, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)part)), esize))); + } + V_interpreter(ctx,Rd,result); +} + +void tbl_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t len, uint64_t Rn, uint64_t Rd) +{ + store_context_interpreter(ctx); + uint64_t vector_context = get_vector_context_interpreter(ctx); + call_interpreter(ctx,vector_context,(uint64_t)Rd,(uint64_t)Rn,(uint64_t)len,(uint64_t)Rm,(uint64_t)Q,(uint64_t)table_lookup_fallback); + load_context_interpreter(ctx); +} + +void ld4_st4_multiple_structures_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t L, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_4_interpreter(ctx,Q,L,size,-1ULL,Rn,Rt); +} + +void ld4_st4_multiple_structures_post_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t L, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_4_interpreter(ctx,Q,L,size,Rm,Rn,Rt); +} + +void ld1r_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_interpreter(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,6ULL,0ULL,size,Rn,Rt,1ULL); +} + +void ld1r_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_interpreter(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,6ULL,0ULL,size,Rn,Rt,1ULL); +} + +void ld1_single_structure_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_interpreter(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,1ULL); +} + +void ld1_single_structure_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_interpreter(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,1ULL); +} + +void st1_multiple_structures_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + uint64_t opcode = ophi; + opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)1ULL); + opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)oplo); + st1_interpreter(ctx,0ULL,Q,0ULL,opcode,size,0ULL,Rn,Rt); +} + +void st1_multiple_structures_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + uint64_t opcode = ophi; + opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)1ULL); + opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)oplo); + st1_interpreter(ctx,1ULL,Q,0ULL,opcode,size,Rm,Rn,Rt); +} + +void st2_multiple_structures_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + st_interpreter(ctx,0ULL,Q,0ULL,4ULL,size,0ULL,Rn,Rt); +} + +void st2_multiple_structures_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + st_interpreter(ctx,1ULL,Q,0ULL,4ULL,size,Rm,Rn,Rt); +} + +void st1_single_structure_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_interpreter(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,0ULL); +} + +void st1_single_structure_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_interpreter(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,0ULL); +} + +void floating_point_conditional_select_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd) +{ + uint64_t fltsize = get_flt_size_interpreter(ctx,ftype); + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint128_t result = 0; + if ((condition_holds_interpreter(ctx,cond))) + { + result = operand1; + } + else + { + result = operand2; + } + result = clear_vector_scalar_interpreter(ctx,result,fltsize); + V_interpreter(ctx,Rd,result); +} + +void fcmp_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t opc) +{ + uint64_t datasize = get_flt_size_interpreter(ctx,ftype); + uint64_t cmp_with_zero = ((uint64_t)opc == (uint64_t)1ULL); + uint64_t operand1 = V_interpreter(ctx,Rn); + uint64_t operand2; + uint64_t fpcr_state = _sys_interpreter(ctx,(uint64_t)fpcr); + if ((cmp_with_zero)) + { + operand2 = 0ULL; + } + else + { + operand2 = V_interpreter(ctx,Rm); + } + uint64_t nzcv = FPCompare_interpreter(ctx,operand1,operand2,fpcr_state,datasize); + _sys_interpreter(ctx,(uint64_t)nzcv_n,((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_z,((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_v,((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); +} + +void fccmp_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t nzcv) +{ + uint64_t datasize = get_flt_size_interpreter(ctx,ftype); + uint64_t operand1 = V_interpreter(ctx,Rn); + uint64_t operand2 = V_interpreter(ctx,Rm); + uint64_t fpcr_state = _sys_interpreter(ctx,(uint64_t)fpcr); + if ((condition_holds_interpreter(ctx,cond))) + { + uint64_t success_nzcv = FPCompare_interpreter(ctx,operand1,operand2,fpcr_state,datasize); + _sys_interpreter(ctx,(uint64_t)nzcv_n,((uint64_t)(((uint64_t)success_nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_z,((uint64_t)(((uint64_t)success_nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,((uint64_t)(((uint64_t)success_nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_v,((uint64_t)(((uint64_t)success_nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); + } + else + { + _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); + _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); + } +} + uint64_t create_mask_interpreter(interpreter_data* ctx, uint64_t bits) { if ((((uint64_t)bits >= (uint64_t)64ULL))) @@ -6306,2440 +9958,77 @@ uint128_t clear_vector_scalar_interpreter(interpreter_data* ctx, uint128_t worki return working; } -void add_subtract_imm12_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t sh, uint64_t imm12, uint64_t Rn, uint64_t Rd) +uint64_t _compare_and_swap_interpreter(interpreter_data* ctx, uint64_t physical_address, uint64_t expecting, uint64_t to_swap, uint64_t size) { - if (sf == 0ULL) + if ((use_x86_interpreter(ctx))) { - uint32_t operand1 = XSP_interpreter(ctx,Rn); - uint32_t operand2 = decode_add_subtract_imm_12_interpreter(ctx,imm12,sh); - uint32_t d = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); - if ((S)) + if ((((uint64_t)size != (uint64_t)64ULL))) { - X_interpreter(ctx,Rd,(uint64_t)d); - } - else - { - XSP_interpreter(ctx,Rd,(uint64_t)d); + uint64_t mask = ((uint64_t)(((uint64_t)1ULL << (uint64_t)size)) - (uint64_t)1ULL); + uint64_t masking_value = *(uint64_t*)physical_address; + masking_value = ((uint64_t)masking_value & (uint64_t)~mask); + expecting = ((uint64_t)(((uint64_t)expecting & (uint64_t)mask)) | (uint64_t)masking_value); + to_swap = ((uint64_t)(((uint64_t)to_swap & (uint64_t)mask)) | (uint64_t)masking_value); } + return intrinsic_ternary_interpreter(ctx,(uint64_t)x86_cmpxchg,physical_address,expecting,to_swap); } - if (sf == 1ULL) - { - uint64_t operand1 = XSP_interpreter(ctx,Rn); - uint64_t operand2 = decode_add_subtract_imm_12_interpreter(ctx,imm12,sh); - uint64_t d = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); - if ((S)) - { - X_interpreter(ctx,Rd,(uint64_t)d); - } - else - { - XSP_interpreter(ctx,Rd,(uint64_t)d); - } - } - + return call_interpreter(ctx,physical_address,expecting,to_swap,(uint64_t)size,(uint64_t)0ULL,(uint64_t)0ULL,(uint64_t)compare_and_swap_interpreter_cpp); } -void add_subtract_shifted_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t shift, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd) +uint64_t compare_and_swap_interpreter(interpreter_data* ctx, uint64_t address, uint64_t expecting, uint64_t to_swap, uint64_t size) { - uint64_t shift_ammount = imm6; - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = a_shift_reg_interpreter(ctx,Rm,shift,shift_ammount); - uint32_t result = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = a_shift_reg_interpreter(ctx,Rm,shift,shift_ammount); - uint64_t result = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); - X_interpreter(ctx,Rd,(uint64_t)result); - } - + address = translate_address_interpreter(ctx,address); + return _compare_and_swap_interpreter(ctx,address,expecting,to_swap,size); } -void add_subtract_extended_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t option, uint64_t imm3, uint64_t Rn, uint64_t Rd) +template +void mem_interpreter(interpreter_data* ctx, uint64_t address, O value) { - if (sf == 0ULL) - { - uint64_t shift = imm3; - uint64_t extend_type = option; - uint32_t operand1 = XSP_interpreter(ctx,Rn); - uint32_t operand2 = a_extend_reg_interpreter(ctx,Rm,extend_type,shift); - uint32_t result = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); - if ((S)) - { - X_interpreter(ctx,Rd,(uint64_t)result); - } - else - { - XSP_interpreter(ctx,Rd,(uint64_t)result); - } - } - if (sf == 1ULL) - { - uint64_t shift = imm3; - uint64_t extend_type = option; - uint64_t operand1 = XSP_interpreter(ctx,Rn); - uint64_t operand2 = a_extend_reg_interpreter(ctx,Rm,extend_type,shift); - uint64_t result = add_subtract_impl_interpreter(ctx,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)); - if ((S)) - { - X_interpreter(ctx,Rd,(uint64_t)result); - } - else - { - XSP_interpreter(ctx,Rd,(uint64_t)result); - } - } - + address = translate_address_interpreter(ctx,address); + *(O*)address = value; } -void add_subtract_carry_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t Rn, uint64_t Rd) +template +O mem_interpreter(interpreter_data* ctx, uint64_t address) { - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = X_interpreter(ctx,Rm); - uint32_t result = add_subtract_carry_impl_interpreter(ctx,operand1,operand2,((uint64_t)S == (uint64_t)1ULL),((uint64_t)op == (uint64_t)0ULL),(uint32_t)_sys_interpreter(ctx,(uint64_t)nzcv_c)); - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = X_interpreter(ctx,Rm); - uint64_t result = add_subtract_carry_impl_interpreter(ctx,operand1,operand2,((uint64_t)S == (uint64_t)1ULL),((uint64_t)op == (uint64_t)0ULL),(uint64_t)_sys_interpreter(ctx,(uint64_t)nzcv_c)); - X_interpreter(ctx,Rd,(uint64_t)result); - } - + address = translate_address_interpreter(ctx,address); + return *(O*)address; } -void shift_variable_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t op2, uint64_t Rn, uint64_t Rd) +uint64_t XSP_interpreter(interpreter_data* ctx, uint64_t reg_id) { - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = X_interpreter(ctx,Rm); - uint64_t mask = ((uint64_t)(((uint64_t)32ULL << (uint64_t)sf)) - (uint64_t)1ULL); - uint32_t result; - operand2 = ((uint32_t)operand2 & (uint32_t)mask); - if ((((uint64_t)op2 == (uint64_t)0ULL))) - { - result = ((uint32_t)operand1 << (uint32_t)operand2); - } - else if ((((uint64_t)op2 == (uint64_t)1ULL))) - { - result = ((uint32_t)operand1 >> (uint32_t)operand2); - } - else if ((((uint64_t)op2 == (uint64_t)2ULL))) - { - result = ((uint32_t)(sign_extend((uint32_t)operand1) >> sign_extend((uint32_t)operand2))); - } - else - { - result = (rotate_right((uint32_t)operand1,(uint32_t)operand2)); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = X_interpreter(ctx,Rm); - uint64_t mask = ((uint64_t)(((uint64_t)32ULL << (uint64_t)sf)) - (uint64_t)1ULL); - uint64_t result; - operand2 = ((uint64_t)operand2 & (uint64_t)mask); - if ((((uint64_t)op2 == (uint64_t)0ULL))) - { - result = ((uint64_t)operand1 << (uint64_t)operand2); - } - else if ((((uint64_t)op2 == (uint64_t)1ULL))) - { - result = ((uint64_t)operand1 >> (uint64_t)operand2); - } - else if ((((uint64_t)op2 == (uint64_t)2ULL))) - { - result = ((uint64_t)(sign_extend((uint64_t)operand1) >> sign_extend((uint64_t)operand2))); - } - else - { - result = (rotate_right((uint64_t)operand1,(uint64_t)operand2)); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - + return _x_interpreter(ctx,reg_id); } -void multiply_with_32_interpreter(interpreter_data* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd) +void XSP_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value) { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = X_interpreter(ctx,Rm); - uint64_t operand3 = X_interpreter(ctx,Ra); - uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); - uint64_t is_signed = ((uint64_t)U == (uint64_t)0ULL); - if ((is_signed)) + _x_interpreter(ctx,reg_id,value); +} + +uint64_t X_interpreter(interpreter_data* ctx, uint64_t reg_id) +{ + if ((((uint64_t)reg_id == (uint64_t)31ULL))) { - operand1 = (uint64_t)sign_extend((uint32_t)operand1); - operand2 = (uint64_t)sign_extend((uint32_t)operand2); + return 0ULL; } else { - operand1 = ((uint64_t)operand1 & (uint64_t)4294967295ULL); - operand2 = ((uint64_t)operand2 & (uint64_t)4294967295ULL); - } - uint64_t result; - if ((is_add)) - { - result = ((uint64_t)operand3 + (uint64_t)(((uint64_t)operand1 * (uint64_t)operand2))); - } - else - { - result = ((uint64_t)operand3 - (uint64_t)(((uint64_t)operand1 * (uint64_t)operand2))); - } - X_interpreter(ctx,Rd,result); -} - -void multiply_hi_interpreter(interpreter_data* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Rn, uint64_t Rd) -{ - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = X_interpreter(ctx,Rm); - uint64_t is_signed = ((uint64_t)U == (uint64_t)0ULL); - uint64_t result; - if ((is_signed)) - { - result = (multiply_hi((uint64_t)operand1,(uint64_t)operand2, true)); - } - else - { - result = (multiply_hi((uint64_t)operand1,(uint64_t)operand2, false)); - } - X_interpreter(ctx,Rd,result); -} - -void multiply_additive_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd) -{ - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = X_interpreter(ctx,Rm); - uint32_t operand3 = X_interpreter(ctx,Ra); - uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); - uint32_t result; - if ((is_add)) - { - result = ((uint32_t)operand3 + (uint32_t)(((uint32_t)operand1 * (uint32_t)operand2))); - } - else - { - result = ((uint32_t)operand3 - (uint32_t)(((uint32_t)operand1 * (uint32_t)operand2))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = X_interpreter(ctx,Rm); - uint64_t operand3 = X_interpreter(ctx,Ra); - uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); - uint64_t result; - if ((is_add)) - { - result = ((uint64_t)operand3 + (uint64_t)(((uint64_t)operand1 * (uint64_t)operand2))); - } - else - { - result = ((uint64_t)operand3 - (uint64_t)(((uint64_t)operand1 * (uint64_t)operand2))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void divide_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t o1, uint64_t Rn, uint64_t Rd) -{ - uint64_t is_signed = ((uint64_t)o1 == (uint64_t)1ULL); - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = X_interpreter(ctx,Rm); - uint32_t result; - if ((((uint32_t)operand2 == (uint32_t)0ULL))) - { - X_interpreter(ctx,Rd,(uint64_t)0ULL); - } - else - { - if ((is_signed)) - { - uint64_t min = 9223372036854775808ULL; - if ((!sf)) - { - min = ((uint64_t)min >> (uint64_t)32ULL); - } - if ((((uint32_t)((uint32_t)operand1 == (uint32_t)min) && (uint32_t)((uint32_t)operand2 == (uint32_t)-1ULL)))) - { - X_interpreter(ctx,Rd,(uint64_t)min); - } - else - { - X_interpreter(ctx,Rd,(uint64_t)((uint32_t)(sign_extend((uint32_t)operand1) / sign_extend((uint32_t)operand2)))); - } - } - else - { - X_interpreter(ctx,Rd,(uint64_t)((uint32_t)operand1 / (uint32_t)operand2)); - } - } - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = X_interpreter(ctx,Rm); - uint64_t result; - if ((((uint64_t)operand2 == (uint64_t)0ULL))) - { - X_interpreter(ctx,Rd,(uint64_t)0ULL); - } - else - { - if ((is_signed)) - { - uint64_t min = 9223372036854775808ULL; - if ((!sf)) - { - min = ((uint64_t)min >> (uint64_t)32ULL); - } - if ((((uint64_t)((uint64_t)operand1 == (uint64_t)min) && (uint64_t)((uint64_t)operand2 == (uint64_t)-1ULL)))) - { - X_interpreter(ctx,Rd,(uint64_t)min); - } - else - { - X_interpreter(ctx,Rd,(uint64_t)((uint64_t)(sign_extend((uint64_t)operand1) / sign_extend((uint64_t)operand2)))); - } - } - else - { - X_interpreter(ctx,Rd,(uint64_t)((uint64_t)operand1 / (uint64_t)operand2)); - } - } - } - -} - -uint64_t create_rbit_mask_interpreter(interpreter_data* ctx, uint64_t index) -{ - index = ((uint64_t)1ULL << (uint64_t)index); - uint64_t mask = ((uint64_t)(((uint64_t)(((uint64_t)1ULL << (uint64_t)index)) - (uint64_t)1ULL)) << (uint64_t)index); - mask = replicate_c_interpreter(ctx,mask,((uint64_t)index * (uint64_t)2ULL),((uint64_t)((uint64_t)64ULL / (uint64_t)index) / (uint64_t)2ULL)); - return mask; -} - -void rbit_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - if (sf == 0ULL) - { - uint32_t operand = X_interpreter(ctx,Rn); - uint32_t result = operand; - uint64_t max = ((uint64_t)5ULL + (uint64_t)sf); - for (uint64_t i = 0; i < (max); i++) - { - uint64_t n_mask = create_rbit_mask_interpreter(ctx,i); - uint64_t i_mask = ~n_mask; - uint64_t shift = ((uint64_t)1ULL << (uint64_t)i); - result = ((uint32_t)(((uint32_t)(((uint32_t)result & (uint32_t)n_mask)) >> (uint32_t)shift)) | (uint32_t)(((uint32_t)(((uint32_t)result & (uint32_t)i_mask)) << (uint32_t)shift))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand = X_interpreter(ctx,Rn); - uint64_t result = operand; - uint64_t max = ((uint64_t)5ULL + (uint64_t)sf); - for (uint64_t i = 0; i < (max); i++) - { - uint64_t n_mask = create_rbit_mask_interpreter(ctx,i); - uint64_t i_mask = ~n_mask; - uint64_t shift = ((uint64_t)1ULL << (uint64_t)i); - result = ((uint64_t)(((uint64_t)(((uint64_t)result & (uint64_t)n_mask)) >> (uint64_t)shift)) | (uint64_t)(((uint64_t)(((uint64_t)result & (uint64_t)i_mask)) << (uint64_t)shift))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void rev16_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd) -{ - if (sf == 0ULL) - { - uint64_t count = ((uint64_t)2ULL << (uint64_t)sf); - uint32_t working = X_interpreter(ctx,Rn); - uint32_t result = 0ULL; - for (uint64_t i = 0; i < (count); i++) - { - uint32_t part = ((uint32_t)(((uint32_t)working >> (uint32_t)(((uint64_t)i * (uint64_t)16ULL)))) & (uint32_t)65535ULL); - part = reverse_bytes_interpreter(ctx,part,2ULL); - result = ((uint32_t)result | (uint32_t)(((uint32_t)part << (uint32_t)(((uint64_t)i * (uint64_t)16ULL))))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t count = ((uint64_t)2ULL << (uint64_t)sf); - uint64_t working = X_interpreter(ctx,Rn); - uint64_t result = 0ULL; - for (uint64_t i = 0; i < (count); i++) - { - uint64_t part = ((uint64_t)(((uint64_t)working >> (uint64_t)(((uint64_t)i * (uint64_t)16ULL)))) & (uint64_t)65535ULL); - part = reverse_bytes_interpreter(ctx,part,2ULL); - result = ((uint64_t)result | (uint64_t)(((uint64_t)part << (uint64_t)(((uint64_t)i * (uint64_t)16ULL))))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void reverse_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - if (sf == 0ULL) - { - uint32_t working = X_interpreter(ctx,Rn); - uint32_t result; - if ((((uint64_t)sf == (uint64_t)opc))) - { - result = reverse_bytes_interpreter(ctx,working,((uint64_t)4ULL << (uint64_t)sf)); - } - else - { - result = ((uint32_t)reverse_bytes_interpreter(ctx,working,4ULL) | (uint32_t)(((uint32_t)reverse_bytes_interpreter(ctx,((uint32_t)working >> (uint32_t)32ULL),4ULL) << (uint32_t)32ULL))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t working = X_interpreter(ctx,Rn); - uint64_t result; - if ((((uint64_t)sf == (uint64_t)opc))) - { - result = reverse_bytes_interpreter(ctx,working,((uint64_t)4ULL << (uint64_t)sf)); - } - else - { - result = ((uint64_t)reverse_bytes_interpreter(ctx,working,4ULL) | (uint64_t)(((uint64_t)reverse_bytes_interpreter(ctx,((uint64_t)working >> (uint64_t)32ULL),4ULL) << (uint64_t)32ULL))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void count_leading_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t s, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - if (sf == 0ULL) - { - uint32_t operand = X_interpreter(ctx,Rn); - uint32_t result = 0ULL; - uint32_t done = 0ULL; - uint32_t sig_bit; - if ((s)) - { - sig_bit = ((uint32_t)(((uint32_t)operand >> (uint32_t)(((uint64_t)datasize - (uint64_t)1ULL)))) & (uint32_t)1ULL); - datasize = ((uint64_t)datasize - (uint64_t)1ULL); - } - if ((use_x86_lzcnt_interpreter(ctx))) - { - if ((s)) - { - uint32_t nhigh = ((uint32_t)operand >> (uint32_t)1ULL); - uint32_t mask = -1ULL; - mask = ((uint32_t)mask >> (uint32_t)1ULL); - uint32_t nlow = ((uint32_t)operand & (uint32_t)mask); - result = intrinsic_unary_interpreter(ctx,(uint64_t)x86_lzcnt,(((uint32_t)nhigh ^ (uint32_t)nlow))); - result = ((uint32_t)result - (uint32_t)1ULL); - } - else - { - result = intrinsic_unary_interpreter(ctx,(uint64_t)x86_lzcnt,operand); - } - } - else - { - for (uint64_t i = 0; i < (datasize); i++) - { - uint32_t working = ((uint32_t)(((uint32_t)operand >> (uint32_t)(((uint64_t)((uint64_t)datasize - (uint64_t)i) - (uint64_t)1ULL)))) & (uint32_t)1ULL); - if ((s)) - { - if ((((uint32_t)working != (uint32_t)sig_bit))) - { - done = 1ULL; - } - } - else if ((working)) - { - done = 1ULL; - } - if ((!done)) - { - result = ((uint32_t)result + (uint32_t)1ULL); - } - } - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand = X_interpreter(ctx,Rn); - uint64_t result = 0ULL; - uint64_t done = 0ULL; - uint64_t sig_bit; - if ((s)) - { - sig_bit = ((uint64_t)(((uint64_t)operand >> (uint64_t)(((uint64_t)datasize - (uint64_t)1ULL)))) & (uint64_t)1ULL); - datasize = ((uint64_t)datasize - (uint64_t)1ULL); - } - if ((use_x86_lzcnt_interpreter(ctx))) - { - if ((s)) - { - uint64_t nhigh = ((uint64_t)operand >> (uint64_t)1ULL); - uint64_t mask = -1ULL; - mask = ((uint64_t)mask >> (uint64_t)1ULL); - uint64_t nlow = ((uint64_t)operand & (uint64_t)mask); - result = intrinsic_unary_interpreter(ctx,(uint64_t)x86_lzcnt,(((uint64_t)nhigh ^ (uint64_t)nlow))); - result = ((uint64_t)result - (uint64_t)1ULL); - } - else - { - result = intrinsic_unary_interpreter(ctx,(uint64_t)x86_lzcnt,operand); - } - } - else - { - for (uint64_t i = 0; i < (datasize); i++) - { - uint64_t working = ((uint64_t)(((uint64_t)operand >> (uint64_t)(((uint64_t)((uint64_t)datasize - (uint64_t)i) - (uint64_t)1ULL)))) & (uint64_t)1ULL); - if ((s)) - { - if ((((uint64_t)working != (uint64_t)sig_bit))) - { - done = 1ULL; - } - } - else if ((working)) - { - done = 1ULL; - } - if ((!done)) - { - result = ((uint64_t)result + (uint64_t)1ULL); - } - } - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void extr_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t N, uint64_t Rm, uint64_t imms, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = X_interpreter(ctx,Rm); - uint64_t lsb = imms; - uint32_t result; - if ((((uint64_t)lsb == (uint64_t)0ULL))) - { - result = operand2; - } - else if ((((uint64_t)Rn == (uint64_t)Rm))) - { - result = (rotate_right((uint32_t)operand1,(uint32_t)lsb)); - } - else - { - result = ((uint32_t)(((uint32_t)operand2 >> (uint32_t)lsb)) | (uint32_t)(((uint32_t)operand1 << (uint32_t)(((uint64_t)datasize - (uint64_t)lsb))))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = X_interpreter(ctx,Rm); - uint64_t lsb = imms; - uint64_t result; - if ((((uint64_t)lsb == (uint64_t)0ULL))) - { - result = operand2; - } - else if ((((uint64_t)Rn == (uint64_t)Rm))) - { - result = (rotate_right((uint64_t)operand1,(uint64_t)lsb)); - } - else - { - result = ((uint64_t)(((uint64_t)operand2 >> (uint64_t)lsb)) | (uint64_t)(((uint64_t)operand1 << (uint64_t)(((uint64_t)datasize - (uint64_t)lsb))))); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void bitfield_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t tmask = decode_bitmask_tmask_interpreter(ctx,N,imms,immr,0ULL,datasize,1ULL); - uint64_t wmask = decode_bitmask_tmask_interpreter(ctx,N,imms,immr,0ULL,datasize,0ULL); - uint64_t inzero; - uint64_t _extend; - if ((((uint64_t)opc == (uint64_t)0ULL))) - { - inzero = 1ULL; - _extend = 1ULL; - } - else if ((((uint64_t)opc == (uint64_t)1ULL))) - { - inzero = 0ULL; - _extend = 0ULL; - } - else if ((((uint64_t)opc == (uint64_t)2ULL))) - { - inzero = 1ULL; - _extend = 0ULL; - } - else - { - undefined_interpreter(ctx); - } - if (sf == 0ULL) - { - uint32_t dst; - uint32_t src = X_interpreter(ctx,Rn); - if ((inzero)) - { - dst = 0ULL; - } - else - { - dst = X_interpreter(ctx,Rd); - } - uint32_t bot = ((uint32_t)(((uint32_t)dst & (uint32_t)~wmask)) | (uint32_t)(((uint32_t)((rotate_right((uint32_t)src,(uint32_t)immr))) & (uint32_t)wmask))); - uint32_t top; - if ((_extend)) - { - top = ((uint32_t)0ULL - (uint32_t)(((uint32_t)(((uint32_t)src >> (uint32_t)imms)) & (uint32_t)1ULL))); - } - else - { - top = dst; - } - X_interpreter(ctx,Rd,(uint64_t)((uint32_t)(((uint32_t)top & (uint32_t)~tmask)) | (uint32_t)(((uint32_t)bot & (uint32_t)tmask)))); - } - if (sf == 1ULL) - { - uint64_t dst; - uint64_t src = X_interpreter(ctx,Rn); - if ((inzero)) - { - dst = 0ULL; - } - else - { - dst = X_interpreter(ctx,Rd); - } - uint64_t bot = ((uint64_t)(((uint64_t)dst & (uint64_t)~wmask)) | (uint64_t)(((uint64_t)((rotate_right((uint64_t)src,(uint64_t)immr))) & (uint64_t)wmask))); - uint64_t top; - if ((_extend)) - { - top = ((uint64_t)0ULL - (uint64_t)(((uint64_t)(((uint64_t)src >> (uint64_t)imms)) & (uint64_t)1ULL))); - } - else - { - top = dst; - } - X_interpreter(ctx,Rd,(uint64_t)((uint64_t)(((uint64_t)top & (uint64_t)~tmask)) | (uint64_t)(((uint64_t)bot & (uint64_t)tmask)))); - } - -} - -void logical_immediate_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = decode_bitmask_tmask_interpreter(ctx,N,imms,immr,1ULL,datasize,0ULL); - uint32_t result; - if ((((uint64_t)opc == (uint64_t)0ULL))) - { - result = ((uint32_t)operand1 & (uint32_t)operand2); - } - else if ((((uint64_t)opc == (uint64_t)1ULL))) - { - result = ((uint32_t)operand1 | (uint32_t)operand2); - } - else if ((((uint64_t)opc == (uint64_t)2ULL))) - { - result = ((uint32_t)operand1 ^ (uint32_t)operand2); - } - else if ((((uint64_t)opc == (uint64_t)3ULL))) - { - result = ((uint32_t)operand1 & (uint32_t)operand2); - X_interpreter(ctx,Rd,(uint64_t)result); - _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint32_t)(sign_extend((uint32_t)result) < sign_extend((uint32_t)0ULL)))); - _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint32_t)result == (uint32_t)0ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)0ULL); - _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)0ULL); - return; - } - XSP_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = decode_bitmask_tmask_interpreter(ctx,N,imms,immr,1ULL,datasize,0ULL); - uint64_t result; - if ((((uint64_t)opc == (uint64_t)0ULL))) - { - result = ((uint64_t)operand1 & (uint64_t)operand2); - } - else if ((((uint64_t)opc == (uint64_t)1ULL))) - { - result = ((uint64_t)operand1 | (uint64_t)operand2); - } - else if ((((uint64_t)opc == (uint64_t)2ULL))) - { - result = ((uint64_t)operand1 ^ (uint64_t)operand2); - } - else if ((((uint64_t)opc == (uint64_t)3ULL))) - { - result = ((uint64_t)operand1 & (uint64_t)operand2); - X_interpreter(ctx,Rd,(uint64_t)result); - _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(sign_extend((uint64_t)result) < sign_extend((uint64_t)0ULL)))); - _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)result == (uint64_t)0ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)0ULL); - _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)0ULL); - return; - } - XSP_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void logical_shifted_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t shift, uint64_t N, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd) -{ - uint64_t shift_type = shift; - uint64_t shift_ammount = imm6; - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = a_shift_reg_interpreter(ctx,Rm,shift_type,shift_ammount); - if ((N)) - { - operand2 = ~operand2; - } - uint32_t result; - if ((((uint64_t)((uint64_t)opc == (uint64_t)0ULL) || (uint64_t)((uint64_t)opc == (uint64_t)3ULL)))) - { - result = ((uint32_t)operand1 & (uint32_t)operand2); - if ((((uint64_t)opc == (uint64_t)3ULL))) - { - _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint32_t)(sign_extend((uint32_t)result) < sign_extend((uint32_t)0ULL)))); - _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint32_t)result == (uint32_t)0ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)0ULL); - _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)0ULL); - } - } - else if ((((uint64_t)opc == (uint64_t)1ULL))) - { - result = ((uint32_t)operand1 | (uint32_t)operand2); - } - else if ((((uint64_t)opc == (uint64_t)2ULL))) - { - result = ((uint32_t)operand1 ^ (uint32_t)operand2); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = a_shift_reg_interpreter(ctx,Rm,shift_type,shift_ammount); - if ((N)) - { - operand2 = ~operand2; - } - uint64_t result; - if ((((uint64_t)((uint64_t)opc == (uint64_t)0ULL) || (uint64_t)((uint64_t)opc == (uint64_t)3ULL)))) - { - result = ((uint64_t)operand1 & (uint64_t)operand2); - if ((((uint64_t)opc == (uint64_t)3ULL))) - { - _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(sign_extend((uint64_t)result) < sign_extend((uint64_t)0ULL)))); - _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)result == (uint64_t)0ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)0ULL); - _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)0ULL); - } - } - else if ((((uint64_t)opc == (uint64_t)1ULL))) - { - result = ((uint64_t)operand1 | (uint64_t)operand2); - } - else if ((((uint64_t)opc == (uint64_t)2ULL))) - { - result = ((uint64_t)operand1 ^ (uint64_t)operand2); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void conditional_select_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t cond, uint64_t op2, uint64_t Rn, uint64_t Rd) -{ - uint64_t incrament = op2; - uint64_t invert = op; - if (sf == 0ULL) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2 = X_interpreter(ctx,Rm); - uint32_t condition_pass = condition_holds_interpreter(ctx,cond); - if ((condition_pass)) - { - X_interpreter(ctx,Rd,(uint64_t)operand1); - } - else - { - if ((invert)) - { - operand2 = ~operand2; - } - if ((incrament)) - { - operand2 = ((uint32_t)operand2 + (uint32_t)1ULL); - } - X_interpreter(ctx,Rd,(uint64_t)operand2); - } - } - if (sf == 1ULL) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2 = X_interpreter(ctx,Rm); - uint64_t condition_pass = condition_holds_interpreter(ctx,cond); - if ((condition_pass)) - { - X_interpreter(ctx,Rd,(uint64_t)operand1); - } - else - { - if ((invert)) - { - operand2 = ~operand2; - } - if ((incrament)) - { - operand2 = ((uint64_t)operand2 + (uint64_t)1ULL); - } - X_interpreter(ctx,Rd,(uint64_t)operand2); - } - } - -} - -void conditional_compare_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t Rm, uint64_t cond, uint64_t mode, uint64_t Rn, uint64_t nzcv) -{ - if (sf == 0ULL) - { - if ((condition_holds_interpreter(ctx,cond))) - { - uint32_t operand1 = X_interpreter(ctx,Rn); - uint32_t operand2; - if ((mode)) - { - operand2 = Rm; - } - else - { - operand2 = X_interpreter(ctx,Rm); - } - add_subtract_impl_interpreter(ctx,operand1,operand2,1ULL,((uint64_t)op == (uint64_t)0ULL)); - } - else - { - _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); - } - } - if (sf == 1ULL) - { - if ((condition_holds_interpreter(ctx,cond))) - { - uint64_t operand1 = X_interpreter(ctx,Rn); - uint64_t operand2; - if ((mode)) - { - operand2 = Rm; - } - else - { - operand2 = X_interpreter(ctx,Rm); - } - add_subtract_impl_interpreter(ctx,operand1,operand2,1ULL,((uint64_t)op == (uint64_t)0ULL)); - } - else - { - _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); - } - } - -} - -void move_wide_immediate_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t hw, uint64_t imm16, uint64_t Rd) -{ - uint64_t shift = ((uint64_t)hw * (uint64_t)16ULL); - uint64_t immediate = ((uint64_t)imm16 << (uint64_t)shift); - if (sf == 0ULL) - { - uint32_t result; - if ((((uint64_t)opc == (uint64_t)0ULL))) - { - result = ~immediate; - } - else if ((((uint64_t)opc == (uint64_t)3ULL))) - { - result = X_interpreter(ctx,Rd); - result = ((uint32_t)result & (uint32_t)~(((uint64_t)65535ULL << (uint64_t)shift))); - result = ((uint32_t)result | (uint32_t)immediate); - } - else - { - result = immediate; - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (sf == 1ULL) - { - uint64_t result; - if ((((uint64_t)opc == (uint64_t)0ULL))) - { - result = ~immediate; - } - else if ((((uint64_t)opc == (uint64_t)3ULL))) - { - result = X_interpreter(ctx,Rd); - result = ((uint64_t)result & (uint64_t)~(((uint64_t)65535ULL << (uint64_t)shift))); - result = ((uint64_t)result | (uint64_t)immediate); - } - else - { - result = immediate; - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - -} - -void pc_rel_addressing_interpreter(interpreter_data* ctx, uint64_t op, uint64_t immlo, uint64_t immhi, uint64_t Rd) -{ - uint64_t offset = sign_extend_interpreter(ctx,((uint64_t)(((uint64_t)immhi << (uint64_t)2ULL)) | (uint64_t)immlo),21ULL); - uint64_t instruction_pc = _get_pc_interpreter(ctx); - if ((op)) - { - offset = ((uint64_t)offset << (uint64_t)12ULL); - instruction_pc = ((uint64_t)instruction_pc & (uint64_t)~4095ULL); - } - X_interpreter(ctx,Rd,(uint64_t)((uint64_t)instruction_pc + (uint64_t)offset)); -} - -void branch_register_interpreter(interpreter_data* ctx, uint64_t l, uint64_t Rn) -{ - branch_long_universal_interpreter(ctx,Rn,l); -} - -void return_register_interpreter(interpreter_data* ctx, uint64_t Rn) -{ - _return_from_call_interpreter(ctx,X_interpreter(ctx,Rn)); -} - -void test_bit_branch_interpreter(interpreter_data* ctx, uint64_t b5, uint64_t op, uint64_t b40, uint64_t imm14, uint64_t Rt) -{ - uint64_t bit_pos = ((uint64_t)b40 + (uint64_t)(((uint64_t)b5 << (uint64_t)5ULL))); - uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm14,14ULL) << (uint64_t)2ULL))); - uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); - uint64_t src = X_interpreter(ctx,Rt); - uint8_t branch_pass = ((uint64_t)(((uint64_t)(((uint64_t)src >> (uint64_t)bit_pos)) & (uint64_t)1ULL)) == (uint64_t)op); - _branch_conditional_interpreter(ctx,new_location,next_location,(uint64_t)branch_pass); -} - -void compare_and_branch_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t imm19, uint64_t Rt) -{ - if (sf == 0ULL) - { - uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm19,19ULL) << (uint64_t)2ULL))); - uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); - uint32_t operand = X_interpreter(ctx,Rt); - uint8_t branch_pass; - if ((!op)) - { - branch_pass = ((uint32_t)operand == (uint32_t)0ULL); - } - else - { - branch_pass = ((uint32_t)operand != (uint32_t)0ULL); - } - _branch_conditional_interpreter(ctx,new_location,next_location,(uint64_t)branch_pass); - } - if (sf == 1ULL) - { - uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm19,19ULL) << (uint64_t)2ULL))); - uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); - uint64_t operand = X_interpreter(ctx,Rt); - uint8_t branch_pass; - if ((!op)) - { - branch_pass = ((uint64_t)operand == (uint64_t)0ULL); - } - else - { - branch_pass = ((uint64_t)operand != (uint64_t)0ULL); - } - _branch_conditional_interpreter(ctx,new_location,next_location,(uint64_t)branch_pass); - } - -} - -void b_unconditional_interpreter(interpreter_data* ctx, uint64_t op, uint64_t imm26) -{ - uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm26,26ULL) << (uint64_t)2ULL))); - if ((op)) - { - uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); - X_interpreter(ctx,30ULL,(uint64_t)next_location); - _branch_call_interpreter(ctx,(uint64_t)new_location); - } - else - { - _branch_short_interpreter(ctx,new_location); + return _x_interpreter(ctx,reg_id); } } -void b_conditional_interpreter(interpreter_data* ctx, uint64_t imm19, uint64_t cond) +void X_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value) { - uint64_t new_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)(((uint64_t)sign_extend_interpreter(ctx,imm19,19ULL) << (uint64_t)2ULL))); - uint64_t next_location = ((uint64_t)_get_pc_interpreter(ctx) + (uint64_t)4ULL); - _branch_conditional_interpreter(ctx,new_location,next_location,(uint64_t)condition_holds_interpreter(ctx,cond)); -} - -void svc_interpreter(interpreter_data* ctx, uint64_t imm16) -{ - call_supervisor_interpreter(ctx,imm16); -} - -void msr_register_interpreter(interpreter_data* ctx, uint64_t imm15, uint64_t Rt) -{ - uint64_t operand = X_interpreter(ctx,Rt); - if ((((uint64_t)imm15 == (uint64_t)23072ULL))) - { - _sys_interpreter(ctx,(uint64_t)fpcr,operand); - } - else if ((((uint64_t)imm15 == (uint64_t)23073ULL))) - { - _sys_interpreter(ctx,(uint64_t)fpsr,operand); - } - else if ((((uint64_t)imm15 == (uint64_t)24194ULL))) - { - _sys_interpreter(ctx,(uint64_t)thread_local_1,operand); - } - else if ((((uint64_t)imm15 == (uint64_t)24195ULL))) - { - _sys_interpreter(ctx,(uint64_t)thread_local_0,operand); - } - else - { - undefined_with_interpreter(ctx,imm15); - } -} - -void mrs_register_interpreter(interpreter_data* ctx, uint64_t imm15, uint64_t Rt) -{ - uint64_t operand; - if ((((uint64_t)imm15 == (uint64_t)23072ULL))) - { - operand = _sys_interpreter(ctx,(uint64_t)fpcr); - } - else if ((((uint64_t)imm15 == (uint64_t)23073ULL))) - { - operand = _sys_interpreter(ctx,(uint64_t)fpsr); - } - else if ((((uint64_t)imm15 == (uint64_t)24194ULL))) - { - operand = _sys_interpreter(ctx,(uint64_t)thread_local_1); - } - else if ((((uint64_t)imm15 == (uint64_t)24195ULL))) - { - operand = _sys_interpreter(ctx,(uint64_t)thread_local_0); - } - else if ((((uint64_t)imm15 == (uint64_t)24321ULL))) - { - operand = call_counter_interpreter(ctx); - } - else if ((((uint64_t)imm15 == (uint64_t)22529ULL))) - { - operand = 2219098116ULL; - } - else - { - undefined_with_interpreter(ctx,imm15); - } - X_interpreter(ctx,Rt,operand); -} - -void hints_interpreter(interpreter_data* ctx, uint64_t imm7) -{ -} - -void sys_interpreter(interpreter_data* ctx, uint64_t L, uint64_t imm19) -{ -} - -void barriers_interpreter(interpreter_data* ctx, uint64_t CRm, uint64_t op2, uint64_t Rt) -{ - if ((((uint64_t)((uint64_t)op2 == (uint64_t)2ULL) && (uint64_t)((uint64_t)Rt == (uint64_t)31ULL)))) - { - _sys_interpreter(ctx,(uint64_t)exclusive_address,(uint64_t)-1ULL); - _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)-1ULL); - } -} - -void load_store_register_post_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) -{ - load_store_register_imm_unscaled_interpreter(ctx,size,VR,opc,imm9,1ULL,Rn,Rt); -} - -void load_store_register_pre_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) -{ - load_store_register_imm_unscaled_interpreter(ctx,size,VR,opc,imm9,3ULL,Rn,Rt); -} - -void load_store_register_unscaled_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) -{ - load_store_register_imm_unscaled_interpreter(ctx,size,VR,opc,imm9,0ULL,Rn,Rt); -} - -void load_store_register_pair_imm_offset_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) -{ - load_store_register_pair_imm_interpreter(ctx,opc,VR,2ULL,L,imm7,Rt2,Rn,Rt); -} - -void load_store_register_pair_imm_post_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) -{ - load_store_register_pair_imm_interpreter(ctx,opc,VR,1ULL,L,imm7,Rt2,Rn,Rt); -} - -void load_store_register_pair_imm_pre_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) -{ - load_store_register_pair_imm_interpreter(ctx,opc,VR,3ULL,L,imm7,Rt2,Rn,Rt); -} - -void load_store_register_pair_imm_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t wb, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) -{ - uint64_t wback = ((uint64_t)wb != (uint64_t)2ULL); - uint64_t postindex = ((uint64_t)wb == (uint64_t)1ULL); - uint64_t memop = !L; - uint64_t is_signed = (((uint64_t)opc & (uint64_t)1ULL)); - uint64_t scale; - if ((VR)) - { - scale = ((uint64_t)2ULL + (uint64_t)opc); - } - else - { - scale = ((uint64_t)2ULL + (uint64_t)(((uint64_t)(((uint64_t)opc >> (uint64_t)1ULL)) & (uint64_t)1ULL))); - } - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - uint64_t offset = ((uint64_t)sign_extend_interpreter(ctx,imm7,7ULL) << (uint64_t)scale); - uint64_t dbytes = ((uint64_t)datasize / (uint64_t)8ULL); - uint64_t address = XSP_interpreter(ctx,Rn); - if ((!postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - { - if (datasize == 8ULL) - { - if ((VR)) - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint8_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint8_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - V_interpreter(ctx,Rt,(uint128_t)d0); - V_interpreter(ctx,Rt2,(uint128_t)d1); - } - else - { - mem_interpreter(ctx,address,(uint8_t)V_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint8_t)V_interpreter(ctx,Rt2)); - } - } - else - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - if ((is_signed)) - { - d0 = (uint64_t)sign_extend((uint32_t)d0); - d1 = (uint64_t)sign_extend((uint32_t)d1); - } - X_interpreter(ctx,Rt,d0); - X_interpreter(ctx,Rt2,d1); - } - else - { - mem_interpreter(ctx,address,(uint8_t)X_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint8_t)X_interpreter(ctx,Rt2)); - } - } - } - if (datasize == 16ULL) - { - if ((VR)) - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint16_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint16_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - V_interpreter(ctx,Rt,(uint128_t)d0); - V_interpreter(ctx,Rt2,(uint128_t)d1); - } - else - { - mem_interpreter(ctx,address,(uint16_t)V_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint16_t)V_interpreter(ctx,Rt2)); - } - } - else - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - if ((is_signed)) - { - d0 = (uint64_t)sign_extend((uint32_t)d0); - d1 = (uint64_t)sign_extend((uint32_t)d1); - } - X_interpreter(ctx,Rt,d0); - X_interpreter(ctx,Rt2,d1); - } - else - { - mem_interpreter(ctx,address,(uint16_t)X_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint16_t)X_interpreter(ctx,Rt2)); - } - } - } - if (datasize == 32ULL) - { - if ((VR)) - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint32_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint32_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - V_interpreter(ctx,Rt,(uint128_t)d0); - V_interpreter(ctx,Rt2,(uint128_t)d1); - } - else - { - mem_interpreter(ctx,address,(uint32_t)V_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint32_t)V_interpreter(ctx,Rt2)); - } - } - else - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - if ((is_signed)) - { - d0 = (uint64_t)sign_extend((uint32_t)d0); - d1 = (uint64_t)sign_extend((uint32_t)d1); - } - X_interpreter(ctx,Rt,d0); - X_interpreter(ctx,Rt2,d1); - } - else - { - mem_interpreter(ctx,address,(uint32_t)X_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint32_t)X_interpreter(ctx,Rt2)); - } - } - } - if (datasize == 64ULL) - { - if ((VR)) - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - V_interpreter(ctx,Rt,(uint128_t)d0); - V_interpreter(ctx,Rt2,(uint128_t)d1); - } - else - { - mem_interpreter(ctx,address,(uint64_t)V_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint64_t)V_interpreter(ctx,Rt2)); - } - } - else - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - if ((is_signed)) - { - d0 = (uint64_t)sign_extend((uint32_t)d0); - d1 = (uint64_t)sign_extend((uint32_t)d1); - } - X_interpreter(ctx,Rt,d0); - X_interpreter(ctx,Rt2,d1); - } - else - { - mem_interpreter(ctx,address,(uint64_t)X_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint64_t)X_interpreter(ctx,Rt2)); - } - } - } - if (datasize == 128ULL) - { - if ((VR)) - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint128_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint128_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - V_interpreter(ctx,Rt,(uint128_t)d0); - V_interpreter(ctx,Rt2,(uint128_t)d1); - } - else - { - mem_interpreter(ctx,address,(uint128_t)V_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint128_t)V_interpreter(ctx,Rt2)); - } - } - else - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - uint64_t d0 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)0ULL)); - uint64_t d1 = mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes)); - if ((is_signed)) - { - d0 = (uint64_t)sign_extend((uint32_t)d0); - d1 = (uint64_t)sign_extend((uint32_t)d1); - } - X_interpreter(ctx,Rt,d0); - X_interpreter(ctx,Rt2,d1); - } - else - { - mem_interpreter(ctx,address,(uint128_t)X_interpreter(ctx,Rt)); - mem_interpreter(ctx,((uint64_t)address + (uint64_t)dbytes),(uint128_t)X_interpreter(ctx,Rt2)); - } - } - } - - } - if ((wback)) - { - if ((postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - XSP_interpreter(ctx,Rn,address); - } -} - -void load_store_register_imm_unsigned_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm12, uint64_t Rn, uint64_t Rt) -{ - if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) + if ((((uint64_t)reg_id == (uint64_t)31ULL))) { return; } - uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); - uint64_t wback = 0ULL; - uint64_t postindex = 0ULL; - if ((is_vector)) - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = ((uint64_t)(((uint64_t)bit_c_interpreter(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); - uint64_t offset = ((uint64_t)imm12 << (uint64_t)scale); - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - uint64_t address = XSP_interpreter(ctx,Rn); - if ((!postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - { - if (datasize == 8ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint8_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint8_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 16ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint16_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint16_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint32_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint32_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint64_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 128ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint128_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint128_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - - } - if ((wback)) - { - if ((postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - XSP_interpreter(ctx,Rn,address); - } - } else { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = size; - uint64_t offset = ((uint64_t)imm12 << (uint64_t)scale); - if ((((uint64_t)bit_c_interpreter(ctx,opc,1ULL) == (uint64_t)0ULL))) - { - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - if ((((uint64_t)size == (uint64_t)3ULL))) - regsize = 64ULL; - else - regsize = 32ULL; - _signed = 0ULL; - } - else - { - if ((((uint64_t)size == (uint64_t)3ULL))) - { - undefined_interpreter(ctx); - } - else - { - memop = 0ULL; - if ((((uint64_t)opc & (uint64_t)1ULL))) - regsize = 32ULL; - else - regsize = 64ULL; - _signed = 1ULL; - } - } - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - uint64_t address = XSP_interpreter(ctx,Rn); - if ((!postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - { - if (datasize == 8ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint8_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint8_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint8_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint8_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 16ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint16_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint16_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint16_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint16_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 32ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint32_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint32_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint32_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint32_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 64ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint64_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint64_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint64_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint64_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - - } - if ((wback)) - { - if ((postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - XSP_interpreter(ctx,Rn,address); - } + _x_interpreter(ctx,reg_id,value); } } -void load_store_register_imm_unscaled_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t wb, uint64_t Rn, uint64_t Rt) -{ - if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) - { - return; - } - uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); - uint64_t wback = ((uint64_t)wb != (uint64_t)0ULL); - uint64_t postindex = ((uint64_t)wb == (uint64_t)1ULL); - uint64_t offset = sign_extend_interpreter(ctx,imm9,9ULL); - if ((is_vector)) - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = ((uint64_t)(((uint64_t)bit_c_interpreter(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - uint64_t address = XSP_interpreter(ctx,Rn); - if ((!postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - { - if (datasize == 8ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint8_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint8_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 16ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint16_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint16_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint32_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint32_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint64_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 128ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint128_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint128_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - - } - if ((wback)) - { - if ((postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - XSP_interpreter(ctx,Rn,address); - } - } - else - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = size; - if ((((uint64_t)bit_c_interpreter(ctx,opc,1ULL) == (uint64_t)0ULL))) - { - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - if ((((uint64_t)size == (uint64_t)3ULL))) - regsize = 64ULL; - else - regsize = 32ULL; - _signed = 0ULL; - } - else - { - if ((((uint64_t)size == (uint64_t)3ULL))) - { - undefined_interpreter(ctx); - } - else - { - memop = 0ULL; - if ((((uint64_t)opc & (uint64_t)1ULL))) - regsize = 32ULL; - else - regsize = 64ULL; - _signed = 1ULL; - } - } - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - uint64_t address = XSP_interpreter(ctx,Rn); - if ((!postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - { - if (datasize == 8ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint8_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint8_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint8_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint8_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 16ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint16_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint16_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint16_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint16_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 32ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint32_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint32_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint32_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint32_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 64ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint64_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint64_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint64_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint64_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - - } - if ((wback)) - { - if ((postindex)) - { - address = ((uint64_t)address + (uint64_t)offset); - } - XSP_interpreter(ctx,Rn,address); - } - } -} - -void load_store_register_offset_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t Rm, uint64_t option, uint64_t S, uint64_t Rn, uint64_t Rt) -{ - if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) - { - return; - } - uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); - uint64_t wback = 0ULL; - uint64_t postindex = 0ULL; - if ((is_vector)) - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = ((uint64_t)(((uint64_t)bit_c_interpreter(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); - uint64_t shift = ((uint64_t)scale * (uint64_t)S); - uint64_t offset = a_extend_reg_64_interpreter(ctx,Rm,option,shift); - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - uint64_t address = ((uint64_t)XSP_interpreter(ctx,Rn) + (uint64_t)offset); - if (datasize == 8ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint8_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint8_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 16ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint16_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint16_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint32_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint32_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint64_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - if (datasize == 128ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint128_t data = V_interpreter(ctx,Rt); - mem_interpreter(ctx,address,data); - } - else - { - uint128_t data = mem_interpreter(ctx,address); - V_interpreter(ctx,Rt,(uint128_t)data); - } - } - - } - else - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = size; - uint64_t shift = ((uint64_t)scale * (uint64_t)S); - uint64_t offset = a_extend_reg_64_interpreter(ctx,Rm,option,shift); - if ((((uint64_t)bit_c_interpreter(ctx,opc,1ULL) == (uint64_t)0ULL))) - { - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - if ((((uint64_t)size == (uint64_t)3ULL))) - regsize = 64ULL; - else - regsize = 32ULL; - _signed = 0ULL; - } - else - { - if ((((uint64_t)size == (uint64_t)3ULL))) - { - undefined_interpreter(ctx); - } - else - { - memop = 0ULL; - if ((((uint64_t)opc & (uint64_t)1ULL))) - regsize = 32ULL; - else - regsize = 64ULL; - _signed = 1ULL; - } - } - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - uint64_t address = ((uint64_t)XSP_interpreter(ctx,Rn) + (uint64_t)offset); - if (datasize == 8ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint8_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint8_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint8_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint8_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 16ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint16_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint16_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint16_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint16_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 32ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint32_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint32_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint32_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint32_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - if (datasize == 64ULL) - { - if (regsize == 32ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint64_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint32_t)sign_extend((uint64_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - if (regsize == 64ULL) - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - uint64_t data = X_interpreter(ctx,Rt); - mem_interpreter(ctx,address,(uint64_t)data); - } - else - { - uint64_t n = mem_interpreter(ctx,address); - if ((_signed)) - { - n = (uint64_t)sign_extend((uint64_t)n); - } - X_interpreter(ctx,Rt,n); - } - } - - } - - } -} - -void load_store_exclusive_ordered_interpreter(interpreter_data* ctx, uint64_t size, uint64_t ordered, uint64_t L, uint64_t Rs, uint64_t o0, uint64_t Rn, uint64_t Rt) -{ - uint64_t is_exclusive = ((uint64_t)ordered == (uint64_t)0ULL); - if ((L)) - { - load_exclusive_interpreter(ctx,is_exclusive,size,Rn,Rt); - } - else - { - store_exclusive_interpreter(ctx,is_exclusive,size,Rn,Rt,Rs); - } -} - -uint64_t exclusive_address_mask_interpreter(interpreter_data* ctx) -{ - return ~(((uint64_t)(((uint64_t)4ULL << (uint64_t)4ULL)) - (uint64_t)1ULL)); -} - -void load_exclusive_interpreter(interpreter_data* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t address = XSP_interpreter(ctx,Rn); - if (datasize == 8ULL) - { - uint8_t value = mem_interpreter(ctx,address); - if ((is_exclusive)) - { - _sys_interpreter(ctx,(uint64_t)exclusive_address,((uint64_t)address & (uint64_t)exclusive_address_mask_interpreter(ctx))); - _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)value); - } - X_interpreter(ctx,Rt,(uint64_t)value); - } - if (datasize == 16ULL) - { - uint16_t value = mem_interpreter(ctx,address); - if ((is_exclusive)) - { - _sys_interpreter(ctx,(uint64_t)exclusive_address,((uint64_t)address & (uint64_t)exclusive_address_mask_interpreter(ctx))); - _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)value); - } - X_interpreter(ctx,Rt,(uint64_t)value); - } - if (datasize == 32ULL) - { - uint32_t value = mem_interpreter(ctx,address); - if ((is_exclusive)) - { - _sys_interpreter(ctx,(uint64_t)exclusive_address,((uint64_t)address & (uint64_t)exclusive_address_mask_interpreter(ctx))); - _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)value); - } - X_interpreter(ctx,Rt,(uint64_t)value); - } - if (datasize == 64ULL) - { - uint64_t value = mem_interpreter(ctx,address); - if ((is_exclusive)) - { - _sys_interpreter(ctx,(uint64_t)exclusive_address,((uint64_t)address & (uint64_t)exclusive_address_mask_interpreter(ctx))); - _sys_interpreter(ctx,(uint64_t)exclusive_value,(uint64_t)value); - } - X_interpreter(ctx,Rt,(uint64_t)value); - } - -} - -void store_exclusive_interpreter(interpreter_data* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t Rs) -{ - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t address = XSP_interpreter(ctx,Rn); - if (datasize == 8ULL) - { - if ((is_exclusive)) - { - uint64_t mask = exclusive_address_mask_interpreter(ctx); - uint64_t _exclusive_address = _sys_interpreter(ctx,(uint64_t)exclusive_address); - if ((((uint64_t)_exclusive_address == (uint64_t)(((uint64_t)address & (uint64_t)mask))))) - { - uint8_t to_swap = X_interpreter(ctx,Rt); - uint8_t expecting = _sys_interpreter(ctx,(uint64_t)exclusive_value); - uint8_t cas_success = compare_and_swap_interpreter(ctx,address,(uint64_t)expecting,(uint64_t)to_swap,datasize); - X_interpreter(ctx,Rs,(uint64_t)((uint8_t)(((uint8_t)cas_success ^ (uint8_t)1ULL)) & (uint8_t)1ULL)); - } - else - { - X_interpreter(ctx,Rs,(uint64_t)1ULL); - } - } - else - { - mem_interpreter(ctx,address,(uint8_t)X_interpreter(ctx,Rt)); - } - } - if (datasize == 16ULL) - { - if ((is_exclusive)) - { - uint64_t mask = exclusive_address_mask_interpreter(ctx); - uint64_t _exclusive_address = _sys_interpreter(ctx,(uint64_t)exclusive_address); - if ((((uint64_t)_exclusive_address == (uint64_t)(((uint64_t)address & (uint64_t)mask))))) - { - uint16_t to_swap = X_interpreter(ctx,Rt); - uint16_t expecting = _sys_interpreter(ctx,(uint64_t)exclusive_value); - uint16_t cas_success = compare_and_swap_interpreter(ctx,address,(uint64_t)expecting,(uint64_t)to_swap,datasize); - X_interpreter(ctx,Rs,(uint64_t)((uint16_t)(((uint16_t)cas_success ^ (uint16_t)1ULL)) & (uint16_t)1ULL)); - } - else - { - X_interpreter(ctx,Rs,(uint64_t)1ULL); - } - } - else - { - mem_interpreter(ctx,address,(uint16_t)X_interpreter(ctx,Rt)); - } - } - if (datasize == 32ULL) - { - if ((is_exclusive)) - { - uint64_t mask = exclusive_address_mask_interpreter(ctx); - uint64_t _exclusive_address = _sys_interpreter(ctx,(uint64_t)exclusive_address); - if ((((uint64_t)_exclusive_address == (uint64_t)(((uint64_t)address & (uint64_t)mask))))) - { - uint32_t to_swap = X_interpreter(ctx,Rt); - uint32_t expecting = _sys_interpreter(ctx,(uint64_t)exclusive_value); - uint32_t cas_success = compare_and_swap_interpreter(ctx,address,(uint64_t)expecting,(uint64_t)to_swap,datasize); - X_interpreter(ctx,Rs,(uint64_t)((uint32_t)(((uint32_t)cas_success ^ (uint32_t)1ULL)) & (uint32_t)1ULL)); - } - else - { - X_interpreter(ctx,Rs,(uint64_t)1ULL); - } - } - else - { - mem_interpreter(ctx,address,(uint32_t)X_interpreter(ctx,Rt)); - } - } - if (datasize == 64ULL) - { - if ((is_exclusive)) - { - uint64_t mask = exclusive_address_mask_interpreter(ctx); - uint64_t _exclusive_address = _sys_interpreter(ctx,(uint64_t)exclusive_address); - if ((((uint64_t)_exclusive_address == (uint64_t)(((uint64_t)address & (uint64_t)mask))))) - { - uint64_t to_swap = X_interpreter(ctx,Rt); - uint64_t expecting = _sys_interpreter(ctx,(uint64_t)exclusive_value); - uint64_t cas_success = compare_and_swap_interpreter(ctx,address,(uint64_t)expecting,(uint64_t)to_swap,datasize); - X_interpreter(ctx,Rs,(uint64_t)((uint64_t)(((uint64_t)cas_success ^ (uint64_t)1ULL)) & (uint64_t)1ULL)); - } - else - { - X_interpreter(ctx,Rs,(uint64_t)1ULL); - } - } - else - { - mem_interpreter(ctx,address,(uint64_t)X_interpreter(ctx,Rt)); - } - } - -} - void conversion_between_floating_point_and_fixed_point_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t S, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t scale, uint64_t Rn, uint64_t Rd) { uint64_t intsize = ((uint64_t)32ULL << (uint64_t)sf); @@ -8807,6 +10096,293 @@ void fcvtp_scalar_integer_interpreter(interpreter_data* ctx, uint64_t sf, uint64 convert_to_int_interpreter(ctx,sf,ftype,Rd,Rn,(uint64_t)FPRounding_POSINF,U,0ULL); } +void fadd_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_addss,(uint64_t)x86_addsd); + return; + } + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPAdd_interpreter); +} + +void fsub_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_subss,(uint64_t)x86_subsd); + return; + } + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPSub_interpreter); +} + +void fmul_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_mulss,(uint64_t)x86_mulsd); + return; + } + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMul_interpreter); +} + +void fdiv_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_divss,(uint64_t)x86_divsd); + return; + } + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPDiv_interpreter); +} + +void fmax_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_maxss,(uint64_t)x86_maxsd); + return; + } + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMax_interpreter); +} + +void fmin_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_minss,(uint64_t)x86_minsd); + return; + } + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMin_interpreter); +} + +void fmaxnm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMaxNum_interpreter); +} + +void fminnm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMinNum_interpreter); +} + +void fnmul_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + uint128_t operand1 = V_interpreter(ctx,Rn); + uint128_t operand2 = V_interpreter(ctx,Rm); + uint64_t esize = get_flt_size_interpreter(ctx,ftype); + uint128_t negator = (uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))); + uint64_t multiply_instruction; + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + multiply_instruction = (uint64_t)x86_mulss; + } + else if ((((uint64_t)esize == (uint64_t)64ULL))) + { + multiply_instruction = (uint64_t)x86_mulsd; + } + else + { + undefined_interpreter(ctx); + } + operand2 = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand2,negator); + uint128_t result = intrinsic_binary_interpreter(ctx,multiply_instruction,operand1,operand2); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + uint128_t::insert(&result, 1ULL, 32ULL, (uint64_t)0ULL); + } + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + V_interpreter(ctx,Rd,result); + return; + } + float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPNMul_interpreter); +} + +void fabs_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + { + uint64_t esize = get_flt_size_interpreter(ctx,ftype); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t mask = (uint64_t)(((uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))) - (uint64_t)1ULL)); + uint128_t result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_pand,operand,mask); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + uint128_t::insert(&result, 1ULL, 32ULL, (uint64_t)0ULL); + } + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + V_interpreter(ctx,Rd,result); + return; + } + float_unary_scalar_interpreter(ctx,Rd,Rn,ftype,(uint64_t)FPAbs_interpreter); +} + +void fneg_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + { + uint64_t esize = get_flt_size_interpreter(ctx,ftype); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t mask = (uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))); + uint128_t result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand,mask); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + uint128_t::insert(&result, 1ULL, 32ULL, (uint64_t)0ULL); + } + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + V_interpreter(ctx,Rd,result); + return; + } + float_unary_scalar_interpreter(ctx,Rd,Rn,ftype,(uint64_t)FPNeg_interpreter); +} + +void fneg_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + { + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t mask = sse_coppy_gp_across_lanes_interpreter(ctx,(uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))),esize); + uint128_t result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand,mask); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + } + V_interpreter(ctx,Rd,result); + return; + } + float_unary_vector_interpreter(ctx,Rd,Rn,Q,sz,(uint64_t)FPNeg_interpreter); +} + +void fsqrt_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + uint64_t esize = get_flt_size_interpreter(ctx,ftype); + uint128_t operand = V_interpreter(ctx,Rn); + uint64_t sqrt_instruction; + if ((((uint64_t)esize == (uint64_t)64ULL))) + { + sqrt_instruction = (uint64_t)x86_sqrtsd; + } + else + { + sqrt_instruction = (uint64_t)x86_sqrtss; + } + uint128_t result = intrinsic_unary_interpreter(ctx,sqrt_instruction,operand); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + uint128_t::insert(&result, 1ULL, 32ULL, (uint64_t)0ULL); + } + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + V_interpreter(ctx,Rd,result); + return; + } + float_unary_scalar_interpreter(ctx,Rd,Rn,ftype,(uint64_t)FPSqrt_interpreter); +} + +void fsqrt_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + { + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + uint128_t operand = V_interpreter(ctx,Rn); + uint64_t sqrt_instruction; + if ((((uint64_t)esize == (uint64_t)64ULL))) + { + sqrt_instruction = (uint64_t)x86_sqrtpd; + } + else + { + sqrt_instruction = (uint64_t)x86_sqrtps; + } + uint128_t result = intrinsic_unary_interpreter(ctx,sqrt_instruction,operand); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + } + V_interpreter(ctx,Rd,result); + return; + } + float_unary_vector_interpreter(ctx,Rd,Rn,Q,sz,(uint64_t)FPSqrt_interpreter); +} + +void frecpe_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + { + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + uint128_t operand = V_interpreter(ctx,Rn); + uint128_t one = sse_coppy_gp_across_lanes_interpreter(ctx,float_imm_interpreter(ctx,(uint64_t)1ULL,esize),esize); + uint64_t divide_instruction; + if ((((uint64_t)esize == (uint64_t)64ULL))) + { + divide_instruction = (uint64_t)x86_divpd; + } + else + { + divide_instruction = (uint64_t)x86_divps; + } + uint128_t result = intrinsic_binary_interpreter(ctx,divide_instruction,one,operand); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); + } + V_interpreter(ctx,Rd,result); + return; + } + float_unary_vector_interpreter(ctx,Rd,Rn,Q,sz,(uint64_t)FPRecipEstimate_interpreter); +} + +void frsqrte_scalar_interpreter(interpreter_data* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + uint64_t operand = V_interpreter(ctx,Rn); + if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + { + uint128_t one = float_imm_interpreter(ctx,(uint64_t)1ULL,esize); + uint64_t sqrt_instruction; + uint64_t divide_instruction; + if ((((uint64_t)esize == (uint64_t)64ULL))) + { + sqrt_instruction = (uint64_t)x86_sqrtsd; + divide_instruction = (uint64_t)x86_divsd; + } + else + { + sqrt_instruction = (uint64_t)x86_sqrtss; + divide_instruction = (uint64_t)x86_divss; + } + uint128_t sqrt_result = intrinsic_unary_interpreter(ctx,sqrt_instruction,(uint128_t)operand); + uint128_t reciprocal_result = intrinsic_binary_interpreter(ctx,divide_instruction,one,sqrt_result); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + uint128_t::insert(&reciprocal_result, 1ULL, 32ULL, (uint64_t)0ULL); + } + uint128_t::insert(&reciprocal_result, 1ULL, 64ULL, (uint64_t)0ULL); + V_interpreter(ctx,Rd,reciprocal_result); + } + else + { + uint64_t fpcr_state = _sys_interpreter(ctx,(uint64_t)fpcr); + uint64_t result = FPRSqrtEstimate_interpreter(ctx,operand,fpcr_state,esize); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + result = ((uint64_t)result & (uint64_t)4294967295ULL); + } + V_interpreter(ctx,Rd,(uint128_t)result); + } +} + +void fmov_scalar_immediate_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t imm8, uint64_t Rd) +{ + uint64_t fltsize = get_flt_size_interpreter(ctx,ftype); + uint64_t imm = vfp_expand_imm_interpreter(ctx,imm8,fltsize); + V_interpreter(ctx,Rd,(uint128_t)imm); +} + void fadd_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd) { if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) @@ -9231,1579 +10807,1307 @@ void fcmle_zero_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t s fcm_vector_interpreter(ctx,Rd,Rn,-1ULL,3ULL,Q,sz); } -void fadd_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +void add_subtract_imm12_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t sh, uint64_t imm12, uint64_t Rn, uint64_t Rd) { - if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; { - intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_addss,(uint64_t)x86_addsd); - return; - } - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPAdd_interpreter); -} - -void fsub_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_subss,(uint64_t)x86_subsd); - return; - } - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPSub_interpreter); -} - -void fmul_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_mulss,(uint64_t)x86_mulsd); - return; - } - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMul_interpreter); -} - -void fdiv_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_divss,(uint64_t)x86_divsd); - return; - } - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPDiv_interpreter); -} - -void fmax_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_maxss,(uint64_t)x86_maxsd); - return; - } - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMax_interpreter); -} - -void fmin_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_minss,(uint64_t)x86_minsd); - return; - } - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMin_interpreter); -} - -void fmaxnm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMaxNum_interpreter); -} - -void fminnm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMinNum_interpreter); -} - -void fnmul_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint64_t esize = get_flt_size_interpreter(ctx,ftype); - uint128_t negator = (uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))); - uint64_t multiply_instruction; - if ((((uint64_t)esize == (uint64_t)32ULL))) + ir_operand operand1 = copy_new_raw_size(ctx, XSP_jit(ctx,Rn), O); + ir_operand operand2 = ir_operand::create_con(decode_add_subtract_imm_12_jit(ctx,imm12,sh), O); + ir_operand d = copy_new_raw_size(ctx, add_subtract_impl_jit(ctx,O,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)), O); + if ((S)) { - multiply_instruction = (uint64_t)x86_mulss; - } - else if ((((uint64_t)esize == (uint64_t)64ULL))) - { - multiply_instruction = (uint64_t)x86_mulsd; + X_jit(ctx,Rd,copy_new_raw_size(ctx, d, int64)); } else { - undefined_interpreter(ctx); + XSP_jit(ctx,Rd,copy_new_raw_size(ctx, d, int64)); } - operand2 = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand2,negator); - uint128_t result = intrinsic_binary_interpreter(ctx,multiply_instruction,operand1,operand2); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - uint128_t::insert(&result, 1ULL, 32ULL, (uint64_t)0ULL); - } - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - V_interpreter(ctx,Rd,result); - return; } - float_binary_scalar_interpreter(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPNMul_interpreter); } -void fabs_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) +void add_subtract_shifted_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t shift, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd) { - if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + uint64_t shift_ammount = imm6; + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; { - uint64_t esize = get_flt_size_interpreter(ctx,ftype); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t mask = (uint64_t)(((uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))) - (uint64_t)1ULL)); - uint128_t result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_pand,operand,mask); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - uint128_t::insert(&result, 1ULL, 32ULL, (uint64_t)0ULL); - } - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - V_interpreter(ctx,Rd,result); - return; + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, a_shift_reg_jit(ctx,O,Rm,shift,shift_ammount), O); + ir_operand result = copy_new_raw_size(ctx, add_subtract_impl_jit(ctx,O,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)), O); + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); } - float_unary_scalar_interpreter(ctx,Rd,Rn,ftype,(uint64_t)FPAbs_interpreter); } -void fneg_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) +void add_subtract_extended_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t option, uint64_t imm3, uint64_t Rn, uint64_t Rd) { - if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; { - uint64_t esize = get_flt_size_interpreter(ctx,ftype); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t mask = (uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))); - uint128_t result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand,mask); - if ((((uint64_t)esize == (uint64_t)32ULL))) + uint64_t shift = imm3; + uint64_t extend_type = option; + ir_operand operand1 = copy_new_raw_size(ctx, XSP_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, a_extend_reg_jit(ctx,O,Rm,extend_type,shift), O); + ir_operand result = copy_new_raw_size(ctx, add_subtract_impl_jit(ctx,O,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)), O); + if ((S)) { - uint128_t::insert(&result, 1ULL, 32ULL, (uint64_t)0ULL); - } - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - V_interpreter(ctx,Rd,result); - return; - } - float_unary_scalar_interpreter(ctx,Rd,Rn,ftype,(uint64_t)FPNeg_interpreter); -} - -void fneg_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) - { - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t mask = sse_coppy_gp_across_lanes_interpreter(ctx,(uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))),esize); - uint128_t result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand,mask); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - } - V_interpreter(ctx,Rd,result); - return; - } - float_unary_vector_interpreter(ctx,Rd,Rn,Q,sz,(uint64_t)FPNeg_interpreter); -} - -void fsqrt_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - uint64_t esize = get_flt_size_interpreter(ctx,ftype); - uint128_t operand = V_interpreter(ctx,Rn); - uint64_t sqrt_instruction; - if ((((uint64_t)esize == (uint64_t)64ULL))) - { - sqrt_instruction = (uint64_t)x86_sqrtsd; + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); } else { - sqrt_instruction = (uint64_t)x86_sqrtss; + XSP_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); } - uint128_t result = intrinsic_unary_interpreter(ctx,sqrt_instruction,operand); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - uint128_t::insert(&result, 1ULL, 32ULL, (uint64_t)0ULL); - } - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - V_interpreter(ctx,Rd,result); - return; } - float_unary_scalar_interpreter(ctx,Rd,Rn,ftype,(uint64_t)FPSqrt_interpreter); } -void fsqrt_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) +void add_subtract_carry_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t Rn, uint64_t Rd) { - if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; { - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - uint128_t operand = V_interpreter(ctx,Rn); - uint64_t sqrt_instruction; - if ((((uint64_t)esize == (uint64_t)64ULL))) + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); + ir_operand result = copy_new_raw_size(ctx, add_subtract_carry_impl_jit(ctx,O,operand1,operand2,((uint64_t)S == (uint64_t)1ULL),((uint64_t)op == (uint64_t)0ULL),copy_new_raw_size(ctx, _sys_jit(ctx,(uint64_t)nzcv_c), O)), O); + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void shift_variable_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t op2, uint64_t Rn, uint64_t Rd) +{ + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); + uint64_t mask = ((uint64_t)(((uint64_t)32ULL << (uint64_t)sf)) - (uint64_t)1ULL); + ir_operand result; + operand2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand2, ir_operand::create_con(mask, O)); + if ((((uint64_t)op2 == (uint64_t)0ULL))) { - sqrt_instruction = (uint64_t)x86_sqrtpd; + result = ssa_emit_context::emit_ssa(ctx, ir_shift_left, operand1, operand2); + } + else if ((((uint64_t)op2 == (uint64_t)1ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand1, operand2); + } + else if ((((uint64_t)op2 == (uint64_t)2ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_shift_right_signed, operand1, operand2); } else { - sqrt_instruction = (uint64_t)x86_sqrtps; + result = ssa_emit_context::emit_ssa(ctx, ir_rotate_right, operand1, operand2); } - uint128_t result = intrinsic_unary_interpreter(ctx,sqrt_instruction,operand); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - } - V_interpreter(ctx,Rd,result); - return; + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); } - float_unary_vector_interpreter(ctx,Rd,Rn,Q,sz,(uint64_t)FPSqrt_interpreter); } -void frecpe_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) +void multiply_with_32_jit(ssa_emit_context* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd) { - if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) + ir_operand operand1 = X_jit(ctx,Rn); + ir_operand operand2 = X_jit(ctx,Rm); + ir_operand operand3 = X_jit(ctx,Ra); + uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); + uint64_t is_signed = ((uint64_t)U == (uint64_t)0ULL); + if ((is_signed)) { - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t one = sse_coppy_gp_across_lanes_interpreter(ctx,float_imm_interpreter(ctx,(uint64_t)1ULL,esize),esize); - uint64_t divide_instruction; - if ((((uint64_t)esize == (uint64_t)64ULL))) - { - divide_instruction = (uint64_t)x86_divpd; - } - else - { - divide_instruction = (uint64_t)x86_divps; - } - uint128_t result = intrinsic_binary_interpreter(ctx,divide_instruction,one,operand); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - } - V_interpreter(ctx,Rd,result); - return; - } - float_unary_vector_interpreter(ctx,Rd,Rn,Q,sz,(uint64_t)FPRecipEstimate_interpreter); -} - -void frsqrte_scalar_interpreter(interpreter_data* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - uint64_t operand = V_interpreter(ctx,Rn); - if ((((uint64_t)use_fast_float_interpreter(ctx) && (uint64_t)use_x86_sse_interpreter(ctx)))) - { - uint128_t one = float_imm_interpreter(ctx,(uint64_t)1ULL,esize); - uint64_t sqrt_instruction; - uint64_t divide_instruction; - if ((((uint64_t)esize == (uint64_t)64ULL))) - { - sqrt_instruction = (uint64_t)x86_sqrtsd; - divide_instruction = (uint64_t)x86_divsd; - } - else - { - sqrt_instruction = (uint64_t)x86_sqrtss; - divide_instruction = (uint64_t)x86_divss; - } - uint128_t sqrt_result = intrinsic_unary_interpreter(ctx,sqrt_instruction,(uint128_t)operand); - uint128_t reciprocal_result = intrinsic_binary_interpreter(ctx,divide_instruction,one,sqrt_result); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - uint128_t::insert(&reciprocal_result, 1ULL, 32ULL, (uint64_t)0ULL); - } - uint128_t::insert(&reciprocal_result, 1ULL, 64ULL, (uint64_t)0ULL); - V_interpreter(ctx,Rd,reciprocal_result); + operand1 = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, operand1, int32), int64); + operand2 = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, operand2, int32), int64); } else { - uint64_t fpcr_state = _sys_interpreter(ctx,(uint64_t)fpcr); - uint64_t result = FPRSqrtEstimate_interpreter(ctx,operand,fpcr_state,esize); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - result = ((uint64_t)result & (uint64_t)4294967295ULL); - } - V_interpreter(ctx,Rd,(uint128_t)result); + operand1 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand1, ir_operand::create_con(4294967295ULL, int64)); + operand2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand2, ir_operand::create_con(4294967295ULL, int64)); } -} - -void fmov_scalar_immediate_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t imm8, uint64_t Rd) -{ - uint64_t fltsize = get_flt_size_interpreter(ctx,ftype); - uint64_t imm = vfp_expand_imm_interpreter(ctx,imm8,fltsize); - V_interpreter(ctx,Rd,(uint128_t)imm); -} - -uint64_t _compare_and_swap_interpreter(interpreter_data* ctx, uint64_t physical_address, uint64_t expecting, uint64_t to_swap, uint64_t size) -{ - if ((use_x86_interpreter(ctx))) + ir_operand result; + if ((is_add)) { - if ((((uint64_t)size != (uint64_t)64ULL))) - { - uint64_t mask = ((uint64_t)(((uint64_t)1ULL << (uint64_t)size)) - (uint64_t)1ULL); - uint64_t masking_value = *(uint64_t*)physical_address; - masking_value = ((uint64_t)masking_value & (uint64_t)~mask); - expecting = ((uint64_t)(((uint64_t)expecting & (uint64_t)mask)) | (uint64_t)masking_value); - to_swap = ((uint64_t)(((uint64_t)to_swap & (uint64_t)mask)) | (uint64_t)masking_value); - } - return intrinsic_ternary_interpreter(ctx,(uint64_t)x86_cmpxchg,physical_address,expecting,to_swap); - } - return call_interpreter(ctx,physical_address,expecting,to_swap,(uint64_t)size,(uint64_t)0ULL,(uint64_t)0ULL,(uint64_t)compare_and_swap_interpreter_cpp); -} - -uint64_t compare_and_swap_interpreter(interpreter_data* ctx, uint64_t address, uint64_t expecting, uint64_t to_swap, uint64_t size) -{ - address = translate_address_interpreter(ctx,address); - return _compare_and_swap_interpreter(ctx,address,expecting,to_swap,size); -} - -template -void mem_interpreter(interpreter_data* ctx, uint64_t address, O value) -{ - address = translate_address_interpreter(ctx,address); - *(O*)address = value; -} - -template -O mem_interpreter(interpreter_data* ctx, uint64_t address) -{ - address = translate_address_interpreter(ctx,address); - return *(O*)address; -} - -uint64_t XSP_interpreter(interpreter_data* ctx, uint64_t reg_id) -{ - return _x_interpreter(ctx,reg_id); -} - -void XSP_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value) -{ - _x_interpreter(ctx,reg_id,value); -} - -uint64_t X_interpreter(interpreter_data* ctx, uint64_t reg_id) -{ - if ((((uint64_t)reg_id == (uint64_t)31ULL))) - { - return 0ULL; + result = ssa_emit_context::emit_ssa(ctx, ir_add, operand3, ssa_emit_context::emit_ssa(ctx, ir_multiply, operand1, operand2)); } else { - return _x_interpreter(ctx,reg_id); + result = ssa_emit_context::emit_ssa(ctx, ir_subtract, operand3, ssa_emit_context::emit_ssa(ctx, ir_multiply, operand1, operand2)); } + X_jit(ctx,Rd,result); } -void X_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value) +void multiply_hi_jit(ssa_emit_context* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Rn, uint64_t Rd) { - if ((((uint64_t)reg_id == (uint64_t)31ULL))) + ir_operand operand1 = X_jit(ctx,Rn); + ir_operand operand2 = X_jit(ctx,Rm); + uint64_t is_signed = ((uint64_t)U == (uint64_t)0ULL); + ir_operand result; + if ((is_signed)) { - return; + result = ssa_emit_context::emit_ssa(ctx, ir_multiply_hi_signed, operand1, operand2); } else { - _x_interpreter(ctx,reg_id,value); + result = ssa_emit_context::emit_ssa(ctx, ir_multiply_hi_unsigned, operand1, operand2); + } + X_jit(ctx,Rd,result); +} + +void multiply_additive_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd) +{ + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); + ir_operand operand3 = copy_new_raw_size(ctx, X_jit(ctx,Ra), O); + uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); + ir_operand result; + if ((is_add)) + { + result = ssa_emit_context::emit_ssa(ctx, ir_add, operand3, ssa_emit_context::emit_ssa(ctx, ir_multiply, operand1, operand2)); + } + else + { + result = ssa_emit_context::emit_ssa(ctx, ir_subtract, operand3, ssa_emit_context::emit_ssa(ctx, ir_multiply, operand1, operand2)); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); } } -void dup_general_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd) +void divide_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t o1, uint64_t Rn, uint64_t Rd) { - uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t element = X_interpreter(ctx,Rn); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t result; - if ((use_x86_sse_interpreter(ctx))) + uint64_t is_signed = ((uint64_t)o1 == (uint64_t)1ULL); + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; { - result = sse_coppy_gp_across_lanes_interpreter(ctx,element,esize); - if ((!Q)) + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); + ir_operand result; { - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - } - } - else - { - result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint128_t::insert(&result, e, esize, element); - } - } - V_interpreter(ctx,Rd,result); -} - -void dup_element_scalar_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); - uint64_t index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)bit_c_interpreter(ctx,imm5,4ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = esize; - uint64_t elements = 1ULL; - dup_element_interpreter(ctx,index,esize,elements,Rn,Rd); -} - -void dup_element_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); - uint64_t index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)bit_c_interpreter(ctx,imm5,4ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - dup_element_interpreter(ctx,index,esize,elements,Rn,Rd); -} - -void move_to_gp_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t U, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)Q); - uint64_t index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint128_t operand = V_interpreter(ctx,Rn); - if (esize == 8ULL) - { - if (datasize == 32ULL) - { - uint32_t result = uint128_t::extract(operand, index, esize); - if ((!U)) - { - result = (uint32_t)sign_extend((uint8_t)result); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (datasize == 64ULL) - { - uint64_t result = uint128_t::extract(operand, index, esize); - if ((!U)) - { - result = (uint64_t)sign_extend((uint8_t)result); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); - } - if (esize == 16ULL) - { - if (datasize == 32ULL) - { - uint32_t result = uint128_t::extract(operand, index, esize); - if ((!U)) - { - result = (uint32_t)sign_extend((uint16_t)result); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (datasize == 64ULL) - { - uint64_t result = uint128_t::extract(operand, index, esize); - if ((!U)) - { - result = (uint64_t)sign_extend((uint16_t)result); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } + ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_equal, operand2, ir_operand::create_con(0ULL, O)); - } - if (esize == 32ULL) - { - if (datasize == 32ULL) - { - uint32_t result = uint128_t::extract(operand, index, esize); - if ((!U)) - { - result = (uint32_t)sign_extend((uint32_t)result); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (datasize == 64ULL) - { - uint64_t result = uint128_t::extract(operand, index, esize); - if ((!U)) - { - result = (uint64_t)sign_extend((uint32_t)result); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - - } - if (esize == 64ULL) - { - if (datasize == 32ULL) - { - uint32_t result = uint128_t::extract(operand, index, esize); - if ((!U)) - { - result = (uint32_t)sign_extend((uint64_t)result); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - if (datasize == 64ULL) - { - uint64_t result = uint128_t::extract(operand, index, esize); - if ((!U)) - { - result = (uint64_t)sign_extend((uint64_t)result); - } - X_interpreter(ctx,Rd,(uint64_t)result); - } - - } - -} - -void ins_general_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); - uint64_t index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t element = X_interpreter(ctx,Rn); - uint128_t result = V_interpreter(ctx,Rd); - uint128_t::insert(&result, index, esize, element); - V_interpreter(ctx,Rd,result); -} - -void ins_element_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t imm4, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,imm5,3ULL,0ULL)); - uint64_t dst_index = bits_c_interpreter(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint64_t src_index = bits_c_interpreter(ctx,imm4,3ULL,size); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t result = V_interpreter(ctx,Rd); - uint128_t::insert(&result, dst_index, esize, (uint128_t::extract(operand, src_index, esize))); - V_interpreter(ctx,Rd,result); -} - -void movi_immediate_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t op, uint64_t immhi, uint64_t cmode, uint64_t immlo, uint64_t Rd) -{ - uint64_t d = Rd; - uint64_t imm8 = ((uint64_t)(((uint64_t)immhi << (uint64_t)5ULL)) | (uint64_t)immlo); - uint64_t cmode_helper = ((uint64_t)(((uint64_t)cmode << (uint64_t)1ULL)) | (uint64_t)op); - uint64_t mode = 0ULL; - if ((((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)2ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)18ULL))))) - { - mode = 0ULL; - } - else if ((((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)3ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)19ULL))))) - { - mode = 1ULL; - } - else if ((((uint64_t)((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)1ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)17ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)29ULL)) == (uint64_t)25ULL))))) - { - mode = 2ULL; - } - else if ((((uint64_t)((uint64_t)((uint64_t)((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)0ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)16ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)29ULL)) == (uint64_t)24ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)30ULL)) == (uint64_t)28ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)31ULL)) == (uint64_t)30ULL))))) - { - mode = 3ULL; - } - else if ((((uint64_t)cmode_helper == (uint64_t)31ULL))) - { - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - undefined_interpreter(ctx); - } - mode = 3ULL; - } - else - { - undefined_interpreter(ctx); - } - uint64_t imm64 = expand_imm_interpreter(ctx,op,cmode,imm8); - uint128_t imm = imm64; - if ((Q)) - { - uint128_t::insert(&imm, 1ULL, 64ULL, imm64); - } - uint128_t operand = 0; - uint128_t result = 0; - if ((((uint64_t)mode == (uint64_t)3ULL))) - { - result = imm; - } - else if ((((uint64_t)mode == (uint64_t)2ULL))) - { - for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) - { - uint128_t::insert(&result, e, 64ULL, ~(uint128_t::extract(imm, e, 64ULL))); - } - } - else if ((((uint64_t)mode == (uint64_t)0ULL))) - { - operand = V_interpreter(ctx,Rd); - for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) - { - uint128_t::insert(&result, e, 64ULL, (((uint64_t)(uint128_t::extract(operand, e, 64ULL)) | (uint64_t)(uint128_t::extract(imm, e, 64ULL))))); - } - } - else if ((((uint64_t)mode == (uint64_t)1ULL))) - { - operand = V_interpreter(ctx,Rd); - for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) - { - uint128_t::insert(&result, e, 64ULL, (((uint64_t)(uint128_t::extract(operand, e, 64ULL)) & (uint64_t)~(uint128_t::extract(imm, e, 64ULL))))); - } - } - else - { - undefined_interpreter(ctx); - } - V_interpreter(ctx,Rd,result); -} - -void fmov_general_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t Rn, uint64_t Rd) -{ - uint64_t intsize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t fltsize = get_flt_size_interpreter(ctx,ftype); - if ((((uint64_t)intsize != (uint64_t)fltsize))) - { - undefined_interpreter(ctx); - } - uint64_t size = intsize; - uint64_t part = rmode; - uint64_t int_to_float = opcode; - if ((int_to_float)) - { - uint64_t result = X_interpreter(ctx,Rn); - if (size == 32ULL) - { - VPart_interpreter(ctx,Rd,part,size,(uint64_t)(uint32_t)result); - } - if (size == 64ULL) - { - VPart_interpreter(ctx,Rd,part,size,(uint64_t)(uint64_t)result); - } - - } - else - { - uint128_t v = V_interpreter(ctx,Rn); - uint64_t result = uint128_t::extract(v, part, size); - X_interpreter(ctx,Rd,result); - } -} - -void convert_to_float_gp_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd) -{ - convert_to_float_interpreter(ctx,sf,ftype,U,Rn,Rd,0ULL); -} - -void convert_to_float_vector_scalar_interpreter(interpreter_data* ctx, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - convert_to_float_interpreter(ctx,sz,sz,U,Rn,Rd,1ULL); -} - -void convert_to_float_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t result = 0; - if (esize == 16ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand, e, esize); - uint64_t working; - if ((U)) - { - working = convert_to_float((uint16_t)element, 0); - } - else - { - working = convert_to_float((uint16_t)element, 1); - } - uint128_t::insert(&result, e, esize, working); - } - V_interpreter(ctx,Rd,result); - } - if (esize == 32ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand, e, esize); - uint64_t working; - if ((U)) - { - working = convert_to_float((uint32_t)element, 0); - } - else - { - working = convert_to_float((uint32_t)element, 1); - } - uint128_t::insert(&result, e, esize, working); - } - V_interpreter(ctx,Rd,result); - } - if (esize == 64ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand, e, esize); - uint64_t working; - if ((U)) - { - working = convert_to_float((uint64_t)element, 0); - } - else - { - working = convert_to_float((uint64_t)element, 1); - } - uint128_t::insert(&result, e, esize, working); - } - V_interpreter(ctx,Rd,result); - } - -} - -void shl_immedaite_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_interpreter(ctx,immh,32ULL)); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t shift = ((uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb)) - (uint64_t)esize); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand, e, esize); - element = ((uint64_t)element << (uint64_t)shift); - uint128_t::insert(&result, e, esize, element); - } - V_interpreter(ctx,Rd,result); -} - -void sshr_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_interpreter(ctx,immh,32ULL)); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t shift = ((uint64_t)(((uint64_t)esize * (uint64_t)2ULL)) - (uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb))); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t result = 0; - if (esize == 8ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand, e, esize); - element = shift_right_check_interpreter(ctx,(uint64_t)sign_extend((uint8_t)element),(uint64_t)shift,esize,0ULL); - uint128_t::insert(&result, e, esize, element); - } - V_interpreter(ctx,Rd,result); - } - if (esize == 16ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand, e, esize); - element = shift_right_check_interpreter(ctx,(uint64_t)sign_extend((uint16_t)element),(uint64_t)shift,esize,0ULL); - uint128_t::insert(&result, e, esize, element); - } - V_interpreter(ctx,Rd,result); - } - if (esize == 32ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand, e, esize); - element = shift_right_check_interpreter(ctx,(uint64_t)sign_extend((uint32_t)element),(uint64_t)shift,esize,0ULL); - uint128_t::insert(&result, e, esize, element); - } - V_interpreter(ctx,Rd,result); - } - if (esize == 64ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand, e, esize); - element = shift_right_check_interpreter(ctx,(uint64_t)sign_extend((uint64_t)element),(uint64_t)shift,esize,0ULL); - uint128_t::insert(&result, e, esize, element); - } - V_interpreter(ctx,Rd,result); - } - -} - -void shll_shll2_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,immh,2ULL,0ULL),32ULL)); - uint64_t datasize = 64ULL; - uint64_t part = Q; - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t shift = ((uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb)) - (uint64_t)esize); - uint64_t operand = VPart_interpreter(ctx,Rn,part,datasize); - uint128_t result = 0; - uint128_t working_vector = 0; - uint128_t::insert(&working_vector, 0ULL, datasize, operand); - if (esize == 8ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(working_vector, e, esize); - if ((!U)) - { - element = (uint64_t)sign_extend((uint8_t)element); - } - element = ((uint64_t)element << (uint64_t)shift); - uint128_t::insert(&result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); - } - V_interpreter(ctx,Rd,result); - } - if (esize == 16ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(working_vector, e, esize); - if ((!U)) - { - element = (uint64_t)sign_extend((uint16_t)element); - } - element = ((uint64_t)element << (uint64_t)shift); - uint128_t::insert(&result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); - } - V_interpreter(ctx,Rd,result); - } - if (esize == 32ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(working_vector, e, esize); - if ((!U)) - { - element = (uint64_t)sign_extend((uint32_t)element); - } - element = ((uint64_t)element << (uint64_t)shift); - uint128_t::insert(&result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); - } - V_interpreter(ctx,Rd,result); - } - if (esize == 64ULL) - { - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(working_vector, e, esize); - if ((!U)) - { - element = (uint64_t)sign_extend((uint64_t)element); - } - element = ((uint64_t)element << (uint64_t)shift); - uint128_t::insert(&result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); - } - V_interpreter(ctx,Rd,result); - } - -} - -void shrn_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_interpreter(ctx,bits_c_interpreter(ctx,immh,2ULL,0ULL),32ULL)); - uint64_t datasize = 64ULL; - uint64_t part = Q; - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t shift = ((uint64_t)(((uint64_t)2ULL * (uint64_t)esize)) - (uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb))); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = shift_right_check_interpreter(ctx,uint128_t::extract(operand, e, (((uint64_t)2ULL * (uint64_t)esize))),(uint64_t)shift,((uint64_t)2ULL * (uint64_t)esize),1ULL); - uint128_t::insert(&result, e, esize, element); - } - VPart_interpreter(ctx,Rd,part,datasize,(uint64_t)result); -} - -void rev64_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint64_t csize = 64ULL; - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t containers = ((uint64_t)datasize / (uint64_t)csize); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t result = 0; - for (uint64_t c = 0; c < (containers); c++) - { - uint64_t container = uint128_t::extract(operand, c, csize); - uint128_t::insert(&result, c, csize, reverse_interpreter(ctx,(uint128_t)container,esize,csize)); - } - V_interpreter(ctx,Rd,result); -} - -void neg_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint128_t operand = V_interpreter(ctx,Rn); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint128_t::insert(&result, e, esize, -(uint128_t::extract(operand, e, esize))); - } - V_interpreter(ctx,Rd,result); -} - -void not_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rn, uint64_t Rd) -{ - uint128_t operand = V_interpreter(ctx,Rn); - uint64_t esize = 8ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint128_t::insert(&result, e, esize, ~(uint128_t::extract(operand, e, esize))); - } - V_interpreter(ctx,Rd,result); -} - -void abs_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint128_t operand = V_interpreter(ctx,Rn); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - if (esize == 8ULL) - { - uint8_t working = (uint128_t::extract(operand, e, esize)); - if ((((uint8_t)(sign_extend((uint8_t)working) < sign_extend((uint8_t)0ULL))))) - { - working = -working; - } - uint128_t::insert(&result, e, esize, working); - } - if (esize == 16ULL) - { - uint16_t working = (uint128_t::extract(operand, e, esize)); - if ((((uint16_t)(sign_extend((uint16_t)working) < sign_extend((uint16_t)0ULL))))) - { - working = -working; - } - uint128_t::insert(&result, e, esize, working); - } - if (esize == 32ULL) - { - uint32_t working = (uint128_t::extract(operand, e, esize)); - if ((((uint32_t)(sign_extend((uint32_t)working) < sign_extend((uint32_t)0ULL))))) - { - working = -working; - } - uint128_t::insert(&result, e, esize, working); - } - if (esize == 64ULL) - { - uint64_t working = (uint128_t::extract(operand, e, esize)); - if ((((uint64_t)(sign_extend((uint64_t)working) < sign_extend((uint64_t)0ULL))))) - { - working = -working; - } - uint128_t::insert(&result, e, esize, working); - } - - } - V_interpreter(ctx,Rd,result); -} - -void mul_vector_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd) -{ - uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)H); - uint64_t index; - uint64_t rm_hi; - if ((((uint64_t)size == (uint64_t)1ULL))) - { - index = H; - index = ((uint64_t)L | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); - index = ((uint64_t)M | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); - rm_hi = 0ULL; - } - else if ((((uint64_t)size == (uint64_t)2ULL))) - { - index = H; - index = ((uint64_t)L | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); - rm_hi = M; - } - else - { - undefined_interpreter(ctx); - } - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,((uint64_t)Rm | (uint64_t)(((uint64_t)rm_hi << (uint64_t)4ULL)))); - uint128_t result = 0; - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t element2 = uint128_t::extract(operand2, index, esize); - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element1 = uint128_t::extract(operand1, e, esize); - uint64_t product = ((uint64_t)element1 * (uint64_t)element2); - uint128_t::insert(&result, e, esize, product); - } - V_interpreter(ctx,Rd,result); -} - -void mul_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element1 = uint128_t::extract(operand1, e, esize); - uint64_t element2 = uint128_t::extract(operand2, e, esize); - uint64_t working = ((uint64_t)element1 * (uint64_t)element2); - uint128_t::insert(&result, e, esize, working); - } - V_interpreter(ctx,Rd,result); -} - -void ext_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t imm4, uint64_t Rn, uint64_t Rd) -{ - uint128_t lo = V_interpreter(ctx,Rn); - uint128_t hi = V_interpreter(ctx,Rm); - uint64_t vector_size = ((uint64_t)8ULL << (uint64_t)Q); - uint64_t start = imm4; - uint128_t result = 0; - for (uint64_t e = 0; e < (vector_size); e++) - { - uint8_t working = get_from_concacted_vector_interpreter(ctx,hi,lo,((uint64_t)start + (uint64_t)e),vector_size,8ULL); - uint128_t::insert(&result, e, 8ULL, working); - } - V_interpreter(ctx,Rd,result); -} - -void compare_above_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - if (esize == 8ULL) - { - uint8_t element1 = uint128_t::extract(operand1, e, esize); - uint8_t element2 = uint128_t::extract(operand2, e, esize); - uint8_t working; - if ((U)) - { - working = ((uint8_t)element1 > (uint8_t)element2); - } - else - { - working = ((uint8_t)(sign_extend((uint8_t)element1) > sign_extend((uint8_t)element2))); - } - uint128_t::insert(&result, e, esize, (((uint8_t)0ULL - (uint8_t)working))); - } - if (esize == 16ULL) - { - uint16_t element1 = uint128_t::extract(operand1, e, esize); - uint16_t element2 = uint128_t::extract(operand2, e, esize); - uint16_t working; - if ((U)) - { - working = ((uint16_t)element1 > (uint16_t)element2); - } - else - { - working = ((uint16_t)(sign_extend((uint16_t)element1) > sign_extend((uint16_t)element2))); - } - uint128_t::insert(&result, e, esize, (((uint16_t)0ULL - (uint16_t)working))); - } - if (esize == 32ULL) - { - uint32_t element1 = uint128_t::extract(operand1, e, esize); - uint32_t element2 = uint128_t::extract(operand2, e, esize); - uint32_t working; - if ((U)) - { - working = ((uint32_t)element1 > (uint32_t)element2); - } - else - { - working = ((uint32_t)(sign_extend((uint32_t)element1) > sign_extend((uint32_t)element2))); - } - uint128_t::insert(&result, e, esize, (((uint32_t)0ULL - (uint32_t)working))); - } - if (esize == 64ULL) - { - uint64_t element1 = uint128_t::extract(operand1, e, esize); - uint64_t element2 = uint128_t::extract(operand2, e, esize); - uint64_t working; - if ((U)) - { - working = ((uint64_t)element1 > (uint64_t)element2); - } - else - { - working = ((uint64_t)(sign_extend((uint64_t)element1) > sign_extend((uint64_t)element2))); - } - uint128_t::insert(&result, e, esize, (((uint64_t)0ULL - (uint64_t)working))); - } - - } - V_interpreter(ctx,Rd,result); -} - -void shl_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element = uint128_t::extract(operand1, e, esize); - uint64_t shift = (uint64_t)sign_extend((uint8_t)(uint128_t::extract(operand2, e, esize))); - if ((!U)) - { - if (esize == 8ULL) - { - element = (uint64_t)sign_extend((uint8_t)element); - } - if (esize == 16ULL) - { - element = (uint64_t)sign_extend((uint16_t)element); - } - if (esize == 32ULL) - { - element = (uint64_t)sign_extend((uint32_t)element); - } - if (esize == 64ULL) - { - element = (uint64_t)sign_extend((uint64_t)element); - } - - } - if ((((uint64_t)(sign_extend((uint64_t)shift) >= sign_extend((uint64_t)0ULL))))) - { - element = shift_left_check_interpreter(ctx,element,shift,esize); - } - else - { - shift = -shift; - element = shift_right_check_interpreter(ctx,element,shift,esize,U); - } - uint128_t::insert(&result, e, esize, element); - } - V_interpreter(ctx,Rd,result); -} - -void add_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result; - if ((use_x86_sse2_interpreter(ctx))) - { - uint64_t add_instruction; - if ((((uint64_t)esize == (uint64_t)8ULL))) - add_instruction = (uint64_t)x86_paddb; - else if ((((uint64_t)esize == (uint64_t)16ULL))) - add_instruction = (uint64_t)x86_paddw; - else if ((((uint64_t)esize == (uint64_t)32ULL))) - add_instruction = (uint64_t)x86_paddd; - else if ((((uint64_t)esize == (uint64_t)64ULL))) - add_instruction = (uint64_t)x86_paddq; - else - undefined_interpreter(ctx); - result = intrinsic_binary_interpreter(ctx,add_instruction,operand1,operand2); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - uint128_t::insert(&result, 1ULL, 64ULL, (uint64_t)0ULL); - } - } - else - { - result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element1 = uint128_t::extract(operand1, e, esize); - uint64_t element2 = uint128_t::extract(operand2, e, esize); - uint128_t::insert(&result, e, esize, (((uint64_t)element1 + (uint64_t)element2))); - } - } - V_interpreter(ctx,Rd,result); -} - -void addlv_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t is_unsigned = U; - uint128_t source = V_interpreter(ctx,Rn); - uint128_t operand = V_interpreter(ctx,Rn); - uint64_t sum = 0ULL; - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t working = (uint128_t::extract(operand, e, esize)); - if ((!is_unsigned)) - { - if (esize == 8ULL) - { - working = (uint64_t)sign_extend((uint8_t)working); - } - if (esize == 16ULL) - { - working = (uint64_t)sign_extend((uint16_t)working); - } - if (esize == 32ULL) - { - working = (uint64_t)sign_extend((uint32_t)working); - } - if (esize == 64ULL) - { - working = (uint64_t)sign_extend((uint64_t)working); - } - - } - sum = ((uint64_t)sum + (uint64_t)working); - } - uint128_t final = 0; - uint128_t::insert(&final, 0ULL, (((uint64_t)2ULL * (uint64_t)esize)), sum); - V_interpreter(ctx,Rd,final); -} - -void cnt_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = 8ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)8ULL); - uint128_t source = V_interpreter(ctx,Rn); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint8_t working = uint128_t::extract(source, e, esize); - uint8_t count = 0ULL; - if ((use_x86_interpreter(ctx))) - { - count = intrinsic_unary_interpreter(ctx,(uint64_t)x86_popcnt,(uint16_t)working); - } - else - { - for (uint64_t b = 0; b < (esize); b++) - { - uint8_t bit = ((uint8_t)(((uint8_t)working >> (uint8_t)b)) & (uint8_t)1ULL); - if ((bit)) + ir_operation_block::jump_if(ctx->ir,yes, condition); + { + if ((is_signed)) { - count = (((uint8_t)count + (uint8_t)1ULL)); + uint64_t min = 9223372036854775808ULL; + if ((!sf)) + { + min = ((uint64_t)min >> (uint64_t)32ULL); + } + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, operand1, ir_operand::create_con(min, O)), ssa_emit_context::emit_ssa(ctx, ir_compare_equal, operand2, ir_operand::create_con(-1ULL, O))); + + ir_operation_block::jump_if(ctx->ir,yes, condition); + { + X_jit(ctx,Rd,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_divide_signed, operand1, operand2), int64)); + } + + ir_operation_block::jump(ctx->ir,end); + ir_operation_block::mark_label(ctx->ir, yes); + + { + X_jit(ctx,Rd,ir_operand::create_con(min, int64)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + } + else + { + X_jit(ctx,Rd,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_divide_unsigned, operand1, operand2), int64)); + } + } + + ir_operation_block::jump(ctx->ir,end); + ir_operation_block::mark_label(ctx->ir, yes); + + { + X_jit(ctx,Rd,ir_operand::create_con(0ULL, int64)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + } +} + +uint64_t create_rbit_mask_jit(ssa_emit_context* ctx, uint64_t index) +{ + index = ((uint64_t)1ULL << (uint64_t)index); + uint64_t mask = ((uint64_t)(((uint64_t)(((uint64_t)1ULL << (uint64_t)index)) - (uint64_t)1ULL)) << (uint64_t)index); + mask = replicate_c_jit(ctx,mask,((uint64_t)index * (uint64_t)2ULL),((uint64_t)((uint64_t)64ULL / (uint64_t)index) / (uint64_t)2ULL)); + return mask; +} + +void rbit_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand operand = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand result = operand; + uint64_t max = ((uint64_t)5ULL + (uint64_t)sf); + for (uint64_t i = 0; i < (max); i++) + { + uint64_t n_mask = create_rbit_mask_jit(ctx,i); + uint64_t i_mask = ~n_mask; + uint64_t shift = ((uint64_t)1ULL << (uint64_t)i); + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, result, ir_operand::create_con(n_mask, O)), ir_operand::create_con(shift, O)), ssa_emit_context::emit_ssa(ctx, ir_shift_left, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, result, ir_operand::create_con(i_mask, O)), ir_operand::create_con(shift, O))); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void rev16_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd) +{ + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + uint64_t count = ((uint64_t)2ULL << (uint64_t)sf); + ir_operand working = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand result = ir_operand::create_con(0ULL, O); + for (uint64_t i = 0; i < (count); i++) + { + ir_operand part = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, working, ir_operand::create_con((((uint64_t)i * (uint64_t)16ULL)), O)), ir_operand::create_con(65535ULL, O)); + part = copy_new_raw_size(ctx, reverse_bytes_jit(ctx,O,part,2ULL), O); + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, result, ssa_emit_context::emit_ssa(ctx, ir_shift_left, part, ir_operand::create_con((((uint64_t)i * (uint64_t)16ULL)), O))); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void reverse_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand working = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand result; + if ((((uint64_t)sf == (uint64_t)opc))) + { + result = copy_new_raw_size(ctx, reverse_bytes_jit(ctx,O,working,((uint64_t)4ULL << (uint64_t)sf)), O); + } + else + { + result = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, reverse_bytes_jit(ctx,O,working,4ULL), ssa_emit_context::emit_ssa(ctx, ir_shift_left, reverse_bytes_jit(ctx,O,ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, working, ir_operand::create_con(32ULL, O)),4ULL), ir_operand::create_con(32ULL, O))), O); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void count_leading_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t s, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand operand = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand result = ssa_emit_context::emit_ssa(ctx, ir_move, ir_operand::create_con(0ULL, O)); + ir_operand done = ssa_emit_context::emit_ssa(ctx, ir_move, ir_operand::create_con(0ULL, O)); + ir_operand sig_bit; + if ((s)) + { + sig_bit = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand, ir_operand::create_con((((uint64_t)datasize - (uint64_t)1ULL)), O)), ir_operand::create_con(1ULL, O)); + datasize = ((uint64_t)datasize - (uint64_t)1ULL); + } + if ((use_x86_lzcnt_jit(ctx))) + { + if ((s)) + { + ir_operand nhigh = ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand, ir_operand::create_con(1ULL, O)); + ir_operand mask = ir_operand::create_con(-1ULL, O); + mask = ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, mask, ir_operand::create_con(1ULL, O)); + ir_operand nlow = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand, mask); + result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,O,(uint64_t)x86_lzcnt,ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, nhigh, nlow)), O); + result = ssa_emit_context::emit_ssa(ctx, ir_subtract, result, ir_operand::create_con(1ULL, O)); + } + else + { + result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,O,(uint64_t)x86_lzcnt,operand), O); + } + } + else + { + for (uint64_t i = 0; i < (datasize); i++) + { + ir_operand working = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand, ir_operand::create_con((((uint64_t)((uint64_t)datasize - (uint64_t)i) - (uint64_t)1ULL)), O)), ir_operand::create_con(1ULL, O)); + if ((s)) + { + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_not_equal, working, sig_bit); + + condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); + + ir_operation_block::jump_if(ctx->ir,end, condition); + + { + ssa_emit_context::move(ctx,done,ir_operand::create_con(1ULL, O)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + } + else { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = working; + + condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); + + ir_operation_block::jump_if(ctx->ir,end, condition); + + { + ssa_emit_context::move(ctx,done,ir_operand::create_con(1ULL, O)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_logical_not, done); + + condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); + + ir_operation_block::jump_if(ctx->ir,end, condition); + + { + ssa_emit_context::move(ctx,result,ssa_emit_context::emit_ssa(ctx, ir_add, result, ir_operand::create_con(1ULL, O))); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + } + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void extr_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t N, uint64_t Rm, uint64_t imms, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); + uint64_t lsb = imms; + ir_operand result; + if ((((uint64_t)lsb == (uint64_t)0ULL))) + { + result = operand2; + } + else if ((((uint64_t)Rn == (uint64_t)Rm))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_rotate_right, operand1, ir_operand::create_con(lsb, O)); + } + else + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand2, ir_operand::create_con(lsb, O)), ssa_emit_context::emit_ssa(ctx, ir_shift_left, operand1, ir_operand::create_con((((uint64_t)datasize - (uint64_t)lsb)), O))); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void bitfield_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t tmask = decode_bitmask_tmask_jit(ctx,N,imms,immr,0ULL,datasize,1ULL); + uint64_t wmask = decode_bitmask_tmask_jit(ctx,N,imms,immr,0ULL,datasize,0ULL); + uint64_t inzero; + uint64_t _extend; + if ((((uint64_t)opc == (uint64_t)0ULL))) + { + inzero = 1ULL; + _extend = 1ULL; + } + else if ((((uint64_t)opc == (uint64_t)1ULL))) + { + inzero = 0ULL; + _extend = 0ULL; + } + else if ((((uint64_t)opc == (uint64_t)2ULL))) + { + inzero = 1ULL; + _extend = 0ULL; + } + else + { + undefined_jit(ctx); + } + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand dst; + ir_operand src = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + if ((inzero)) + { + dst = ir_operand::create_con(0ULL, O); + } + else + { + dst = copy_new_raw_size(ctx, X_jit(ctx,Rd), O); + } + ir_operand bot = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, dst, ir_operand::create_con(~wmask, O)), ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_rotate_right, src, ir_operand::create_con(immr, O)), ir_operand::create_con(wmask, O))); + ir_operand top; + if ((_extend)) + { + top = ssa_emit_context::emit_ssa(ctx, ir_subtract, ir_operand::create_con(0ULL, O), ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, src, ir_operand::create_con(imms, O)), ir_operand::create_con(1ULL, O))); + } + else + { + top = dst; + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, top, ir_operand::create_con(~tmask, O)), ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, bot, ir_operand::create_con(tmask, O))), int64)); + } +} + +void logical_immediate_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd) +{ + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = ir_operand::create_con(decode_bitmask_tmask_jit(ctx,N,imms,immr,1ULL,datasize,0ULL), O); + ir_operand result; + if ((((uint64_t)opc == (uint64_t)0ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand1, operand2); + } + else if ((((uint64_t)opc == (uint64_t)1ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, operand1, operand2); + } + else if ((((uint64_t)opc == (uint64_t)2ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, operand1, operand2); + } + else if ((((uint64_t)opc == (uint64_t)3ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand1, operand2); + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + _sys_jit(ctx,(uint64_t)nzcv_n,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_less_signed, result, ir_operand::create_con(0ULL, O)), int64)); + _sys_jit(ctx,(uint64_t)nzcv_z,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, result, ir_operand::create_con(0ULL, O)), int64)); + _sys_jit(ctx,(uint64_t)nzcv_c,ir_operand::create_con(0ULL, int64)); + _sys_jit(ctx,(uint64_t)nzcv_v,ir_operand::create_con(0ULL, int64)); + return; + } + XSP_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void logical_shifted_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t shift, uint64_t N, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd) +{ + uint64_t shift_type = shift; + uint64_t shift_ammount = imm6; + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, a_shift_reg_jit(ctx,O,Rm,shift_type,shift_ammount), O); + if ((N)) + { + operand2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, operand2); + } + ir_operand result; + if ((((uint64_t)((uint64_t)opc == (uint64_t)0ULL) || (uint64_t)((uint64_t)opc == (uint64_t)3ULL)))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand1, operand2); + if ((((uint64_t)opc == (uint64_t)3ULL))) + { + _sys_jit(ctx,(uint64_t)nzcv_n,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_less_signed, result, ir_operand::create_con(0ULL, O)), int64)); + _sys_jit(ctx,(uint64_t)nzcv_z,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, result, ir_operand::create_con(0ULL, O)), int64)); + _sys_jit(ctx,(uint64_t)nzcv_c,ir_operand::create_con(0ULL, int64)); + _sys_jit(ctx,(uint64_t)nzcv_v,ir_operand::create_con(0ULL, int64)); + } + } + else if ((((uint64_t)opc == (uint64_t)1ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, operand1, operand2); + } + else if ((((uint64_t)opc == (uint64_t)2ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, operand1, operand2); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void conditional_select_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t cond, uint64_t op2, uint64_t Rn, uint64_t Rd) +{ + uint64_t incrament = op2; + uint64_t invert = op; + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); + ir_operand condition_pass = copy_new_raw_size(ctx, condition_holds_jit(ctx,cond), O); + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = condition_pass; + + ir_operation_block::jump_if(ctx->ir,yes, condition); + { + if ((invert)) + { + operand2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, operand2); + } + if ((incrament)) + { + operand2 = ssa_emit_context::emit_ssa(ctx, ir_add, operand2, ir_operand::create_con(1ULL, O)); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, operand2, int64)); + } + + ir_operation_block::jump(ctx->ir,end); + ir_operation_block::mark_label(ctx->ir, yes); + + { + X_jit(ctx,Rd,copy_new_raw_size(ctx, operand1, int64)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + } +} + +void conditional_compare_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t Rm, uint64_t cond, uint64_t mode, uint64_t Rn, uint64_t nzcv) +{ + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = condition_holds_jit(ctx,cond); + + ir_operation_block::jump_if(ctx->ir,yes, condition); + { + _sys_jit(ctx,(uint64_t)nzcv_n,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL), int64)); + _sys_jit(ctx,(uint64_t)nzcv_z,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL), int64)); + _sys_jit(ctx,(uint64_t)nzcv_c,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL), int64)); + _sys_jit(ctx,(uint64_t)nzcv_v,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL), int64)); + } + + ir_operation_block::jump(ctx->ir,end); + ir_operation_block::mark_label(ctx->ir, yes); + + { + ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); + ir_operand operand2; + if ((mode)) + { + operand2 = ir_operand::create_con(Rm, O); + } + else + { + operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); + } + add_subtract_impl_jit(ctx,O,operand1,operand2,1ULL,((uint64_t)op == (uint64_t)0ULL)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + } +} + +void move_wide_immediate_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t hw, uint64_t imm16, uint64_t Rd) +{ + uint64_t shift = ((uint64_t)hw * (uint64_t)16ULL); + uint64_t immediate = ((uint64_t)imm16 << (uint64_t)shift); + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + ir_operand result; + if ((((uint64_t)opc == (uint64_t)0ULL))) + { + result = ir_operand::create_con(~immediate, O); + } + else if ((((uint64_t)opc == (uint64_t)3ULL))) + { + result = copy_new_raw_size(ctx, X_jit(ctx,Rd), O); + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, result, ir_operand::create_con(~(((uint64_t)65535ULL << (uint64_t)shift)), O)); + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, result, ir_operand::create_con(immediate, O)); + } + else + { + result = ir_operand::create_con(immediate, O); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } +} + +void pc_rel_addressing_jit(ssa_emit_context* ctx, uint64_t op, uint64_t immlo, uint64_t immhi, uint64_t Rd) +{ + uint64_t offset = sign_extend_jit(ctx,((uint64_t)(((uint64_t)immhi << (uint64_t)2ULL)) | (uint64_t)immlo),21ULL); + uint64_t instruction_pc = _get_pc_jit(ctx); + if ((op)) + { + offset = ((uint64_t)offset << (uint64_t)12ULL); + instruction_pc = ((uint64_t)instruction_pc & (uint64_t)~4095ULL); + } + X_jit(ctx,Rd,ir_operand::create_con(((uint64_t)instruction_pc + (uint64_t)offset), int64)); +} + +void branch_register_jit(ssa_emit_context* ctx, uint64_t l, uint64_t Rn) +{ + branch_long_universal_jit(ctx,Rn,l); +} + +void return_register_jit(ssa_emit_context* ctx, uint64_t Rn) +{ + _return_from_call_jit(ctx,X_jit(ctx,Rn)); +} + +void test_bit_branch_jit(ssa_emit_context* ctx, uint64_t b5, uint64_t op, uint64_t b40, uint64_t imm14, uint64_t Rt) +{ + uint64_t bit_pos = ((uint64_t)b40 + (uint64_t)(((uint64_t)b5 << (uint64_t)5ULL))); + uint64_t new_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)(((uint64_t)sign_extend_jit(ctx,imm14,14ULL) << (uint64_t)2ULL))); + uint64_t next_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)4ULL); + ir_operand src = X_jit(ctx,Rt); + ir_operand branch_pass = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, src, ir_operand::create_con(bit_pos, int64)), ir_operand::create_con(1ULL, int64)), ir_operand::create_con(op, int64)), int8); + _branch_conditional_jit(ctx,new_location,next_location,copy_new_raw_size(ctx, branch_pass, int64)); +} + +void compare_and_branch_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t imm19, uint64_t Rt) +{ + uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + { + uint64_t new_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)(((uint64_t)sign_extend_jit(ctx,imm19,19ULL) << (uint64_t)2ULL))); + uint64_t next_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)4ULL); + ir_operand operand = copy_new_raw_size(ctx, X_jit(ctx,Rt), O); + ir_operand branch_pass; + if ((!op)) + { + branch_pass = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, operand, ir_operand::create_con(0ULL, O)), int8); + } + else + { + branch_pass = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_not_equal, operand, ir_operand::create_con(0ULL, O)), int8); + } + _branch_conditional_jit(ctx,new_location,next_location,copy_new_raw_size(ctx, branch_pass, int64)); + } +} + +void b_unconditional_jit(ssa_emit_context* ctx, uint64_t op, uint64_t imm26) +{ + uint64_t new_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)(((uint64_t)sign_extend_jit(ctx,imm26,26ULL) << (uint64_t)2ULL))); + if ((op)) + { + uint64_t next_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)4ULL); + X_jit(ctx,30ULL,ir_operand::create_con(next_location, int64)); + _branch_call_jit(ctx,ir_operand::create_con(new_location, int64)); + } + else + { + _branch_short_jit(ctx,new_location); + } +} + +void b_conditional_jit(ssa_emit_context* ctx, uint64_t imm19, uint64_t cond) +{ + uint64_t new_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)(((uint64_t)sign_extend_jit(ctx,imm19,19ULL) << (uint64_t)2ULL))); + uint64_t next_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)4ULL); + _branch_conditional_jit(ctx,new_location,next_location,copy_new_raw_size(ctx, condition_holds_jit(ctx,cond), int64)); +} + +void svc_jit(ssa_emit_context* ctx, uint64_t imm16) +{ + call_supervisor_jit(ctx,imm16); +} + +void msr_register_jit(ssa_emit_context* ctx, uint64_t imm15, uint64_t Rt) +{ + ir_operand operand = X_jit(ctx,Rt); + if ((((uint64_t)imm15 == (uint64_t)23072ULL))) + { + _sys_jit(ctx,(uint64_t)fpcr,operand); + } + else if ((((uint64_t)imm15 == (uint64_t)23073ULL))) + { + _sys_jit(ctx,(uint64_t)fpsr,operand); + } + else if ((((uint64_t)imm15 == (uint64_t)24194ULL))) + { + _sys_jit(ctx,(uint64_t)thread_local_1,operand); + } + else if ((((uint64_t)imm15 == (uint64_t)24195ULL))) + { + _sys_jit(ctx,(uint64_t)thread_local_0,operand); + } + else + { + undefined_with_jit(ctx,imm15); + } +} + +void mrs_register_jit(ssa_emit_context* ctx, uint64_t imm15, uint64_t Rt) +{ + ir_operand operand; + if ((((uint64_t)imm15 == (uint64_t)23072ULL))) + { + operand = _sys_jit(ctx,(uint64_t)fpcr); + } + else if ((((uint64_t)imm15 == (uint64_t)23073ULL))) + { + operand = _sys_jit(ctx,(uint64_t)fpsr); + } + else if ((((uint64_t)imm15 == (uint64_t)24194ULL))) + { + operand = _sys_jit(ctx,(uint64_t)thread_local_1); + } + else if ((((uint64_t)imm15 == (uint64_t)24195ULL))) + { + operand = _sys_jit(ctx,(uint64_t)thread_local_0); + } + else if ((((uint64_t)imm15 == (uint64_t)24321ULL))) + { + operand = call_counter_jit(ctx); + } + else if ((((uint64_t)imm15 == (uint64_t)22529ULL))) + { + operand = ir_operand::create_con(2219098116ULL, int64); + } + else + { + undefined_with_jit(ctx,imm15); + } + X_jit(ctx,Rt,operand); +} + +void hints_jit(ssa_emit_context* ctx, uint64_t imm7) +{ +} + +void sys_jit(ssa_emit_context* ctx, uint64_t L, uint64_t imm19) +{ +} + +void barriers_jit(ssa_emit_context* ctx, uint64_t CRm, uint64_t op2, uint64_t Rt) +{ + if ((((uint64_t)((uint64_t)op2 == (uint64_t)2ULL) && (uint64_t)((uint64_t)Rt == (uint64_t)31ULL)))) + { + _sys_jit(ctx,(uint64_t)exclusive_address,ir_operand::create_con(-1ULL, int64)); + _sys_jit(ctx,(uint64_t)exclusive_value,ir_operand::create_con(-1ULL, int64)); + } +} + +void load_store_register_post_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) +{ + load_store_register_imm_unscaled_jit(ctx,size,VR,opc,imm9,1ULL,Rn,Rt); +} + +void load_store_register_pre_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) +{ + load_store_register_imm_unscaled_jit(ctx,size,VR,opc,imm9,3ULL,Rn,Rt); +} + +void load_store_register_unscaled_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) +{ + load_store_register_imm_unscaled_jit(ctx,size,VR,opc,imm9,0ULL,Rn,Rt); +} + +void load_store_register_pair_imm_offset_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) +{ + load_store_register_pair_imm_jit(ctx,opc,VR,2ULL,L,imm7,Rt2,Rn,Rt); +} + +void load_store_register_pair_imm_post_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) +{ + load_store_register_pair_imm_jit(ctx,opc,VR,1ULL,L,imm7,Rt2,Rn,Rt); +} + +void load_store_register_pair_imm_pre_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) +{ + load_store_register_pair_imm_jit(ctx,opc,VR,3ULL,L,imm7,Rt2,Rn,Rt); +} + +void load_store_register_pair_imm_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t wb, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) +{ + uint64_t wback = ((uint64_t)wb != (uint64_t)2ULL); + uint64_t postindex = ((uint64_t)wb == (uint64_t)1ULL); + uint64_t memop = !L; + uint64_t is_signed = (((uint64_t)opc & (uint64_t)1ULL)); + uint64_t scale; + if ((VR)) + { + scale = ((uint64_t)2ULL + (uint64_t)opc); + } + else + { + scale = ((uint64_t)2ULL + (uint64_t)(((uint64_t)(((uint64_t)opc >> (uint64_t)1ULL)) & (uint64_t)1ULL))); + } + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + uint64_t offset = ((uint64_t)sign_extend_jit(ctx,imm7,7ULL) << (uint64_t)scale); + uint64_t dbytes = ((uint64_t)datasize / (uint64_t)8ULL); + ir_operand address = XSP_jit(ctx,Rn); + if ((!postindex)) + { + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + { + uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : datasize == 128ULL ? int128 : 0; + { + if ((VR)) + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + ir_operand d0 = copy_new_raw_size(ctx, mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(0ULL, int64))), S); + ir_operand d1 = copy_new_raw_size(ctx, mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(dbytes, int64))), S); + V_jit(ctx,Rt,copy_new_raw_size(ctx, d0, int128)); + V_jit(ctx,Rt2,copy_new_raw_size(ctx, d1, int128)); + } + else + { + mem_jit(ctx,S,address,copy_new_raw_size(ctx, V_jit(ctx,Rt), S)); + mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(dbytes, int64)),copy_new_raw_size(ctx, V_jit(ctx,Rt2), S)); + } + } + else + { + if ((((uint64_t)memop == (uint64_t)0ULL))) + { + ir_operand d0 = copy_new_raw_size(ctx, mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(0ULL, int64))), int64); + ir_operand d1 = copy_new_raw_size(ctx, mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(dbytes, int64))), int64); + if ((is_signed)) + { + d0 = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, d0, int32), int64); + d1 = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, d1, int32), int64); + } + X_jit(ctx,Rt,d0); + X_jit(ctx,Rt2,d1); + } + else + { + mem_jit(ctx,S,address,copy_new_raw_size(ctx, X_jit(ctx,Rt), S)); + mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(dbytes, int64)),copy_new_raw_size(ctx, X_jit(ctx,Rt2), S)); } } } - uint128_t::insert(&result, e, esize, count); } - V_interpreter(ctx,Rd,result); + if ((wback)) + { + if ((postindex)) + { + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + XSP_jit(ctx,Rn,address); + } } -void orr_orn_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd) +void load_store_register_imm_unsigned_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm12, uint64_t Rn, uint64_t Rt) { - if ((use_x86_sse_interpreter(ctx))) + if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) { - x86_sse_logic_vector_interpreter(ctx,Rd,Rn,Rm,Q,invert,(uint64_t)x86_orps); + return; } - else + uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); + uint64_t wback = 0ULL; + uint64_t postindex = 0ULL; + if ((is_vector)) { - uint64_t esize = 64ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = ((uint64_t)(((uint64_t)bit_c_jit(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); + uint64_t offset = ((uint64_t)imm12 << (uint64_t)scale); + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + ir_operand address = XSP_jit(ctx,Rn); + if ((!postindex)) { - uint64_t element1 = uint128_t::extract(operand1, e, esize); - uint64_t element2 = uint128_t::extract(operand2, e, esize); - if ((invert)) + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + { + uint64_t O = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : datasize == 128ULL ? int128 : 0; { - element2 = ~element2; + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + ir_operand data = copy_new_raw_size(ctx, V_jit(ctx,Rt), O); + mem_jit(ctx,O,address,data); + } + else + { + ir_operand data = copy_new_raw_size(ctx, mem_jit(ctx,O,address), O); + V_jit(ctx,Rt,copy_new_raw_size(ctx, data, int128)); + } } - uint128_t::insert(&result, e, esize, (((uint64_t)element1 | (uint64_t)element2))); } - V_interpreter(ctx,Rd,result); - } -} - -void bsl_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = 64ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand1 = V_interpreter(ctx,Rm); - uint128_t operand2 = V_interpreter(ctx,Rd); - uint128_t operand3 = V_interpreter(ctx,Rn); - if ((use_x86_sse_interpreter(ctx))) - { - uint128_t xor_result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand1,operand3); - uint128_t and_result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_pand,xor_result,operand2); - uint128_t final_result = intrinsic_binary_interpreter(ctx,(uint64_t)x86_xorps,operand1,and_result); - if ((((uint64_t)Q == (uint64_t)0ULL))) + if ((wback)) { - uint128_t::insert(&final_result, 1ULL, 64ULL, (uint64_t)0ULL); + if ((postindex)) + { + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + XSP_jit(ctx,Rn,address); } - V_interpreter(ctx,Rd,final_result); } else { - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = size; + uint64_t offset = ((uint64_t)imm12 << (uint64_t)scale); + if ((((uint64_t)bit_c_jit(ctx,opc,1ULL) == (uint64_t)0ULL))) { - uint64_t element1 = uint128_t::extract(operand1, e, esize); - uint64_t element2 = uint128_t::extract(operand2, e, esize); - uint64_t element3 = uint128_t::extract(operand3, e, esize); - uint128_t::insert(&result, e, esize, (((uint64_t)element1 ^ (uint64_t)(((uint64_t)(((uint64_t)element1 ^ (uint64_t)element3)) & (uint64_t)element2))))); - } - V_interpreter(ctx,Rd,result); - } -} - -void and_bic_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((use_x86_sse2_interpreter(ctx))) - { - if ((invert)) - { - x86_sse_logic_vector_interpreter(ctx,Rd,Rm,Rn,Q,0ULL,(uint64_t)x86_pandn); + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + if ((((uint64_t)size == (uint64_t)3ULL))) + regsize = 64ULL; + else + regsize = 32ULL; + _signed = 0ULL; } else { - x86_sse_logic_vector_interpreter(ctx,Rd,Rn,Rm,Q,0ULL,(uint64_t)x86_pand); - } - } - else - { - uint64_t esize = 64ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t element1 = uint128_t::extract(operand1, e, esize); - uint64_t element2 = uint128_t::extract(operand2, e, esize); - if ((invert)) + if ((((uint64_t)size == (uint64_t)3ULL))) { - element2 = ~element2; + undefined_jit(ctx); + } + else + { + memop = 0ULL; + if ((((uint64_t)opc & (uint64_t)1ULL))) + regsize = 32ULL; + else + regsize = 64ULL; + _signed = 1ULL; } - uint128_t::insert(&result, e, esize, (((uint64_t)element1 & (uint64_t)element2))); } - V_interpreter(ctx,Rd,result); - } -} - -void eor_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((use_x86_sse_interpreter(ctx))) - { - x86_sse_logic_vector_interpreter(ctx,Rd,Rn,Rm,Q,0ULL,(uint64_t)x86_xorps); - } - else - { - uint64_t esize = 64ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - for (uint64_t e = 0; e < (elements); e++) + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + ir_operand address = XSP_jit(ctx,Rn); + if ((!postindex)) { - uint64_t element1 = uint128_t::extract(operand1, e, esize); - uint64_t element2 = uint128_t::extract(operand2, e, esize); - uint128_t::insert(&result, e, esize, (((uint64_t)element1 ^ (uint64_t)element2))); + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + { + uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; + { + uint64_t R = regsize == 32ULL ? int32 : regsize == 64ULL ? int64 : 0; + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + ir_operand data = X_jit(ctx,Rt); + mem_jit(ctx,S,address,copy_new_raw_size(ctx, data, S)); + } + else + { + ir_operand n = copy_new_raw_size(ctx, mem_jit(ctx,S,address), int64); + if ((_signed)) + { + n = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, n, S), R), int64); + } + X_jit(ctx,Rt,n); + } + } + } + } + if ((wback)) + { + if ((postindex)) + { + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + XSP_jit(ctx,Rn,address); } - V_interpreter(ctx,Rd,result); } } -void xnt_xnt2_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +void load_store_register_imm_unscaled_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t wb, uint64_t Rn, uint64_t Rt) { - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = 64ULL; - uint64_t part = Q; - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint128_t operand = V_interpreter(ctx,Rn); - uint128_t result = 0; - uint64_t mask = -1ULL; - if ((((uint64_t)esize != (uint64_t)64ULL))) + if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) { - mask = ((uint64_t)(((uint64_t)1ULL << (uint64_t)esize)) - (uint64_t)1ULL); + return; } - for (uint64_t e = 0; e < (elements); e++) + uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); + uint64_t wback = ((uint64_t)wb != (uint64_t)0ULL); + uint64_t postindex = ((uint64_t)wb == (uint64_t)1ULL); + uint64_t offset = sign_extend_jit(ctx,imm9,9ULL); + if ((is_vector)) { - uint64_t element = uint128_t::extract(operand, e, (((uint64_t)2ULL * (uint64_t)esize))); - uint128_t::insert(&result, e, esize, (((uint64_t)element & (uint64_t)mask))); - } - VPart_interpreter(ctx,Rd,part,datasize,(uint64_t)result); -} - -void zip_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t part = op; - uint64_t pairs = ((uint64_t)elements / (uint64_t)2ULL); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - uint64_t base = ((uint64_t)part * (uint64_t)pairs); - for (uint64_t p = 0; p < (pairs); p++) - { - uint128_t::insert(&result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)0ULL)), esize, (uint128_t::extract(operand1, (((uint64_t)base + (uint64_t)p)), esize))); - uint128_t::insert(&result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)1ULL)), esize, (uint128_t::extract(operand2, (((uint64_t)base + (uint64_t)p)), esize))); - } - V_interpreter(ctx,Rd,result); -} - -void trn_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t part = op; - uint64_t pairs = ((uint64_t)elements / (uint64_t)2ULL); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - for (uint64_t p = 0; p < (pairs); p++) - { - uint128_t::insert(&result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)0ULL)), esize, (uint128_t::extract(operand1, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)part)), esize))); - uint128_t::insert(&result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)1ULL)), esize, (uint128_t::extract(operand2, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)part)), esize))); - } - V_interpreter(ctx,Rd,result); -} - -void tbl_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t len, uint64_t Rn, uint64_t Rd) -{ - store_context_interpreter(ctx); - uint64_t vector_context = get_vector_context_interpreter(ctx); - call_interpreter(ctx,vector_context,(uint64_t)Rd,(uint64_t)Rn,(uint64_t)len,(uint64_t)Rm,(uint64_t)Q,(uint64_t)table_lookup_fallback); - load_context_interpreter(ctx); -} - -void ld4_st4_multiple_structures_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t L, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_4_interpreter(ctx,Q,L,size,-1ULL,Rn,Rt); -} - -void ld4_st4_multiple_structures_post_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t L, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_4_interpreter(ctx,Q,L,size,Rm,Rn,Rt); -} - -void ld1r_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_interpreter(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,6ULL,0ULL,size,Rn,Rt,1ULL); -} - -void ld1r_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_interpreter(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,6ULL,0ULL,size,Rn,Rt,1ULL); -} - -void ld1_single_structure_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_interpreter(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,1ULL); -} - -void ld1_single_structure_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_interpreter(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,1ULL); -} - -void st1_multiple_structures_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - uint64_t opcode = ophi; - opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)1ULL); - opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)oplo); - st1_interpreter(ctx,0ULL,Q,0ULL,opcode,size,0ULL,Rn,Rt); -} - -void st1_multiple_structures_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - uint64_t opcode = ophi; - opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)1ULL); - opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)oplo); - st1_interpreter(ctx,1ULL,Q,0ULL,opcode,size,Rm,Rn,Rt); -} - -void st2_multiple_structures_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - st_interpreter(ctx,0ULL,Q,0ULL,4ULL,size,0ULL,Rn,Rt); -} - -void st2_multiple_structures_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - st_interpreter(ctx,1ULL,Q,0ULL,4ULL,size,Rm,Rn,Rt); -} - -void st1_single_structure_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_interpreter(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,0ULL); -} - -void st1_single_structure_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_interpreter(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,0ULL); -} - -void floating_point_conditional_select_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd) -{ - uint64_t fltsize = get_flt_size_interpreter(ctx,ftype); - uint128_t operand1 = V_interpreter(ctx,Rn); - uint128_t operand2 = V_interpreter(ctx,Rm); - uint128_t result = 0; - if ((condition_holds_interpreter(ctx,cond))) - { - result = operand1; + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = ((uint64_t)(((uint64_t)bit_c_jit(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + ir_operand address = XSP_jit(ctx,Rn); + if ((!postindex)) + { + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + { + uint64_t O = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : datasize == 128ULL ? int128 : 0; + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + ir_operand data = copy_new_raw_size(ctx, V_jit(ctx,Rt), O); + mem_jit(ctx,O,address,data); + } + else + { + ir_operand data = copy_new_raw_size(ctx, mem_jit(ctx,O,address), O); + V_jit(ctx,Rt,copy_new_raw_size(ctx, data, int128)); + } + } + } + if ((wback)) + { + if ((postindex)) + { + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + XSP_jit(ctx,Rn,address); + } } else { - result = operand2; + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = size; + if ((((uint64_t)bit_c_jit(ctx,opc,1ULL) == (uint64_t)0ULL))) + { + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + if ((((uint64_t)size == (uint64_t)3ULL))) + regsize = 64ULL; + else + regsize = 32ULL; + _signed = 0ULL; + } + else + { + if ((((uint64_t)size == (uint64_t)3ULL))) + { + undefined_jit(ctx); + } + else + { + memop = 0ULL; + if ((((uint64_t)opc & (uint64_t)1ULL))) + regsize = 32ULL; + else + regsize = 64ULL; + _signed = 1ULL; + } + } + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + ir_operand address = XSP_jit(ctx,Rn); + if ((!postindex)) + { + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + { + uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; + { + uint64_t R = regsize == 32ULL ? int32 : regsize == 64ULL ? int64 : 0; + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + ir_operand data = X_jit(ctx,Rt); + mem_jit(ctx,S,address,copy_new_raw_size(ctx, data, S)); + } + else + { + ir_operand n = copy_new_raw_size(ctx, mem_jit(ctx,S,address), int64); + if ((_signed)) + { + n = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, n, S), R), int64); + } + X_jit(ctx,Rt,n); + } + } + } + } + if ((wback)) + { + if ((postindex)) + { + address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); + } + XSP_jit(ctx,Rn,address); + } } - result = clear_vector_scalar_interpreter(ctx,result,fltsize); - V_interpreter(ctx,Rd,result); } -void fcmp_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t opc) +void load_store_register_offset_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t Rm, uint64_t option, uint64_t S, uint64_t Rn, uint64_t Rt) { - uint64_t datasize = get_flt_size_interpreter(ctx,ftype); - uint64_t cmp_with_zero = ((uint64_t)opc == (uint64_t)1ULL); - uint64_t operand1 = V_interpreter(ctx,Rn); - uint64_t operand2; - uint64_t fpcr_state = _sys_interpreter(ctx,(uint64_t)fpcr); - if ((cmp_with_zero)) + if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) { - operand2 = 0ULL; + return; + } + uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); + uint64_t wback = 0ULL; + uint64_t postindex = 0ULL; + if ((is_vector)) + { + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = ((uint64_t)(((uint64_t)bit_c_jit(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); + uint64_t shift = ((uint64_t)scale * (uint64_t)S); + ir_operand offset = a_extend_reg_64_jit(ctx,Rm,option,shift); + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + ir_operand address = ssa_emit_context::emit_ssa(ctx, ir_add, XSP_jit(ctx,Rn), offset); + uint64_t O = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : datasize == 128ULL ? int128 : 0; + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + ir_operand data = copy_new_raw_size(ctx, V_jit(ctx,Rt), O); + mem_jit(ctx,O,address,data); + } + else + { + ir_operand data = copy_new_raw_size(ctx, mem_jit(ctx,O,address), O); + V_jit(ctx,Rt,copy_new_raw_size(ctx, data, int128)); + } + } } else { - operand2 = V_interpreter(ctx,Rm); + uint64_t memop; + uint64_t regsize; + uint64_t _signed; + uint64_t scale = size; + uint64_t shift = ((uint64_t)scale * (uint64_t)S); + ir_operand offset = a_extend_reg_64_jit(ctx,Rm,option,shift); + if ((((uint64_t)bit_c_jit(ctx,opc,1ULL) == (uint64_t)0ULL))) + { + if ((((uint64_t)opc & (uint64_t)1ULL))) + memop = 0ULL; + else + memop = 1ULL; + if ((((uint64_t)size == (uint64_t)3ULL))) + regsize = 64ULL; + else + regsize = 32ULL; + _signed = 0ULL; + } + else + { + if ((((uint64_t)size == (uint64_t)3ULL))) + { + undefined_jit(ctx); + } + else + { + memop = 0ULL; + if ((((uint64_t)opc & (uint64_t)1ULL))) + regsize = 32ULL; + else + regsize = 64ULL; + _signed = 1ULL; + } + } + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); + ir_operand address = ssa_emit_context::emit_ssa(ctx, ir_add, XSP_jit(ctx,Rn), offset); + uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; + { + uint64_t R = regsize == 32ULL ? int32 : regsize == 64ULL ? int64 : 0; + { + if ((((uint64_t)memop == (uint64_t)1ULL))) + { + ir_operand data = X_jit(ctx,Rt); + mem_jit(ctx,S,address,copy_new_raw_size(ctx, data, S)); + } + else + { + ir_operand n = copy_new_raw_size(ctx, mem_jit(ctx,S,address), int64); + if ((_signed)) + { + n = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, n, S), R), int64); + } + X_jit(ctx,Rt,n); + } + } + } } - uint64_t nzcv = FPCompare_interpreter(ctx,operand1,operand2,fpcr_state,datasize); - _sys_interpreter(ctx,(uint64_t)nzcv_n,((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_z,((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_v,((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); } -void fccmp_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t nzcv) +void load_store_exclusive_ordered_jit(ssa_emit_context* ctx, uint64_t size, uint64_t ordered, uint64_t L, uint64_t Rs, uint64_t o0, uint64_t Rn, uint64_t Rt) { - uint64_t datasize = get_flt_size_interpreter(ctx,ftype); - uint64_t operand1 = V_interpreter(ctx,Rn); - uint64_t operand2 = V_interpreter(ctx,Rm); - uint64_t fpcr_state = _sys_interpreter(ctx,(uint64_t)fpcr); - if ((condition_holds_interpreter(ctx,cond))) + uint64_t is_exclusive = ((uint64_t)ordered == (uint64_t)0ULL); + if ((L)) { - uint64_t success_nzcv = FPCompare_interpreter(ctx,operand1,operand2,fpcr_state,datasize); - _sys_interpreter(ctx,(uint64_t)nzcv_n,((uint64_t)(((uint64_t)success_nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_z,((uint64_t)(((uint64_t)success_nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,((uint64_t)(((uint64_t)success_nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_v,((uint64_t)(((uint64_t)success_nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); + load_exclusive_jit(ctx,is_exclusive,size,Rn,Rt); } else { - _sys_interpreter(ctx,(uint64_t)nzcv_n,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_z,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_c,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL)); - _sys_interpreter(ctx,(uint64_t)nzcv_v,(uint64_t)((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL)); + store_exclusive_jit(ctx,is_exclusive,size,Rn,Rt,Rs); + } +} + +ir_operand exclusive_address_mask_jit(ssa_emit_context* ctx) +{ + return ir_operand::create_con(~(((uint64_t)(((uint64_t)4ULL << (uint64_t)4ULL)) - (uint64_t)1ULL)), int64); +} + +void load_exclusive_jit(ssa_emit_context* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)size); + ir_operand address = XSP_jit(ctx,Rn); + uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; + { + ir_operand value = copy_new_raw_size(ctx, mem_jit(ctx,S,address), S); + if ((is_exclusive)) + { + _sys_jit(ctx,(uint64_t)exclusive_address,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, address, exclusive_address_mask_jit(ctx))); + _sys_jit(ctx,(uint64_t)exclusive_value,copy_new_raw_size(ctx, value, int64)); + } + X_jit(ctx,Rt,copy_new_raw_size(ctx, value, int64)); + } +} + +void store_exclusive_jit(ssa_emit_context* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t Rs) +{ + uint64_t datasize = ((uint64_t)8ULL << (uint64_t)size); + ir_operand address = XSP_jit(ctx,Rn); + uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; + { + if ((is_exclusive)) + { + ir_operand mask = exclusive_address_mask_jit(ctx); + ir_operand _exclusive_address = _sys_jit(ctx,(uint64_t)exclusive_address); + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_equal, _exclusive_address, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, address, mask)); + + ir_operation_block::jump_if(ctx->ir,yes, condition); + { + X_jit(ctx,Rs,ir_operand::create_con(1ULL, int64)); + } + + ir_operation_block::jump(ctx->ir,end); + ir_operation_block::mark_label(ctx->ir, yes); + + { + ir_operand to_swap = copy_new_raw_size(ctx, X_jit(ctx,Rt), S); + ir_operand expecting = copy_new_raw_size(ctx, _sys_jit(ctx,(uint64_t)exclusive_value), S); + ir_operand cas_success = copy_new_raw_size(ctx, compare_and_swap_jit(ctx,address,copy_new_raw_size(ctx, expecting, int64),copy_new_raw_size(ctx, to_swap, int64),datasize), S); + X_jit(ctx,Rs,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, cas_success, ir_operand::create_con(1ULL, S)), ir_operand::create_con(1ULL, S)), int64)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + } + else + { + mem_jit(ctx,S,address,copy_new_raw_size(ctx, X_jit(ctx,Rt), S)); + } } } @@ -11132,6 +12436,991 @@ uint64_t select_jit(ssa_emit_context* ctx, uint64_t condition, uint64_t yes, uin return no; } +void dup_general_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + ir_operand element = X_jit(ctx,Rn); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand result; + if ((use_x86_sse_jit(ctx))) + { + result = sse_coppy_gp_across_lanes_jit(ctx,element,esize); + if ((!Q)) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + } + } + else + { + result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ssa_emit_context::vector_insert(ctx,result, e, esize, element); + } + } + V_jit(ctx,Rd,result); +} + +void dup_element_scalar_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); + uint64_t index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)bit_c_jit(ctx,imm5,4ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = esize; + uint64_t elements = 1ULL; + dup_element_jit(ctx,index,esize,elements,Rn,Rd); +} + +void dup_element_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); + uint64_t index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)bit_c_jit(ctx,imm5,4ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + dup_element_jit(ctx,index,esize,elements,Rn,Rd); +} + +void move_to_gp_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t U, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)32ULL << (uint64_t)Q); + uint64_t index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + ir_operand operand = V_jit(ctx,Rn); + uint64_t S = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; + { + uint64_t R = datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; + { + ir_operand result = copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand, index, esize), R); + if ((!U)) + { + result = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, result, S), R); + } + X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + } + } +} + +void ins_general_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); + uint64_t index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + ir_operand element = X_jit(ctx,Rn); + ir_operand result = V_jit(ctx,Rd); + ssa_emit_context::vector_insert(ctx,result, index, esize, element); + V_jit(ctx,Rd,result); +} + +void ins_element_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t imm4, uint64_t Rn, uint64_t Rd) +{ + uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); + uint64_t dst_index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); + uint64_t src_index = bits_c_jit(ctx,imm4,3ULL,size); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + ir_operand operand = V_jit(ctx,Rn); + ir_operand result = V_jit(ctx,Rd); + ssa_emit_context::vector_insert(ctx,result, dst_index, esize, ssa_emit_context::vector_extract(ctx,operand, src_index, esize)); + V_jit(ctx,Rd,result); +} + +void movi_immediate_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t op, uint64_t immhi, uint64_t cmode, uint64_t immlo, uint64_t Rd) +{ + uint64_t d = Rd; + uint64_t imm8 = ((uint64_t)(((uint64_t)immhi << (uint64_t)5ULL)) | (uint64_t)immlo); + uint64_t cmode_helper = ((uint64_t)(((uint64_t)cmode << (uint64_t)1ULL)) | (uint64_t)op); + uint64_t mode = 0ULL; + if ((((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)2ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)18ULL))))) + { + mode = 0ULL; + } + else if ((((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)3ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)19ULL))))) + { + mode = 1ULL; + } + else if ((((uint64_t)((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)1ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)17ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)29ULL)) == (uint64_t)25ULL))))) + { + mode = 2ULL; + } + else if ((((uint64_t)((uint64_t)((uint64_t)((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)0ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)16ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)29ULL)) == (uint64_t)24ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)30ULL)) == (uint64_t)28ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)31ULL)) == (uint64_t)30ULL))))) + { + mode = 3ULL; + } + else if ((((uint64_t)cmode_helper == (uint64_t)31ULL))) + { + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + undefined_jit(ctx); + } + mode = 3ULL; + } + else + { + undefined_jit(ctx); + } + ir_operand imm64 = ir_operand::create_con(expand_imm_jit(ctx,op,cmode,imm8), int64); + ir_operand imm = copy_new_raw_size(ctx, imm64, int128); + if ((Q)) + { + ssa_emit_context::vector_insert(ctx,imm, 1ULL, 64ULL, imm64); + } + ir_operand operand = ssa_emit_context::vector_zero(ctx); + ir_operand result = ssa_emit_context::vector_zero(ctx); + if ((((uint64_t)mode == (uint64_t)3ULL))) + { + result = imm; + } + else if ((((uint64_t)mode == (uint64_t)2ULL))) + { + for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) + { + ssa_emit_context::vector_insert(ctx,result, e, 64ULL, ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, ssa_emit_context::vector_extract(ctx,imm, e, 64ULL))); + } + } + else if ((((uint64_t)mode == (uint64_t)0ULL))) + { + operand = V_jit(ctx,Rd); + for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) + { + ssa_emit_context::vector_insert(ctx,result, e, 64ULL, ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::vector_extract(ctx,operand, e, 64ULL), ssa_emit_context::vector_extract(ctx,imm, e, 64ULL))); + } + } + else if ((((uint64_t)mode == (uint64_t)1ULL))) + { + operand = V_jit(ctx,Rd); + for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) + { + ssa_emit_context::vector_insert(ctx,result, e, 64ULL, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::vector_extract(ctx,operand, e, 64ULL), ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, ssa_emit_context::vector_extract(ctx,imm, e, 64ULL)))); + } + } + else + { + undefined_jit(ctx); + } + V_jit(ctx,Rd,result); +} + +void fmov_general_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t Rn, uint64_t Rd) +{ + uint64_t intsize = ((uint64_t)32ULL << (uint64_t)sf); + uint64_t fltsize = get_flt_size_jit(ctx,ftype); + if ((((uint64_t)intsize != (uint64_t)fltsize))) + { + undefined_jit(ctx); + } + uint64_t size = intsize; + uint64_t part = rmode; + uint64_t int_to_float = opcode; + if ((int_to_float)) + { + ir_operand result = X_jit(ctx,Rn); + uint64_t O = size == 32ULL ? int32 : size == 64ULL ? int64 : 0; + { + VPart_jit(ctx,Rd,part,size,copy_new_raw_size(ctx, copy_new_raw_size(ctx, result, O), int64)); + } + } + else + { + ir_operand v = V_jit(ctx,Rn); + ir_operand result = ssa_emit_context::vector_extract(ctx,v, part, size); + X_jit(ctx,Rd,result); + } +} + +void convert_to_float_gp_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd) +{ + convert_to_float_jit(ctx,sf,ftype,U,Rn,Rd,0ULL); +} + +void convert_to_float_vector_scalar_jit(ssa_emit_context* ctx, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + convert_to_float_jit(ctx,sz,sz,U,Rn,Rd,1ULL); +} + +void convert_to_float_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand = V_jit(ctx,Rn); + ir_operand result = ssa_emit_context::vector_zero(ctx); + uint64_t F = esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; + { + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element = ssa_emit_context::vector_extract(ctx,operand, e, esize); + ir_operand working; + if ((U)) + { + working = copy_new_raw_size(ctx, ssa_emit_context::convert_to_float(ctx,copy_new_raw_size(ctx, element, F),F,F, 0), int64); + } + else + { + working = copy_new_raw_size(ctx, ssa_emit_context::convert_to_float(ctx,copy_new_raw_size(ctx, element, F),F,F, 1), int64); + } + ssa_emit_context::vector_insert(ctx,result, e, esize, working); + } + V_jit(ctx,Rd,result); + } +} + +void shl_immedaite_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_jit(ctx,immh,32ULL)); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t shift = ((uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb)) - (uint64_t)esize); + ir_operand operand = V_jit(ctx,Rn); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element = ssa_emit_context::vector_extract(ctx,operand, e, esize); + element = ssa_emit_context::emit_ssa(ctx, ir_shift_left, element, ir_operand::create_con(shift, int64)); + ssa_emit_context::vector_insert(ctx,result, e, esize, element); + } + V_jit(ctx,Rd,result); +} + +void sshr_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_jit(ctx,immh,32ULL)); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t shift = ((uint64_t)(((uint64_t)esize * (uint64_t)2ULL)) - (uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb))); + ir_operand operand = V_jit(ctx,Rn); + ir_operand result = ssa_emit_context::vector_zero(ctx); + uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; + { + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element = ssa_emit_context::vector_extract(ctx,operand, e, esize); + element = shift_right_check_jit(ctx,ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, element, O), int64),ir_operand::create_con(shift, int64),esize,0ULL); + ssa_emit_context::vector_insert(ctx,result, e, esize, element); + } + V_jit(ctx,Rd,result); + } +} + +void shll_shll2_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_jit(ctx,bits_c_jit(ctx,immh,2ULL,0ULL),32ULL)); + uint64_t datasize = 64ULL; + uint64_t part = Q; + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t shift = ((uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb)) - (uint64_t)esize); + ir_operand operand = VPart_jit(ctx,Rn,part,datasize); + ir_operand result = ssa_emit_context::vector_zero(ctx); + ir_operand working_vector = ssa_emit_context::vector_zero(ctx); + ssa_emit_context::vector_insert(ctx,working_vector, 0ULL, datasize, operand); + uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; + { + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element = ssa_emit_context::vector_extract(ctx,working_vector, e, esize); + if ((!U)) + { + element = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, element, O), int64); + } + element = ssa_emit_context::emit_ssa(ctx, ir_shift_left, element, ir_operand::create_con(shift, int64)); + ssa_emit_context::vector_insert(ctx,result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); + } + V_jit(ctx,Rd,result); + } +} + +void shrn_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_jit(ctx,bits_c_jit(ctx,immh,2ULL,0ULL),32ULL)); + uint64_t datasize = 64ULL; + uint64_t part = Q; + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t shift = ((uint64_t)(((uint64_t)2ULL * (uint64_t)esize)) - (uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb))); + ir_operand operand = V_jit(ctx,Rn); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element = shift_right_check_jit(ctx,ssa_emit_context::vector_extract(ctx,operand, e, (((uint64_t)2ULL * (uint64_t)esize))),ir_operand::create_con(shift, int64),((uint64_t)2ULL * (uint64_t)esize),1ULL); + ssa_emit_context::vector_insert(ctx,result, e, esize, element); + } + VPart_jit(ctx,Rd,part,datasize,copy_new_raw_size(ctx, result, int64)); +} + +void rev64_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint64_t csize = 64ULL; + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t containers = ((uint64_t)datasize / (uint64_t)csize); + ir_operand operand = V_jit(ctx,Rn); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t c = 0; c < (containers); c++) + { + ir_operand container = ssa_emit_context::vector_extract(ctx,operand, c, csize); + ssa_emit_context::vector_insert(ctx,result, c, csize, reverse_jit(ctx,copy_new_raw_size(ctx, container, int128),esize,csize)); + } + V_jit(ctx,Rd,result); +} + +void neg_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + ir_operand operand = V_jit(ctx,Rn); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_negate, ssa_emit_context::vector_extract(ctx,operand, e, esize))); + } + V_jit(ctx,Rd,result); +} + +void not_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rn, uint64_t Rd) +{ + ir_operand operand = V_jit(ctx,Rn); + uint64_t esize = 8ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, ssa_emit_context::vector_extract(ctx,operand, e, esize))); + } + V_jit(ctx,Rd,result); +} + +void abs_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + ir_operand operand = V_jit(ctx,Rn); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; + { + ir_operand working = ssa_emit_context::emit_ssa(ctx, ir_move, copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand, e, esize), O)); + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_less_signed, working, ir_operand::create_con(0ULL, O)); + + condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); + + ir_operation_block::jump_if(ctx->ir,end, condition); + + { + ssa_emit_context::move(ctx,working,ssa_emit_context::emit_ssa(ctx, ir_negate, working)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + ssa_emit_context::vector_insert(ctx,result, e, esize, working); + } + } + V_jit(ctx,Rd,result); +} + +void mul_vector_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd) +{ + uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)H); + uint64_t index; + uint64_t rm_hi; + if ((((uint64_t)size == (uint64_t)1ULL))) + { + index = H; + index = ((uint64_t)L | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); + index = ((uint64_t)M | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); + rm_hi = 0ULL; + } + else if ((((uint64_t)size == (uint64_t)2ULL))) + { + index = H; + index = ((uint64_t)L | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); + rm_hi = M; + } + else + { + undefined_jit(ctx); + } + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,((uint64_t)Rm | (uint64_t)(((uint64_t)rm_hi << (uint64_t)4ULL)))); + ir_operand result = ssa_emit_context::vector_zero(ctx); + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, index, esize); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); + ir_operand product = ssa_emit_context::emit_ssa(ctx, ir_multiply, element1, element2); + ssa_emit_context::vector_insert(ctx,result, e, esize, product); + } + V_jit(ctx,Rd,result); +} + +void mul_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); + ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); + ir_operand working = ssa_emit_context::emit_ssa(ctx, ir_multiply, element1, element2); + ssa_emit_context::vector_insert(ctx,result, e, esize, working); + } + V_jit(ctx,Rd,result); +} + +void ext_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t imm4, uint64_t Rn, uint64_t Rd) +{ + ir_operand lo = V_jit(ctx,Rn); + ir_operand hi = V_jit(ctx,Rm); + uint64_t vector_size = ((uint64_t)8ULL << (uint64_t)Q); + uint64_t start = imm4; + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (vector_size); e++) + { + ir_operand working = copy_new_raw_size(ctx, get_from_concacted_vector_jit(ctx,hi,lo,((uint64_t)start + (uint64_t)e),vector_size,8ULL), int8); + ssa_emit_context::vector_insert(ctx,result, e, 8ULL, working); + } + V_jit(ctx,Rd,result); +} + +void compare_above_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; + { + ir_operand element1 = copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand1, e, esize), O); + ir_operand element2 = copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand2, e, esize), O); + ir_operand working; + if ((U)) + { + working = ssa_emit_context::emit_ssa(ctx, ir_compare_greater_unsigned, element1, element2); + } + else + { + working = ssa_emit_context::emit_ssa(ctx, ir_compare_greater_signed, element1, element2); + } + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_subtract, ir_operand::create_con(0ULL, O), working)); + } + } + V_jit(ctx,Rd,result); +} + +void shl_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element = ssa_emit_context::emit_ssa(ctx, ir_move, ssa_emit_context::vector_extract(ctx,operand1, e, esize)); + ir_operand shift = ssa_emit_context::emit_ssa(ctx, ir_move, ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand2, e, esize), int8), int64)); + if ((!U)) + { + uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; + { + element = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, element, O), int64); + } + } + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_greater_equal_signed, shift, ir_operand::create_con(0ULL, int64)); + + ir_operation_block::jump_if(ctx->ir,yes, condition); + { + ssa_emit_context::move(ctx,shift,ssa_emit_context::emit_ssa(ctx, ir_negate, shift)); + ssa_emit_context::move(ctx,element,shift_right_check_jit(ctx,element,shift,esize,U)); + } + + ir_operation_block::jump(ctx->ir,end); + ir_operation_block::mark_label(ctx->ir, yes); + + { + ssa_emit_context::move(ctx,element,shift_left_check_jit(ctx,element,shift,esize)); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + ssa_emit_context::vector_insert(ctx,result, e, esize, element); + } + V_jit(ctx,Rd,result); +} + +void add_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result; + if ((use_x86_sse2_jit(ctx))) + { + uint64_t add_instruction; + if ((((uint64_t)esize == (uint64_t)8ULL))) + add_instruction = (uint64_t)x86_paddb; + else if ((((uint64_t)esize == (uint64_t)16ULL))) + add_instruction = (uint64_t)x86_paddw; + else if ((((uint64_t)esize == (uint64_t)32ULL))) + add_instruction = (uint64_t)x86_paddd; + else if ((((uint64_t)esize == (uint64_t)64ULL))) + add_instruction = (uint64_t)x86_paddq; + else + undefined_jit(ctx); + result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,add_instruction,operand1,operand2), int128); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + } + } + else + { + result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); + ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_add, element1, element2)); + } + } + V_jit(ctx,Rd,result); +} + +void addlv_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t is_unsigned = U; + ir_operand source = V_jit(ctx,Rn); + ir_operand operand = V_jit(ctx,Rn); + ir_operand sum = ir_operand::create_con(0ULL, int64); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand working = ssa_emit_context::vector_extract(ctx,operand, e, esize); + if ((!is_unsigned)) + { + uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; + { + working = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, working, O), int64); + } + } + sum = ssa_emit_context::emit_ssa(ctx, ir_add, sum, working); + } + ir_operand final = ssa_emit_context::vector_zero(ctx); + ssa_emit_context::vector_insert(ctx,final, 0ULL, (((uint64_t)2ULL * (uint64_t)esize)), sum); + V_jit(ctx,Rd,final); +} + +void cnt_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = 8ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)8ULL); + ir_operand source = V_jit(ctx,Rn); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand working = copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,source, e, esize), int8); + ir_operand count = ssa_emit_context::emit_ssa(ctx, ir_move, ir_operand::create_con(0ULL, int8)); + if ((use_x86_jit(ctx))) + { + count = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,int16,(uint64_t)x86_popcnt,copy_new_raw_size(ctx, working, int16)), int8); + } + else + { + for (uint64_t b = 0; b < (esize); b++) + { + ir_operand bit = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, working, ir_operand::create_con(b, int8)), ir_operand::create_con(1ULL, int8)); + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = bit; + + condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); + + ir_operation_block::jump_if(ctx->ir,end, condition); + + { + ssa_emit_context::move(ctx,count,ssa_emit_context::emit_ssa(ctx, ir_add, count, ir_operand::create_con(1ULL, int8))); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + } + } + ssa_emit_context::vector_insert(ctx,result, e, esize, count); + } + V_jit(ctx,Rd,result); +} + +void orr_orn_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((use_x86_sse_jit(ctx))) + { + x86_sse_logic_vector_jit(ctx,Rd,Rn,Rm,Q,invert,(uint64_t)x86_orps); + } + else + { + uint64_t esize = 64ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); + ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); + if ((invert)) + { + element2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, element2); + } + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, element1, element2)); + } + V_jit(ctx,Rd,result); + } +} + +void bsl_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = 64ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand1 = V_jit(ctx,Rm); + ir_operand operand2 = V_jit(ctx,Rd); + ir_operand operand3 = V_jit(ctx,Rn); + if ((use_x86_sse_jit(ctx))) + { + ir_operand xor_result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand1,operand3), int128); + ir_operand and_result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_pand,xor_result,operand2), int128); + ir_operand final_result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand1,and_result), int128); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + ssa_emit_context::vector_insert(ctx,final_result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + } + V_jit(ctx,Rd,final_result); + } + else + { + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); + ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); + ir_operand element3 = ssa_emit_context::vector_extract(ctx,operand3, e, esize); + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, element1, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, element1, element3), element2))); + } + V_jit(ctx,Rd,result); + } +} + +void and_bic_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((use_x86_sse2_jit(ctx))) + { + if ((invert)) + { + x86_sse_logic_vector_jit(ctx,Rd,Rm,Rn,Q,0ULL,(uint64_t)x86_pandn); + } + else + { + x86_sse_logic_vector_jit(ctx,Rd,Rn,Rm,Q,0ULL,(uint64_t)x86_pand); + } + } + else + { + uint64_t esize = 64ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); + ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); + if ((invert)) + { + element2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, element2); + } + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, element1, element2)); + } + V_jit(ctx,Rd,result); + } +} + +void eor_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((use_x86_sse_jit(ctx))) + { + x86_sse_logic_vector_jit(ctx,Rd,Rn,Rm,Q,0ULL,(uint64_t)x86_xorps); + } + else + { + uint64_t esize = 64ULL; + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); + ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, element1, element2)); + } + V_jit(ctx,Rd,result); + } +} + +void xnt_xnt2_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = 64ULL; + uint64_t part = Q; + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + ir_operand operand = V_jit(ctx,Rn); + ir_operand result = ssa_emit_context::vector_zero(ctx); + ir_operand mask = ir_operand::create_con(-1ULL, int64); + if ((((uint64_t)esize != (uint64_t)64ULL))) + { + mask = ir_operand::create_con(((uint64_t)(((uint64_t)1ULL << (uint64_t)esize)) - (uint64_t)1ULL), int64); + } + for (uint64_t e = 0; e < (elements); e++) + { + ir_operand element = ssa_emit_context::vector_extract(ctx,operand, e, (((uint64_t)2ULL * (uint64_t)esize))); + ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, element, mask)); + } + VPart_jit(ctx,Rd,part,datasize,copy_new_raw_size(ctx, result, int64)); +} + +void zip_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t part = op; + uint64_t pairs = ((uint64_t)elements / (uint64_t)2ULL); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::vector_zero(ctx); + uint64_t base = ((uint64_t)part * (uint64_t)pairs); + for (uint64_t p = 0; p < (pairs); p++) + { + ssa_emit_context::vector_insert(ctx,result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)0ULL)), esize, ssa_emit_context::vector_extract(ctx,operand1, (((uint64_t)base + (uint64_t)p)), esize)); + ssa_emit_context::vector_insert(ctx,result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)1ULL)), esize, ssa_emit_context::vector_extract(ctx,operand2, (((uint64_t)base + (uint64_t)p)), esize)); + } + V_jit(ctx,Rd,result); +} + +void trn_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); + uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); + uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); + uint64_t part = op; + uint64_t pairs = ((uint64_t)elements / (uint64_t)2ULL); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::vector_zero(ctx); + for (uint64_t p = 0; p < (pairs); p++) + { + ssa_emit_context::vector_insert(ctx,result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)0ULL)), esize, ssa_emit_context::vector_extract(ctx,operand1, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)part)), esize)); + ssa_emit_context::vector_insert(ctx,result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)1ULL)), esize, ssa_emit_context::vector_extract(ctx,operand2, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)part)), esize)); + } + V_jit(ctx,Rd,result); +} + +void tbl_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t len, uint64_t Rn, uint64_t Rd) +{ + store_context_jit(ctx); + ir_operand vector_context = get_vector_context_jit(ctx); + call_jit(ctx,vector_context,ir_operand::create_con(Rd, int64),ir_operand::create_con(Rn, int64),ir_operand::create_con(len, int64),ir_operand::create_con(Rm, int64),ir_operand::create_con(Q, int64),(uint64_t)table_lookup_fallback); + load_context_jit(ctx); +} + +void ld4_st4_multiple_structures_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t L, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_4_jit(ctx,Q,L,size,-1ULL,Rn,Rt); +} + +void ld4_st4_multiple_structures_post_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t L, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_4_jit(ctx,Q,L,size,Rm,Rn,Rt); +} + +void ld1r_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_jit(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,6ULL,0ULL,size,Rn,Rt,1ULL); +} + +void ld1r_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_jit(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,6ULL,0ULL,size,Rn,Rt,1ULL); +} + +void ld1_single_structure_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_jit(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,1ULL); +} + +void ld1_single_structure_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_jit(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,1ULL); +} + +void st1_multiple_structures_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + uint64_t opcode = ophi; + opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)1ULL); + opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)oplo); + st1_jit(ctx,0ULL,Q,0ULL,opcode,size,0ULL,Rn,Rt); +} + +void st1_multiple_structures_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + uint64_t opcode = ophi; + opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)1ULL); + opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)oplo); + st1_jit(ctx,1ULL,Q,0ULL,opcode,size,Rm,Rn,Rt); +} + +void st2_multiple_structures_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + st_jit(ctx,0ULL,Q,0ULL,4ULL,size,0ULL,Rn,Rt); +} + +void st2_multiple_structures_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + st_jit(ctx,1ULL,Q,0ULL,4ULL,size,Rm,Rn,Rt); +} + +void st1_single_structure_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_jit(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,0ULL); +} + +void st1_single_structure_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) +{ + memory_1_jit(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,0ULL); +} + +void floating_point_conditional_select_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd) +{ + uint64_t fltsize = get_flt_size_jit(ctx,ftype); + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + ir_operand result = ssa_emit_context::emit_ssa(ctx, ir_move, ssa_emit_context::vector_zero(ctx)); + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = condition_holds_jit(ctx,cond); + + ir_operation_block::jump_if(ctx->ir,yes, condition); + { + ssa_emit_context::move(ctx,result,operand2); + } + + ir_operation_block::jump(ctx->ir,end); + ir_operation_block::mark_label(ctx->ir, yes); + + { + ssa_emit_context::move(ctx,result,operand1); + } + + ir_operation_block::mark_label(ctx->ir, end); + } + result = clear_vector_scalar_jit(ctx,result,fltsize); + V_jit(ctx,Rd,result); +} + +void fcmp_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t opc) +{ + uint64_t datasize = get_flt_size_jit(ctx,ftype); + uint64_t cmp_with_zero = ((uint64_t)opc == (uint64_t)1ULL); + ir_operand operand1 = copy_new_raw_size(ctx, V_jit(ctx,Rn), int64); + ir_operand operand2; + ir_operand fpcr_state = _sys_jit(ctx,(uint64_t)fpcr); + if ((cmp_with_zero)) + { + operand2 = ir_operand::create_con(0ULL, int64); + } + else + { + operand2 = copy_new_raw_size(ctx, V_jit(ctx,Rm), int64); + } + ir_operand nzcv = FPCompare_jit(ctx,operand1,operand2,fpcr_state,datasize); + _sys_jit(ctx,(uint64_t)nzcv_n,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, nzcv, ir_operand::create_con(3ULL, int64)), ir_operand::create_con(1ULL, int64))); + _sys_jit(ctx,(uint64_t)nzcv_z,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, nzcv, ir_operand::create_con(2ULL, int64)), ir_operand::create_con(1ULL, int64))); + _sys_jit(ctx,(uint64_t)nzcv_c,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, nzcv, ir_operand::create_con(1ULL, int64)), ir_operand::create_con(1ULL, int64))); + _sys_jit(ctx,(uint64_t)nzcv_v,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, nzcv, ir_operand::create_con(0ULL, int64)), ir_operand::create_con(1ULL, int64))); +} + +void fccmp_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t nzcv) +{ + uint64_t datasize = get_flt_size_jit(ctx,ftype); + ir_operand operand1 = copy_new_raw_size(ctx, V_jit(ctx,Rn), int64); + ir_operand operand2 = copy_new_raw_size(ctx, V_jit(ctx,Rm), int64); + ir_operand fpcr_state = _sys_jit(ctx,(uint64_t)fpcr); + { + ir_operand end = ir_operation_block::create_label(ctx->ir); + ir_operand yes = ir_operation_block::create_label(ctx->ir); + + ir_operand condition = condition_holds_jit(ctx,cond); + + ir_operation_block::jump_if(ctx->ir,yes, condition); + { + _sys_jit(ctx,(uint64_t)nzcv_n,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL), int64)); + _sys_jit(ctx,(uint64_t)nzcv_z,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL), int64)); + _sys_jit(ctx,(uint64_t)nzcv_c,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL), int64)); + _sys_jit(ctx,(uint64_t)nzcv_v,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL), int64)); + } + + ir_operation_block::jump(ctx->ir,end); + ir_operation_block::mark_label(ctx->ir, yes); + + { + ir_operand success_nzcv = FPCompare_jit(ctx,operand1,operand2,fpcr_state,datasize); + _sys_jit(ctx,(uint64_t)nzcv_n,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, success_nzcv, ir_operand::create_con(3ULL, int64)), ir_operand::create_con(1ULL, int64))); + _sys_jit(ctx,(uint64_t)nzcv_z,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, success_nzcv, ir_operand::create_con(2ULL, int64)), ir_operand::create_con(1ULL, int64))); + _sys_jit(ctx,(uint64_t)nzcv_c,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, success_nzcv, ir_operand::create_con(1ULL, int64)), ir_operand::create_con(1ULL, int64))); + _sys_jit(ctx,(uint64_t)nzcv_v,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, success_nzcv, ir_operand::create_con(0ULL, int64)), ir_operand::create_con(1ULL, int64))); + } + + ir_operation_block::mark_label(ctx->ir, end); + } +} + ir_operand create_mask_jit(ssa_emit_context* ctx, uint64_t bits) { if ((((uint64_t)bits >= (uint64_t)64ULL))) @@ -13000,1307 +15289,72 @@ ir_operand clear_vector_scalar_jit(ssa_emit_context* ctx, ir_operand working, ui return working; } -void add_subtract_imm12_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t sh, uint64_t imm12, uint64_t Rn, uint64_t Rd) +ir_operand _compare_and_swap_jit(ssa_emit_context* ctx, ir_operand physical_address, ir_operand expecting, ir_operand to_swap, uint64_t size) { - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; + if ((use_x86_jit(ctx))) { - ir_operand operand1 = copy_new_raw_size(ctx, XSP_jit(ctx,Rn), O); - ir_operand operand2 = ir_operand::create_con(decode_add_subtract_imm_12_jit(ctx,imm12,sh), O); - ir_operand d = copy_new_raw_size(ctx, add_subtract_impl_jit(ctx,O,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)), O); - if ((S)) + if ((((uint64_t)size != (uint64_t)64ULL))) { - X_jit(ctx,Rd,copy_new_raw_size(ctx, d, int64)); - } - else - { - XSP_jit(ctx,Rd,copy_new_raw_size(ctx, d, int64)); + ir_operand mask = ir_operand::create_con(((uint64_t)(((uint64_t)1ULL << (uint64_t)size)) - (uint64_t)1ULL), int64); + ir_operand masking_value = ssa_emit_context::emit_ssa(ctx, ir_load, physical_address, int64); + masking_value = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, masking_value, ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, mask)); + expecting = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, expecting, mask), masking_value); + to_swap = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, to_swap, mask), masking_value); } + return copy_new_raw_size(ctx, intrinsic_ternary_jit(ctx,int64,(uint64_t)x86_cmpxchg,physical_address,expecting,to_swap), int64); } + return call_jit(ctx,physical_address,expecting,to_swap,ir_operand::create_con(size, int64),ir_operand::create_con(0ULL, int64),ir_operand::create_con(0ULL, int64),(uint64_t)compare_and_swap_interpreter_cpp); } -void add_subtract_shifted_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t shift, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd) +ir_operand compare_and_swap_jit(ssa_emit_context* ctx, ir_operand address, ir_operand expecting, ir_operand to_swap, uint64_t size) { - uint64_t shift_ammount = imm6; - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, a_shift_reg_jit(ctx,O,Rm,shift,shift_ammount), O); - ir_operand result = copy_new_raw_size(ctx, add_subtract_impl_jit(ctx,O,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)), O); - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } + address = translate_address_jit(ctx,address); + return _compare_and_swap_jit(ctx,address,expecting,to_swap,size); } -void add_subtract_extended_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t option, uint64_t imm3, uint64_t Rn, uint64_t Rd) +void mem_jit(ssa_emit_context* ctx,uint64_t O, ir_operand address, ir_operand value) { - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - uint64_t shift = imm3; - uint64_t extend_type = option; - ir_operand operand1 = copy_new_raw_size(ctx, XSP_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, a_extend_reg_jit(ctx,O,Rm,extend_type,shift), O); - ir_operand result = copy_new_raw_size(ctx, add_subtract_impl_jit(ctx,O,operand1,operand2,S,((uint64_t)op == (uint64_t)0ULL)), O); - if ((S)) - { - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } - else - { - XSP_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } - } + address = translate_address_jit(ctx,address); + ssa_emit_context::store(ctx, address, value); } -void add_subtract_carry_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t Rn, uint64_t Rd) +ir_operand mem_jit(ssa_emit_context* ctx,uint64_t O, ir_operand address) { - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); - ir_operand result = copy_new_raw_size(ctx, add_subtract_carry_impl_jit(ctx,O,operand1,operand2,((uint64_t)S == (uint64_t)1ULL),((uint64_t)op == (uint64_t)0ULL),copy_new_raw_size(ctx, _sys_jit(ctx,(uint64_t)nzcv_c), O)), O); - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } + address = translate_address_jit(ctx,address); + return ssa_emit_context::emit_ssa(ctx, ir_load, address, O); } -void shift_variable_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t op2, uint64_t Rn, uint64_t Rd) +ir_operand XSP_jit(ssa_emit_context* ctx, uint64_t reg_id) { - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); - uint64_t mask = ((uint64_t)(((uint64_t)32ULL << (uint64_t)sf)) - (uint64_t)1ULL); - ir_operand result; - operand2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand2, ir_operand::create_con(mask, O)); - if ((((uint64_t)op2 == (uint64_t)0ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_shift_left, operand1, operand2); - } - else if ((((uint64_t)op2 == (uint64_t)1ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand1, operand2); - } - else if ((((uint64_t)op2 == (uint64_t)2ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_shift_right_signed, operand1, operand2); - } - else - { - result = ssa_emit_context::emit_ssa(ctx, ir_rotate_right, operand1, operand2); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } + return _x_jit(ctx,reg_id); } -void multiply_with_32_jit(ssa_emit_context* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd) +void XSP_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value) { - ir_operand operand1 = X_jit(ctx,Rn); - ir_operand operand2 = X_jit(ctx,Rm); - ir_operand operand3 = X_jit(ctx,Ra); - uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); - uint64_t is_signed = ((uint64_t)U == (uint64_t)0ULL); - if ((is_signed)) + _x_jit(ctx,reg_id,value); +} + +ir_operand X_jit(ssa_emit_context* ctx, uint64_t reg_id) +{ + if ((((uint64_t)reg_id == (uint64_t)31ULL))) { - operand1 = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, operand1, int32), int64); - operand2 = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, operand2, int32), int64); + return ir_operand::create_con(0ULL, int64); } else { - operand1 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand1, ir_operand::create_con(4294967295ULL, int64)); - operand2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand2, ir_operand::create_con(4294967295ULL, int64)); - } - ir_operand result; - if ((is_add)) - { - result = ssa_emit_context::emit_ssa(ctx, ir_add, operand3, ssa_emit_context::emit_ssa(ctx, ir_multiply, operand1, operand2)); - } - else - { - result = ssa_emit_context::emit_ssa(ctx, ir_subtract, operand3, ssa_emit_context::emit_ssa(ctx, ir_multiply, operand1, operand2)); - } - X_jit(ctx,Rd,result); -} - -void multiply_hi_jit(ssa_emit_context* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Rn, uint64_t Rd) -{ - ir_operand operand1 = X_jit(ctx,Rn); - ir_operand operand2 = X_jit(ctx,Rm); - uint64_t is_signed = ((uint64_t)U == (uint64_t)0ULL); - ir_operand result; - if ((is_signed)) - { - result = ssa_emit_context::emit_ssa(ctx, ir_multiply_hi_signed, operand1, operand2); - } - else - { - result = ssa_emit_context::emit_ssa(ctx, ir_multiply_hi_unsigned, operand1, operand2); - } - X_jit(ctx,Rd,result); -} - -void multiply_additive_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd) -{ - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); - ir_operand operand3 = copy_new_raw_size(ctx, X_jit(ctx,Ra), O); - uint64_t is_add = ((uint64_t)o0 == (uint64_t)0ULL); - ir_operand result; - if ((is_add)) - { - result = ssa_emit_context::emit_ssa(ctx, ir_add, operand3, ssa_emit_context::emit_ssa(ctx, ir_multiply, operand1, operand2)); - } - else - { - result = ssa_emit_context::emit_ssa(ctx, ir_subtract, operand3, ssa_emit_context::emit_ssa(ctx, ir_multiply, operand1, operand2)); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); + return _x_jit(ctx,reg_id); } } -void divide_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t o1, uint64_t Rn, uint64_t Rd) +void X_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value) { - uint64_t is_signed = ((uint64_t)o1 == (uint64_t)1ULL); - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); - ir_operand result; - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_equal, operand2, ir_operand::create_con(0ULL, O)); - - ir_operation_block::jump_if(ctx->ir,yes, condition); - { - if ((is_signed)) - { - uint64_t min = 9223372036854775808ULL; - if ((!sf)) - { - min = ((uint64_t)min >> (uint64_t)32ULL); - } - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, operand1, ir_operand::create_con(min, O)), ssa_emit_context::emit_ssa(ctx, ir_compare_equal, operand2, ir_operand::create_con(-1ULL, O))); - - ir_operation_block::jump_if(ctx->ir,yes, condition); - { - X_jit(ctx,Rd,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_divide_signed, operand1, operand2), int64)); - } - - ir_operation_block::jump(ctx->ir,end); - ir_operation_block::mark_label(ctx->ir, yes); - - { - X_jit(ctx,Rd,ir_operand::create_con(min, int64)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - } - else - { - X_jit(ctx,Rd,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_divide_unsigned, operand1, operand2), int64)); - } - } - - ir_operation_block::jump(ctx->ir,end); - ir_operation_block::mark_label(ctx->ir, yes); - - { - X_jit(ctx,Rd,ir_operand::create_con(0ULL, int64)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - } -} - -uint64_t create_rbit_mask_jit(ssa_emit_context* ctx, uint64_t index) -{ - index = ((uint64_t)1ULL << (uint64_t)index); - uint64_t mask = ((uint64_t)(((uint64_t)(((uint64_t)1ULL << (uint64_t)index)) - (uint64_t)1ULL)) << (uint64_t)index); - mask = replicate_c_jit(ctx,mask,((uint64_t)index * (uint64_t)2ULL),((uint64_t)((uint64_t)64ULL / (uint64_t)index) / (uint64_t)2ULL)); - return mask; -} - -void rbit_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand result = operand; - uint64_t max = ((uint64_t)5ULL + (uint64_t)sf); - for (uint64_t i = 0; i < (max); i++) - { - uint64_t n_mask = create_rbit_mask_jit(ctx,i); - uint64_t i_mask = ~n_mask; - uint64_t shift = ((uint64_t)1ULL << (uint64_t)i); - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, result, ir_operand::create_con(n_mask, O)), ir_operand::create_con(shift, O)), ssa_emit_context::emit_ssa(ctx, ir_shift_left, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, result, ir_operand::create_con(i_mask, O)), ir_operand::create_con(shift, O))); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } -} - -void rev16_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd) -{ - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - uint64_t count = ((uint64_t)2ULL << (uint64_t)sf); - ir_operand working = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand result = ir_operand::create_con(0ULL, O); - for (uint64_t i = 0; i < (count); i++) - { - ir_operand part = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, working, ir_operand::create_con((((uint64_t)i * (uint64_t)16ULL)), O)), ir_operand::create_con(65535ULL, O)); - part = copy_new_raw_size(ctx, reverse_bytes_jit(ctx,O,part,2ULL), O); - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, result, ssa_emit_context::emit_ssa(ctx, ir_shift_left, part, ir_operand::create_con((((uint64_t)i * (uint64_t)16ULL)), O))); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } -} - -void reverse_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand working = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand result; - if ((((uint64_t)sf == (uint64_t)opc))) - { - result = copy_new_raw_size(ctx, reverse_bytes_jit(ctx,O,working,((uint64_t)4ULL << (uint64_t)sf)), O); - } - else - { - result = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, reverse_bytes_jit(ctx,O,working,4ULL), ssa_emit_context::emit_ssa(ctx, ir_shift_left, reverse_bytes_jit(ctx,O,ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, working, ir_operand::create_con(32ULL, O)),4ULL), ir_operand::create_con(32ULL, O))), O); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } -} - -void count_leading_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t s, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand result = ssa_emit_context::emit_ssa(ctx, ir_move, ir_operand::create_con(0ULL, O)); - ir_operand done = ssa_emit_context::emit_ssa(ctx, ir_move, ir_operand::create_con(0ULL, O)); - ir_operand sig_bit; - if ((s)) - { - sig_bit = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand, ir_operand::create_con((((uint64_t)datasize - (uint64_t)1ULL)), O)), ir_operand::create_con(1ULL, O)); - datasize = ((uint64_t)datasize - (uint64_t)1ULL); - } - if ((use_x86_lzcnt_jit(ctx))) - { - if ((s)) - { - ir_operand nhigh = ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand, ir_operand::create_con(1ULL, O)); - ir_operand mask = ir_operand::create_con(-1ULL, O); - mask = ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, mask, ir_operand::create_con(1ULL, O)); - ir_operand nlow = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand, mask); - result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,O,(uint64_t)x86_lzcnt,ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, nhigh, nlow)), O); - result = ssa_emit_context::emit_ssa(ctx, ir_subtract, result, ir_operand::create_con(1ULL, O)); - } - else - { - result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,O,(uint64_t)x86_lzcnt,operand), O); - } - } - else - { - for (uint64_t i = 0; i < (datasize); i++) - { - ir_operand working = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand, ir_operand::create_con((((uint64_t)((uint64_t)datasize - (uint64_t)i) - (uint64_t)1ULL)), O)), ir_operand::create_con(1ULL, O)); - if ((s)) - { - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_not_equal, working, sig_bit); - - condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); - - ir_operation_block::jump_if(ctx->ir,end, condition); - - { - ssa_emit_context::move(ctx,done,ir_operand::create_con(1ULL, O)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - } - else { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = working; - - condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); - - ir_operation_block::jump_if(ctx->ir,end, condition); - - { - ssa_emit_context::move(ctx,done,ir_operand::create_con(1ULL, O)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_logical_not, done); - - condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); - - ir_operation_block::jump_if(ctx->ir,end, condition); - - { - ssa_emit_context::move(ctx,result,ssa_emit_context::emit_ssa(ctx, ir_add, result, ir_operand::create_con(1ULL, O))); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - } - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } -} - -void extr_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t N, uint64_t Rm, uint64_t imms, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); - uint64_t lsb = imms; - ir_operand result; - if ((((uint64_t)lsb == (uint64_t)0ULL))) - { - result = operand2; - } - else if ((((uint64_t)Rn == (uint64_t)Rm))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_rotate_right, operand1, ir_operand::create_con(lsb, O)); - } - else - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, operand2, ir_operand::create_con(lsb, O)), ssa_emit_context::emit_ssa(ctx, ir_shift_left, operand1, ir_operand::create_con((((uint64_t)datasize - (uint64_t)lsb)), O))); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } -} - -void bitfield_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t tmask = decode_bitmask_tmask_jit(ctx,N,imms,immr,0ULL,datasize,1ULL); - uint64_t wmask = decode_bitmask_tmask_jit(ctx,N,imms,immr,0ULL,datasize,0ULL); - uint64_t inzero; - uint64_t _extend; - if ((((uint64_t)opc == (uint64_t)0ULL))) - { - inzero = 1ULL; - _extend = 1ULL; - } - else if ((((uint64_t)opc == (uint64_t)1ULL))) - { - inzero = 0ULL; - _extend = 0ULL; - } - else if ((((uint64_t)opc == (uint64_t)2ULL))) - { - inzero = 1ULL; - _extend = 0ULL; - } - else - { - undefined_jit(ctx); - } - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand dst; - ir_operand src = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - if ((inzero)) - { - dst = ir_operand::create_con(0ULL, O); - } - else - { - dst = copy_new_raw_size(ctx, X_jit(ctx,Rd), O); - } - ir_operand bot = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, dst, ir_operand::create_con(~wmask, O)), ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_rotate_right, src, ir_operand::create_con(immr, O)), ir_operand::create_con(wmask, O))); - ir_operand top; - if ((_extend)) - { - top = ssa_emit_context::emit_ssa(ctx, ir_subtract, ir_operand::create_con(0ULL, O), ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, src, ir_operand::create_con(imms, O)), ir_operand::create_con(1ULL, O))); - } - else - { - top = dst; - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, top, ir_operand::create_con(~tmask, O)), ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, bot, ir_operand::create_con(tmask, O))), int64)); - } -} - -void logical_immediate_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd) -{ - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = ir_operand::create_con(decode_bitmask_tmask_jit(ctx,N,imms,immr,1ULL,datasize,0ULL), O); - ir_operand result; - if ((((uint64_t)opc == (uint64_t)0ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand1, operand2); - } - else if ((((uint64_t)opc == (uint64_t)1ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, operand1, operand2); - } - else if ((((uint64_t)opc == (uint64_t)2ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, operand1, operand2); - } - else if ((((uint64_t)opc == (uint64_t)3ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand1, operand2); - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - _sys_jit(ctx,(uint64_t)nzcv_n,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_less_signed, result, ir_operand::create_con(0ULL, O)), int64)); - _sys_jit(ctx,(uint64_t)nzcv_z,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, result, ir_operand::create_con(0ULL, O)), int64)); - _sys_jit(ctx,(uint64_t)nzcv_c,ir_operand::create_con(0ULL, int64)); - _sys_jit(ctx,(uint64_t)nzcv_v,ir_operand::create_con(0ULL, int64)); - return; - } - XSP_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } -} - -void logical_shifted_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t shift, uint64_t N, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd) -{ - uint64_t shift_type = shift; - uint64_t shift_ammount = imm6; - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, a_shift_reg_jit(ctx,O,Rm,shift_type,shift_ammount), O); - if ((N)) - { - operand2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, operand2); - } - ir_operand result; - if ((((uint64_t)((uint64_t)opc == (uint64_t)0ULL) || (uint64_t)((uint64_t)opc == (uint64_t)3ULL)))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, operand1, operand2); - if ((((uint64_t)opc == (uint64_t)3ULL))) - { - _sys_jit(ctx,(uint64_t)nzcv_n,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_less_signed, result, ir_operand::create_con(0ULL, O)), int64)); - _sys_jit(ctx,(uint64_t)nzcv_z,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, result, ir_operand::create_con(0ULL, O)), int64)); - _sys_jit(ctx,(uint64_t)nzcv_c,ir_operand::create_con(0ULL, int64)); - _sys_jit(ctx,(uint64_t)nzcv_v,ir_operand::create_con(0ULL, int64)); - } - } - else if ((((uint64_t)opc == (uint64_t)1ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, operand1, operand2); - } - else if ((((uint64_t)opc == (uint64_t)2ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, operand1, operand2); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } -} - -void conditional_select_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t cond, uint64_t op2, uint64_t Rn, uint64_t Rd) -{ - uint64_t incrament = op2; - uint64_t invert = op; - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); - ir_operand condition_pass = copy_new_raw_size(ctx, condition_holds_jit(ctx,cond), O); - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = condition_pass; - - ir_operation_block::jump_if(ctx->ir,yes, condition); - { - if ((invert)) - { - operand2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, operand2); - } - if ((incrament)) - { - operand2 = ssa_emit_context::emit_ssa(ctx, ir_add, operand2, ir_operand::create_con(1ULL, O)); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, operand2, int64)); - } - - ir_operation_block::jump(ctx->ir,end); - ir_operation_block::mark_label(ctx->ir, yes); - - { - X_jit(ctx,Rd,copy_new_raw_size(ctx, operand1, int64)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - } -} - -void conditional_compare_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t Rm, uint64_t cond, uint64_t mode, uint64_t Rn, uint64_t nzcv) -{ - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = condition_holds_jit(ctx,cond); - - ir_operation_block::jump_if(ctx->ir,yes, condition); - { - _sys_jit(ctx,(uint64_t)nzcv_n,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL), int64)); - _sys_jit(ctx,(uint64_t)nzcv_z,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL), int64)); - _sys_jit(ctx,(uint64_t)nzcv_c,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL), int64)); - _sys_jit(ctx,(uint64_t)nzcv_v,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL), int64)); - } - - ir_operation_block::jump(ctx->ir,end); - ir_operation_block::mark_label(ctx->ir, yes); - - { - ir_operand operand1 = copy_new_raw_size(ctx, X_jit(ctx,Rn), O); - ir_operand operand2; - if ((mode)) - { - operand2 = ir_operand::create_con(Rm, O); - } - else - { - operand2 = copy_new_raw_size(ctx, X_jit(ctx,Rm), O); - } - add_subtract_impl_jit(ctx,O,operand1,operand2,1ULL,((uint64_t)op == (uint64_t)0ULL)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - } -} - -void move_wide_immediate_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t hw, uint64_t imm16, uint64_t Rd) -{ - uint64_t shift = ((uint64_t)hw * (uint64_t)16ULL); - uint64_t immediate = ((uint64_t)imm16 << (uint64_t)shift); - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - ir_operand result; - if ((((uint64_t)opc == (uint64_t)0ULL))) - { - result = ir_operand::create_con(~immediate, O); - } - else if ((((uint64_t)opc == (uint64_t)3ULL))) - { - result = copy_new_raw_size(ctx, X_jit(ctx,Rd), O); - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, result, ir_operand::create_con(~(((uint64_t)65535ULL << (uint64_t)shift)), O)); - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, result, ir_operand::create_con(immediate, O)); - } - else - { - result = ir_operand::create_con(immediate, O); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } -} - -void pc_rel_addressing_jit(ssa_emit_context* ctx, uint64_t op, uint64_t immlo, uint64_t immhi, uint64_t Rd) -{ - uint64_t offset = sign_extend_jit(ctx,((uint64_t)(((uint64_t)immhi << (uint64_t)2ULL)) | (uint64_t)immlo),21ULL); - uint64_t instruction_pc = _get_pc_jit(ctx); - if ((op)) - { - offset = ((uint64_t)offset << (uint64_t)12ULL); - instruction_pc = ((uint64_t)instruction_pc & (uint64_t)~4095ULL); - } - X_jit(ctx,Rd,ir_operand::create_con(((uint64_t)instruction_pc + (uint64_t)offset), int64)); -} - -void branch_register_jit(ssa_emit_context* ctx, uint64_t l, uint64_t Rn) -{ - branch_long_universal_jit(ctx,Rn,l); -} - -void return_register_jit(ssa_emit_context* ctx, uint64_t Rn) -{ - _return_from_call_jit(ctx,X_jit(ctx,Rn)); -} - -void test_bit_branch_jit(ssa_emit_context* ctx, uint64_t b5, uint64_t op, uint64_t b40, uint64_t imm14, uint64_t Rt) -{ - uint64_t bit_pos = ((uint64_t)b40 + (uint64_t)(((uint64_t)b5 << (uint64_t)5ULL))); - uint64_t new_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)(((uint64_t)sign_extend_jit(ctx,imm14,14ULL) << (uint64_t)2ULL))); - uint64_t next_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)4ULL); - ir_operand src = X_jit(ctx,Rt); - ir_operand branch_pass = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, src, ir_operand::create_con(bit_pos, int64)), ir_operand::create_con(1ULL, int64)), ir_operand::create_con(op, int64)), int8); - _branch_conditional_jit(ctx,new_location,next_location,copy_new_raw_size(ctx, branch_pass, int64)); -} - -void compare_and_branch_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t imm19, uint64_t Rt) -{ - uint64_t O = sf == 0ULL ? int32 : sf == 1ULL ? int64 : 0; - { - uint64_t new_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)(((uint64_t)sign_extend_jit(ctx,imm19,19ULL) << (uint64_t)2ULL))); - uint64_t next_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)4ULL); - ir_operand operand = copy_new_raw_size(ctx, X_jit(ctx,Rt), O); - ir_operand branch_pass; - if ((!op)) - { - branch_pass = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_equal, operand, ir_operand::create_con(0ULL, O)), int8); - } - else - { - branch_pass = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_compare_not_equal, operand, ir_operand::create_con(0ULL, O)), int8); - } - _branch_conditional_jit(ctx,new_location,next_location,copy_new_raw_size(ctx, branch_pass, int64)); - } -} - -void b_unconditional_jit(ssa_emit_context* ctx, uint64_t op, uint64_t imm26) -{ - uint64_t new_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)(((uint64_t)sign_extend_jit(ctx,imm26,26ULL) << (uint64_t)2ULL))); - if ((op)) - { - uint64_t next_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)4ULL); - X_jit(ctx,30ULL,ir_operand::create_con(next_location, int64)); - _branch_call_jit(ctx,ir_operand::create_con(new_location, int64)); - } - else - { - _branch_short_jit(ctx,new_location); - } -} - -void b_conditional_jit(ssa_emit_context* ctx, uint64_t imm19, uint64_t cond) -{ - uint64_t new_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)(((uint64_t)sign_extend_jit(ctx,imm19,19ULL) << (uint64_t)2ULL))); - uint64_t next_location = ((uint64_t)_get_pc_jit(ctx) + (uint64_t)4ULL); - _branch_conditional_jit(ctx,new_location,next_location,copy_new_raw_size(ctx, condition_holds_jit(ctx,cond), int64)); -} - -void svc_jit(ssa_emit_context* ctx, uint64_t imm16) -{ - call_supervisor_jit(ctx,imm16); -} - -void msr_register_jit(ssa_emit_context* ctx, uint64_t imm15, uint64_t Rt) -{ - ir_operand operand = X_jit(ctx,Rt); - if ((((uint64_t)imm15 == (uint64_t)23072ULL))) - { - _sys_jit(ctx,(uint64_t)fpcr,operand); - } - else if ((((uint64_t)imm15 == (uint64_t)23073ULL))) - { - _sys_jit(ctx,(uint64_t)fpsr,operand); - } - else if ((((uint64_t)imm15 == (uint64_t)24194ULL))) - { - _sys_jit(ctx,(uint64_t)thread_local_1,operand); - } - else if ((((uint64_t)imm15 == (uint64_t)24195ULL))) - { - _sys_jit(ctx,(uint64_t)thread_local_0,operand); - } - else - { - undefined_with_jit(ctx,imm15); - } -} - -void mrs_register_jit(ssa_emit_context* ctx, uint64_t imm15, uint64_t Rt) -{ - ir_operand operand; - if ((((uint64_t)imm15 == (uint64_t)23072ULL))) - { - operand = _sys_jit(ctx,(uint64_t)fpcr); - } - else if ((((uint64_t)imm15 == (uint64_t)23073ULL))) - { - operand = _sys_jit(ctx,(uint64_t)fpsr); - } - else if ((((uint64_t)imm15 == (uint64_t)24194ULL))) - { - operand = _sys_jit(ctx,(uint64_t)thread_local_1); - } - else if ((((uint64_t)imm15 == (uint64_t)24195ULL))) - { - operand = _sys_jit(ctx,(uint64_t)thread_local_0); - } - else if ((((uint64_t)imm15 == (uint64_t)24321ULL))) - { - operand = call_counter_jit(ctx); - } - else if ((((uint64_t)imm15 == (uint64_t)22529ULL))) - { - operand = ir_operand::create_con(2219098116ULL, int64); - } - else - { - undefined_with_jit(ctx,imm15); - } - X_jit(ctx,Rt,operand); -} - -void hints_jit(ssa_emit_context* ctx, uint64_t imm7) -{ -} - -void sys_jit(ssa_emit_context* ctx, uint64_t L, uint64_t imm19) -{ -} - -void barriers_jit(ssa_emit_context* ctx, uint64_t CRm, uint64_t op2, uint64_t Rt) -{ - if ((((uint64_t)((uint64_t)op2 == (uint64_t)2ULL) && (uint64_t)((uint64_t)Rt == (uint64_t)31ULL)))) - { - _sys_jit(ctx,(uint64_t)exclusive_address,ir_operand::create_con(-1ULL, int64)); - _sys_jit(ctx,(uint64_t)exclusive_value,ir_operand::create_con(-1ULL, int64)); - } -} - -void load_store_register_post_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) -{ - load_store_register_imm_unscaled_jit(ctx,size,VR,opc,imm9,1ULL,Rn,Rt); -} - -void load_store_register_pre_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) -{ - load_store_register_imm_unscaled_jit(ctx,size,VR,opc,imm9,3ULL,Rn,Rt); -} - -void load_store_register_unscaled_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt) -{ - load_store_register_imm_unscaled_jit(ctx,size,VR,opc,imm9,0ULL,Rn,Rt); -} - -void load_store_register_pair_imm_offset_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) -{ - load_store_register_pair_imm_jit(ctx,opc,VR,2ULL,L,imm7,Rt2,Rn,Rt); -} - -void load_store_register_pair_imm_post_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) -{ - load_store_register_pair_imm_jit(ctx,opc,VR,1ULL,L,imm7,Rt2,Rn,Rt); -} - -void load_store_register_pair_imm_pre_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) -{ - load_store_register_pair_imm_jit(ctx,opc,VR,3ULL,L,imm7,Rt2,Rn,Rt); -} - -void load_store_register_pair_imm_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t wb, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt) -{ - uint64_t wback = ((uint64_t)wb != (uint64_t)2ULL); - uint64_t postindex = ((uint64_t)wb == (uint64_t)1ULL); - uint64_t memop = !L; - uint64_t is_signed = (((uint64_t)opc & (uint64_t)1ULL)); - uint64_t scale; - if ((VR)) - { - scale = ((uint64_t)2ULL + (uint64_t)opc); - } - else - { - scale = ((uint64_t)2ULL + (uint64_t)(((uint64_t)(((uint64_t)opc >> (uint64_t)1ULL)) & (uint64_t)1ULL))); - } - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - uint64_t offset = ((uint64_t)sign_extend_jit(ctx,imm7,7ULL) << (uint64_t)scale); - uint64_t dbytes = ((uint64_t)datasize / (uint64_t)8ULL); - ir_operand address = XSP_jit(ctx,Rn); - if ((!postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - { - uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : datasize == 128ULL ? int128 : 0; - { - if ((VR)) - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - ir_operand d0 = copy_new_raw_size(ctx, mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(0ULL, int64))), S); - ir_operand d1 = copy_new_raw_size(ctx, mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(dbytes, int64))), S); - V_jit(ctx,Rt,copy_new_raw_size(ctx, d0, int128)); - V_jit(ctx,Rt2,copy_new_raw_size(ctx, d1, int128)); - } - else - { - mem_jit(ctx,S,address,copy_new_raw_size(ctx, V_jit(ctx,Rt), S)); - mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(dbytes, int64)),copy_new_raw_size(ctx, V_jit(ctx,Rt2), S)); - } - } - else - { - if ((((uint64_t)memop == (uint64_t)0ULL))) - { - ir_operand d0 = copy_new_raw_size(ctx, mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(0ULL, int64))), int64); - ir_operand d1 = copy_new_raw_size(ctx, mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(dbytes, int64))), int64); - if ((is_signed)) - { - d0 = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, d0, int32), int64); - d1 = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, d1, int32), int64); - } - X_jit(ctx,Rt,d0); - X_jit(ctx,Rt2,d1); - } - else - { - mem_jit(ctx,S,address,copy_new_raw_size(ctx, X_jit(ctx,Rt), S)); - mem_jit(ctx,S,ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(dbytes, int64)),copy_new_raw_size(ctx, X_jit(ctx,Rt2), S)); - } - } - } - } - if ((wback)) - { - if ((postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - XSP_jit(ctx,Rn,address); - } -} - -void load_store_register_imm_unsigned_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm12, uint64_t Rn, uint64_t Rt) -{ - if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) + if ((((uint64_t)reg_id == (uint64_t)31ULL))) { return; } - uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); - uint64_t wback = 0ULL; - uint64_t postindex = 0ULL; - if ((is_vector)) - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = ((uint64_t)(((uint64_t)bit_c_jit(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); - uint64_t offset = ((uint64_t)imm12 << (uint64_t)scale); - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - ir_operand address = XSP_jit(ctx,Rn); - if ((!postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - { - uint64_t O = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : datasize == 128ULL ? int128 : 0; - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - ir_operand data = copy_new_raw_size(ctx, V_jit(ctx,Rt), O); - mem_jit(ctx,O,address,data); - } - else - { - ir_operand data = copy_new_raw_size(ctx, mem_jit(ctx,O,address), O); - V_jit(ctx,Rt,copy_new_raw_size(ctx, data, int128)); - } - } - } - if ((wback)) - { - if ((postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - XSP_jit(ctx,Rn,address); - } - } else { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = size; - uint64_t offset = ((uint64_t)imm12 << (uint64_t)scale); - if ((((uint64_t)bit_c_jit(ctx,opc,1ULL) == (uint64_t)0ULL))) - { - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - if ((((uint64_t)size == (uint64_t)3ULL))) - regsize = 64ULL; - else - regsize = 32ULL; - _signed = 0ULL; - } - else - { - if ((((uint64_t)size == (uint64_t)3ULL))) - { - undefined_jit(ctx); - } - else - { - memop = 0ULL; - if ((((uint64_t)opc & (uint64_t)1ULL))) - regsize = 32ULL; - else - regsize = 64ULL; - _signed = 1ULL; - } - } - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - ir_operand address = XSP_jit(ctx,Rn); - if ((!postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - { - uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; - { - uint64_t R = regsize == 32ULL ? int32 : regsize == 64ULL ? int64 : 0; - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - ir_operand data = X_jit(ctx,Rt); - mem_jit(ctx,S,address,copy_new_raw_size(ctx, data, S)); - } - else - { - ir_operand n = copy_new_raw_size(ctx, mem_jit(ctx,S,address), int64); - if ((_signed)) - { - n = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, n, S), R), int64); - } - X_jit(ctx,Rt,n); - } - } - } - } - if ((wback)) - { - if ((postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - XSP_jit(ctx,Rn,address); - } - } -} - -void load_store_register_imm_unscaled_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t wb, uint64_t Rn, uint64_t Rt) -{ - if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) - { - return; - } - uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); - uint64_t wback = ((uint64_t)wb != (uint64_t)0ULL); - uint64_t postindex = ((uint64_t)wb == (uint64_t)1ULL); - uint64_t offset = sign_extend_jit(ctx,imm9,9ULL); - if ((is_vector)) - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = ((uint64_t)(((uint64_t)bit_c_jit(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - ir_operand address = XSP_jit(ctx,Rn); - if ((!postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - { - uint64_t O = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : datasize == 128ULL ? int128 : 0; - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - ir_operand data = copy_new_raw_size(ctx, V_jit(ctx,Rt), O); - mem_jit(ctx,O,address,data); - } - else - { - ir_operand data = copy_new_raw_size(ctx, mem_jit(ctx,O,address), O); - V_jit(ctx,Rt,copy_new_raw_size(ctx, data, int128)); - } - } - } - if ((wback)) - { - if ((postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - XSP_jit(ctx,Rn,address); - } - } - else - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = size; - if ((((uint64_t)bit_c_jit(ctx,opc,1ULL) == (uint64_t)0ULL))) - { - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - if ((((uint64_t)size == (uint64_t)3ULL))) - regsize = 64ULL; - else - regsize = 32ULL; - _signed = 0ULL; - } - else - { - if ((((uint64_t)size == (uint64_t)3ULL))) - { - undefined_jit(ctx); - } - else - { - memop = 0ULL; - if ((((uint64_t)opc & (uint64_t)1ULL))) - regsize = 32ULL; - else - regsize = 64ULL; - _signed = 1ULL; - } - } - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - ir_operand address = XSP_jit(ctx,Rn); - if ((!postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - { - uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; - { - uint64_t R = regsize == 32ULL ? int32 : regsize == 64ULL ? int64 : 0; - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - ir_operand data = X_jit(ctx,Rt); - mem_jit(ctx,S,address,copy_new_raw_size(ctx, data, S)); - } - else - { - ir_operand n = copy_new_raw_size(ctx, mem_jit(ctx,S,address), int64); - if ((_signed)) - { - n = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, n, S), R), int64); - } - X_jit(ctx,Rt,n); - } - } - } - } - if ((wback)) - { - if ((postindex)) - { - address = ssa_emit_context::emit_ssa(ctx, ir_add, address, ir_operand::create_con(offset, int64)); - } - XSP_jit(ctx,Rn,address); - } - } -} - -void load_store_register_offset_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t Rm, uint64_t option, uint64_t S, uint64_t Rn, uint64_t Rt) -{ - if ((((uint64_t)((uint64_t)((uint64_t)size == (uint64_t)3ULL) && (uint64_t)((uint64_t)VR == (uint64_t)0ULL)) && (uint64_t)((uint64_t)opc == (uint64_t)2ULL)))) - { - return; - } - uint64_t is_vector = ((uint64_t)VR == (uint64_t)1ULL); - uint64_t wback = 0ULL; - uint64_t postindex = 0ULL; - if ((is_vector)) - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = ((uint64_t)(((uint64_t)bit_c_jit(ctx,opc,1ULL) << (uint64_t)2ULL)) | (uint64_t)size); - uint64_t shift = ((uint64_t)scale * (uint64_t)S); - ir_operand offset = a_extend_reg_64_jit(ctx,Rm,option,shift); - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - ir_operand address = ssa_emit_context::emit_ssa(ctx, ir_add, XSP_jit(ctx,Rn), offset); - uint64_t O = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : datasize == 128ULL ? int128 : 0; - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - ir_operand data = copy_new_raw_size(ctx, V_jit(ctx,Rt), O); - mem_jit(ctx,O,address,data); - } - else - { - ir_operand data = copy_new_raw_size(ctx, mem_jit(ctx,O,address), O); - V_jit(ctx,Rt,copy_new_raw_size(ctx, data, int128)); - } - } - } - else - { - uint64_t memop; - uint64_t regsize; - uint64_t _signed; - uint64_t scale = size; - uint64_t shift = ((uint64_t)scale * (uint64_t)S); - ir_operand offset = a_extend_reg_64_jit(ctx,Rm,option,shift); - if ((((uint64_t)bit_c_jit(ctx,opc,1ULL) == (uint64_t)0ULL))) - { - if ((((uint64_t)opc & (uint64_t)1ULL))) - memop = 0ULL; - else - memop = 1ULL; - if ((((uint64_t)size == (uint64_t)3ULL))) - regsize = 64ULL; - else - regsize = 32ULL; - _signed = 0ULL; - } - else - { - if ((((uint64_t)size == (uint64_t)3ULL))) - { - undefined_jit(ctx); - } - else - { - memop = 0ULL; - if ((((uint64_t)opc & (uint64_t)1ULL))) - regsize = 32ULL; - else - regsize = 64ULL; - _signed = 1ULL; - } - } - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)scale); - ir_operand address = ssa_emit_context::emit_ssa(ctx, ir_add, XSP_jit(ctx,Rn), offset); - uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; - { - uint64_t R = regsize == 32ULL ? int32 : regsize == 64ULL ? int64 : 0; - { - if ((((uint64_t)memop == (uint64_t)1ULL))) - { - ir_operand data = X_jit(ctx,Rt); - mem_jit(ctx,S,address,copy_new_raw_size(ctx, data, S)); - } - else - { - ir_operand n = copy_new_raw_size(ctx, mem_jit(ctx,S,address), int64); - if ((_signed)) - { - n = copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, n, S), R), int64); - } - X_jit(ctx,Rt,n); - } - } - } - } -} - -void load_store_exclusive_ordered_jit(ssa_emit_context* ctx, uint64_t size, uint64_t ordered, uint64_t L, uint64_t Rs, uint64_t o0, uint64_t Rn, uint64_t Rt) -{ - uint64_t is_exclusive = ((uint64_t)ordered == (uint64_t)0ULL); - if ((L)) - { - load_exclusive_jit(ctx,is_exclusive,size,Rn,Rt); - } - else - { - store_exclusive_jit(ctx,is_exclusive,size,Rn,Rt,Rs); - } -} - -ir_operand exclusive_address_mask_jit(ssa_emit_context* ctx) -{ - return ir_operand::create_con(~(((uint64_t)(((uint64_t)4ULL << (uint64_t)4ULL)) - (uint64_t)1ULL)), int64); -} - -void load_exclusive_jit(ssa_emit_context* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)size); - ir_operand address = XSP_jit(ctx,Rn); - uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; - { - ir_operand value = copy_new_raw_size(ctx, mem_jit(ctx,S,address), S); - if ((is_exclusive)) - { - _sys_jit(ctx,(uint64_t)exclusive_address,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, address, exclusive_address_mask_jit(ctx))); - _sys_jit(ctx,(uint64_t)exclusive_value,copy_new_raw_size(ctx, value, int64)); - } - X_jit(ctx,Rt,copy_new_raw_size(ctx, value, int64)); - } -} - -void store_exclusive_jit(ssa_emit_context* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t Rs) -{ - uint64_t datasize = ((uint64_t)8ULL << (uint64_t)size); - ir_operand address = XSP_jit(ctx,Rn); - uint64_t S = datasize == 8ULL ? int8 : datasize == 16ULL ? int16 : datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; - { - if ((is_exclusive)) - { - ir_operand mask = exclusive_address_mask_jit(ctx); - ir_operand _exclusive_address = _sys_jit(ctx,(uint64_t)exclusive_address); - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_equal, _exclusive_address, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, address, mask)); - - ir_operation_block::jump_if(ctx->ir,yes, condition); - { - X_jit(ctx,Rs,ir_operand::create_con(1ULL, int64)); - } - - ir_operation_block::jump(ctx->ir,end); - ir_operation_block::mark_label(ctx->ir, yes); - - { - ir_operand to_swap = copy_new_raw_size(ctx, X_jit(ctx,Rt), S); - ir_operand expecting = copy_new_raw_size(ctx, _sys_jit(ctx,(uint64_t)exclusive_value), S); - ir_operand cas_success = copy_new_raw_size(ctx, compare_and_swap_jit(ctx,address,copy_new_raw_size(ctx, expecting, int64),copy_new_raw_size(ctx, to_swap, int64),datasize), S); - X_jit(ctx,Rs,copy_new_raw_size(ctx, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, cas_success, ir_operand::create_con(1ULL, S)), ir_operand::create_con(1ULL, S)), int64)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - } - else - { - mem_jit(ctx,S,address,copy_new_raw_size(ctx, X_jit(ctx,Rt), S)); - } + _x_jit(ctx,reg_id,value); } } @@ -14371,6 +15425,293 @@ void fcvtp_scalar_integer_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype convert_to_int_jit(ctx,sf,ftype,Rd,Rn,(uint64_t)FPRounding_POSINF,U,0ULL); } +void fadd_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_addss,(uint64_t)x86_addsd); + return; + } + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPAdd_jit); +} + +void fsub_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_subss,(uint64_t)x86_subsd); + return; + } + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPSub_jit); +} + +void fmul_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_mulss,(uint64_t)x86_mulsd); + return; + } + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMul_jit); +} + +void fdiv_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_divss,(uint64_t)x86_divsd); + return; + } + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPDiv_jit); +} + +void fmax_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_maxss,(uint64_t)x86_maxsd); + return; + } + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMax_jit); +} + +void fmin_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_minss,(uint64_t)x86_minsd); + return; + } + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMin_jit); +} + +void fmaxnm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMaxNum_jit); +} + +void fminnm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMinNum_jit); +} + +void fnmul_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + ir_operand operand1 = V_jit(ctx,Rn); + ir_operand operand2 = V_jit(ctx,Rm); + uint64_t esize = get_flt_size_jit(ctx,ftype); + ir_operand negator = copy_new_raw_size(ctx, ir_operand::create_con((((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))), int64), int128); + uint64_t multiply_instruction; + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + multiply_instruction = (uint64_t)x86_mulss; + } + else if ((((uint64_t)esize == (uint64_t)64ULL))) + { + multiply_instruction = (uint64_t)x86_mulsd; + } + else + { + undefined_jit(ctx); + } + operand2 = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand2,negator), int128); + ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,multiply_instruction,operand1,operand2), int128); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); + } + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + V_jit(ctx,Rd,result); + return; + } + float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPNMul_jit); +} + +void fabs_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) + { + uint64_t esize = get_flt_size_jit(ctx,ftype); + ir_operand operand = V_jit(ctx,Rn); + ir_operand mask = copy_new_raw_size(ctx, ir_operand::create_con((((uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))) - (uint64_t)1ULL)), int64), int128); + ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_pand,operand,mask), int128); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); + } + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + V_jit(ctx,Rd,result); + return; + } + float_unary_scalar_jit(ctx,Rd,Rn,ftype,(uint64_t)FPAbs_jit); +} + +void fneg_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) + { + uint64_t esize = get_flt_size_jit(ctx,ftype); + ir_operand operand = V_jit(ctx,Rn); + ir_operand mask = copy_new_raw_size(ctx, ir_operand::create_con((((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))), int64), int128); + ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand,mask), int128); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); + } + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + V_jit(ctx,Rd,result); + return; + } + float_unary_scalar_jit(ctx,Rd,Rn,ftype,(uint64_t)FPNeg_jit); +} + +void fneg_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) + { + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + ir_operand operand = V_jit(ctx,Rn); + ir_operand mask = sse_coppy_gp_across_lanes_jit(ctx,ir_operand::create_con((((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))), int64),esize); + ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand,mask), int128); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + } + V_jit(ctx,Rd,result); + return; + } + float_unary_vector_jit(ctx,Rd,Rn,Q,sz,(uint64_t)FPNeg_jit); +} + +void fsqrt_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) + { + uint64_t esize = get_flt_size_jit(ctx,ftype); + ir_operand operand = V_jit(ctx,Rn); + uint64_t sqrt_instruction; + if ((((uint64_t)esize == (uint64_t)64ULL))) + { + sqrt_instruction = (uint64_t)x86_sqrtsd; + } + else + { + sqrt_instruction = (uint64_t)x86_sqrtss; + } + ir_operand result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,int128,sqrt_instruction,operand), int128); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); + } + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + V_jit(ctx,Rd,result); + return; + } + float_unary_scalar_jit(ctx,Rd,Rn,ftype,(uint64_t)FPSqrt_jit); +} + +void fsqrt_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) + { + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + ir_operand operand = V_jit(ctx,Rn); + uint64_t sqrt_instruction; + if ((((uint64_t)esize == (uint64_t)64ULL))) + { + sqrt_instruction = (uint64_t)x86_sqrtpd; + } + else + { + sqrt_instruction = (uint64_t)x86_sqrtps; + } + ir_operand result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,int128,sqrt_instruction,operand), int128); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + } + V_jit(ctx,Rd,result); + return; + } + float_unary_vector_jit(ctx,Rd,Rn,Q,sz,(uint64_t)FPSqrt_jit); +} + +void frecpe_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) + { + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + ir_operand operand = V_jit(ctx,Rn); + ir_operand one = sse_coppy_gp_across_lanes_jit(ctx,float_imm_jit(ctx,ir_operand::create_con(1ULL, int64),esize),esize); + uint64_t divide_instruction; + if ((((uint64_t)esize == (uint64_t)64ULL))) + { + divide_instruction = (uint64_t)x86_divpd; + } + else + { + divide_instruction = (uint64_t)x86_divps; + } + ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,divide_instruction,one,operand), int128); + if ((((uint64_t)Q == (uint64_t)0ULL))) + { + ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + } + V_jit(ctx,Rd,result); + return; + } + float_unary_vector_jit(ctx,Rd,Rn,Q,sz,(uint64_t)FPRecipEstimate_jit); +} + +void frsqrte_scalar_jit(ssa_emit_context* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd) +{ + uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); + ir_operand operand = copy_new_raw_size(ctx, V_jit(ctx,Rn), int64); + if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) + { + ir_operand one = copy_new_raw_size(ctx, float_imm_jit(ctx,ir_operand::create_con(1ULL, int64),esize), int128); + uint64_t sqrt_instruction; + uint64_t divide_instruction; + if ((((uint64_t)esize == (uint64_t)64ULL))) + { + sqrt_instruction = (uint64_t)x86_sqrtsd; + divide_instruction = (uint64_t)x86_divsd; + } + else + { + sqrt_instruction = (uint64_t)x86_sqrtss; + divide_instruction = (uint64_t)x86_divss; + } + ir_operand sqrt_result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,int128,sqrt_instruction,copy_new_raw_size(ctx, operand, int128)), int128); + ir_operand reciprocal_result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,divide_instruction,one,sqrt_result), int128); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + ssa_emit_context::vector_insert(ctx,reciprocal_result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); + } + ssa_emit_context::vector_insert(ctx,reciprocal_result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); + V_jit(ctx,Rd,reciprocal_result); + } + else + { + ir_operand fpcr_state = _sys_jit(ctx,(uint64_t)fpcr); + ir_operand result = FPRSqrtEstimate_jit(ctx,operand,fpcr_state,esize); + if ((((uint64_t)esize == (uint64_t)32ULL))) + { + result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, result, ir_operand::create_con(4294967295ULL, int64)); + } + V_jit(ctx,Rd,copy_new_raw_size(ctx, result, int128)); + } +} + +void fmov_scalar_immediate_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t imm8, uint64_t Rd) +{ + uint64_t fltsize = get_flt_size_jit(ctx,ftype); + ir_operand imm = ir_operand::create_con(vfp_expand_imm_jit(ctx,imm8,fltsize), int64); + V_jit(ctx,Rd,copy_new_raw_size(ctx, imm, int128)); +} + void fadd_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd) { if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) @@ -14795,1344 +16136,3 @@ void fcmle_zero_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint6 fcm_vector_jit(ctx,Rd,Rn,-1ULL,3ULL,Q,sz); } -void fadd_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_addss,(uint64_t)x86_addsd); - return; - } - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPAdd_jit); -} - -void fsub_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_subss,(uint64_t)x86_subsd); - return; - } - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPSub_jit); -} - -void fmul_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_mulss,(uint64_t)x86_mulsd); - return; - } - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMul_jit); -} - -void fdiv_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_divss,(uint64_t)x86_divsd); - return; - } - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPDiv_jit); -} - -void fmax_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_maxss,(uint64_t)x86_maxsd); - return; - } - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMax_jit); -} - -void fmin_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - intrinsic_float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,-1ULL,(uint64_t)x86_minss,(uint64_t)x86_minsd); - return; - } - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMin_jit); -} - -void fmaxnm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMaxNum_jit); -} - -void fminnm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPMinNum_jit); -} - -void fnmul_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - uint64_t esize = get_flt_size_jit(ctx,ftype); - ir_operand negator = copy_new_raw_size(ctx, ir_operand::create_con((((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))), int64), int128); - uint64_t multiply_instruction; - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - multiply_instruction = (uint64_t)x86_mulss; - } - else if ((((uint64_t)esize == (uint64_t)64ULL))) - { - multiply_instruction = (uint64_t)x86_mulsd; - } - else - { - undefined_jit(ctx); - } - operand2 = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand2,negator), int128); - ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,multiply_instruction,operand1,operand2), int128); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); - } - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - V_jit(ctx,Rd,result); - return; - } - float_binary_scalar_jit(ctx,Rd,Rn,Rm,ftype,(uint64_t)FPNMul_jit); -} - -void fabs_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) - { - uint64_t esize = get_flt_size_jit(ctx,ftype); - ir_operand operand = V_jit(ctx,Rn); - ir_operand mask = copy_new_raw_size(ctx, ir_operand::create_con((((uint64_t)(((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))) - (uint64_t)1ULL)), int64), int128); - ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_pand,operand,mask), int128); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); - } - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - V_jit(ctx,Rd,result); - return; - } - float_unary_scalar_jit(ctx,Rd,Rn,ftype,(uint64_t)FPAbs_jit); -} - -void fneg_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) - { - uint64_t esize = get_flt_size_jit(ctx,ftype); - ir_operand operand = V_jit(ctx,Rn); - ir_operand mask = copy_new_raw_size(ctx, ir_operand::create_con((((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))), int64), int128); - ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand,mask), int128); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); - } - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - V_jit(ctx,Rd,result); - return; - } - float_unary_scalar_jit(ctx,Rd,Rn,ftype,(uint64_t)FPNeg_jit); -} - -void fneg_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) - { - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - ir_operand operand = V_jit(ctx,Rn); - ir_operand mask = sse_coppy_gp_across_lanes_jit(ctx,ir_operand::create_con((((uint64_t)1ULL << (uint64_t)(((uint64_t)esize - (uint64_t)1ULL)))), int64),esize); - ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand,mask), int128); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - } - V_jit(ctx,Rd,result); - return; - } - float_unary_vector_jit(ctx,Rd,Rn,Q,sz,(uint64_t)FPNeg_jit); -} - -void fsqrt_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)) && (uint64_t)((uint64_t)ftype != (uint64_t)3ULL)))) - { - uint64_t esize = get_flt_size_jit(ctx,ftype); - ir_operand operand = V_jit(ctx,Rn); - uint64_t sqrt_instruction; - if ((((uint64_t)esize == (uint64_t)64ULL))) - { - sqrt_instruction = (uint64_t)x86_sqrtsd; - } - else - { - sqrt_instruction = (uint64_t)x86_sqrtss; - } - ir_operand result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,int128,sqrt_instruction,operand), int128); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); - } - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - V_jit(ctx,Rd,result); - return; - } - float_unary_scalar_jit(ctx,Rd,Rn,ftype,(uint64_t)FPSqrt_jit); -} - -void fsqrt_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) - { - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - ir_operand operand = V_jit(ctx,Rn); - uint64_t sqrt_instruction; - if ((((uint64_t)esize == (uint64_t)64ULL))) - { - sqrt_instruction = (uint64_t)x86_sqrtpd; - } - else - { - sqrt_instruction = (uint64_t)x86_sqrtps; - } - ir_operand result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,int128,sqrt_instruction,operand), int128); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - } - V_jit(ctx,Rd,result); - return; - } - float_unary_vector_jit(ctx,Rd,Rn,Q,sz,(uint64_t)FPSqrt_jit); -} - -void frecpe_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) - { - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - ir_operand operand = V_jit(ctx,Rn); - ir_operand one = sse_coppy_gp_across_lanes_jit(ctx,float_imm_jit(ctx,ir_operand::create_con(1ULL, int64),esize),esize); - uint64_t divide_instruction; - if ((((uint64_t)esize == (uint64_t)64ULL))) - { - divide_instruction = (uint64_t)x86_divpd; - } - else - { - divide_instruction = (uint64_t)x86_divps; - } - ir_operand result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,divide_instruction,one,operand), int128); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - } - V_jit(ctx,Rd,result); - return; - } - float_unary_vector_jit(ctx,Rd,Rn,Q,sz,(uint64_t)FPRecipEstimate_jit); -} - -void frsqrte_scalar_jit(ssa_emit_context* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - ir_operand operand = copy_new_raw_size(ctx, V_jit(ctx,Rn), int64); - if ((((uint64_t)use_fast_float_jit(ctx) && (uint64_t)use_x86_sse_jit(ctx)))) - { - ir_operand one = copy_new_raw_size(ctx, float_imm_jit(ctx,ir_operand::create_con(1ULL, int64),esize), int128); - uint64_t sqrt_instruction; - uint64_t divide_instruction; - if ((((uint64_t)esize == (uint64_t)64ULL))) - { - sqrt_instruction = (uint64_t)x86_sqrtsd; - divide_instruction = (uint64_t)x86_divsd; - } - else - { - sqrt_instruction = (uint64_t)x86_sqrtss; - divide_instruction = (uint64_t)x86_divss; - } - ir_operand sqrt_result = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,int128,sqrt_instruction,copy_new_raw_size(ctx, operand, int128)), int128); - ir_operand reciprocal_result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,divide_instruction,one,sqrt_result), int128); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - ssa_emit_context::vector_insert(ctx,reciprocal_result, 1ULL, 32ULL, ir_operand::create_con(0ULL, int64)); - } - ssa_emit_context::vector_insert(ctx,reciprocal_result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - V_jit(ctx,Rd,reciprocal_result); - } - else - { - ir_operand fpcr_state = _sys_jit(ctx,(uint64_t)fpcr); - ir_operand result = FPRSqrtEstimate_jit(ctx,operand,fpcr_state,esize); - if ((((uint64_t)esize == (uint64_t)32ULL))) - { - result = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, result, ir_operand::create_con(4294967295ULL, int64)); - } - V_jit(ctx,Rd,copy_new_raw_size(ctx, result, int128)); - } -} - -void fmov_scalar_immediate_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t imm8, uint64_t Rd) -{ - uint64_t fltsize = get_flt_size_jit(ctx,ftype); - ir_operand imm = ir_operand::create_con(vfp_expand_imm_jit(ctx,imm8,fltsize), int64); - V_jit(ctx,Rd,copy_new_raw_size(ctx, imm, int128)); -} - -ir_operand _compare_and_swap_jit(ssa_emit_context* ctx, ir_operand physical_address, ir_operand expecting, ir_operand to_swap, uint64_t size) -{ - if ((use_x86_jit(ctx))) - { - if ((((uint64_t)size != (uint64_t)64ULL))) - { - ir_operand mask = ir_operand::create_con(((uint64_t)(((uint64_t)1ULL << (uint64_t)size)) - (uint64_t)1ULL), int64); - ir_operand masking_value = ssa_emit_context::emit_ssa(ctx, ir_load, physical_address, int64); - masking_value = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, masking_value, ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, mask)); - expecting = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, expecting, mask), masking_value); - to_swap = ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, to_swap, mask), masking_value); - } - return copy_new_raw_size(ctx, intrinsic_ternary_jit(ctx,int64,(uint64_t)x86_cmpxchg,physical_address,expecting,to_swap), int64); - } - return call_jit(ctx,physical_address,expecting,to_swap,ir_operand::create_con(size, int64),ir_operand::create_con(0ULL, int64),ir_operand::create_con(0ULL, int64),(uint64_t)compare_and_swap_interpreter_cpp); -} - -ir_operand compare_and_swap_jit(ssa_emit_context* ctx, ir_operand address, ir_operand expecting, ir_operand to_swap, uint64_t size) -{ - address = translate_address_jit(ctx,address); - return _compare_and_swap_jit(ctx,address,expecting,to_swap,size); -} - -void mem_jit(ssa_emit_context* ctx,uint64_t O, ir_operand address, ir_operand value) -{ - address = translate_address_jit(ctx,address); - ssa_emit_context::store(ctx, address, value); -} - -ir_operand mem_jit(ssa_emit_context* ctx,uint64_t O, ir_operand address) -{ - address = translate_address_jit(ctx,address); - return ssa_emit_context::emit_ssa(ctx, ir_load, address, O); -} - -ir_operand XSP_jit(ssa_emit_context* ctx, uint64_t reg_id) -{ - return _x_jit(ctx,reg_id); -} - -void XSP_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value) -{ - _x_jit(ctx,reg_id,value); -} - -ir_operand X_jit(ssa_emit_context* ctx, uint64_t reg_id) -{ - if ((((uint64_t)reg_id == (uint64_t)31ULL))) - { - return ir_operand::create_con(0ULL, int64); - } - else - { - return _x_jit(ctx,reg_id); - } -} - -void X_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value) -{ - if ((((uint64_t)reg_id == (uint64_t)31ULL))) - { - return; - } - else - { - _x_jit(ctx,reg_id,value); - } -} - -void dup_general_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - ir_operand element = X_jit(ctx,Rn); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand result; - if ((use_x86_sse_jit(ctx))) - { - result = sse_coppy_gp_across_lanes_jit(ctx,element,esize); - if ((!Q)) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - } - } - else - { - result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ssa_emit_context::vector_insert(ctx,result, e, esize, element); - } - } - V_jit(ctx,Rd,result); -} - -void dup_element_scalar_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); - uint64_t index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)bit_c_jit(ctx,imm5,4ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = esize; - uint64_t elements = 1ULL; - dup_element_jit(ctx,index,esize,elements,Rn,Rd); -} - -void dup_element_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); - uint64_t index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)bit_c_jit(ctx,imm5,4ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - dup_element_jit(ctx,index,esize,elements,Rn,Rd); -} - -void move_to_gp_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t U, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)32ULL << (uint64_t)Q); - uint64_t index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - ir_operand operand = V_jit(ctx,Rn); - uint64_t S = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; - { - uint64_t R = datasize == 32ULL ? int32 : datasize == 64ULL ? int64 : 0; - { - ir_operand result = copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand, index, esize), R); - if ((!U)) - { - result = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, result, S), R); - } - X_jit(ctx,Rd,copy_new_raw_size(ctx, result, int64)); - } - } -} - -void ins_general_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); - uint64_t index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - ir_operand element = X_jit(ctx,Rn); - ir_operand result = V_jit(ctx,Rd); - ssa_emit_context::vector_insert(ctx,result, index, esize, element); - V_jit(ctx,Rd,result); -} - -void ins_element_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t imm4, uint64_t Rn, uint64_t Rd) -{ - uint64_t size = lowest_bit_set_c_jit(ctx,bits_c_jit(ctx,imm5,3ULL,0ULL)); - uint64_t dst_index = bits_c_jit(ctx,imm5,4ULL,((uint64_t)size + (uint64_t)1ULL)); - uint64_t src_index = bits_c_jit(ctx,imm4,3ULL,size); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - ir_operand operand = V_jit(ctx,Rn); - ir_operand result = V_jit(ctx,Rd); - ssa_emit_context::vector_insert(ctx,result, dst_index, esize, ssa_emit_context::vector_extract(ctx,operand, src_index, esize)); - V_jit(ctx,Rd,result); -} - -void movi_immediate_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t op, uint64_t immhi, uint64_t cmode, uint64_t immlo, uint64_t Rd) -{ - uint64_t d = Rd; - uint64_t imm8 = ((uint64_t)(((uint64_t)immhi << (uint64_t)5ULL)) | (uint64_t)immlo); - uint64_t cmode_helper = ((uint64_t)(((uint64_t)cmode << (uint64_t)1ULL)) | (uint64_t)op); - uint64_t mode = 0ULL; - if ((((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)2ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)18ULL))))) - { - mode = 0ULL; - } - else if ((((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)3ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)19ULL))))) - { - mode = 1ULL; - } - else if ((((uint64_t)((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)1ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)17ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)29ULL)) == (uint64_t)25ULL))))) - { - mode = 2ULL; - } - else if ((((uint64_t)((uint64_t)((uint64_t)((uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)19ULL)) == (uint64_t)0ULL)) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)27ULL)) == (uint64_t)16ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)29ULL)) == (uint64_t)24ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)30ULL)) == (uint64_t)28ULL))) || (uint64_t)(((uint64_t)(((uint64_t)cmode_helper & (uint64_t)31ULL)) == (uint64_t)30ULL))))) - { - mode = 3ULL; - } - else if ((((uint64_t)cmode_helper == (uint64_t)31ULL))) - { - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - undefined_jit(ctx); - } - mode = 3ULL; - } - else - { - undefined_jit(ctx); - } - ir_operand imm64 = ir_operand::create_con(expand_imm_jit(ctx,op,cmode,imm8), int64); - ir_operand imm = copy_new_raw_size(ctx, imm64, int128); - if ((Q)) - { - ssa_emit_context::vector_insert(ctx,imm, 1ULL, 64ULL, imm64); - } - ir_operand operand = ssa_emit_context::vector_zero(ctx); - ir_operand result = ssa_emit_context::vector_zero(ctx); - if ((((uint64_t)mode == (uint64_t)3ULL))) - { - result = imm; - } - else if ((((uint64_t)mode == (uint64_t)2ULL))) - { - for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) - { - ssa_emit_context::vector_insert(ctx,result, e, 64ULL, ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, ssa_emit_context::vector_extract(ctx,imm, e, 64ULL))); - } - } - else if ((((uint64_t)mode == (uint64_t)0ULL))) - { - operand = V_jit(ctx,Rd); - for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) - { - ssa_emit_context::vector_insert(ctx,result, e, 64ULL, ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, ssa_emit_context::vector_extract(ctx,operand, e, 64ULL), ssa_emit_context::vector_extract(ctx,imm, e, 64ULL))); - } - } - else if ((((uint64_t)mode == (uint64_t)1ULL))) - { - operand = V_jit(ctx,Rd); - for (uint64_t e = 0; e < (((uint64_t)Q + (uint64_t)1ULL)); e++) - { - ssa_emit_context::vector_insert(ctx,result, e, 64ULL, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::vector_extract(ctx,operand, e, 64ULL), ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, ssa_emit_context::vector_extract(ctx,imm, e, 64ULL)))); - } - } - else - { - undefined_jit(ctx); - } - V_jit(ctx,Rd,result); -} - -void fmov_general_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t Rn, uint64_t Rd) -{ - uint64_t intsize = ((uint64_t)32ULL << (uint64_t)sf); - uint64_t fltsize = get_flt_size_jit(ctx,ftype); - if ((((uint64_t)intsize != (uint64_t)fltsize))) - { - undefined_jit(ctx); - } - uint64_t size = intsize; - uint64_t part = rmode; - uint64_t int_to_float = opcode; - if ((int_to_float)) - { - ir_operand result = X_jit(ctx,Rn); - uint64_t O = size == 32ULL ? int32 : size == 64ULL ? int64 : 0; - { - VPart_jit(ctx,Rd,part,size,copy_new_raw_size(ctx, copy_new_raw_size(ctx, result, O), int64)); - } - } - else - { - ir_operand v = V_jit(ctx,Rn); - ir_operand result = ssa_emit_context::vector_extract(ctx,v, part, size); - X_jit(ctx,Rd,result); - } -} - -void convert_to_float_gp_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd) -{ - convert_to_float_jit(ctx,sf,ftype,U,Rn,Rd,0ULL); -} - -void convert_to_float_vector_scalar_jit(ssa_emit_context* ctx, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - convert_to_float_jit(ctx,sz,sz,U,Rn,Rd,1ULL); -} - -void convert_to_float_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)32ULL << (uint64_t)sz); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand = V_jit(ctx,Rn); - ir_operand result = ssa_emit_context::vector_zero(ctx); - uint64_t F = esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; - { - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element = ssa_emit_context::vector_extract(ctx,operand, e, esize); - ir_operand working; - if ((U)) - { - working = copy_new_raw_size(ctx, ssa_emit_context::convert_to_float(ctx,copy_new_raw_size(ctx, element, F),F,F, 0), int64); - } - else - { - working = copy_new_raw_size(ctx, ssa_emit_context::convert_to_float(ctx,copy_new_raw_size(ctx, element, F),F,F, 1), int64); - } - ssa_emit_context::vector_insert(ctx,result, e, esize, working); - } - V_jit(ctx,Rd,result); - } -} - -void shl_immedaite_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_jit(ctx,immh,32ULL)); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t shift = ((uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb)) - (uint64_t)esize); - ir_operand operand = V_jit(ctx,Rn); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element = ssa_emit_context::vector_extract(ctx,operand, e, esize); - element = ssa_emit_context::emit_ssa(ctx, ir_shift_left, element, ir_operand::create_con(shift, int64)); - ssa_emit_context::vector_insert(ctx,result, e, esize, element); - } - V_jit(ctx,Rd,result); -} - -void sshr_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_jit(ctx,immh,32ULL)); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t shift = ((uint64_t)(((uint64_t)esize * (uint64_t)2ULL)) - (uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb))); - ir_operand operand = V_jit(ctx,Rn); - ir_operand result = ssa_emit_context::vector_zero(ctx); - uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; - { - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element = ssa_emit_context::vector_extract(ctx,operand, e, esize); - element = shift_right_check_jit(ctx,ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, element, O), int64),ir_operand::create_con(shift, int64),esize,0ULL); - ssa_emit_context::vector_insert(ctx,result, e, esize, element); - } - V_jit(ctx,Rd,result); - } -} - -void shll_shll2_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_jit(ctx,bits_c_jit(ctx,immh,2ULL,0ULL),32ULL)); - uint64_t datasize = 64ULL; - uint64_t part = Q; - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t shift = ((uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb)) - (uint64_t)esize); - ir_operand operand = VPart_jit(ctx,Rn,part,datasize); - ir_operand result = ssa_emit_context::vector_zero(ctx); - ir_operand working_vector = ssa_emit_context::vector_zero(ctx); - ssa_emit_context::vector_insert(ctx,working_vector, 0ULL, datasize, operand); - uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; - { - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element = ssa_emit_context::vector_extract(ctx,working_vector, e, esize); - if ((!U)) - { - element = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, element, O), int64); - } - element = ssa_emit_context::emit_ssa(ctx, ir_shift_left, element, ir_operand::create_con(shift, int64)); - ssa_emit_context::vector_insert(ctx,result, e, (((uint64_t)2ULL * (uint64_t)esize)), element); - } - V_jit(ctx,Rd,result); - } -} - -void shrn_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)highest_bit_set_c_jit(ctx,bits_c_jit(ctx,immh,2ULL,0ULL),32ULL)); - uint64_t datasize = 64ULL; - uint64_t part = Q; - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t shift = ((uint64_t)(((uint64_t)2ULL * (uint64_t)esize)) - (uint64_t)(((uint64_t)(((uint64_t)immh << (uint64_t)3ULL)) | (uint64_t)immb))); - ir_operand operand = V_jit(ctx,Rn); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element = shift_right_check_jit(ctx,ssa_emit_context::vector_extract(ctx,operand, e, (((uint64_t)2ULL * (uint64_t)esize))),ir_operand::create_con(shift, int64),((uint64_t)2ULL * (uint64_t)esize),1ULL); - ssa_emit_context::vector_insert(ctx,result, e, esize, element); - } - VPart_jit(ctx,Rd,part,datasize,copy_new_raw_size(ctx, result, int64)); -} - -void rev64_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint64_t csize = 64ULL; - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t containers = ((uint64_t)datasize / (uint64_t)csize); - ir_operand operand = V_jit(ctx,Rn); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t c = 0; c < (containers); c++) - { - ir_operand container = ssa_emit_context::vector_extract(ctx,operand, c, csize); - ssa_emit_context::vector_insert(ctx,result, c, csize, reverse_jit(ctx,copy_new_raw_size(ctx, container, int128),esize,csize)); - } - V_jit(ctx,Rd,result); -} - -void neg_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - ir_operand operand = V_jit(ctx,Rn); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_negate, ssa_emit_context::vector_extract(ctx,operand, e, esize))); - } - V_jit(ctx,Rd,result); -} - -void not_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rn, uint64_t Rd) -{ - ir_operand operand = V_jit(ctx,Rn); - uint64_t esize = 8ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, ssa_emit_context::vector_extract(ctx,operand, e, esize))); - } - V_jit(ctx,Rd,result); -} - -void abs_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - ir_operand operand = V_jit(ctx,Rn); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; - { - ir_operand working = ssa_emit_context::emit_ssa(ctx, ir_move, copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand, e, esize), O)); - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_less_signed, working, ir_operand::create_con(0ULL, O)); - - condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); - - ir_operation_block::jump_if(ctx->ir,end, condition); - - { - ssa_emit_context::move(ctx,working,ssa_emit_context::emit_ssa(ctx, ir_negate, working)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - ssa_emit_context::vector_insert(ctx,result, e, esize, working); - } - } - V_jit(ctx,Rd,result); -} - -void mul_vector_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd) -{ - uint64_t idxdsize = ((uint64_t)64ULL << (uint64_t)H); - uint64_t index; - uint64_t rm_hi; - if ((((uint64_t)size == (uint64_t)1ULL))) - { - index = H; - index = ((uint64_t)L | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); - index = ((uint64_t)M | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); - rm_hi = 0ULL; - } - else if ((((uint64_t)size == (uint64_t)2ULL))) - { - index = H; - index = ((uint64_t)L | (uint64_t)(((uint64_t)index << (uint64_t)1ULL))); - rm_hi = M; - } - else - { - undefined_jit(ctx); - } - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,((uint64_t)Rm | (uint64_t)(((uint64_t)rm_hi << (uint64_t)4ULL)))); - ir_operand result = ssa_emit_context::vector_zero(ctx); - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, index, esize); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); - ir_operand product = ssa_emit_context::emit_ssa(ctx, ir_multiply, element1, element2); - ssa_emit_context::vector_insert(ctx,result, e, esize, product); - } - V_jit(ctx,Rd,result); -} - -void mul_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); - ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); - ir_operand working = ssa_emit_context::emit_ssa(ctx, ir_multiply, element1, element2); - ssa_emit_context::vector_insert(ctx,result, e, esize, working); - } - V_jit(ctx,Rd,result); -} - -void ext_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t imm4, uint64_t Rn, uint64_t Rd) -{ - ir_operand lo = V_jit(ctx,Rn); - ir_operand hi = V_jit(ctx,Rm); - uint64_t vector_size = ((uint64_t)8ULL << (uint64_t)Q); - uint64_t start = imm4; - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (vector_size); e++) - { - ir_operand working = copy_new_raw_size(ctx, get_from_concacted_vector_jit(ctx,hi,lo,((uint64_t)start + (uint64_t)e),vector_size,8ULL), int8); - ssa_emit_context::vector_insert(ctx,result, e, 8ULL, working); - } - V_jit(ctx,Rd,result); -} - -void compare_above_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; - { - ir_operand element1 = copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand1, e, esize), O); - ir_operand element2 = copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand2, e, esize), O); - ir_operand working; - if ((U)) - { - working = ssa_emit_context::emit_ssa(ctx, ir_compare_greater_unsigned, element1, element2); - } - else - { - working = ssa_emit_context::emit_ssa(ctx, ir_compare_greater_signed, element1, element2); - } - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_subtract, ir_operand::create_con(0ULL, O), working)); - } - } - V_jit(ctx,Rd,result); -} - -void shl_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element = ssa_emit_context::emit_ssa(ctx, ir_move, ssa_emit_context::vector_extract(ctx,operand1, e, esize)); - ir_operand shift = ssa_emit_context::emit_ssa(ctx, ir_move, ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,operand2, e, esize), int8), int64)); - if ((!U)) - { - uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; - { - element = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, element, O), int64); - } - } - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = ssa_emit_context::emit_ssa(ctx, ir_compare_greater_equal_signed, shift, ir_operand::create_con(0ULL, int64)); - - ir_operation_block::jump_if(ctx->ir,yes, condition); - { - ssa_emit_context::move(ctx,shift,ssa_emit_context::emit_ssa(ctx, ir_negate, shift)); - ssa_emit_context::move(ctx,element,shift_right_check_jit(ctx,element,shift,esize,U)); - } - - ir_operation_block::jump(ctx->ir,end); - ir_operation_block::mark_label(ctx->ir, yes); - - { - ssa_emit_context::move(ctx,element,shift_left_check_jit(ctx,element,shift,esize)); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - ssa_emit_context::vector_insert(ctx,result, e, esize, element); - } - V_jit(ctx,Rd,result); -} - -void add_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result; - if ((use_x86_sse2_jit(ctx))) - { - uint64_t add_instruction; - if ((((uint64_t)esize == (uint64_t)8ULL))) - add_instruction = (uint64_t)x86_paddb; - else if ((((uint64_t)esize == (uint64_t)16ULL))) - add_instruction = (uint64_t)x86_paddw; - else if ((((uint64_t)esize == (uint64_t)32ULL))) - add_instruction = (uint64_t)x86_paddd; - else if ((((uint64_t)esize == (uint64_t)64ULL))) - add_instruction = (uint64_t)x86_paddq; - else - undefined_jit(ctx); - result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,add_instruction,operand1,operand2), int128); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - ssa_emit_context::vector_insert(ctx,result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - } - } - else - { - result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); - ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_add, element1, element2)); - } - } - V_jit(ctx,Rd,result); -} - -void addlv_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t is_unsigned = U; - ir_operand source = V_jit(ctx,Rn); - ir_operand operand = V_jit(ctx,Rn); - ir_operand sum = ir_operand::create_con(0ULL, int64); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand working = ssa_emit_context::vector_extract(ctx,operand, e, esize); - if ((!is_unsigned)) - { - uint64_t O = esize == 8ULL ? int8 : esize == 16ULL ? int16 : esize == 32ULL ? int32 : esize == 64ULL ? int64 : 0; - { - working = ssa_emit_context::emit_ssa(ctx,ir_sign_extend,copy_new_raw_size(ctx, working, O), int64); - } - } - sum = ssa_emit_context::emit_ssa(ctx, ir_add, sum, working); - } - ir_operand final = ssa_emit_context::vector_zero(ctx); - ssa_emit_context::vector_insert(ctx,final, 0ULL, (((uint64_t)2ULL * (uint64_t)esize)), sum); - V_jit(ctx,Rd,final); -} - -void cnt_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = 8ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)8ULL); - ir_operand source = V_jit(ctx,Rn); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand working = copy_new_raw_size(ctx, ssa_emit_context::vector_extract(ctx,source, e, esize), int8); - ir_operand count = ssa_emit_context::emit_ssa(ctx, ir_move, ir_operand::create_con(0ULL, int8)); - if ((use_x86_jit(ctx))) - { - count = copy_new_raw_size(ctx, intrinsic_unary_jit(ctx,int16,(uint64_t)x86_popcnt,copy_new_raw_size(ctx, working, int16)), int8); - } - else - { - for (uint64_t b = 0; b < (esize); b++) - { - ir_operand bit = ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, working, ir_operand::create_con(b, int8)), ir_operand::create_con(1ULL, int8)); - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = bit; - - condition = ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, condition, ir_operand::create_con(1, condition.meta_data)); - - ir_operation_block::jump_if(ctx->ir,end, condition); - - { - ssa_emit_context::move(ctx,count,ssa_emit_context::emit_ssa(ctx, ir_add, count, ir_operand::create_con(1ULL, int8))); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - } - } - ssa_emit_context::vector_insert(ctx,result, e, esize, count); - } - V_jit(ctx,Rd,result); -} - -void orr_orn_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((use_x86_sse_jit(ctx))) - { - x86_sse_logic_vector_jit(ctx,Rd,Rn,Rm,Q,invert,(uint64_t)x86_orps); - } - else - { - uint64_t esize = 64ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); - ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); - if ((invert)) - { - element2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, element2); - } - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_or, element1, element2)); - } - V_jit(ctx,Rd,result); - } -} - -void bsl_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = 64ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand1 = V_jit(ctx,Rm); - ir_operand operand2 = V_jit(ctx,Rd); - ir_operand operand3 = V_jit(ctx,Rn); - if ((use_x86_sse_jit(ctx))) - { - ir_operand xor_result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand1,operand3), int128); - ir_operand and_result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_pand,xor_result,operand2), int128); - ir_operand final_result = copy_new_raw_size(ctx, intrinsic_binary_jit(ctx,int128,(uint64_t)x86_xorps,operand1,and_result), int128); - if ((((uint64_t)Q == (uint64_t)0ULL))) - { - ssa_emit_context::vector_insert(ctx,final_result, 1ULL, 64ULL, ir_operand::create_con(0ULL, int64)); - } - V_jit(ctx,Rd,final_result); - } - else - { - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); - ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); - ir_operand element3 = ssa_emit_context::vector_extract(ctx,operand3, e, esize); - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, element1, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, element1, element3), element2))); - } - V_jit(ctx,Rd,result); - } -} - -void and_bic_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((use_x86_sse2_jit(ctx))) - { - if ((invert)) - { - x86_sse_logic_vector_jit(ctx,Rd,Rm,Rn,Q,0ULL,(uint64_t)x86_pandn); - } - else - { - x86_sse_logic_vector_jit(ctx,Rd,Rn,Rm,Q,0ULL,(uint64_t)x86_pand); - } - } - else - { - uint64_t esize = 64ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); - ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); - if ((invert)) - { - element2 = ssa_emit_context::emit_ssa(ctx, ir_bitwise_not, element2); - } - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, element1, element2)); - } - V_jit(ctx,Rd,result); - } -} - -void eor_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd) -{ - if ((use_x86_sse_jit(ctx))) - { - x86_sse_logic_vector_jit(ctx,Rd,Rn,Rm,Q,0ULL,(uint64_t)x86_xorps); - } - else - { - uint64_t esize = 64ULL; - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element1 = ssa_emit_context::vector_extract(ctx,operand1, e, esize); - ir_operand element2 = ssa_emit_context::vector_extract(ctx,operand2, e, esize); - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_exclusive_or, element1, element2)); - } - V_jit(ctx,Rd,result); - } -} - -void xnt_xnt2_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = 64ULL; - uint64_t part = Q; - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - ir_operand operand = V_jit(ctx,Rn); - ir_operand result = ssa_emit_context::vector_zero(ctx); - ir_operand mask = ir_operand::create_con(-1ULL, int64); - if ((((uint64_t)esize != (uint64_t)64ULL))) - { - mask = ir_operand::create_con(((uint64_t)(((uint64_t)1ULL << (uint64_t)esize)) - (uint64_t)1ULL), int64); - } - for (uint64_t e = 0; e < (elements); e++) - { - ir_operand element = ssa_emit_context::vector_extract(ctx,operand, e, (((uint64_t)2ULL * (uint64_t)esize))); - ssa_emit_context::vector_insert(ctx,result, e, esize, ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, element, mask)); - } - VPart_jit(ctx,Rd,part,datasize,copy_new_raw_size(ctx, result, int64)); -} - -void zip_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t part = op; - uint64_t pairs = ((uint64_t)elements / (uint64_t)2ULL); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::vector_zero(ctx); - uint64_t base = ((uint64_t)part * (uint64_t)pairs); - for (uint64_t p = 0; p < (pairs); p++) - { - ssa_emit_context::vector_insert(ctx,result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)0ULL)), esize, ssa_emit_context::vector_extract(ctx,operand1, (((uint64_t)base + (uint64_t)p)), esize)); - ssa_emit_context::vector_insert(ctx,result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)1ULL)), esize, ssa_emit_context::vector_extract(ctx,operand2, (((uint64_t)base + (uint64_t)p)), esize)); - } - V_jit(ctx,Rd,result); -} - -void trn_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd) -{ - uint64_t esize = ((uint64_t)8ULL << (uint64_t)size); - uint64_t datasize = ((uint64_t)64ULL << (uint64_t)Q); - uint64_t elements = ((uint64_t)datasize / (uint64_t)esize); - uint64_t part = op; - uint64_t pairs = ((uint64_t)elements / (uint64_t)2ULL); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::vector_zero(ctx); - for (uint64_t p = 0; p < (pairs); p++) - { - ssa_emit_context::vector_insert(ctx,result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)0ULL)), esize, ssa_emit_context::vector_extract(ctx,operand1, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)part)), esize)); - ssa_emit_context::vector_insert(ctx,result, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)1ULL)), esize, ssa_emit_context::vector_extract(ctx,operand2, (((uint64_t)((uint64_t)2ULL * (uint64_t)p) + (uint64_t)part)), esize)); - } - V_jit(ctx,Rd,result); -} - -void tbl_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t len, uint64_t Rn, uint64_t Rd) -{ - store_context_jit(ctx); - ir_operand vector_context = get_vector_context_jit(ctx); - call_jit(ctx,vector_context,ir_operand::create_con(Rd, int64),ir_operand::create_con(Rn, int64),ir_operand::create_con(len, int64),ir_operand::create_con(Rm, int64),ir_operand::create_con(Q, int64),(uint64_t)table_lookup_fallback); - load_context_jit(ctx); -} - -void ld4_st4_multiple_structures_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t L, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_4_jit(ctx,Q,L,size,-1ULL,Rn,Rt); -} - -void ld4_st4_multiple_structures_post_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t L, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_4_jit(ctx,Q,L,size,Rm,Rn,Rt); -} - -void ld1r_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_jit(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,6ULL,0ULL,size,Rn,Rt,1ULL); -} - -void ld1r_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_jit(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,6ULL,0ULL,size,Rn,Rt,1ULL); -} - -void ld1_single_structure_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_jit(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,1ULL); -} - -void ld1_single_structure_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_jit(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,1ULL); -} - -void st1_multiple_structures_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - uint64_t opcode = ophi; - opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)1ULL); - opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)oplo); - st1_jit(ctx,0ULL,Q,0ULL,opcode,size,0ULL,Rn,Rt); -} - -void st1_multiple_structures_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - uint64_t opcode = ophi; - opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)1ULL); - opcode = ((uint64_t)(((uint64_t)opcode << (uint64_t)1ULL)) | (uint64_t)oplo); - st1_jit(ctx,1ULL,Q,0ULL,opcode,size,Rm,Rn,Rt); -} - -void st2_multiple_structures_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - st_jit(ctx,0ULL,Q,0ULL,4ULL,size,0ULL,Rn,Rt); -} - -void st2_multiple_structures_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - st_jit(ctx,1ULL,Q,0ULL,4ULL,size,Rm,Rn,Rt); -} - -void st1_single_structure_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_jit(ctx,0ULL,Q,1ULL,0ULL,0ULL,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,0ULL); -} - -void st1_single_structure_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt) -{ - memory_1_jit(ctx,1ULL,Q,1ULL,0ULL,Rm,0ULL,((uint64_t)opcode << (uint64_t)1ULL),S,size,Rn,Rt,0ULL); -} - -void floating_point_conditional_select_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd) -{ - uint64_t fltsize = get_flt_size_jit(ctx,ftype); - ir_operand operand1 = V_jit(ctx,Rn); - ir_operand operand2 = V_jit(ctx,Rm); - ir_operand result = ssa_emit_context::emit_ssa(ctx, ir_move, ssa_emit_context::vector_zero(ctx)); - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = condition_holds_jit(ctx,cond); - - ir_operation_block::jump_if(ctx->ir,yes, condition); - { - ssa_emit_context::move(ctx,result,operand2); - } - - ir_operation_block::jump(ctx->ir,end); - ir_operation_block::mark_label(ctx->ir, yes); - - { - ssa_emit_context::move(ctx,result,operand1); - } - - ir_operation_block::mark_label(ctx->ir, end); - } - result = clear_vector_scalar_jit(ctx,result,fltsize); - V_jit(ctx,Rd,result); -} - -void fcmp_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t opc) -{ - uint64_t datasize = get_flt_size_jit(ctx,ftype); - uint64_t cmp_with_zero = ((uint64_t)opc == (uint64_t)1ULL); - ir_operand operand1 = copy_new_raw_size(ctx, V_jit(ctx,Rn), int64); - ir_operand operand2; - ir_operand fpcr_state = _sys_jit(ctx,(uint64_t)fpcr); - if ((cmp_with_zero)) - { - operand2 = ir_operand::create_con(0ULL, int64); - } - else - { - operand2 = copy_new_raw_size(ctx, V_jit(ctx,Rm), int64); - } - ir_operand nzcv = FPCompare_jit(ctx,operand1,operand2,fpcr_state,datasize); - _sys_jit(ctx,(uint64_t)nzcv_n,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, nzcv, ir_operand::create_con(3ULL, int64)), ir_operand::create_con(1ULL, int64))); - _sys_jit(ctx,(uint64_t)nzcv_z,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, nzcv, ir_operand::create_con(2ULL, int64)), ir_operand::create_con(1ULL, int64))); - _sys_jit(ctx,(uint64_t)nzcv_c,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, nzcv, ir_operand::create_con(1ULL, int64)), ir_operand::create_con(1ULL, int64))); - _sys_jit(ctx,(uint64_t)nzcv_v,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, nzcv, ir_operand::create_con(0ULL, int64)), ir_operand::create_con(1ULL, int64))); -} - -void fccmp_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t nzcv) -{ - uint64_t datasize = get_flt_size_jit(ctx,ftype); - ir_operand operand1 = copy_new_raw_size(ctx, V_jit(ctx,Rn), int64); - ir_operand operand2 = copy_new_raw_size(ctx, V_jit(ctx,Rm), int64); - ir_operand fpcr_state = _sys_jit(ctx,(uint64_t)fpcr); - { - ir_operand end = ir_operation_block::create_label(ctx->ir); - ir_operand yes = ir_operation_block::create_label(ctx->ir); - - ir_operand condition = condition_holds_jit(ctx,cond); - - ir_operation_block::jump_if(ctx->ir,yes, condition); - { - _sys_jit(ctx,(uint64_t)nzcv_n,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)3ULL)) & (uint64_t)1ULL), int64)); - _sys_jit(ctx,(uint64_t)nzcv_z,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)2ULL)) & (uint64_t)1ULL), int64)); - _sys_jit(ctx,(uint64_t)nzcv_c,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)1ULL)) & (uint64_t)1ULL), int64)); - _sys_jit(ctx,(uint64_t)nzcv_v,ir_operand::create_con(((uint64_t)(((uint64_t)nzcv >> (uint64_t)0ULL)) & (uint64_t)1ULL), int64)); - } - - ir_operation_block::jump(ctx->ir,end); - ir_operation_block::mark_label(ctx->ir, yes); - - { - ir_operand success_nzcv = FPCompare_jit(ctx,operand1,operand2,fpcr_state,datasize); - _sys_jit(ctx,(uint64_t)nzcv_n,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, success_nzcv, ir_operand::create_con(3ULL, int64)), ir_operand::create_con(1ULL, int64))); - _sys_jit(ctx,(uint64_t)nzcv_z,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, success_nzcv, ir_operand::create_con(2ULL, int64)), ir_operand::create_con(1ULL, int64))); - _sys_jit(ctx,(uint64_t)nzcv_c,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, success_nzcv, ir_operand::create_con(1ULL, int64)), ir_operand::create_con(1ULL, int64))); - _sys_jit(ctx,(uint64_t)nzcv_v,ssa_emit_context::emit_ssa(ctx, ir_bitwise_and, ssa_emit_context::emit_ssa(ctx, ir_shift_right_unsigned, success_nzcv, ir_operand::create_con(0ULL, int64)), ir_operand::create_con(1ULL, int64))); - } - - ir_operation_block::mark_label(ctx->ir, end); - } -} - diff --git a/src/emulator/aarch64/aarch64_impl.h b/src/emulator/aarch64/aarch64_impl.h index 01822bd..f8092c7 100755 --- a/src/emulator/aarch64/aarch64_impl.h +++ b/src/emulator/aarch64/aarch64_impl.h @@ -93,6 +93,54 @@ static uint64_t undefined_value() } //INTERPRETER +void add_subtract_imm12_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t sh, uint64_t imm12, uint64_t Rn, uint64_t Rd); +void add_subtract_shifted_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t shift, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd); +void add_subtract_extended_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t option, uint64_t imm3, uint64_t Rn, uint64_t Rd); +void add_subtract_carry_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void shift_variable_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t op2, uint64_t Rn, uint64_t Rd); +void multiply_with_32_interpreter(interpreter_data* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd); +void multiply_hi_interpreter(interpreter_data* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Rn, uint64_t Rd); +void multiply_additive_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd); +void divide_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t o1, uint64_t Rn, uint64_t Rd); +uint64_t create_rbit_mask_interpreter(interpreter_data* ctx, uint64_t index); +void rbit_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd); +void rev16_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd); +void reverse_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t Rn, uint64_t Rd); +void count_leading_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t s, uint64_t Rn, uint64_t Rd); +void extr_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t N, uint64_t Rm, uint64_t imms, uint64_t Rn, uint64_t Rd); +void bitfield_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd); +void logical_immediate_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd); +void logical_shifted_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t shift, uint64_t N, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd); +void conditional_select_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t cond, uint64_t op2, uint64_t Rn, uint64_t Rd); +void conditional_compare_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t Rm, uint64_t cond, uint64_t mode, uint64_t Rn, uint64_t nzcv); +void move_wide_immediate_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t hw, uint64_t imm16, uint64_t Rd); +void pc_rel_addressing_interpreter(interpreter_data* ctx, uint64_t op, uint64_t immlo, uint64_t immhi, uint64_t Rd); +void branch_register_interpreter(interpreter_data* ctx, uint64_t l, uint64_t Rn); +void return_register_interpreter(interpreter_data* ctx, uint64_t Rn); +void test_bit_branch_interpreter(interpreter_data* ctx, uint64_t b5, uint64_t op, uint64_t b40, uint64_t imm14, uint64_t Rt); +void compare_and_branch_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t imm19, uint64_t Rt); +void b_unconditional_interpreter(interpreter_data* ctx, uint64_t op, uint64_t imm26); +void b_conditional_interpreter(interpreter_data* ctx, uint64_t imm19, uint64_t cond); +void svc_interpreter(interpreter_data* ctx, uint64_t imm16); +void msr_register_interpreter(interpreter_data* ctx, uint64_t imm15, uint64_t Rt); +void mrs_register_interpreter(interpreter_data* ctx, uint64_t imm15, uint64_t Rt); +void hints_interpreter(interpreter_data* ctx, uint64_t imm7); +void sys_interpreter(interpreter_data* ctx, uint64_t L, uint64_t imm19); +void barriers_interpreter(interpreter_data* ctx, uint64_t CRm, uint64_t op2, uint64_t Rt); +void load_store_register_post_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); +void load_store_register_pre_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); +void load_store_register_unscaled_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); +void load_store_register_pair_imm_offset_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); +void load_store_register_pair_imm_post_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); +void load_store_register_pair_imm_pre_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); +void load_store_register_pair_imm_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t wb, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); +void load_store_register_imm_unsigned_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm12, uint64_t Rn, uint64_t Rt); +void load_store_register_imm_unscaled_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t wb, uint64_t Rn, uint64_t Rt); +void load_store_register_offset_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t Rm, uint64_t option, uint64_t S, uint64_t Rn, uint64_t Rt); +void load_store_exclusive_ordered_interpreter(interpreter_data* ctx, uint64_t size, uint64_t ordered, uint64_t L, uint64_t Rs, uint64_t o0, uint64_t Rn, uint64_t Rt); +uint64_t exclusive_address_mask_interpreter(interpreter_data* ctx); +void load_exclusive_interpreter(interpreter_data* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt); +void store_exclusive_interpreter(interpreter_data* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t Rs); uint64_t sign_extend_interpreter(interpreter_data* ctx, uint64_t source, uint64_t count); template O a_shift_reg_interpreter(interpreter_data* ctx, uint64_t m, uint64_t shift_type, uint64_t ammount); @@ -116,6 +164,56 @@ O add_subtract_carry_impl_interpreter(interpreter_data* ctx, O n, O m, uint64_t uint32_t condition_holds_interpreter(interpreter_data* ctx, uint64_t cond); void branch_long_universal_interpreter(interpreter_data* ctx, uint64_t Rn, uint64_t link); uint64_t select_interpreter(interpreter_data* ctx, uint64_t condition, uint64_t yes, uint64_t no); +void dup_general_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd); +void dup_element_scalar_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd); +void dup_element_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd); +void move_to_gp_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t U, uint64_t Rn, uint64_t Rd); +void ins_general_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd); +void ins_element_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t imm4, uint64_t Rn, uint64_t Rd); +void movi_immediate_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t op, uint64_t immhi, uint64_t cmode, uint64_t immlo, uint64_t Rd); +void fmov_general_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t Rn, uint64_t Rd); +void convert_to_float_gp_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd); +void convert_to_float_vector_scalar_interpreter(interpreter_data* ctx, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd); +void convert_to_float_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd); +void shl_immedaite_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); +void sshr_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); +void shll_shll2_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); +void shrn_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); +void rev64_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void neg_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void not_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rn, uint64_t Rd); +void abs_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void mul_vector_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd); +void mul_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void ext_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t imm4, uint64_t Rn, uint64_t Rd); +void compare_above_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void shl_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void add_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void addlv_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rn, uint64_t Rd); +void cnt_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void orr_orn_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void bsl_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void and_bic_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void eor_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void xnt_xnt2_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void zip_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd); +void trn_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd); +void tbl_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t len, uint64_t Rn, uint64_t Rd); +void ld4_st4_multiple_structures_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t L, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld4_st4_multiple_structures_post_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t L, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld1r_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld1r_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld1_single_structure_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld1_single_structure_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); +void st1_multiple_structures_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt); +void st1_multiple_structures_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt); +void st2_multiple_structures_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt); +void st2_multiple_structures_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); +void st1_single_structure_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); +void st1_single_structure_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); +void floating_point_conditional_select_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd); +void fcmp_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t opc); +void fccmp_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t nzcv); uint64_t create_mask_interpreter(interpreter_data* ctx, uint64_t bits); uint64_t shift_left_check_interpreter(interpreter_data* ctx, uint64_t to_shift, uint64_t shift, uint64_t size); uint64_t get_x86_rounding_mode_interpreter(interpreter_data* ctx, uint64_t rounding); @@ -186,54 +284,16 @@ void floating_point_multiply_accumulate_scalar_element_interpreter(interpreter_d void floating_point_multiply_accumulate_vector_element_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rd, uint64_t Rn, uint64_t Rm, uint64_t neg, uint64_t sz, uint64_t index); void fcm_vector_interpreter(interpreter_data* ctx, uint64_t Rd, uint64_t Rn, uint64_t Rm, uint64_t mode, uint64_t Q, uint64_t sz); uint128_t clear_vector_scalar_interpreter(interpreter_data* ctx, uint128_t working, uint64_t fltsize); -void add_subtract_imm12_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t sh, uint64_t imm12, uint64_t Rn, uint64_t Rd); -void add_subtract_shifted_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t shift, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd); -void add_subtract_extended_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t option, uint64_t imm3, uint64_t Rn, uint64_t Rd); -void add_subtract_carry_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void shift_variable_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t op2, uint64_t Rn, uint64_t Rd); -void multiply_with_32_interpreter(interpreter_data* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd); -void multiply_hi_interpreter(interpreter_data* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Rn, uint64_t Rd); -void multiply_additive_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd); -void divide_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rm, uint64_t o1, uint64_t Rn, uint64_t Rd); -uint64_t create_rbit_mask_interpreter(interpreter_data* ctx, uint64_t index); -void rbit_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd); -void rev16_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd); -void reverse_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t Rn, uint64_t Rd); -void count_leading_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t s, uint64_t Rn, uint64_t Rd); -void extr_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t N, uint64_t Rm, uint64_t imms, uint64_t Rn, uint64_t Rd); -void bitfield_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd); -void logical_immediate_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd); -void logical_shifted_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t shift, uint64_t N, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd); -void conditional_select_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t cond, uint64_t op2, uint64_t Rn, uint64_t Rd); -void conditional_compare_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t Rm, uint64_t cond, uint64_t mode, uint64_t Rn, uint64_t nzcv); -void move_wide_immediate_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t opc, uint64_t hw, uint64_t imm16, uint64_t Rd); -void pc_rel_addressing_interpreter(interpreter_data* ctx, uint64_t op, uint64_t immlo, uint64_t immhi, uint64_t Rd); -void branch_register_interpreter(interpreter_data* ctx, uint64_t l, uint64_t Rn); -void return_register_interpreter(interpreter_data* ctx, uint64_t Rn); -void test_bit_branch_interpreter(interpreter_data* ctx, uint64_t b5, uint64_t op, uint64_t b40, uint64_t imm14, uint64_t Rt); -void compare_and_branch_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t op, uint64_t imm19, uint64_t Rt); -void b_unconditional_interpreter(interpreter_data* ctx, uint64_t op, uint64_t imm26); -void b_conditional_interpreter(interpreter_data* ctx, uint64_t imm19, uint64_t cond); -void svc_interpreter(interpreter_data* ctx, uint64_t imm16); -void msr_register_interpreter(interpreter_data* ctx, uint64_t imm15, uint64_t Rt); -void mrs_register_interpreter(interpreter_data* ctx, uint64_t imm15, uint64_t Rt); -void hints_interpreter(interpreter_data* ctx, uint64_t imm7); -void sys_interpreter(interpreter_data* ctx, uint64_t L, uint64_t imm19); -void barriers_interpreter(interpreter_data* ctx, uint64_t CRm, uint64_t op2, uint64_t Rt); -void load_store_register_post_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); -void load_store_register_pre_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); -void load_store_register_unscaled_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); -void load_store_register_pair_imm_offset_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); -void load_store_register_pair_imm_post_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); -void load_store_register_pair_imm_pre_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); -void load_store_register_pair_imm_interpreter(interpreter_data* ctx, uint64_t opc, uint64_t VR, uint64_t wb, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); -void load_store_register_imm_unsigned_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm12, uint64_t Rn, uint64_t Rt); -void load_store_register_imm_unscaled_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t wb, uint64_t Rn, uint64_t Rt); -void load_store_register_offset_interpreter(interpreter_data* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t Rm, uint64_t option, uint64_t S, uint64_t Rn, uint64_t Rt); -void load_store_exclusive_ordered_interpreter(interpreter_data* ctx, uint64_t size, uint64_t ordered, uint64_t L, uint64_t Rs, uint64_t o0, uint64_t Rn, uint64_t Rt); -uint64_t exclusive_address_mask_interpreter(interpreter_data* ctx); -void load_exclusive_interpreter(interpreter_data* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt); -void store_exclusive_interpreter(interpreter_data* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t Rs); +uint64_t _compare_and_swap_interpreter(interpreter_data* ctx, uint64_t physical_address, uint64_t expecting, uint64_t to_swap, uint64_t size); +uint64_t compare_and_swap_interpreter(interpreter_data* ctx, uint64_t address, uint64_t expecting, uint64_t to_swap, uint64_t size); +template +void mem_interpreter(interpreter_data* ctx, uint64_t address, O value); +template +O mem_interpreter(interpreter_data* ctx, uint64_t address); +uint64_t XSP_interpreter(interpreter_data* ctx, uint64_t reg_id); +void XSP_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value); +uint64_t X_interpreter(interpreter_data* ctx, uint64_t reg_id); +void X_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value); void conversion_between_floating_point_and_fixed_point_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t S, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t scale, uint64_t Rn, uint64_t Rd); void fcvt_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t opc, uint64_t Rn, uint64_t Rd); void fcvtz_scalar_integer_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd); @@ -243,6 +303,23 @@ void fcvtm_scalar_integer_interpreter(interpreter_data* ctx, uint64_t sf, uint64 void frintp_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); void frintm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); void fcvtp_scalar_integer_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd); +void fadd_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fsub_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fmul_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fdiv_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fmax_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fmin_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fmaxnm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fminnm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fnmul_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fabs_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); +void fneg_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); +void fneg_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); +void fsqrt_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); +void fsqrt_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); +void frecpe_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); +void frsqrte_scalar_interpreter(interpreter_data* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd); +void fmov_scalar_immediate_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t imm8, uint64_t Rd); void fadd_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); void fmul_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); void fsub_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); @@ -266,83 +343,6 @@ void fcmeq_vector_register_interpreter(interpreter_data* ctx, uint64_t Q, uint64 void fcmgt_vector_register_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); void fcmge_vector_register_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); void fcmle_zero_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); -void fadd_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fsub_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fmul_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fdiv_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fmax_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fmin_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fmaxnm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fminnm_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fnmul_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fabs_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); -void fneg_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); -void fneg_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); -void fsqrt_scalar_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); -void fsqrt_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); -void frecpe_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); -void frsqrte_scalar_interpreter(interpreter_data* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd); -void fmov_scalar_immediate_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t imm8, uint64_t Rd); -uint64_t _compare_and_swap_interpreter(interpreter_data* ctx, uint64_t physical_address, uint64_t expecting, uint64_t to_swap, uint64_t size); -uint64_t compare_and_swap_interpreter(interpreter_data* ctx, uint64_t address, uint64_t expecting, uint64_t to_swap, uint64_t size); -template -void mem_interpreter(interpreter_data* ctx, uint64_t address, O value); -template -O mem_interpreter(interpreter_data* ctx, uint64_t address); -uint64_t XSP_interpreter(interpreter_data* ctx, uint64_t reg_id); -void XSP_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value); -uint64_t X_interpreter(interpreter_data* ctx, uint64_t reg_id); -void X_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value); -void dup_general_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd); -void dup_element_scalar_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd); -void dup_element_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd); -void move_to_gp_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t imm5, uint64_t U, uint64_t Rn, uint64_t Rd); -void ins_general_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd); -void ins_element_interpreter(interpreter_data* ctx, uint64_t imm5, uint64_t imm4, uint64_t Rn, uint64_t Rd); -void movi_immediate_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t op, uint64_t immhi, uint64_t cmode, uint64_t immlo, uint64_t Rd); -void fmov_general_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t Rn, uint64_t Rd); -void convert_to_float_gp_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd); -void convert_to_float_vector_scalar_interpreter(interpreter_data* ctx, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd); -void convert_to_float_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd); -void shl_immedaite_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); -void sshr_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); -void shll_shll2_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); -void shrn_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); -void rev64_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void neg_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void not_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rn, uint64_t Rd); -void abs_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void mul_vector_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd); -void mul_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void ext_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t imm4, uint64_t Rn, uint64_t Rd); -void compare_above_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void shl_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void add_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void addlv_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rn, uint64_t Rd); -void cnt_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void orr_orn_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void bsl_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void and_bic_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void eor_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void xnt_xnt2_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void zip_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd); -void trn_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd); -void tbl_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t len, uint64_t Rn, uint64_t Rd); -void ld4_st4_multiple_structures_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t L, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld4_st4_multiple_structures_post_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t L, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld1r_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld1r_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld1_single_structure_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld1_single_structure_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); -void st1_multiple_structures_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt); -void st1_multiple_structures_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt); -void st2_multiple_structures_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt); -void st2_multiple_structures_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); -void st1_single_structure_no_offset_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); -void st1_single_structure_post_index_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); -void floating_point_conditional_select_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd); -void fcmp_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t opc); -void fccmp_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t nzcv); uint64_t _x_interpreter(interpreter_data* ctx, uint64_t reg_id);//THIS FUNCTION IS USER DEFINED void _x_interpreter(interpreter_data* ctx, uint64_t reg_id, uint64_t value);//THIS FUNCTION IS USER DEFINED uint64_t _sys_interpreter(interpreter_data* ctx, uint64_t reg_id);//THIS FUNCTION IS USER DEFINED @@ -386,6 +386,54 @@ template R intrinsic_ternary_imm_interpreter(interpreter_data* ctx, uint64_t instruction, R source_0, R source_1, uint64_t source_2);//THIS FUNCTION IS USER DEFINED //JIT +void add_subtract_imm12_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t sh, uint64_t imm12, uint64_t Rn, uint64_t Rd); +void add_subtract_shifted_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t shift, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd); +void add_subtract_extended_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t option, uint64_t imm3, uint64_t Rn, uint64_t Rd); +void add_subtract_carry_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void shift_variable_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t op2, uint64_t Rn, uint64_t Rd); +void multiply_with_32_jit(ssa_emit_context* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd); +void multiply_hi_jit(ssa_emit_context* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Rn, uint64_t Rd); +void multiply_additive_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd); +void divide_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t o1, uint64_t Rn, uint64_t Rd); +uint64_t create_rbit_mask_jit(ssa_emit_context* ctx, uint64_t index); +void rbit_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd); +void rev16_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd); +void reverse_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t Rn, uint64_t Rd); +void count_leading_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t s, uint64_t Rn, uint64_t Rd); +void extr_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t N, uint64_t Rm, uint64_t imms, uint64_t Rn, uint64_t Rd); +void bitfield_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd); +void logical_immediate_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd); +void logical_shifted_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t shift, uint64_t N, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd); +void conditional_select_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t cond, uint64_t op2, uint64_t Rn, uint64_t Rd); +void conditional_compare_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t Rm, uint64_t cond, uint64_t mode, uint64_t Rn, uint64_t nzcv); +void move_wide_immediate_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t hw, uint64_t imm16, uint64_t Rd); +void pc_rel_addressing_jit(ssa_emit_context* ctx, uint64_t op, uint64_t immlo, uint64_t immhi, uint64_t Rd); +void branch_register_jit(ssa_emit_context* ctx, uint64_t l, uint64_t Rn); +void return_register_jit(ssa_emit_context* ctx, uint64_t Rn); +void test_bit_branch_jit(ssa_emit_context* ctx, uint64_t b5, uint64_t op, uint64_t b40, uint64_t imm14, uint64_t Rt); +void compare_and_branch_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t imm19, uint64_t Rt); +void b_unconditional_jit(ssa_emit_context* ctx, uint64_t op, uint64_t imm26); +void b_conditional_jit(ssa_emit_context* ctx, uint64_t imm19, uint64_t cond); +void svc_jit(ssa_emit_context* ctx, uint64_t imm16); +void msr_register_jit(ssa_emit_context* ctx, uint64_t imm15, uint64_t Rt); +void mrs_register_jit(ssa_emit_context* ctx, uint64_t imm15, uint64_t Rt); +void hints_jit(ssa_emit_context* ctx, uint64_t imm7); +void sys_jit(ssa_emit_context* ctx, uint64_t L, uint64_t imm19); +void barriers_jit(ssa_emit_context* ctx, uint64_t CRm, uint64_t op2, uint64_t Rt); +void load_store_register_post_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); +void load_store_register_pre_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); +void load_store_register_unscaled_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); +void load_store_register_pair_imm_offset_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); +void load_store_register_pair_imm_post_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); +void load_store_register_pair_imm_pre_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); +void load_store_register_pair_imm_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t wb, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); +void load_store_register_imm_unsigned_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm12, uint64_t Rn, uint64_t Rt); +void load_store_register_imm_unscaled_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t wb, uint64_t Rn, uint64_t Rt); +void load_store_register_offset_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t Rm, uint64_t option, uint64_t S, uint64_t Rn, uint64_t Rt); +void load_store_exclusive_ordered_jit(ssa_emit_context* ctx, uint64_t size, uint64_t ordered, uint64_t L, uint64_t Rs, uint64_t o0, uint64_t Rn, uint64_t Rt); +ir_operand exclusive_address_mask_jit(ssa_emit_context* ctx); +void load_exclusive_jit(ssa_emit_context* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt); +void store_exclusive_jit(ssa_emit_context* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t Rs); uint64_t sign_extend_jit(ssa_emit_context* ctx, uint64_t source, uint64_t count); ir_operand a_shift_reg_jit(ssa_emit_context* ctx,uint64_t O, uint64_t m, uint64_t shift_type, uint64_t ammount); ir_operand a_extend_reg_jit(ssa_emit_context* ctx,uint64_t O, uint64_t m, uint64_t extend_type, uint64_t shift); @@ -404,6 +452,56 @@ ir_operand add_subtract_carry_impl_jit(ssa_emit_context* ctx,uint64_t O, ir_oper ir_operand condition_holds_jit(ssa_emit_context* ctx, uint64_t cond); void branch_long_universal_jit(ssa_emit_context* ctx, uint64_t Rn, uint64_t link); uint64_t select_jit(ssa_emit_context* ctx, uint64_t condition, uint64_t yes, uint64_t no); +void dup_general_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd); +void dup_element_scalar_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd); +void dup_element_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd); +void move_to_gp_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t U, uint64_t Rn, uint64_t Rd); +void ins_general_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd); +void ins_element_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t imm4, uint64_t Rn, uint64_t Rd); +void movi_immediate_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t op, uint64_t immhi, uint64_t cmode, uint64_t immlo, uint64_t Rd); +void fmov_general_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t Rn, uint64_t Rd); +void convert_to_float_gp_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd); +void convert_to_float_vector_scalar_jit(ssa_emit_context* ctx, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd); +void convert_to_float_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd); +void shl_immedaite_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); +void sshr_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); +void shll_shll2_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); +void shrn_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); +void rev64_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void neg_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void not_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rn, uint64_t Rd); +void abs_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void mul_vector_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd); +void mul_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void ext_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t imm4, uint64_t Rn, uint64_t Rd); +void compare_above_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void shl_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void add_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void addlv_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rn, uint64_t Rd); +void cnt_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void orr_orn_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void bsl_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void and_bic_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void eor_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void xnt_xnt2_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); +void zip_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd); +void trn_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd); +void tbl_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t len, uint64_t Rn, uint64_t Rd); +void ld4_st4_multiple_structures_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t L, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld4_st4_multiple_structures_post_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t L, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld1r_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld1r_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld1_single_structure_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); +void ld1_single_structure_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); +void st1_multiple_structures_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt); +void st1_multiple_structures_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt); +void st2_multiple_structures_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt); +void st2_multiple_structures_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); +void st1_single_structure_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); +void st1_single_structure_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); +void floating_point_conditional_select_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd); +void fcmp_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t opc); +void fccmp_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t nzcv); ir_operand create_mask_jit(ssa_emit_context* ctx, uint64_t bits); ir_operand shift_left_check_jit(ssa_emit_context* ctx, ir_operand to_shift, ir_operand shift, uint64_t size); uint64_t get_x86_rounding_mode_jit(ssa_emit_context* ctx, uint64_t rounding); @@ -473,54 +571,14 @@ void floating_point_multiply_accumulate_scalar_element_jit(ssa_emit_context* ctx void floating_point_multiply_accumulate_vector_element_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rd, uint64_t Rn, uint64_t Rm, uint64_t neg, uint64_t sz, uint64_t index); void fcm_vector_jit(ssa_emit_context* ctx, uint64_t Rd, uint64_t Rn, uint64_t Rm, uint64_t mode, uint64_t Q, uint64_t sz); ir_operand clear_vector_scalar_jit(ssa_emit_context* ctx, ir_operand working, uint64_t fltsize); -void add_subtract_imm12_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t sh, uint64_t imm12, uint64_t Rn, uint64_t Rd); -void add_subtract_shifted_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t shift, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd); -void add_subtract_extended_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t option, uint64_t imm3, uint64_t Rn, uint64_t Rd); -void add_subtract_carry_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void shift_variable_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t op2, uint64_t Rn, uint64_t Rd); -void multiply_with_32_jit(ssa_emit_context* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd); -void multiply_hi_jit(ssa_emit_context* ctx, uint64_t U, uint64_t Rm, uint64_t o0, uint64_t Rn, uint64_t Rd); -void multiply_additive_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t o0, uint64_t Ra, uint64_t Rn, uint64_t Rd); -void divide_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rm, uint64_t o1, uint64_t Rn, uint64_t Rd); -uint64_t create_rbit_mask_jit(ssa_emit_context* ctx, uint64_t index); -void rbit_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd); -void rev16_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t Rn, uint64_t Rd); -void reverse_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t Rn, uint64_t Rd); -void count_leading_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t s, uint64_t Rn, uint64_t Rd); -void extr_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t N, uint64_t Rm, uint64_t imms, uint64_t Rn, uint64_t Rd); -void bitfield_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd); -void logical_immediate_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t N, uint64_t immr, uint64_t imms, uint64_t Rn, uint64_t Rd); -void logical_shifted_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t shift, uint64_t N, uint64_t Rm, uint64_t imm6, uint64_t Rn, uint64_t Rd); -void conditional_select_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t S, uint64_t Rm, uint64_t cond, uint64_t op2, uint64_t Rn, uint64_t Rd); -void conditional_compare_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t Rm, uint64_t cond, uint64_t mode, uint64_t Rn, uint64_t nzcv); -void move_wide_immediate_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t opc, uint64_t hw, uint64_t imm16, uint64_t Rd); -void pc_rel_addressing_jit(ssa_emit_context* ctx, uint64_t op, uint64_t immlo, uint64_t immhi, uint64_t Rd); -void branch_register_jit(ssa_emit_context* ctx, uint64_t l, uint64_t Rn); -void return_register_jit(ssa_emit_context* ctx, uint64_t Rn); -void test_bit_branch_jit(ssa_emit_context* ctx, uint64_t b5, uint64_t op, uint64_t b40, uint64_t imm14, uint64_t Rt); -void compare_and_branch_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t op, uint64_t imm19, uint64_t Rt); -void b_unconditional_jit(ssa_emit_context* ctx, uint64_t op, uint64_t imm26); -void b_conditional_jit(ssa_emit_context* ctx, uint64_t imm19, uint64_t cond); -void svc_jit(ssa_emit_context* ctx, uint64_t imm16); -void msr_register_jit(ssa_emit_context* ctx, uint64_t imm15, uint64_t Rt); -void mrs_register_jit(ssa_emit_context* ctx, uint64_t imm15, uint64_t Rt); -void hints_jit(ssa_emit_context* ctx, uint64_t imm7); -void sys_jit(ssa_emit_context* ctx, uint64_t L, uint64_t imm19); -void barriers_jit(ssa_emit_context* ctx, uint64_t CRm, uint64_t op2, uint64_t Rt); -void load_store_register_post_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); -void load_store_register_pre_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); -void load_store_register_unscaled_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t Rn, uint64_t Rt); -void load_store_register_pair_imm_offset_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); -void load_store_register_pair_imm_post_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); -void load_store_register_pair_imm_pre_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); -void load_store_register_pair_imm_jit(ssa_emit_context* ctx, uint64_t opc, uint64_t VR, uint64_t wb, uint64_t L, uint64_t imm7, uint64_t Rt2, uint64_t Rn, uint64_t Rt); -void load_store_register_imm_unsigned_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm12, uint64_t Rn, uint64_t Rt); -void load_store_register_imm_unscaled_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t imm9, uint64_t wb, uint64_t Rn, uint64_t Rt); -void load_store_register_offset_jit(ssa_emit_context* ctx, uint64_t size, uint64_t VR, uint64_t opc, uint64_t Rm, uint64_t option, uint64_t S, uint64_t Rn, uint64_t Rt); -void load_store_exclusive_ordered_jit(ssa_emit_context* ctx, uint64_t size, uint64_t ordered, uint64_t L, uint64_t Rs, uint64_t o0, uint64_t Rn, uint64_t Rt); -ir_operand exclusive_address_mask_jit(ssa_emit_context* ctx); -void load_exclusive_jit(ssa_emit_context* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt); -void store_exclusive_jit(ssa_emit_context* ctx, uint64_t is_exclusive, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t Rs); +ir_operand _compare_and_swap_jit(ssa_emit_context* ctx, ir_operand physical_address, ir_operand expecting, ir_operand to_swap, uint64_t size); +ir_operand compare_and_swap_jit(ssa_emit_context* ctx, ir_operand address, ir_operand expecting, ir_operand to_swap, uint64_t size); +void mem_jit(ssa_emit_context* ctx,uint64_t O, ir_operand address, ir_operand value); +ir_operand mem_jit(ssa_emit_context* ctx,uint64_t O, ir_operand address); +ir_operand XSP_jit(ssa_emit_context* ctx, uint64_t reg_id); +void XSP_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value); +ir_operand X_jit(ssa_emit_context* ctx, uint64_t reg_id); +void X_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value); void conversion_between_floating_point_and_fixed_point_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t S, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t scale, uint64_t Rn, uint64_t Rd); void fcvt_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t opc, uint64_t Rn, uint64_t Rd); void fcvtz_scalar_integer_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd); @@ -530,6 +588,23 @@ void fcvtm_scalar_integer_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype void frintp_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); void frintm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); void fcvtp_scalar_integer_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd); +void fadd_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fsub_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fmul_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fdiv_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fmax_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fmin_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fmaxnm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fminnm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fnmul_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); +void fabs_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); +void fneg_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); +void fneg_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); +void fsqrt_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); +void fsqrt_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); +void frecpe_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); +void frsqrte_scalar_jit(ssa_emit_context* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd); +void fmov_scalar_immediate_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t imm8, uint64_t Rd); void fadd_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); void fmul_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); void fsub_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); @@ -553,81 +628,6 @@ void fcmeq_vector_register_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, u void fcmgt_vector_register_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); void fcmge_vector_register_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd); void fcmle_zero_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); -void fadd_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fsub_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fmul_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fdiv_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fmax_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fmin_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fmaxnm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fminnm_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fnmul_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void fabs_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); -void fneg_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); -void fneg_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); -void fsqrt_scalar_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd); -void fsqrt_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); -void frecpe_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd); -void frsqrte_scalar_jit(ssa_emit_context* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd); -void fmov_scalar_immediate_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t imm8, uint64_t Rd); -ir_operand _compare_and_swap_jit(ssa_emit_context* ctx, ir_operand physical_address, ir_operand expecting, ir_operand to_swap, uint64_t size); -ir_operand compare_and_swap_jit(ssa_emit_context* ctx, ir_operand address, ir_operand expecting, ir_operand to_swap, uint64_t size); -void mem_jit(ssa_emit_context* ctx,uint64_t O, ir_operand address, ir_operand value); -ir_operand mem_jit(ssa_emit_context* ctx,uint64_t O, ir_operand address); -ir_operand XSP_jit(ssa_emit_context* ctx, uint64_t reg_id); -void XSP_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value); -ir_operand X_jit(ssa_emit_context* ctx, uint64_t reg_id); -void X_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value); -void dup_general_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd); -void dup_element_scalar_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd); -void dup_element_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t Rn, uint64_t Rd); -void move_to_gp_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t imm5, uint64_t U, uint64_t Rn, uint64_t Rd); -void ins_general_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t Rn, uint64_t Rd); -void ins_element_jit(ssa_emit_context* ctx, uint64_t imm5, uint64_t imm4, uint64_t Rn, uint64_t Rd); -void movi_immediate_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t op, uint64_t immhi, uint64_t cmode, uint64_t immlo, uint64_t Rd); -void fmov_general_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t rmode, uint64_t opcode, uint64_t Rn, uint64_t Rd); -void convert_to_float_gp_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd); -void convert_to_float_vector_scalar_jit(ssa_emit_context* ctx, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd); -void convert_to_float_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t sz, uint64_t Rn, uint64_t Rd); -void shl_immedaite_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); -void sshr_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); -void shll_shll2_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); -void shrn_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t immh, uint64_t immb, uint64_t Rn, uint64_t Rd); -void rev64_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void neg_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void not_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rn, uint64_t Rd); -void abs_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void mul_vector_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd); -void mul_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void ext_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t imm4, uint64_t Rn, uint64_t Rd); -void compare_above_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void shl_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void add_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void addlv_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t U, uint64_t size, uint64_t Rn, uint64_t Rd); -void cnt_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void orr_orn_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void bsl_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void and_bic_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void eor_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t Rn, uint64_t Rd); -void xnt_xnt2_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rd); -void zip_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd); -void trn_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rm, uint64_t op, uint64_t Rn, uint64_t Rd); -void tbl_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t len, uint64_t Rn, uint64_t Rd); -void ld4_st4_multiple_structures_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t L, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld4_st4_multiple_structures_post_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t L, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld1r_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld1r_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld1_single_structure_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); -void ld1_single_structure_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); -void st1_multiple_structures_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt); -void st1_multiple_structures_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t ophi, uint64_t oplo, uint64_t size, uint64_t Rn, uint64_t Rt); -void st2_multiple_structures_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t size, uint64_t Rn, uint64_t Rt); -void st2_multiple_structures_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t size, uint64_t Rn, uint64_t Rt); -void st1_single_structure_no_offset_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); -void st1_single_structure_post_index_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t Rm, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt); -void floating_point_conditional_select_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t Rd); -void fcmp_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t Rn, uint64_t opc); -void fccmp_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rm, uint64_t cond, uint64_t Rn, uint64_t nzcv); ir_operand _x_jit(ssa_emit_context* ctx, uint64_t reg_id);//THIS FUNCTION IS USER DEFINED void _x_jit(ssa_emit_context* ctx, uint64_t reg_id, ir_operand value);//THIS FUNCTION IS USER DEFINED ir_operand _sys_jit(ssa_emit_context* ctx, uint64_t reg_id);//THIS FUNCTION IS USER DEFINED diff --git a/src/ir/ssa.cpp b/src/ir/ssa.cpp index 8e5e5e8..a09ceff 100755 --- a/src/ir/ssa.cpp +++ b/src/ir/ssa.cpp @@ -29,6 +29,7 @@ struct ssa_node std::unordered_set declared_in_block; std::unordered_map> declaration_time_map; std::unordered_map last_declared; + std::unordered_map cached_global_declarations; std::vector inlets; std::vector outlets; @@ -196,6 +197,13 @@ static void find_same_register_pools(ssa_node* node) continue; } + if (in_map(&node->cached_global_declarations, current_source->value)) + { + connect_global_usages(this_global_usage,node->cached_global_declarations[current_source->value]); + + continue; + } + this_global_usage->is_global = true; for (auto inlet : node->inlets) @@ -204,6 +212,8 @@ static void find_same_register_pools(ssa_node* node) find_register_in_parents(inlet, current_source->value, this_global_usage, &visited); } + + node->cached_global_declarations[current_source->value] = this_global_usage; } time++; @@ -544,6 +554,7 @@ static bool optimize_math(ssa_node* working_node) }; break; case ir_bitwise_or: + case x86_orps: { if (check_constant(src[0], 0)) { @@ -571,6 +582,12 @@ static bool optimize_math(ssa_node* working_node) convert_to_move(working_operation, ir_operand::create_con(value, des[0].meta_data)); + is_done = false; + } + else if (ir_operand::are_equal(src[0], src[1])) + { + convert_to_move(working_operation, src[0]); + is_done = false; } }; break; @@ -595,6 +612,12 @@ static bool optimize_math(ssa_node* working_node) convert_to_move(working_operation, ir_operand::create_con(value, des[0].meta_data)); + is_done = false; + } + else if (ir_operand::are_equal(src[0], src[1])) + { + convert_to_move(working_operation, ir_operand::create_con(0)); + is_done = false; } }; break; @@ -620,6 +643,14 @@ static bool optimize_math(ssa_node* working_node) is_done = false; } + else if (ir_operand::are_equal(src[0], src[1])) + { + src[1] = ir_operand::create_con(1, src[1].meta_data); + + working_operation->instruction = ir_shift_left; + + is_done = false; + } else if (check_constant(src[0]) && check_constant(src[1])) { uint64_t value = src[0].value + src[1].value; @@ -628,6 +659,7 @@ static bool optimize_math(ssa_node* working_node) is_done = false; } + }; break; case ir_subtract: @@ -654,6 +686,12 @@ static bool optimize_math(ssa_node* working_node) is_done = false; } + else if (ir_operand::are_equal(src[0], src[1])) + { + convert_to_move(working_operation, ir_operand::create_con(0)); + + is_done = false; + } else if (check_constant(src[0]) && check_constant(src[1])) { uint64_t value = src[0].value - src[1].value; @@ -836,7 +874,7 @@ static void loop_through_operands_find_usage_count(ir_operand* operands, int cou } } -static bool check_for_register_in_instruction(ir_operand* operands,int count, uint64_t to_check) +static bool check_for_register_in_collection(ir_operand* operands,int count, uint64_t to_check) { for (int i = 0; i < count; ++i) { @@ -854,7 +892,7 @@ static bool check_for_register_in_instruction(ir_operand* operands,int count, ui static bool check_for_register_in_instruction(ir_operation* operation, uint64_t to_check) { - return check_for_register_in_instruction(operation->destinations.data, operation->destinations.count, to_check) | check_for_register_in_instruction(operation->sources.data, operation->sources.count, to_check); + return check_for_register_in_collection(operation->destinations.data, operation->destinations.count, to_check) | check_for_register_in_collection(operation->sources.data, operation->sources.count, to_check); } void copy_operands(ir_operand* destination,ir_operand* source, int count) @@ -898,10 +936,10 @@ static bool optimize_multiple_instructions(ssa_node* working_node) loop_through_operands_find_usage_count(working_operation->sources.data, working_operation->sources.count, &usage_count); - if (working_operation->destinations.count != 1) - continue; - - declaration_location[working_operation->destinations[0].value] = working_operation; + for (int r = 0; r < working_operation->destinations.count; ++r) + { + declaration_location[working_operation->destinations[r].value] = working_operation; + } } time = 0; @@ -1081,9 +1119,28 @@ static bool optimize_multiple_instructions(ssa_node* working_node) is_done = false; }; break; + + case ir_compare_greater_equal_unsigned: + { + replace_jump_with_condition(ir, label, working_operation, condition_source, ir_jump_if_greater_equal_unsigned); + + is_done = false; + }; break; + + case ir_compare_greater_equal_signed: + { + replace_jump_with_condition(ir, label, working_operation, condition_source, ir_jump_if_greater_equal_signed); + + is_done = false; + }; break; default: - break; + { + if (ir_operation_block::is_compare(condition_source)) + { + std::cout << instruction_names[condition_source->instruction] << std::endl; + } + }; break; } }; break; @@ -1096,70 +1153,143 @@ static bool optimize_multiple_instructions(ssa_node* working_node) if (ir_operand::is_constant(&source_operand)) continue; - if (!is_global(context, destination_operand)) - continue; - - if (is_global(context, source_operand)) - continue; - - ir_operation* local_declared_operation = declaration_location[source_operand.value]; - - if (local_declared_operation == nullptr) - continue; - - if (usage_count[source_operand.value] > 1) - continue; - - if (local_declared_operation->destinations.count == 0) - continue; - - bool is_valid = true; - - for (auto b = i->prev; b != raw_node->entry_instruction->prev; b = b->prev) + if (is_global(context, destination_operand) && !is_global(context, source_operand)) { - ir_operation* check_operation = &b->data; + ir_operation* local_declared_operation = declaration_location[source_operand.value]; - if (check_operation == local_declared_operation) - break; - - if (check_for_register_in_instruction(check_operation, destination_operand.value)) + if (local_declared_operation == nullptr) + continue; + + if (usage_count[source_operand.value] > 1) + continue; + + if (local_declared_operation->destinations.count == 0) + continue; + + bool is_valid = true; + + for (auto b = i->prev; b != raw_node->entry_instruction->prev; b = b->prev) { - is_valid = false; - - break; - } - } - - if (!is_valid) - continue; - - for (int o = 0; o < local_declared_operation->destinations.count; ++o) - { - ir_operand* replace_candidate = &local_declared_operation->destinations.data[o]; - - if (replace_candidate->value == source_operand.value) - { - if (replace_candidate->meta_data != source_operand.meta_data) + ir_operation* check_operation = &b->data; + + if (check_operation == local_declared_operation) + break; + + if (check_for_register_in_instruction(check_operation, destination_operand.value)) { - //is_valid = false; + is_valid = false; + + break; + } + } + + if (!is_valid) + continue; + + for (int o = 0; o < local_declared_operation->destinations.count; ++o) + { + ir_operand* replace_candidate = &local_declared_operation->destinations.data[o]; + + if (replace_candidate->value == source_operand.value) + { + if (replace_candidate->meta_data != source_operand.meta_data) + { + //is_valid = false; + + //IN A LOT OF CACES, THIS CAN BE IGNORED + //TODO, FIND THOSE CASES + + //break; + } + + replace_candidate->value = destination_operand.value; + } + } + + if (!is_valid) + continue; + + nop_operation(working_operation); + + is_done = false; + } + else if (!is_global(context,destination_operand) && is_global(context, source_operand)) + { + bool is_zero_extend = false; + bool ignore = false; - //IN A LOT OF CACES, THIS CAN BE IGNORED - //TODO, FIND THOSE CASES + std::vector to_replace; + intrusive_linked_list_element* look_next = nullptr; - //break; + for (auto check = i->next; check != raw_node->final_instruction->next; check = check->next) + { + ir_operation* check_operation = &check->data; + + if (check_if_zero_extend(&check->data,destination_operand)) + { + is_zero_extend = true; + + break; } - replace_candidate->value = destination_operand.value; + for (int o = 0; o < check_operation->sources.count; ++o) + { + ir_operand* to_replace_candidate = &check_operation->sources[o]; + + if (ir_operand::is_constant(to_replace_candidate)) + continue; + + if (to_replace_candidate->value != destination_operand.value) + continue; + + to_replace.push_back(to_replace_candidate); + } + + if (check_for_register_in_collection(check_operation->destinations.data, check_operation->destinations.count, source_operand.value)) + { + look_next = check->next; + + break; + } } + + if (look_next != nullptr) + { + for (auto check = look_next; check != raw_node->final_instruction->next; check = check->next) + { + ir_operation* check_operation = &check->data; + + if (!check_for_register_in_collection(check_operation->sources.data, check_operation->sources.count, destination_operand.value)) + continue; + + ignore = true; + + break; + } + } + + if (ignore) + { + continue; + } + + if (is_zero_extend) + { + i->data.instruction = ir_zero_extend; + + continue; + } + + for (auto i : to_replace) + { + i->value = source_operand.value; + } + + nop_operation(working_operation); + + is_done = false; } - if (!is_valid) - continue; - - nop_operation(working_operation); - - is_done = false; - }; break; default: @@ -1269,6 +1399,10 @@ void convert_to_ssa(ir_operation_block* ir, bool optimize) } } + //ir_operation_block::log(ssa.ir); + + //std::cin.get(); + linier_scan_register_allocator_pass(ssa.cfg); destroy_ssa_context(&ssa); diff --git a/src/jit/jit_memory.cpp b/src/jit/jit_memory.cpp index 8b964b9..e95b586 100755 --- a/src/jit/jit_memory.cpp +++ b/src/jit/jit_memory.cpp @@ -49,9 +49,11 @@ static void unmark_memory_executable(void* memory, uint64_t size) static uint64_t align_64_kb(uint64_t source) { - uint64_t mask = ~63ULL; + uint64_t page_size = 64 * 1024; - return (source & mask) + 64; + uint64_t mask = page_size - 1; + + return (source & ~mask) + page_size; } bool jit_memory::create(jit_memory** result, uint64_t allocation_size, abi host_abi) diff --git a/src/jit/rem_tester_arm.code-workspace b/src/jit/rem_tester_arm.code-workspace new file mode 100644 index 0000000..7758b18 --- /dev/null +++ b/src/jit/rem_tester_arm.code-workspace @@ -0,0 +1,11 @@ +{ + "folders": [ + { + "path": "../../../rem_tester_arm" + }, + { + "path": "../.." + } + ], + "settings": {} +} \ No newline at end of file