mirror of
https://github.com/pound-emu/rem.git
synced 2026-06-17 04:16:28 -07:00
Super Mario Odyssey playable!
Super Mario Odyssey is playable using rem emulator in Ryujinx with full implementation.
This commit is contained in:
@@ -103,8 +103,10 @@ void assemble_x86_64_code(void** result_code, uint64_t* result_code_size, ir_ope
|
||||
{
|
||||
arena_allocator* allocator = source_ir->allocator;
|
||||
|
||||
*result_code = arena_allocator::allocate_recursive(allocator, ONE_MB);
|
||||
Xbyak::CodeGenerator c(ONE_MB, *result_code);
|
||||
int buffer_size = ONE_MB * 5;
|
||||
|
||||
*result_code = arena_allocator::allocate_recursive(allocator, buffer_size);
|
||||
Xbyak::CodeGenerator c(buffer_size, *result_code);
|
||||
|
||||
c.setDefaultJmpNEAR(true);
|
||||
|
||||
@@ -113,6 +115,11 @@ void assemble_x86_64_code(void** result_code, uint64_t* result_code_size, ir_ope
|
||||
ir_operation working_operation = i->data;
|
||||
ir_instructions instruction = (ir_instructions)working_operation.instruction;
|
||||
|
||||
if (c.getSize() > buffer_size - 1024)
|
||||
{
|
||||
throw_error();
|
||||
}
|
||||
|
||||
switch (instruction)
|
||||
{
|
||||
case ir_negate: c.neg(create_operand(working_operation.destinations[0])); assert_valid_unary_operation(&working_operation); break;
|
||||
@@ -138,7 +145,6 @@ void assemble_x86_64_code(void** result_code, uint64_t* result_code_size, ir_ope
|
||||
case ir_external_call:
|
||||
{
|
||||
auto function_to_call = create_operand(working_operation.sources[0]);
|
||||
|
||||
int caller_size = 120;
|
||||
|
||||
c.sub(c.rsp, caller_size);
|
||||
@@ -755,6 +761,50 @@ void assemble_x86_64_code(void** result_code, uint64_t* result_code_size, ir_ope
|
||||
case x86_subsd: assert_valid_binary_float_operation(&working_operation); c.subsd(create_operand<Xbyak::Xmm>(working_operation.destinations[0]), create_operand<Xbyak::Xmm>(working_operation.sources[1])); break;
|
||||
case x86_subss: assert_valid_binary_float_operation(&working_operation); c.subss(create_operand<Xbyak::Xmm>(working_operation.destinations[0]), create_operand<Xbyak::Xmm>(working_operation.sources[1])); break;
|
||||
|
||||
case x86_sqrtss: c.sqrtss(create_operand<Xbyak::Xmm>(working_operation.destinations[0]), create_operand<Xbyak::Xmm>(working_operation.sources[0])); break;
|
||||
case x86_sqrtsd: c.sqrtsd(create_operand<Xbyak::Xmm>(working_operation.destinations[0]), create_operand<Xbyak::Xmm>(working_operation.sources[0])); break;
|
||||
|
||||
case ir_floating_point_compare_equal:
|
||||
case ir_floating_point_compare_less:
|
||||
case ir_floating_point_compare_not_equal:
|
||||
case ir_floating_point_compare_greater:
|
||||
case ir_floating_point_compare_greater_equal:
|
||||
{
|
||||
ir_operand destination = working_operation.destinations[0];
|
||||
ir_operand source_0 = working_operation.sources[0];
|
||||
ir_operand source_1 = working_operation.sources[1];
|
||||
|
||||
assert(!ir_operand::is_vector(&destination));
|
||||
assert(ir_operand::is_vector(&source_0));
|
||||
assert(ir_operand::is_vector(&source_1));
|
||||
|
||||
switch (ir_operand::get_raw_size(&destination))
|
||||
{
|
||||
case int32:
|
||||
{
|
||||
c.comiss(create_operand<Xbyak::Xmm>(source_0), create_operand<Xbyak::Xmm>(source_1));
|
||||
}; break;
|
||||
|
||||
case int64:
|
||||
{
|
||||
c.comisd(create_operand<Xbyak::Xmm>(source_0), create_operand<Xbyak::Xmm>(source_1));
|
||||
}; break;
|
||||
default: throw_error();
|
||||
}
|
||||
|
||||
switch (instruction)
|
||||
{
|
||||
case ir_floating_point_compare_equal: c.sete(create_operand<Xbyak::Reg8>(destination)); break;
|
||||
case ir_floating_point_compare_not_equal: c.setne(create_operand<Xbyak::Reg8>(destination)); break;
|
||||
case ir_floating_point_compare_less: c.setb(create_operand<Xbyak::Reg8>(destination)); break;
|
||||
case ir_floating_point_compare_greater: c.seta(create_operand<Xbyak::Reg8>(destination)); break;
|
||||
case ir_floating_point_compare_greater_equal: c.setae(create_operand<Xbyak::Reg8>(destination)); break;
|
||||
default: throw_error();
|
||||
}
|
||||
|
||||
c.and_(create_operand<Xbyak::Reg64>(destination), 1);
|
||||
}; break;
|
||||
|
||||
default:
|
||||
{
|
||||
std::cout << "UNDEFINED X86 INSTRUCTION " << std::endl;
|
||||
|
||||
@@ -77,6 +77,16 @@ static ir_operand register_or_constant(x86_pre_allocator_context* context, ir_op
|
||||
return register_or_constant(context, &source, force_copy);
|
||||
}
|
||||
|
||||
static ir_operand vector_from_register(x86_pre_allocator_context* context, ir_operand source)
|
||||
{
|
||||
source = register_or_constant(context, source);
|
||||
ir_operand result = create_scrap_operand(context, int128);
|
||||
|
||||
ir_operation_block::emitds(context->ir, x86_movq_to_vec, result, source);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void emit_throw_exception(x86_pre_allocator_context* context)
|
||||
{
|
||||
ir_operand zero = register_or_constant(context, ir_operand::create_con(0));
|
||||
@@ -181,6 +191,70 @@ static void emit_d_n_f_d_n_m(x86_pre_allocator_context* result, uint64_t instruc
|
||||
emit_move(result, working_destination, working_scrap);
|
||||
}
|
||||
|
||||
static void emit_floating_point_compare(x86_pre_allocator_context* result, uint64_t instruction, ir_operand destination, ir_operand source_0, ir_operand source_1)
|
||||
{
|
||||
assert_same_size({ destination, source_0, source_1 });
|
||||
|
||||
ir_operand working_destination = destination;
|
||||
|
||||
ir_operand working_vector_0 = vector_from_register(result, source_0);
|
||||
ir_operand working_vector_1 = vector_from_register(result, source_1);
|
||||
|
||||
ir_operation_block::emitds(result->ir, instruction, working_destination, working_vector_0, working_vector_1);
|
||||
}
|
||||
|
||||
static void emit_floating_point_binary(x86_pre_allocator_context* result, uint64_t instruction, ir_operand destination, ir_operand source_0, ir_operand source_1)
|
||||
{
|
||||
assert_same_size({ destination, source_0, source_1 });
|
||||
|
||||
ir_operand working_destination = destination;
|
||||
ir_operand working_source_0 = register_or_constant(result, &source_0);
|
||||
ir_operand working_source_1 = register_or_constant(result, &source_1);
|
||||
|
||||
ir_operand working_vector_0 = vector_from_register(result, working_source_0);
|
||||
ir_operand working_vector_1 = vector_from_register(result, working_source_1);
|
||||
|
||||
int working_instruction;
|
||||
|
||||
switch (instruction)
|
||||
{
|
||||
case ir_floating_point_add: working_instruction = ir_operand::get_raw_size(&destination) == int64 ? x86_addsd : x86_addss; break;
|
||||
case ir_floating_point_subtract: working_instruction = ir_operand::get_raw_size(&destination) == int64 ? x86_subsd : x86_subss; break;
|
||||
case ir_floating_point_multiply: working_instruction = ir_operand::get_raw_size(&destination) == int64 ? x86_mulsd : x86_mulss; break;
|
||||
case ir_floating_point_divide: working_instruction = ir_operand::get_raw_size(&destination) == int64 ? x86_divsd : x86_divss; break;
|
||||
case ir_floating_point_select_min: working_instruction = ir_operand::get_raw_size(&destination) == int64 ? x86_minsd : x86_minss; break;
|
||||
case ir_floating_point_select_max: working_instruction = ir_operand::get_raw_size(&destination) == int64 ? x86_maxsd : x86_maxss; break;
|
||||
|
||||
default: throw_error();
|
||||
}
|
||||
|
||||
ir_operation_block::emitds(result->ir, working_instruction, working_vector_0, working_vector_0, working_vector_1);
|
||||
|
||||
ir_operation_block::emitds(result->ir, x86_movq_to_gp, working_destination, working_vector_0);
|
||||
}
|
||||
|
||||
static void emit_floating_point_unary(x86_pre_allocator_context* result, uint64_t instruction, ir_operand destination, ir_operand source_0)
|
||||
{
|
||||
assert_same_size({ destination, source_0 });
|
||||
|
||||
ir_operand working_destination = destination;
|
||||
ir_operand working_source_0 = register_or_constant(result, &source_0);
|
||||
|
||||
ir_operand working_vector_0 = vector_from_register(result, working_source_0);
|
||||
|
||||
int working_instruction;
|
||||
|
||||
switch (instruction)
|
||||
{
|
||||
case ir_floating_point_square_root: working_instruction = ir_operand::get_raw_size(&destination) == int64 ? x86_sqrtsd : x86_sqrtss; break;
|
||||
default: throw_error();
|
||||
}
|
||||
|
||||
ir_operation_block::emitds(result->ir, working_instruction, working_vector_0, working_vector_0);
|
||||
|
||||
ir_operation_block::emitds(result->ir, x86_movq_to_gp, working_destination, working_vector_0);
|
||||
}
|
||||
|
||||
static void emit_compare(x86_pre_allocator_context* result, uint64_t instruction, ir_operand destination, ir_operand source_0, ir_operand source_1)
|
||||
{
|
||||
assert_same_size({ destination, source_0, source_1 });
|
||||
@@ -635,6 +709,31 @@ static void emit_pre_allocation_instruction(x86_pre_allocator_context* pre_alloc
|
||||
emit_d_n_f_d_n_m(pre_allocator_context, operation->instruction, operation->destinations[0], operation->sources[0], operation->sources[1]);
|
||||
}; break;
|
||||
|
||||
case ir_floating_point_add:
|
||||
case ir_floating_point_subtract:
|
||||
case ir_floating_point_multiply:
|
||||
case ir_floating_point_divide:
|
||||
case ir_floating_point_select_min:
|
||||
case ir_floating_point_select_max:
|
||||
{
|
||||
assert_operand_count(operation, 1, 2);
|
||||
assert_is_register(operation->destinations[0]);
|
||||
|
||||
emit_floating_point_binary(pre_allocator_context, operation->instruction, operation->destinations[0], operation->sources[0], operation->sources[1]);
|
||||
}; break;
|
||||
|
||||
case ir_floating_point_compare_equal:
|
||||
case ir_floating_point_compare_less:
|
||||
case ir_floating_point_compare_not_equal:
|
||||
case ir_floating_point_compare_greater:
|
||||
case ir_floating_point_compare_greater_equal:
|
||||
{
|
||||
assert_operand_count(operation, 1, 2);
|
||||
assert_is_register(operation->destinations[0]);
|
||||
|
||||
emit_floating_point_compare(pre_allocator_context, operation->instruction, operation->destinations[0], operation->sources[0], operation->sources[1]);
|
||||
}; break;
|
||||
|
||||
case ir_multiply_hi_signed:
|
||||
case ir_multiply_hi_unsigned:
|
||||
case ir_divide_unsigned:
|
||||
@@ -715,6 +814,14 @@ static void emit_pre_allocation_instruction(x86_pre_allocator_context* pre_alloc
|
||||
|
||||
}; break;
|
||||
|
||||
case ir_floating_point_square_root:
|
||||
{
|
||||
assert_operand_count(operation, 1, 1);
|
||||
assert_is_register(operation->destinations[0]);
|
||||
|
||||
emit_floating_point_unary(pre_allocator_context, operation->instruction, operation->destinations[0], operation->sources[0]);
|
||||
}; break;
|
||||
|
||||
case ir_sign_extend:
|
||||
{
|
||||
assert_operand_count(operation, 1, 1);
|
||||
|
||||
@@ -183,4 +183,15 @@ uint64_t call_counter_interpreter(interpreter_data* ctx)
|
||||
uint64_t call_interpreter(interpreter_data* ctx, uint64_t a0, uint64_t a1, uint64_t a2, uint64_t a3, uint64_t a4, uint64_t a5, uint64_t function)
|
||||
{
|
||||
return ((uint64_t(*)(uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t))function)(a0, a1, a2, a3, a4, a5);
|
||||
}
|
||||
|
||||
//Optimize
|
||||
uint64_t use_fast_float_interpreter(interpreter_data* ctx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t use_x86_sse(interpreter_data* ctx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -221,4 +221,15 @@ ir_operand call_jit(ssa_emit_context* ctx, ir_operand a0, ir_operand a1, ir_oper
|
||||
ir_operation_block::emitds(ctx->ir, ir_external_call, result, ir_operand::create_con(function), a0, a1, a2, a3, a4, a5);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//Optimization
|
||||
uint64_t use_fast_float_jit(ssa_emit_context* ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint64_t use_x86_sse(ssa_emit_context* ctx)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -66,6 +66,32 @@ uint64_t convert_to_float(uint64_t source, bool is_signed)
|
||||
return *(uint64_t*)&temp;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
double get_float(uint64_t source)
|
||||
{
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 4: return convert<float, uint32_t>(source);
|
||||
case 8: return convert<double, uint64_t>(source);
|
||||
default: throw_error();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
uint64_t get_int(double source)
|
||||
{
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case 4: return convert<uint32_t, float>(source);
|
||||
case 8: return convert<uint64_t, double>(source);
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t undefined_value()
|
||||
{
|
||||
throw_error();
|
||||
}
|
||||
|
||||
//INTERPRETER
|
||||
uint64_t sign_extend_interpreter(interpreter_data* ctx, uint64_t source, uint64_t count);
|
||||
template <typename O>
|
||||
@@ -108,6 +134,12 @@ uint128_t replicate_vector_interpreter(interpreter_data* ctx, uint128_t source,
|
||||
void st_interpreter(interpreter_data* ctx, uint64_t wback, uint64_t Q, uint64_t L, uint64_t opcode, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rt);
|
||||
void memory_1_interpreter(interpreter_data* ctx, uint64_t wback, uint64_t Q, uint64_t L, uint64_t R, uint64_t Rm, uint64_t o2, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t is_load);
|
||||
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);
|
||||
uint64_t bits_r_interpreter(interpreter_data* ctx, uint64_t operand, uint64_t top, uint64_t bottom);
|
||||
uint64_t infinity_interpreter(interpreter_data* ctx, uint64_t sign, uint64_t N);
|
||||
uint64_t float_is_nan_interpreter(interpreter_data* ctx, uint64_t operand, uint64_t N);
|
||||
uint64_t float_imm_interpreter(interpreter_data* ctx, uint64_t source, uint64_t N);
|
||||
template <typename F>
|
||||
F create_fixed_from_fbits_interpreter(interpreter_data* ctx, uint64_t fbits, uint64_t N);
|
||||
uint64_t FPAdd_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPSub_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPMul_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
@@ -118,6 +150,7 @@ uint64_t FPMaxNum_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t
|
||||
uint64_t FPMinNum_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPCompare_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPRSqrtStepFused_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPRecipStepFused_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPCompareEQ_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPCompareGT_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPCompareGE_interpreter(interpreter_data* ctx, uint64_t operand1, uint64_t operand2, uint64_t FPCR, uint64_t N);
|
||||
@@ -125,6 +158,7 @@ uint64_t FPSqrt_interpreter(interpreter_data* ctx, uint64_t operand, uint64_t FP
|
||||
uint64_t FPNeg_interpreter(interpreter_data* ctx, uint64_t operand, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPAbs_interpreter(interpreter_data* ctx, uint64_t operand, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPRSqrtEstimate_interpreter(interpreter_data* ctx, uint64_t operand, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FPRecipEstimate_interpreter(interpreter_data* ctx, uint64_t operand, uint64_t FPCR, uint64_t N);
|
||||
uint64_t FixedToFP_interpreter(interpreter_data* ctx, uint64_t source, uint64_t fracbits, uint64_t is_unsigned, uint64_t to, uint64_t from);
|
||||
uint64_t FPToFixed_interpreter(interpreter_data* ctx, uint64_t source, uint64_t fracbits, uint64_t is_unsigned, uint64_t round, uint64_t to, uint64_t from);
|
||||
uint64_t FPConvert_interpreter(interpreter_data* ctx, uint64_t source, uint64_t to, uint64_t from);
|
||||
@@ -202,6 +236,7 @@ void conversion_between_floating_point_and_fixed_point_interpreter(interpreter_d
|
||||
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);
|
||||
@@ -220,6 +255,7 @@ void and_bic_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t inve
|
||||
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 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);
|
||||
@@ -240,8 +276,10 @@ void fmov_scalar_immediate_interpreter(interpreter_data* ctx, uint64_t ftype, ui
|
||||
void fcvt_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t opc, 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 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);
|
||||
void fcvtz_scalar_integer_interpreter(interpreter_data* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd);
|
||||
@@ -257,6 +295,7 @@ void faddp_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, ui
|
||||
void frsqrte_scalar_interpreter(interpreter_data* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd);
|
||||
void frsqrte_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd);
|
||||
void frsqrts_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd);
|
||||
void frecps_vector_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd);
|
||||
void fmul_scalar_by_element_interpreter(interpreter_data* ctx, uint64_t sz, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd);
|
||||
void fmul_vector_by_element_interpreter(interpreter_data* ctx, uint64_t Q, uint64_t sz, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd);
|
||||
void fmul_accumulate_scalar_interpreter(interpreter_data* ctx, uint64_t sz, uint64_t L, uint64_t M, uint64_t Rm, uint64_t neg, uint64_t H, uint64_t Rn, uint64_t Rd);
|
||||
@@ -265,6 +304,7 @@ void frint_interpreter(interpreter_data* ctx, uint64_t ftype, uint64_t Rn, uint6
|
||||
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 faddp_scalar_interpreter(interpreter_data* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd);
|
||||
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
|
||||
@@ -277,6 +317,8 @@ void _branch_conditional_interpreter(interpreter_data* ctx, uint64_t yes, uint64
|
||||
uint64_t get_vector_context_interpreter(interpreter_data* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
void store_context_interpreter(interpreter_data* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
void load_context_interpreter(interpreter_data* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
uint64_t use_fast_float_interpreter(interpreter_data* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
uint64_t use_x86_sse_interpreter(interpreter_data* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
uint64_t _get_pc_interpreter(interpreter_data* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
uint64_t translate_address_interpreter(interpreter_data* ctx, uint64_t address);//THIS FUNCTION IS USER DEFINED
|
||||
void call_supervisor_interpreter(interpreter_data* ctx, uint64_t svc);//THIS FUNCTION IS USER DEFINED
|
||||
@@ -322,6 +364,11 @@ ir_operand replicate_vector_jit(ssa_emit_context* ctx, ir_operand source, uint64
|
||||
void st_jit(ssa_emit_context* ctx, uint64_t wback, uint64_t Q, uint64_t L, uint64_t opcode, uint64_t size, uint64_t Rm, uint64_t Rn, uint64_t Rt);
|
||||
void memory_1_jit(ssa_emit_context* ctx, uint64_t wback, uint64_t Q, uint64_t L, uint64_t R, uint64_t Rm, uint64_t o2, uint64_t opcode, uint64_t S, uint64_t size, uint64_t Rn, uint64_t Rt, uint64_t is_load);
|
||||
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 bits_r_jit(ssa_emit_context* ctx, ir_operand operand, uint64_t top, uint64_t bottom);
|
||||
ir_operand infinity_jit(ssa_emit_context* ctx, uint64_t sign, uint64_t N);
|
||||
ir_operand float_is_nan_jit(ssa_emit_context* ctx, ir_operand operand, uint64_t N);
|
||||
ir_operand float_imm_jit(ssa_emit_context* ctx, ir_operand source, uint64_t N);
|
||||
ir_operand create_fixed_from_fbits_jit(ssa_emit_context* ctx,uint64_t F, uint64_t fbits, uint64_t N);
|
||||
ir_operand FPAdd_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPSub_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPMul_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
@@ -332,6 +379,7 @@ ir_operand FPMaxNum_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand o
|
||||
ir_operand FPMinNum_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPCompare_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPRSqrtStepFused_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPRecipStepFused_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPCompareEQ_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPCompareGT_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPCompareGE_jit(ssa_emit_context* ctx, ir_operand operand1, ir_operand operand2, ir_operand FPCR, uint64_t N);
|
||||
@@ -339,6 +387,7 @@ ir_operand FPSqrt_jit(ssa_emit_context* ctx, ir_operand operand, ir_operand FPCR
|
||||
ir_operand FPNeg_jit(ssa_emit_context* ctx, ir_operand operand, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPAbs_jit(ssa_emit_context* ctx, ir_operand operand, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPRSqrtEstimate_jit(ssa_emit_context* ctx, ir_operand operand, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FPRecipEstimate_jit(ssa_emit_context* ctx, ir_operand operand, ir_operand FPCR, uint64_t N);
|
||||
ir_operand FixedToFP_jit(ssa_emit_context* ctx, ir_operand source, uint64_t fracbits, uint64_t is_unsigned, uint64_t to, uint64_t from);
|
||||
ir_operand FPToFixed_jit(ssa_emit_context* ctx, ir_operand source, uint64_t fracbits, uint64_t is_unsigned, uint64_t round, uint64_t to, uint64_t from);
|
||||
ir_operand FPConvert_jit(ssa_emit_context* ctx, ir_operand source, uint64_t to, uint64_t from);
|
||||
@@ -414,6 +463,7 @@ void conversion_between_floating_point_and_fixed_point_jit(ssa_emit_context* ctx
|
||||
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);
|
||||
@@ -432,6 +482,7 @@ void and_bic_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t invert, uint
|
||||
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 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);
|
||||
@@ -452,8 +503,10 @@ void fmov_scalar_immediate_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t i
|
||||
void fcvt_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t opc, 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 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);
|
||||
void fcvtz_scalar_integer_jit(ssa_emit_context* ctx, uint64_t sf, uint64_t ftype, uint64_t U, uint64_t Rn, uint64_t Rd);
|
||||
@@ -469,6 +522,7 @@ void faddp_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t R
|
||||
void frsqrte_scalar_jit(ssa_emit_context* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd);
|
||||
void frsqrte_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rn, uint64_t Rd);
|
||||
void frsqrts_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd);
|
||||
void frecps_vector_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t Rm, uint64_t Rn, uint64_t Rd);
|
||||
void fmul_scalar_by_element_jit(ssa_emit_context* ctx, uint64_t sz, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd);
|
||||
void fmul_vector_by_element_jit(ssa_emit_context* ctx, uint64_t Q, uint64_t sz, uint64_t L, uint64_t M, uint64_t Rm, uint64_t H, uint64_t Rn, uint64_t Rd);
|
||||
void fmul_accumulate_scalar_jit(ssa_emit_context* ctx, uint64_t sz, uint64_t L, uint64_t M, uint64_t Rm, uint64_t neg, uint64_t H, uint64_t Rn, uint64_t Rd);
|
||||
@@ -477,6 +531,7 @@ void frint_jit(ssa_emit_context* ctx, uint64_t ftype, uint64_t Rn, uint64_t Rd,
|
||||
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 faddp_scalar_jit(ssa_emit_context* ctx, uint64_t sz, uint64_t Rn, uint64_t Rd);
|
||||
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
|
||||
@@ -489,6 +544,8 @@ void _branch_conditional_jit(ssa_emit_context* ctx, uint64_t yes, uint64_t no, i
|
||||
ir_operand get_vector_context_jit(ssa_emit_context* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
void store_context_jit(ssa_emit_context* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
void load_context_jit(ssa_emit_context* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
uint64_t use_fast_float_jit(ssa_emit_context* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
uint64_t use_x86_sse_jit(ssa_emit_context* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
uint64_t _get_pc_jit(ssa_emit_context* ctx);//THIS FUNCTION IS USER DEFINED
|
||||
ir_operand translate_address_jit(ssa_emit_context* ctx, ir_operand address);//THIS FUNCTION IS USER DEFINED
|
||||
void call_supervisor_jit(ssa_emit_context* ctx, uint64_t svc);//THIS FUNCTION IS USER DEFINED
|
||||
|
||||
@@ -231,6 +231,16 @@ static meta_number NOT(meta_number source)
|
||||
return source;
|
||||
}
|
||||
|
||||
enum ReduceOp
|
||||
{
|
||||
ReduceOp_FMINNUM,
|
||||
ReduceOp_FMAXNUM,
|
||||
ReduceOp_FMIN,
|
||||
ReduceOp_FMAX,
|
||||
ReduceOp_FADD,
|
||||
ReduceOp_ADD
|
||||
};
|
||||
|
||||
enum FPType
|
||||
{
|
||||
FPType_Zero,
|
||||
@@ -1733,7 +1743,7 @@ static bits(N) FPRoundInt(bits(N) op, FPCR_Type fpcr, FPRounding rounding, boole
|
||||
|
||||
// When alternative floating-point support is TRUE, do not generate
|
||||
// Input Denormal floating-point exceptions.
|
||||
auto altfp = IsFeatureImplemented(FEAT_AFP) && !UsingAArch32() && fpcr.AH() == '1';
|
||||
auto altfp = IsFeatureImplemented(FEAT_AFP) && !UsingAArch32() && fpcr.AH() == 1;
|
||||
auto fpexc = !altfp;
|
||||
|
||||
// Unpack using FPCR to determine if subnormals are flushed-to-zero.
|
||||
@@ -1992,6 +2002,46 @@ static bits(N) FPRSqrtEstimate(bits(N) operand, FPCR_Type fpcr_in)
|
||||
return result;
|
||||
}
|
||||
|
||||
static bits(N) FPRecipEstimate(bits(N) operand, FPCR_Type fpcr_in)
|
||||
{
|
||||
int N = operand.size;
|
||||
|
||||
assert_in(N, {16,32,64});
|
||||
FPCR_Type fpcr = fpcr_in;
|
||||
bits(N) result;
|
||||
boolean overflow_to_inf;
|
||||
// When using alternative floating-point behavior, do not generate
|
||||
// floating-point exceptions, flush denormal input and output to zero,
|
||||
// and use RNE rounding mode.
|
||||
boolean altfp = IsFeatureImplemented(FEAT_AFP) && !UsingAArch32() && fpcr.AH() == 1;
|
||||
boolean fpexc = !altfp;
|
||||
//if altfp then fpcr.<FIZ,FZ> = 11;
|
||||
//if altfp then fpcr.RMode = 00;
|
||||
|
||||
auto [fptype,sign,value] = FPUnpack(operand, fpcr, fpexc);
|
||||
|
||||
FPRounding rounding = FPRoundingMode(fpcr);
|
||||
if (fptype == FPType_SNaN || fptype == FPType_QNaN)
|
||||
{
|
||||
result = FPProcessNaN(fptype, operand, fpcr, fpexc);
|
||||
}
|
||||
else if (fptype == FPType_Infinity)
|
||||
{
|
||||
result = FPZero(sign, N);
|
||||
}
|
||||
else if (fptype == FPType_Zero)
|
||||
{
|
||||
result = FPInfinity(sign, N);
|
||||
if (fpexc) FPProcessException(FPExc_DivideByZero, fpcr);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = FPRound(1.0 / value,fpcr, N);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bits(N) FPOnePointFive(bit sign, integer N)
|
||||
{
|
||||
assert_in(N,{16,32,64});
|
||||
@@ -2004,6 +2054,73 @@ static bits(N) FPOnePointFive(bit sign, integer N)
|
||||
return result;
|
||||
}
|
||||
|
||||
static bits(N) FPTwo(bit sign, integer N)
|
||||
{
|
||||
assert_in(N,{16,32,64});
|
||||
integer E = (N == 16 ? 5 : N == 32 ? 8 : 11);
|
||||
integer F = N - (E + 1);
|
||||
auto exp = meta_number(1,1) | Zeros(E-1);
|
||||
auto frac = Zeros(F);
|
||||
auto result = sign | exp | frac;
|
||||
return result;
|
||||
}
|
||||
|
||||
static bits(N) FPRecipStepFused(bits(N) op1_in, bits(N) op2, FPCR_Type fpcr_in)
|
||||
{
|
||||
int N = op1_in.size;
|
||||
|
||||
assert_in(N , {16, 32, 64});
|
||||
FPCR_Type fpcr = fpcr_in;
|
||||
bits(N) op1 = op1_in;
|
||||
//bits(N) result;
|
||||
//boolean done;
|
||||
op1 = FPNeg(op1, fpcr);
|
||||
|
||||
boolean altfp = IsFeatureImplemented(FEAT_AFP) && fpcr.AH() == 1;
|
||||
boolean fpexc = !altfp; // Generate no floating-point exceptions
|
||||
//if altfp then fpcr.<FIZ,FZ> = 11; // Flush denormal input and output to zero
|
||||
//if altfp then fpcr.RMode = 00; // Use RNE rounding mode
|
||||
|
||||
auto [type1,sign1,value1] = FPUnpack(op1, fpcr, fpexc);
|
||||
auto [type2,sign2,value2] = FPUnpack(op2, fpcr, fpexc);
|
||||
auto [done,result] = FPProcessNaNs(type1, type2, op1, op2, fpcr, fpexc);
|
||||
FPRounding rounding = FPRoundingMode(fpcr);
|
||||
|
||||
if (!done)
|
||||
{
|
||||
auto inf1 = (type1 == FPType_Infinity);
|
||||
auto inf2 = (type2 == FPType_Infinity);
|
||||
auto zero1 = (type1 == FPType_Zero);
|
||||
auto zero2 = (type2 == FPType_Zero);
|
||||
|
||||
if ((inf1 && zero2) || (zero1 && inf2))
|
||||
{
|
||||
result = FPTwo(0, N);
|
||||
}
|
||||
else if (inf1 || inf2)
|
||||
{
|
||||
result = FPInfinity(sign1 ^ sign2, N);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Fully fused multiply-add
|
||||
auto result_value = 2.0 + (value1 * value2);
|
||||
if (result_value == 0.0)
|
||||
{
|
||||
// Sign of exact zero result depends on rounding mode
|
||||
auto sign = rounding == FPRounding_NEGINF ? 1 : 0;
|
||||
result = FPZero(sign, N);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = FPRound(result_value, fpcr, rounding, fpexc, N);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bits(N) FPRSqrtStepFused(bits(N) op1_in, bits(N) op2, FPCR_Type fpcr_in)
|
||||
{
|
||||
int N = op1_in.size;
|
||||
@@ -2089,6 +2206,11 @@ static uint64_t FPRSqrtEstimate_I(uint64_t op, uint64_t fpcr, uint64_t N)
|
||||
return FPRSqrtEstimate({op, N}, {fpcr});
|
||||
}
|
||||
|
||||
static uint64_t FPRecipEstimate_I(uint64_t op, uint64_t fpcr, uint64_t N)
|
||||
{
|
||||
return FPRecipEstimate({op, N}, {fpcr});
|
||||
}
|
||||
|
||||
static uint64_t FPNeg_I(uint64_t op, uint64_t fpcr, uint64_t N)
|
||||
{
|
||||
return FPNeg({op, N}, {fpcr});
|
||||
@@ -2134,6 +2256,11 @@ static uint64_t FPRSqrtStepFused_I(uint64_t op1, uint64_t op2, uint64_t fpcr, ui
|
||||
return FPRSqrtStepFused({op1, N}, {op2, N}, {fpcr});
|
||||
}
|
||||
|
||||
static uint64_t FPRecipStepFused_I(uint64_t op1, uint64_t op2, uint64_t fpcr, uint64_t N)
|
||||
{
|
||||
return FPRecipStepFused({op1, N}, {op2, N}, {fpcr});
|
||||
}
|
||||
|
||||
static uint64_t FPMul_I(uint64_t op1, uint64_t op2, uint64_t fpcr, uint64_t N)
|
||||
{
|
||||
return FPMul({op1, N}, {op2, N}, {fpcr});
|
||||
|
||||
+17
@@ -38,6 +38,17 @@ enum ir_instructions : uint64_t
|
||||
ir_shift_right_signed,
|
||||
ir_shift_right_unsigned,
|
||||
ir_subtract,
|
||||
ir_floating_point_add,
|
||||
ir_floating_point_subtract,
|
||||
ir_floating_point_multiply,
|
||||
ir_floating_point_divide,
|
||||
ir_floating_point_select_min,
|
||||
ir_floating_point_select_max,
|
||||
ir_floating_point_compare_equal,
|
||||
ir_floating_point_compare_not_equal,
|
||||
ir_floating_point_compare_less,
|
||||
ir_floating_point_compare_greater,
|
||||
ir_floating_point_compare_greater_equal,
|
||||
|
||||
ir_binary_end,
|
||||
|
||||
@@ -52,6 +63,7 @@ enum ir_instructions : uint64_t
|
||||
ir_logical_not,
|
||||
ir_convert_to_float_signed,
|
||||
ir_convert_to_float_unsigned,
|
||||
ir_floating_point_square_root,
|
||||
|
||||
ir_unary_end,
|
||||
|
||||
@@ -123,6 +135,11 @@ enum ir_instructions : uint64_t
|
||||
x86_subsd,
|
||||
x86_subss,
|
||||
|
||||
x86_sqrtss,
|
||||
x86_sqrtsd,
|
||||
x86_sqrtps,
|
||||
x86_sqrtpd,
|
||||
|
||||
//Emulator Helpers
|
||||
ir_guest_store_context,
|
||||
ir_guest_load_context,
|
||||
|
||||
Reference in New Issue
Block a user