mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-05-19 16:11:33 +00:00
Implement float comparison, conversion and numeric opcodes (#1170)
This commit is contained in:
parent
4746eaa029
commit
b01ae11217
|
@ -73,6 +73,7 @@ wasm_exec_env_create_internal(struct WASMModuleInstanceCommon *module_inst,
|
||||||
#if WASM_ENABLE_MEMORY_TRACING != 0
|
#if WASM_ENABLE_MEMORY_TRACING != 0
|
||||||
wasm_runtime_dump_exec_env_mem_consumption(exec_env);
|
wasm_runtime_dump_exec_env_mem_consumption(exec_env);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return exec_env;
|
return exec_env;
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
|
|
|
@ -85,13 +85,15 @@ typedef struct WASMExecEnv {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if WASM_ENABLE_FAST_JIT != 0
|
#if WASM_ENABLE_FAST_JIT != 0
|
||||||
#if defined(BUILD_TARGET_X86_32)
|
/**
|
||||||
/* Cache for jit native operations in 32-bit target which hasn't 64-bit
|
* Cache for
|
||||||
int/float registers, mainly for the operations of double and int64,
|
* - jit native operations in 32-bit target which hasn't 64-bit
|
||||||
such as F64TOI64, F32TOI64, I64 MUL/REM, and so on. */
|
* int/float registers, mainly for the operations of double and int64,
|
||||||
|
* such as F64TOI64, F32TOI64, I64 MUL/REM, and so on.
|
||||||
|
* - SSE instructions.
|
||||||
|
**/
|
||||||
uint64 jit_cache[2];
|
uint64 jit_cache[2];
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WASM_ENABLE_THREAD_MGR != 0
|
#if WASM_ENABLE_THREAD_MGR != 0
|
||||||
/* thread return value */
|
/* thread return value */
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,7 +7,7 @@
|
||||||
#include "../jit_frontend.h"
|
#include "../jit_frontend.h"
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
jit_compile_op_compare(JitCompContext *cc, IntCond cond, bool is64Bit)
|
jit_compile_op_compare_integer(JitCompContext *cc, IntCond cond, bool is64Bit)
|
||||||
{
|
{
|
||||||
JitReg lhs, rhs, res, const_zero, const_one;
|
JitReg lhs, rhs, res, const_zero, const_one;
|
||||||
|
|
||||||
|
@ -107,25 +107,92 @@ fail:
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i32_compare(JitCompContext *cc, IntCond cond)
|
jit_compile_op_i32_compare(JitCompContext *cc, IntCond cond)
|
||||||
{
|
{
|
||||||
return jit_compile_op_compare(cc, cond, false);
|
return jit_compile_op_compare_integer(cc, cond, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i64_compare(JitCompContext *cc, IntCond cond)
|
jit_compile_op_i64_compare(JitCompContext *cc, IntCond cond)
|
||||||
{
|
{
|
||||||
return jit_compile_op_compare(cc, cond, true);
|
return jit_compile_op_compare_integer(cc, cond, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
jit_compile_op_compare_float_point(JitCompContext *cc, FloatCond cond,
|
||||||
|
JitReg lhs, JitReg rhs)
|
||||||
|
{
|
||||||
|
JitReg res, const_zero, const_one;
|
||||||
|
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, lhs, rhs);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_I32(cc);
|
||||||
|
const_zero = NEW_CONST(I32, 0);
|
||||||
|
const_one = NEW_CONST(I32, 1);
|
||||||
|
switch (cond) {
|
||||||
|
case FLOAT_EQ:
|
||||||
|
{
|
||||||
|
GEN_INSN(SELECTEQ, res, cc->cmp_reg, const_one, const_zero);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_NE:
|
||||||
|
{
|
||||||
|
GEN_INSN(SELECTNE, res, cc->cmp_reg, const_one, const_zero);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_LT:
|
||||||
|
{
|
||||||
|
GEN_INSN(SELECTLTS, res, cc->cmp_reg, const_one, const_zero);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_GT:
|
||||||
|
{
|
||||||
|
GEN_INSN(SELECTGTS, res, cc->cmp_reg, const_one, const_zero);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_LE:
|
||||||
|
{
|
||||||
|
GEN_INSN(SELECTLES, res, cc->cmp_reg, const_one, const_zero);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_GE:
|
||||||
|
{
|
||||||
|
GEN_INSN(SELECTGES, res, cc->cmp_reg, const_one, const_zero);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
bh_assert(!"unknown FloatCond");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PUSH_I32(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_compare(JitCompContext *cc, FloatCond cond)
|
jit_compile_op_f32_compare(JitCompContext *cc, FloatCond cond)
|
||||||
{
|
{
|
||||||
jit_set_last_error(cc, "unimplement f32 comparison");
|
JitReg lhs, rhs;
|
||||||
|
|
||||||
|
POP_F32(rhs);
|
||||||
|
POP_F32(lhs);
|
||||||
|
|
||||||
|
return jit_compile_op_compare_float_point(cc, cond, lhs, rhs);
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f64_compare(JitCompContext *cc, FloatCond cond)
|
jit_compile_op_f64_compare(JitCompContext *cc, FloatCond cond)
|
||||||
{
|
{
|
||||||
jit_set_last_error(cc, "unimplement f64 comparison");
|
JitReg lhs, rhs;
|
||||||
|
|
||||||
|
POP_F64(rhs);
|
||||||
|
POP_F64(lhs);
|
||||||
|
|
||||||
|
return jit_compile_op_compare_float_point(cc, cond, lhs, rhs);
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,22 @@
|
||||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../jit_codegen.h"
|
||||||
#include "jit_emit_conversion.h"
|
#include "jit_emit_conversion.h"
|
||||||
#include "../jit_frontend.h"
|
#include "../jit_frontend.h"
|
||||||
|
#include "jit_emit_exception.h"
|
||||||
|
|
||||||
|
static double
|
||||||
|
uint64_to_double(uint64 u64)
|
||||||
|
{
|
||||||
|
return (double)u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float
|
||||||
|
uint64_to_float(uint64 u64)
|
||||||
|
{
|
||||||
|
return (float)u64;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i32_wrap_i64(JitCompContext *cc)
|
jit_compile_op_i32_wrap_i64(JitCompContext *cc)
|
||||||
|
@ -25,12 +39,138 @@ fail:
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i32_trunc_f32(JitCompContext *cc, bool sign, bool saturating)
|
jit_compile_op_i32_trunc_f32(JitCompContext *cc, bool sign, bool saturating)
|
||||||
{
|
{
|
||||||
|
JitReg value, nan_ret, max_valid_float, min_valid_float, res;
|
||||||
|
JitInsn *insn = NULL;
|
||||||
|
|
||||||
|
POP_F32(value);
|
||||||
|
|
||||||
|
min_valid_float =
|
||||||
|
sign ? NEW_CONST(F32, -2147483904.0f) : NEW_CONST(F32, -1.0f);
|
||||||
|
max_valid_float =
|
||||||
|
sign ? NEW_CONST(F32, 2147483648.0f) : NEW_CONST(F32, 4294967296.0f);
|
||||||
|
|
||||||
|
if (!saturating) {
|
||||||
|
/*if (value is Nan) goto exception*/
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
/* Set nan_ret to x86::eax */
|
||||||
|
nan_ret = jit_codegen_get_hreg_by_name("eax");
|
||||||
|
#else
|
||||||
|
nan_ret = jit_cc_new_reg_I32(cc);
|
||||||
|
#endif
|
||||||
|
insn =
|
||||||
|
GEN_INSN(CALLNATIVE, nan_ret, NEW_CONST(PTR, (uintptr_t)isnanf), 1);
|
||||||
|
if (!insn) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
*(jit_insn_opndv(insn, 2)) = value;
|
||||||
|
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, nan_ret, NEW_CONST(I32, 1));
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER,
|
||||||
|
JIT_OP_BEQ, cc->cmp_reg, NULL)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (value is out of integer range) goto exception*/
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, value, min_valid_float);
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_BLES,
|
||||||
|
cc->cmp_reg, NULL)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, value, max_valid_float);
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_BGES,
|
||||||
|
cc->cmp_reg, NULL)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saturating) {
|
||||||
|
JitReg tmp = jit_cc_new_reg_F32(cc);
|
||||||
|
GEN_INSN(MAX, tmp, value, min_valid_float);
|
||||||
|
GEN_INSN(MIN, value, tmp, max_valid_float);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_I32(cc);
|
||||||
|
if (sign) {
|
||||||
|
GEN_INSN(F32TOI32, res, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GEN_INSN(F32TOU32, res, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
PUSH_I32(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i32_trunc_f64(JitCompContext *cc, bool sign, bool saturating)
|
jit_compile_op_i32_trunc_f64(JitCompContext *cc, bool sign, bool saturating)
|
||||||
{
|
{
|
||||||
|
JitReg value, nan_ret, max_valid_double, min_valid_double, res;
|
||||||
|
JitInsn *insn = NULL;
|
||||||
|
|
||||||
|
POP_F64(value);
|
||||||
|
|
||||||
|
min_valid_double =
|
||||||
|
sign ? NEW_CONST(F64, -2147483649.0) : NEW_CONST(F64, -1.0);
|
||||||
|
max_valid_double =
|
||||||
|
sign ? NEW_CONST(F64, 2147483648.0) : NEW_CONST(F64, 4294967296.0);
|
||||||
|
|
||||||
|
if (!saturating) {
|
||||||
|
/*if (value is Nan) goto exception*/
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
/* Set nan_ret to x86::eax */
|
||||||
|
nan_ret = jit_codegen_get_hreg_by_name("eax");
|
||||||
|
#else
|
||||||
|
nan_ret = jit_cc_new_reg_I32(cc);
|
||||||
|
#endif
|
||||||
|
insn =
|
||||||
|
GEN_INSN(CALLNATIVE, nan_ret, NEW_CONST(PTR, (uintptr_t)isnan), 1);
|
||||||
|
if (!insn) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
*(jit_insn_opndv(insn, 2)) = value;
|
||||||
|
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, nan_ret, NEW_CONST(I32, 1));
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INVALID_CONVERSION_TO_INTEGER,
|
||||||
|
JIT_OP_BEQ, cc->cmp_reg, NULL)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (value is out of integer range) goto exception*/
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, value, min_valid_double);
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_BLES,
|
||||||
|
cc->cmp_reg, NULL)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
GEN_INSN(CMP, cc->cmp_reg, value, max_valid_double);
|
||||||
|
if (!jit_emit_exception(cc, EXCE_INTEGER_OVERFLOW, JIT_OP_BGES,
|
||||||
|
cc->cmp_reg, NULL)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (saturating) {
|
||||||
|
JitReg tmp = jit_cc_new_reg_F64(cc);
|
||||||
|
GEN_INSN(MAX, tmp, value, min_valid_double);
|
||||||
|
GEN_INSN(MIN, value, tmp, max_valid_double);
|
||||||
|
}
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_I32(cc);
|
||||||
|
if (sign) {
|
||||||
|
GEN_INSN(F64TOI32, res, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GEN_INSN(F64TOU32, res, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
PUSH_I32(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,85 +196,234 @@ fail:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i64_extend_i64(JitCompContext *comp_ctx, int8 bitwidth)
|
jit_compile_op_i64_extend_i64(JitCompContext *cc, int8 bitwidth)
|
||||||
{
|
{
|
||||||
|
bh_assert(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i32_extend_i32(JitCompContext *comp_ctx, int8 bitwidth)
|
jit_compile_op_i32_extend_i32(JitCompContext *cc, int8 bitwidth)
|
||||||
{
|
{
|
||||||
|
bh_assert(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i64_trunc_f32(JitCompContext *cc, bool sign, bool saturating)
|
jit_compile_op_i64_trunc_f32(JitCompContext *cc, bool sign, bool saturating)
|
||||||
{
|
{
|
||||||
|
/* TODO: f32 -> u64 algorithm */
|
||||||
|
bh_assert(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i64_trunc_f64(JitCompContext *cc, bool sign, bool saturating)
|
jit_compile_op_i64_trunc_f64(JitCompContext *cc, bool sign, bool saturating)
|
||||||
{
|
{
|
||||||
|
/* TODO: f64 -> u64 algorithm */
|
||||||
|
bh_assert(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_convert_i32(JitCompContext *comp_ctx, bool sign)
|
jit_compile_op_f32_convert_i32(JitCompContext *cc, bool sign)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_I32(value);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_F32(cc);
|
||||||
|
if (sign) {
|
||||||
|
GEN_INSN(I32TOF32, res, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GEN_INSN(U32TOF32, res, value);
|
||||||
|
}
|
||||||
|
PUSH_F32(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_convert_i64(JitCompContext *comp_ctx, bool sign)
|
jit_compile_op_f32_convert_i64(JitCompContext *cc, bool sign)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_I64(value);
|
||||||
|
|
||||||
|
if (sign) {
|
||||||
|
res = jit_cc_new_reg_F32(cc);
|
||||||
|
GEN_INSN(I64TOF32, res, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JitInsn *insn;
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
res = jit_codegen_get_hreg_by_name("xmm0");
|
||||||
|
#else
|
||||||
|
res = jit_cc_new_reg_F32(cc);
|
||||||
|
#endif
|
||||||
|
insn = GEN_INSN(CALLNATIVE, res,
|
||||||
|
NEW_CONST(PTR, (uintptr_t)uint64_to_float), 1);
|
||||||
|
if (!insn) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
*(jit_insn_opndv(insn, 2)) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PUSH_F32(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_demote_f64(JitCompContext *comp_ctx)
|
jit_compile_op_f32_demote_f64(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_F64(value);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_F32(cc);
|
||||||
|
GEN_INSN(F64TOF32, res, value);
|
||||||
|
PUSH_F32(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f64_convert_i32(JitCompContext *comp_ctx, bool sign)
|
jit_compile_op_f64_convert_i32(JitCompContext *cc, bool sign)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_I32(value);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_F64(cc);
|
||||||
|
if (sign) {
|
||||||
|
GEN_INSN(I32TOF64, res, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
GEN_INSN(U32TOF64, res, value);
|
||||||
|
}
|
||||||
|
PUSH_F64(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f64_convert_i64(JitCompContext *comp_ctx, bool sign)
|
jit_compile_op_f64_convert_i64(JitCompContext *cc, bool sign)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_I64(value);
|
||||||
|
|
||||||
|
if (sign) {
|
||||||
|
res = jit_cc_new_reg_F64(cc);
|
||||||
|
GEN_INSN(I64TOF64, res, value);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JitInsn *insn;
|
||||||
|
#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
|
||||||
|
res = jit_codegen_get_hreg_by_name("xmm0_f64");
|
||||||
|
#else
|
||||||
|
res = jit_cc_new_reg_F64(cc);
|
||||||
|
#endif
|
||||||
|
insn = GEN_INSN(CALLNATIVE, res,
|
||||||
|
NEW_CONST(PTR, (uintptr_t)uint64_to_double), 1);
|
||||||
|
if (!insn) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
*(jit_insn_opndv(insn, 2)) = value;
|
||||||
|
}
|
||||||
|
PUSH_F64(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f64_promote_f32(JitCompContext *comp_ctx)
|
jit_compile_op_f64_promote_f32(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_F32(value);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_F64(cc);
|
||||||
|
GEN_INSN(F32TOF64, res, value);
|
||||||
|
PUSH_F64(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i64_reinterpret_f64(JitCompContext *comp_ctx)
|
jit_compile_op_i64_reinterpret_f64(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_F64(value);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_I64(cc);
|
||||||
|
GEN_INSN(F64CASTI64, res, value);
|
||||||
|
PUSH_I64(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_i32_reinterpret_f32(JitCompContext *comp_ctx)
|
jit_compile_op_i32_reinterpret_f32(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_F32(value);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_I32(cc);
|
||||||
|
GEN_INSN(F32CASTI32, res, value);
|
||||||
|
PUSH_I32(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f64_reinterpret_i64(JitCompContext *comp_ctx)
|
jit_compile_op_f64_reinterpret_i64(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_I64(value);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_F64(cc);
|
||||||
|
GEN_INSN(I64CASTF64, res, value);
|
||||||
|
PUSH_F64(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_reinterpret_i32(JitCompContext *comp_ctx)
|
jit_compile_op_f32_reinterpret_i32(JitCompContext *cc)
|
||||||
{
|
{
|
||||||
|
JitReg value, res;
|
||||||
|
|
||||||
|
POP_I32(value);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_F32(cc);
|
||||||
|
GEN_INSN(I32CASTF32, res, value);
|
||||||
|
PUSH_F32(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1159,24 +1159,76 @@ jit_compile_op_i64_shift(JitCompContext *cc, IntShift shift_op)
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_math(JitCompContext *cc, FloatMath math_op)
|
jit_compile_op_f32_math(JitCompContext *cc, FloatMath math_op)
|
||||||
{
|
{
|
||||||
|
bh_assert(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f64_math(JitCompContext *cc, FloatMath math_op)
|
jit_compile_op_f64_math(JitCompContext *cc, FloatMath math_op)
|
||||||
{
|
{
|
||||||
|
bh_assert(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f32_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
jit_compile_op_f32_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
||||||
{
|
{
|
||||||
|
bh_assert(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
jit_compile_op_f64_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
jit_compile_op_f64_arithmetic(JitCompContext *cc, FloatArithmetic arith_op)
|
||||||
{
|
{
|
||||||
|
JitReg lhs, rhs, res;
|
||||||
|
|
||||||
|
POP_F64(rhs);
|
||||||
|
POP_F64(lhs);
|
||||||
|
|
||||||
|
res = jit_cc_new_reg_F64(cc);
|
||||||
|
switch (arith_op) {
|
||||||
|
case FLOAT_ADD:
|
||||||
|
{
|
||||||
|
GEN_INSN(ADD, res, lhs, rhs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_SUB:
|
||||||
|
{
|
||||||
|
GEN_INSN(SUB, res, lhs, rhs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_MUL:
|
||||||
|
{
|
||||||
|
GEN_INSN(MUL, res, lhs, rhs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_DIV:
|
||||||
|
{
|
||||||
|
/*TODO: add divided by zero interception */
|
||||||
|
GEN_INSN(DIV_S, res, lhs, rhs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_MIN:
|
||||||
|
{
|
||||||
|
GEN_INSN(MIN, res, lhs, rhs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FLOAT_MAX:
|
||||||
|
{
|
||||||
|
GEN_INSN(MAX, res, lhs, rhs);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
bh_assert(0);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PUSH_F64(res);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
fail:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -817,7 +817,7 @@ init_func_translation(JitCompContext *cc)
|
||||||
local_off = (uint32)offsetof(WASMInterpFrame, lp)
|
local_off = (uint32)offsetof(WASMInterpFrame, lp)
|
||||||
+ cur_wasm_func->param_cell_num * 4;
|
+ cur_wasm_func->param_cell_num * 4;
|
||||||
for (i = 0; i < cur_wasm_func->local_cell_num / 2; i++, local_off += 8) {
|
for (i = 0; i < cur_wasm_func->local_cell_num / 2; i++, local_off += 8) {
|
||||||
GEN_INSN(STI64, NEW_CONST(I32, 0), cc->fp_reg,
|
GEN_INSN(STI64, NEW_CONST(I64, 0), cc->fp_reg,
|
||||||
NEW_CONST(I32, local_off));
|
NEW_CONST(I32, local_off));
|
||||||
}
|
}
|
||||||
if (cur_wasm_func->local_cell_num & 1) {
|
if (cur_wasm_func->local_cell_num & 1) {
|
||||||
|
|
|
@ -76,6 +76,8 @@
|
||||||
registers of the same kind (move) or different kinds (convert) */
|
registers of the same kind (move) or different kinds (convert) */
|
||||||
INSN(MOV, Reg, 2, 1)
|
INSN(MOV, Reg, 2, 1)
|
||||||
INSN(PHI, VReg, 1, 1)
|
INSN(PHI, VReg, 1, 1)
|
||||||
|
|
||||||
|
/* conversion. will extend or truncate */
|
||||||
INSN(I32TOI8, Reg, 2, 1)
|
INSN(I32TOI8, Reg, 2, 1)
|
||||||
INSN(I32TOU8, Reg, 2, 1)
|
INSN(I32TOU8, Reg, 2, 1)
|
||||||
INSN(I32TOI16, Reg, 2, 1)
|
INSN(I32TOI16, Reg, 2, 1)
|
||||||
|
@ -92,9 +94,17 @@ INSN(I64TOF64, Reg, 2, 1)
|
||||||
INSN(F32TOI32, Reg, 2, 1)
|
INSN(F32TOI32, Reg, 2, 1)
|
||||||
INSN(F32TOI64, Reg, 2, 1)
|
INSN(F32TOI64, Reg, 2, 1)
|
||||||
INSN(F32TOF64, Reg, 2, 1)
|
INSN(F32TOF64, Reg, 2, 1)
|
||||||
|
INSN(F32TOU32, Reg, 2, 1)
|
||||||
INSN(F64TOI32, Reg, 2, 1)
|
INSN(F64TOI32, Reg, 2, 1)
|
||||||
INSN(F64TOI64, Reg, 2, 1)
|
INSN(F64TOI64, Reg, 2, 1)
|
||||||
INSN(F64TOF32, Reg, 2, 1)
|
INSN(F64TOF32, Reg, 2, 1)
|
||||||
|
INSN(F64TOU32, Reg, 2, 1)
|
||||||
|
|
||||||
|
/* re-interpreter binary presentation. like *(integer*)&floating_point, and *(floating_point*)&integer */
|
||||||
|
INSN(I32CASTF32, Reg, 2, 1)
|
||||||
|
INSN(I64CASTF64, Reg, 2, 1)
|
||||||
|
INSN(F32CASTI32, Reg, 2, 1)
|
||||||
|
INSN(F64CASTI64, Reg, 2, 1)
|
||||||
|
|
||||||
/* Arithmetic and bitwise instructions: */
|
/* Arithmetic and bitwise instructions: */
|
||||||
INSN(NEG, Reg, 2, 1)
|
INSN(NEG, Reg, 2, 1)
|
||||||
|
@ -115,6 +125,8 @@ INSN(OR, Reg, 3, 1)
|
||||||
INSN(XOR, Reg, 3, 1)
|
INSN(XOR, Reg, 3, 1)
|
||||||
INSN(AND, Reg, 3, 1)
|
INSN(AND, Reg, 3, 1)
|
||||||
INSN(CMP, Reg, 3, 1)
|
INSN(CMP, Reg, 3, 1)
|
||||||
|
INSN(MAX, Reg, 3, 1)
|
||||||
|
INSN(MIN, Reg, 3, 1)
|
||||||
|
|
||||||
/* Select instruction: */
|
/* Select instruction: */
|
||||||
INSN(SELECTEQ, Reg, 4, 1)
|
INSN(SELECTEQ, Reg, 4, 1)
|
||||||
|
|
|
@ -1181,6 +1181,10 @@ typedef struct JitCompContext {
|
||||||
/* The hash table. */
|
/* The hash table. */
|
||||||
JitInsn **_table;
|
JitInsn **_table;
|
||||||
} _insn_hash_table;
|
} _insn_hash_table;
|
||||||
|
|
||||||
|
/* indicate if the last comparision is about floating-point numbers or not
|
||||||
|
*/
|
||||||
|
bool last_cmp_on_fp;
|
||||||
} JitCompContext;
|
} JitCompContext;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue
Block a user