libjit.git - libjit

index : libjit.git
libjit
summary refs log tree commit diff
path: root/jit/jit-interp.c
diff options
context:
space:
mode:
Diffstat (limited to 'jit/jit-interp.c')
-rw-r--r--jit/jit-interp.c 4734
1 files changed, 4734 insertions, 0 deletions
diff --git a/jit/jit-interp.c b/jit/jit-interp.c
new file mode 100644
index 0000000..6e5d5a2
--- /dev/null
+++ b/jit/jit-interp.c
@@ -0,0 +1,4734 @@
+/*
+ * jit-interp.c - Fallback interpreter implementation.
+ *
+ * Copyright (C) 2004 Southern Storm Software, Pty Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+
+This file must be compiled with a C++ compiler, because it uses
+C++ exceptions to manage JIT exception throws. It is otherwise
+straight vanilla ANSI C.
+
+*/
+
+#include "jit-interp.h"
+#include "jit-rules.h"
+#include "jit-memory.h"
+#include <config.h>
+#if HAVE_ALLOCA_H
+ #include <alloca.h>
+#endif
+#ifdef JIT_WIN32_PLATFORM
+ #include <malloc.h>
+ #ifndef alloca
+ #define alloca _alloca
+ #endif
+#endif
+#include "jit-setjmp.h"
+
+#if defined(JIT_BACKEND_INTERP)
+
+/*
+ * Macros that help with the definition of the interpreter switch loop.
+ */
+#define VMSWITCH(pc) \
+ for(;;) \
+ { \
+ switch((int)*((jit_nint *)(pc)))
+#define VMSWITCHEND \
+ }
+#define VMCASE(opcode) \
+ case opcode
+#define VMBREAK \
+ break
+
+/*
+ * Modify the program counter and stack pointer.
+ */
+#define VM_MODIFY_PC_AND_STACK(pcmod,stkmod) \
+ do { \
+ pc += (jit_nint)(int)(pcmod); \
+ stacktop += (jit_nint)(int)(stkmod); \
+ } while (0)
+#define VM_MODIFY_STACK(stkmod) \
+ do { \
+ stacktop += (jit_nint)(int)(stkmod); \
+ } while (0)
+
+/*
+ * Fetch arguments of various types from the instruction stream.
+ */
+#define VM_NINT_ARG (((jit_nint *)(pc))[1])
+#define VM_NINT_ARG2 (((jit_nint *)(pc))[2])
+#define VM_NINT_ARG3 (((jit_nint *)(pc))[3])
+#define VM_BR_TARGET (pc + VM_NINT_ARG)
+
+/*
+ * Fetch stack items from various positions.
+ */
+#define VM_STK_INT0 (stacktop[0].int_value)
+#define VM_STK_INT1 (stacktop[1].int_value)
+#define VM_STK_INTP (stacktop[-1].int_value)
+#define VM_STK_UINT0 (stacktop[0].uint_value)
+#define VM_STK_UINT1 (stacktop[1].uint_value)
+#define VM_STK_UINTP (stacktop[-1].uint_value)
+#define VM_STK_LONG0 (stacktop[0].long_value)
+#define VM_STK_LONG1 (stacktop[1].long_value)
+#define VM_STK_LONGP (stacktop[-1].long_value)
+#define VM_STK_ULONG0 (stacktop[0].ulong_value)
+#define VM_STK_ULONG1 (stacktop[1].ulong_value)
+#define VM_STK_ULONGP (stacktop[-1].ulong_value)
+#define VM_STK_FLOAT320 (stacktop[0].float32_value)
+#define VM_STK_FLOAT321 (stacktop[1].float32_value)
+#define VM_STK_FLOAT32P (stacktop[-1].float32_value)
+#define VM_STK_FLOAT640 (stacktop[0].float64_value)
+#define VM_STK_FLOAT641 (stacktop[1].float64_value)
+#define VM_STK_FLOAT64P (stacktop[-1].float64_value)
+#define VM_STK_NFLOAT0 (stacktop[0].nfloat_value)
+#define VM_STK_NFLOAT1 (stacktop[1].nfloat_value)
+#define VM_STK_NFLOATP (stacktop[-1].nfloat_value)
+#define VM_STK_PTR0 (stacktop[0].ptr_value)
+#define VM_STK_PTR1 (stacktop[1].ptr_value)
+#define VM_STK_PTR2 (stacktop[2].ptr_value)
+#define VM_STK_PTRP (stacktop[-1].ptr_value)
+#define VM_STK_PTRP2 (stacktop[-2].ptr_value)
+#ifdef JIT_NATIVE_INT32
+#define VM_STK_NINT0 VM_STK_INT0
+#define VM_STK_NINT1 VM_STK_INT1
+#define VM_STK_NUINT0 VM_STK_UINT0
+#define VM_STK_NUINT1 VM_STK_UINT1
+#else
+#define VM_STK_NINT0 VM_STK_LONG0
+#define VM_STK_NINT1 VM_STK_LONG1
+#define VM_STK_NUINT0 VM_STK_ULONG0
+#define VM_STK_NUINT1 VM_STK_ULONG1
+#endif
+
+/*
+ * Apply a relative adjustment to a pointer and cast to a specific type.
+ */
+#define VM_REL(type,ptr) \
+ ((type *)(((unsigned char *)(ptr)) + VM_NINT_ARG))
+
+/*
+ * Apply an array adjustment to a pointer.
+ */
+#define VM_LOAD_ELEM(type) \
+ (*(((type *)VM_STK_PTR1) + VM_STK_NINT0))
+#define VM_STORE_ELEM(type,value) \
+ (*(((type *)VM_STK_PTR2) + VM_STK_NINT1) = (type)(value))
+
+/*
+ * Get the address of an argument or local variable at a particular offset.
+ */
+#define VM_ARG(type) \
+ ((type *)(((jit_item *)args) + VM_NINT_ARG))
+#define VM_LOC(type) \
+ ((type *)(((jit_item *)frame) + VM_NINT_ARG))
+
+/*
+ * Handle the return value from a function that reports a builtin exception.
+ */
+#define VM_BUILTIN(value) \
+ do { \
+ builtin_exception = (value); \
+ if(builtin_exception < JIT_RESULT_OK) \
+ { \
+ goto handle_builtin; \
+ } \
+ } while (0)
+
+/*
+ * Call "jit_apply" from the interpreter, to invoke a native function.
+ */
+static void apply_from_interpreter
+ (jit_type_t signature, void *func,
+ jit_item *args, unsigned int num_fixed_args,
+ void *return_area)
+{
+ unsigned int num_params;
+ unsigned int param;
+ jit_type_t type;
+ void **apply_args;
+
+ /* Allocate space for the apply arguments and initialize them */
+ num_params = jit_type_num_params(signature);
+ apply_args = (void **)alloca(sizeof(void *) * num_params);
+ for(param = 0; param < num_params; ++param)
+ {
+ type = jit_type_normalize(jit_type_get_param(signature, param));
+ switch(type->kind)
+ {
+ case JIT_TYPE_SBYTE:
+ case JIT_TYPE_UBYTE:
+ {
+ apply_args[param] =
+ ((unsigned char *)args) + _jit_int_lowest_byte();
+ ++args;
+ }
+ break;
+
+ case JIT_TYPE_SHORT:
+ case JIT_TYPE_USHORT:
+ {
+ apply_args[param] =
+ ((unsigned char *)args) + _jit_int_lowest_short();
+ ++args;
+ }
+ break;
+
+ case JIT_TYPE_INT:
+ case JIT_TYPE_UINT:
+ case JIT_TYPE_LONG:
+ case JIT_TYPE_ULONG:
+ case JIT_TYPE_FLOAT32:
+ case JIT_TYPE_FLOAT64:
+ case JIT_TYPE_NFLOAT:
+ {
+ apply_args[param] = args;
+ ++args;
+ }
+ break;
+
+ case JIT_TYPE_STRUCT:
+ case JIT_TYPE_UNION:
+ {
+ apply_args[param] = args;
+ args += JIT_NUM_ITEMS_IN_STRUCT(jit_type_get_size(type));
+ }
+ break;
+
+ default:
+ {
+ /* Shouldn't happen, but do something sane */
+ apply_args[param] = args;
+ }
+ break;
+ }
+ }
+
+ /* Apply the function */
+ jit_apply(signature, func, apply_args, num_fixed_args, return_area);
+}
+
+void _jit_run_function(jit_function_interp_t func, jit_item *args,
+ jit_item *return_area)
+{
+ jit_item *frame;
+ jit_item *stacktop;
+ void **pc;
+ jit_int builtin_exception;
+ jit_nint temparg;
+ void *tempptr;
+ void *tempptr2;
+ jit_function_t call_func;
+ struct jit_backtrace call_trace;
+ void *entry;
+ void *exception_object = 0;
+ void *handler;
+ jit_jmp_buf *jbuf;
+
+ /* Set up the stack frame for this function */
+ frame = (jit_item *)alloca(func->frame_size);
+ stacktop = frame + func->working_area;
+ frame = stacktop;
+
+ /* Get the initial program counter */
+ pc = jit_function_interp_entry_pc(func);
+
+ /* Create a "setjmp" point if this function has a "try" block.
+ This is used to catch exceptions on their way up the stack */
+ if(func->func->has_try)
+ {
+ jbuf = (jit_jmp_buf *)alloca(sizeof(jit_jmp_buf));
+ _jit_unwind_push_setjmp(jbuf);
+ if(setjmp(jbuf->buf))
+ {
+ /* An exception has been thrown by lower-level code */
+ exception_object = jit_exception_get_last_and_clear();
+ goto handle_exception;
+ }
+ }
+ else
+ {
+ jbuf = 0;
+ }
+
+ /* Enter the instruction dispatch loop */
+ VMSWITCH(pc)
+ {
+ /******************************************************************
+ * Simple opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_NOP):
+ {
+ /* Nothing to do except move on to the next instruction */
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Conversion opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_TRUNC_SBYTE):
+ {
+ /* Truncate an integer to a signed 8-bit value */
+ VM_STK_INT0 = (jit_int)(jit_sbyte)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_TRUNC_UBYTE):
+ {
+ /* Truncate an integer to an unsigned 8-bit value */
+ VM_STK_INT0 = (jit_int)(jit_ubyte)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_TRUNC_SHORT):
+ {
+ /* Truncate an integer to a signed 16-bit value */
+ VM_STK_INT0 = (jit_int)(jit_short)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_TRUNC_USHORT):
+ {
+ /* Truncate an integer to an unsigned 16-bit value */
+ VM_STK_INT0 = (jit_int)(jit_ushort)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_TRUNC_INT):
+ {
+ /* Truncate an integer to a signed 32-bit value */
+ /* In the interpreter, this is a NOP */
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_TRUNC_UINT):
+ {
+ /* Truncate an integer to an unsigned 32-bit value */
+ /* In the interpreter, this is a NOP */
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_SBYTE):
+ {
+ /* Truncate an integer to a signed 8-bit value, and check */
+ VM_BUILTIN(jit_int_to_sbyte_ovf(&VM_STK_INT0, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_UBYTE):
+ {
+ /* Truncate an integer to an unsigned 8-bit value, and check */
+ VM_BUILTIN(jit_int_to_ubyte_ovf(&VM_STK_INT0, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_SHORT):
+ {
+ /* Truncate an integer to a signed 16-bit value, and check */
+ VM_BUILTIN(jit_int_to_short_ovf(&VM_STK_INT0, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_USHORT):
+ {
+ /* Truncate an integer to an unsigned 16-bit value, and check */
+ VM_BUILTIN(jit_int_to_ushort_ovf(&VM_STK_INT0, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_INT):
+ {
+ /* Truncate an integer to a signed 32-bit value, and check */
+ VM_BUILTIN(jit_uint_to_int_ovf(&VM_STK_INT0, VM_STK_UINT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_UINT):
+ {
+ /* Truncate an integer to an unsigned 32-bit value, and check */
+ VM_BUILTIN(jit_int_to_uint_ovf(&VM_STK_UINT0, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOW_WORD):
+ {
+ /* Fetch the low word of a 64-bit value */
+ VM_STK_UINT0 = (jit_uint)VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_EXPAND_INT):
+ {
+ /* Expand a signed 32-bit value to a 64-bit value */
+ VM_STK_LONG0 = (jit_long)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_EXPAND_UINT):
+ {
+ /* Expand an unsigned 32-bit value to a 64-bit value */
+ VM_STK_ULONG0 = (jit_ulong)VM_STK_UINT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_LOW_WORD):
+ {
+ /* Fetch the low word of a 64-bit value, and check */
+ VM_BUILTIN(jit_long_to_uint_ovf(&VM_STK_UINT0, VM_STK_LONG0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_SIGNED_LOW_WORD):
+ {
+ /* Fetch the signed low word of a 64-bit value, and check */
+ VM_BUILTIN(jit_long_to_int_ovf(&VM_STK_INT0, VM_STK_LONG0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_LONG):
+ {
+ /* Convert unsigned 64-bit into signed, and check */
+ VM_BUILTIN(jit_ulong_to_long_ovf(&VM_STK_LONG0, VM_STK_ULONG0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_ULONG):
+ {
+ /* Convert signed 64-bit into unsigned, and check */
+ VM_BUILTIN(jit_long_to_ulong_ovf(&VM_STK_ULONG0, VM_STK_LONG0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLOAT_TO_INT):
+ {
+ /* Convert native float into 32-bit signed integer */
+ VM_STK_INT0 = jit_nfloat_to_int(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLOAT_TO_UINT):
+ {
+ /* Convert native float into 32-bit unsigned integer */
+ VM_STK_UINT0 = jit_nfloat_to_uint(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLOAT_TO_LONG):
+ {
+ /* Convert native float into 64-bit signed integer */
+ VM_STK_LONG0 = jit_nfloat_to_long(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLOAT_TO_ULONG):
+ {
+ /* Convert native float into 64-bit unsigned integer */
+ VM_STK_ULONG0 = jit_nfloat_to_ulong(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_NFLOAT_TO_INT):
+ {
+ /* Convert native float into 32-bit signed integer, and check */
+ VM_BUILTIN(jit_nfloat_to_int_ovf(&VM_STK_INT0, VM_STK_NFLOAT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_NFLOAT_TO_UINT):
+ {
+ /* Convert native float into 32-bit unsigned integer, and check */
+ VM_BUILTIN(jit_nfloat_to_uint_ovf(&VM_STK_UINT0, VM_STK_NFLOAT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_NFLOAT_TO_LONG):
+ {
+ /* Convert native float into 64-bit signed integer, and check */
+ VM_BUILTIN(jit_nfloat_to_long_ovf(&VM_STK_LONG0, VM_STK_NFLOAT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_NFLOAT_TO_ULONG):
+ {
+ /* Convert native float into 64-bit unsigned integer, and check */
+ VM_BUILTIN(jit_nfloat_to_ulong_ovf(&VM_STK_ULONG0, VM_STK_NFLOAT0));
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_INT_TO_NFLOAT):
+ {
+ /* Convert 32-bit signed integer into native float */
+ VM_STK_NFLOAT0 = jit_int_to_nfloat(VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_UINT_TO_NFLOAT):
+ {
+ /* Convert 32-bit unsigned integer into native float */
+ VM_STK_NFLOAT0 = jit_uint_to_nfloat(VM_STK_UINT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LONG_TO_NFLOAT):
+ {
+ /* Convert 64-bit signed integer into native float */
+ VM_STK_NFLOAT0 = jit_long_to_nfloat(VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ULONG_TO_NFLOAT):
+ {
+ /* Convert 64-bit unsigned integer into native float */
+ VM_STK_NFLOAT0 = jit_ulong_to_nfloat(VM_STK_ULONG0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLOAT_TO_FLOAT32):
+ {
+ /* Convert native float into 32-bit float */
+ VM_STK_FLOAT320 = jit_nfloat_to_float32(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLOAT_TO_FLOAT64):
+ {
+ /* Convert native float into 64-bit float */
+ VM_STK_FLOAT640 = jit_nfloat_to_float64(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FLOAT32_TO_NFLOAT):
+ {
+ /* Convert 32-bit float into native float */
+ VM_STK_NFLOAT0 = jit_float32_to_nfloat(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FLOAT64_TO_NFLOAT):
+ {
+ /* Convert 64-bit float into native float */
+ VM_STK_NFLOAT0 = jit_float64_to_nfloat(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Arithmetic opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_IADD):
+ {
+ /* Add signed 32-bit integers */
+ VM_STK_INT1 = VM_STK_INT1 + VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IADD_OVF):
+ {
+ /* Add signed 32-bit integers, and check */
+ VM_BUILTIN(jit_int_add_ovf
+ (&VM_STK_INT1, VM_STK_INT1, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IADD_OVF_UN):
+ {
+ /* Add unsigned 32-bit integers, and check */
+ VM_BUILTIN(jit_uint_add_ovf
+ (&VM_STK_UINT1, VM_STK_UINT1, VM_STK_UINT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ISUB):
+ {
+ /* Subtract signed 32-bit integers */
+ VM_STK_INT1 = VM_STK_INT1 - VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ISUB_OVF):
+ {
+ /* Subtract signed 32-bit integers, and check */
+ VM_BUILTIN(jit_int_sub_ovf
+ (&VM_STK_INT1, VM_STK_INT1, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ISUB_OVF_UN):
+ {
+ /* Subtract unsigned 32-bit integers, and check */
+ VM_BUILTIN(jit_uint_sub_ovf
+ (&VM_STK_UINT1, VM_STK_UINT1, VM_STK_UINT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMUL):
+ {
+ /* Multiply signed 32-bit integers */
+ VM_STK_INT1 = VM_STK_INT1 * VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMUL_OVF):
+ {
+ /* Multiply signed 32-bit integers, and check */
+ VM_BUILTIN(jit_int_mul_ovf
+ (&VM_STK_INT1, VM_STK_INT1, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMUL_OVF_UN):
+ {
+ /* Multiply unsigned 32-bit integers, and check */
+ VM_BUILTIN(jit_uint_mul_ovf
+ (&VM_STK_UINT1, VM_STK_UINT1, VM_STK_UINT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IDIV):
+ {
+ /* Divide signed 32-bit integers */
+ VM_BUILTIN(jit_int_div
+ (&VM_STK_INT1, VM_STK_INT1, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IDIV_UN):
+ {
+ /* Divide unsigned 32-bit integers */
+ VM_BUILTIN(jit_uint_div
+ (&VM_STK_UINT1, VM_STK_UINT1, VM_STK_UINT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IREM):
+ {
+ /* Remainder signed 32-bit integers */
+ VM_BUILTIN(jit_int_rem
+ (&VM_STK_INT1, VM_STK_INT1, VM_STK_INT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IREM_UN):
+ {
+ /* Remainder unsigned 32-bit integers */
+ VM_BUILTIN(jit_uint_rem
+ (&VM_STK_UINT1, VM_STK_UINT1, VM_STK_UINT0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_INEG):
+ {
+ /* Negate signed 32-bit integer */
+ VM_STK_INT0 = -VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LADD):
+ {
+ /* Add signed 64-bit integers */
+ VM_STK_LONG1 = VM_STK_LONG1 + VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LADD_OVF):
+ {
+ /* Add signed 64-bit integers, and check */
+ VM_BUILTIN(jit_long_add_ovf
+ (&VM_STK_LONG1, VM_STK_LONG1, VM_STK_LONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LADD_OVF_UN):
+ {
+ /* Add unsigned 64-bit integers, and check */
+ VM_BUILTIN(jit_ulong_add_ovf
+ (&VM_STK_ULONG1, VM_STK_ULONG1, VM_STK_ULONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LSUB):
+ {
+ /* Subtract signed 64-bit integers */
+ VM_STK_LONG1 = VM_STK_LONG1 - VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LSUB_OVF):
+ {
+ /* Subtract signed 64-bit integers, and check */
+ VM_BUILTIN(jit_long_sub_ovf
+ (&VM_STK_LONG1, VM_STK_LONG1, VM_STK_LONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LSUB_OVF_UN):
+ {
+ /* Subtract unsigned 64-bit integers, and check */
+ VM_BUILTIN(jit_ulong_sub_ovf
+ (&VM_STK_ULONG1, VM_STK_ULONG1, VM_STK_ULONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LMUL):
+ {
+ /* Multiply signed 64-bit integers */
+ VM_STK_LONG1 = VM_STK_LONG1 * VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LMUL_OVF):
+ {
+ /* Multiply signed 64-bit integers, and check */
+ VM_BUILTIN(jit_long_mul_ovf
+ (&VM_STK_LONG1, VM_STK_LONG1, VM_STK_LONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LMUL_OVF_UN):
+ {
+ /* Multiply unsigned 64-bit integers, and check */
+ VM_BUILTIN(jit_ulong_mul_ovf
+ (&VM_STK_ULONG1, VM_STK_ULONG1, VM_STK_ULONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDIV):
+ {
+ /* Divide signed 64-bit integers */
+ VM_BUILTIN(jit_long_div
+ (&VM_STK_LONG1, VM_STK_LONG1, VM_STK_LONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDIV_UN):
+ {
+ /* Divide unsigned 64-bit integers */
+ VM_BUILTIN(jit_ulong_div
+ (&VM_STK_ULONG1, VM_STK_ULONG1, VM_STK_ULONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LREM):
+ {
+ /* Remainder signed 64-bit integers */
+ VM_BUILTIN(jit_long_rem
+ (&VM_STK_LONG1, VM_STK_LONG1, VM_STK_LONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LREM_UN):
+ {
+ /* Remainder unsigned 64-bit integers */
+ VM_BUILTIN(jit_ulong_rem
+ (&VM_STK_ULONG1, VM_STK_ULONG1, VM_STK_ULONG0));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LNEG):
+ {
+ /* Negate signed 64-bit integer */
+ VM_STK_LONG0 = -VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FADD):
+ {
+ /* Add 32-bit floats */
+ VM_STK_FLOAT321 = VM_STK_FLOAT321 + VM_STK_FLOAT320;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FSUB):
+ {
+ /* Subtract 32-bit floats */
+ VM_STK_FLOAT321 = VM_STK_FLOAT321 - VM_STK_FLOAT320;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FMUL):
+ {
+ /* Multiply 32-bit floats */
+ VM_STK_FLOAT321 = VM_STK_FLOAT321 * VM_STK_FLOAT320;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FDIV):
+ {
+ /* Divide 32-bit floats */
+ VM_STK_FLOAT321 = VM_STK_FLOAT321 / VM_STK_FLOAT320;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FREM):
+ {
+ /* Remainder 32-bit floats */
+ VM_STK_FLOAT321 = jit_float32_rem
+ (VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FREM_IEEE):
+ {
+ /* Remainder 32-bit floats, with IEEE rules */
+ VM_STK_FLOAT321 = jit_float32_ieee_rem
+ (VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FNEG):
+ {
+ /* Negate 32-bit float */
+ VM_STK_FLOAT320 = -VM_STK_FLOAT320;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DADD):
+ {
+ /* Add 64-bit floats */
+ VM_STK_FLOAT641 = VM_STK_FLOAT641 + VM_STK_FLOAT640;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DSUB):
+ {
+ /* Subtract 64-bit floats */
+ VM_STK_FLOAT641 = VM_STK_FLOAT641 - VM_STK_FLOAT640;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DMUL):
+ {
+ /* Multiply 64-bit floats */
+ VM_STK_FLOAT641 = VM_STK_FLOAT641 * VM_STK_FLOAT640;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DDIV):
+ {
+ /* Divide 64-bit floats */
+ VM_STK_FLOAT641 = VM_STK_FLOAT641 / VM_STK_FLOAT640;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DREM):
+ {
+ /* Remainder 64-bit floats */
+ VM_STK_FLOAT641 = jit_float64_rem
+ (VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DREM_IEEE):
+ {
+ /* Remainder 64-bit floats, with IEEE rules */
+ VM_STK_FLOAT641 = jit_float64_ieee_rem
+ (VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DNEG):
+ {
+ /* Negate 64-bit float */
+ VM_STK_FLOAT640 = -VM_STK_FLOAT640;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFADD):
+ {
+ /* Add native floats */
+ VM_STK_NFLOAT1 = VM_STK_NFLOAT1 + VM_STK_NFLOAT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFSUB):
+ {
+ /* Subtract native floats */
+ VM_STK_NFLOAT1 = VM_STK_NFLOAT1 - VM_STK_NFLOAT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFMUL):
+ {
+ /* Multiply native floats */
+ VM_STK_NFLOAT1 = VM_STK_NFLOAT1 * VM_STK_NFLOAT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFDIV):
+ {
+ /* Divide native floats */
+ VM_STK_NFLOAT1 = VM_STK_NFLOAT1 / VM_STK_NFLOAT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFREM):
+ {
+ /* Remainder native floats */
+ VM_STK_NFLOAT1 = jit_nfloat_rem
+ (VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFREM_IEEE):
+ {
+ /* Remainder native floats, with IEEE rules */
+ VM_STK_NFLOAT1 = jit_nfloat_ieee_rem
+ (VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFNEG):
+ {
+ /* Negate native float */
+ VM_STK_NFLOAT0 = -VM_STK_NFLOAT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Bitwise opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_IAND):
+ {
+ /* Bitwise and signed 32-bit integers */
+ VM_STK_INT1 = VM_STK_INT1 & VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IOR):
+ {
+ /* Bitwise or signed 32-bit integers */
+ VM_STK_INT1 = VM_STK_INT1 | VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IXOR):
+ {
+ /* Bitwise xor signed 32-bit integers */
+ VM_STK_INT1 = VM_STK_INT1 ^ VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_INOT):
+ {
+ /* Bitwise not signed 32-bit integers */
+ VM_STK_INT0 = ~VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ISHL):
+ {
+ /* Shift left signed 32-bit integers */
+ VM_STK_INT1 = VM_STK_INT1 << (VM_STK_UINT0 & 0x1F);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ISHR):
+ {
+ /* Shift right signed 32-bit integers */
+ VM_STK_INT1 = VM_STK_INT1 >> (VM_STK_UINT0 & 0x1F);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ISHR_UN):
+ {
+ /* Shift right unsigned 32-bit integers */
+ VM_STK_UINT1 = VM_STK_UINT1 >> (VM_STK_UINT0 & 0x1F);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LAND):
+ {
+ /* Bitwise and signed 64-bit integers */
+ VM_STK_LONG1 = VM_STK_LONG1 & VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOR):
+ {
+ /* Bitwise or signed 64-bit integers */
+ VM_STK_LONG1 = VM_STK_LONG1 | VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LXOR):
+ {
+ /* Bitwise xor signed 64-bit integers */
+ VM_STK_LONG1 = VM_STK_LONG1 ^ VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LNOT):
+ {
+ /* Bitwise not signed 64-bit integers */
+ VM_STK_LONG0 = ~VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LSHL):
+ {
+ /* Shift left signed 64-bit integers */
+ VM_STK_LONG1 = (VM_STK_LONG1 << (VM_STK_UINT0 & 0x3F));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LSHR):
+ {
+ /* Shift right signed 64-bit integers */
+ VM_STK_LONG1 = (VM_STK_LONG1 >> (VM_STK_UINT0 & 0x3F));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LSHR_UN):
+ {
+ /* Shift right signed 64-bit integers */
+ VM_STK_ULONG1 = (VM_STK_ULONG1 >> (VM_STK_UINT0 & 0x3F));
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Branch opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_BR):
+ {
+ /* Unconditional branch */
+ pc = VM_BR_TARGET;
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_IFALSE):
+ {
+ /* Branch if signed 32-bit integer is false */
+ if(VM_STK_INT0 == 0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(1);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_ITRUE):
+ {
+ /* Branch if signed 32-bit integer is true */
+ if(VM_STK_INT0 != 0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(1);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_IEQ):
+ {
+ /* Branch if signed 32-bit integers are equal */
+ if(VM_STK_INT1 == VM_STK_INT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_INE):
+ {
+ /* Branch if signed 32-bit integers are not equal */
+ if(VM_STK_INT1 != VM_STK_INT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_ILT):
+ {
+ /* Branch if signed 32-bit integers are less than */
+ if(VM_STK_INT1 < VM_STK_INT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_ILT_UN):
+ {
+ /* Branch if unsigned 32-bit integers are less than */
+ if(VM_STK_UINT1 < VM_STK_UINT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_ILE):
+ {
+ /* Branch if signed 32-bit integers are less than or equal */
+ if(VM_STK_INT1 <= VM_STK_INT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_ILE_UN):
+ {
+ /* Branch if unsigned 32-bit integers are less than or equal */
+ if(VM_STK_UINT1 <= VM_STK_UINT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_IGT):
+ {
+ /* Branch if signed 32-bit integers are greater than */
+ if(VM_STK_INT1 > VM_STK_INT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_IGT_UN):
+ {
+ /* Branch if unsigned 32-bit integers are greater than */
+ if(VM_STK_UINT1 > VM_STK_UINT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_IGE):
+ {
+ /* Branch if signed 32-bit integers are greater than or equal */
+ if(VM_STK_INT1 >= VM_STK_INT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_IGE_UN):
+ {
+ /* Branch if unsigned 32-bit integers are greater than or equal */
+ if(VM_STK_UINT1 >= VM_STK_UINT0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LFALSE):
+ {
+ /* Branch if signed 64-bit integer is false */
+ if(VM_STK_LONG0 == 0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(1);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LTRUE):
+ {
+ /* Branch if signed 64-bit integer is true */
+ if(VM_STK_LONG0 != 0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(1);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LEQ):
+ {
+ /* Branch if signed 64-bit integers are equal */
+ if(VM_STK_LONG1 == VM_STK_LONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LNE):
+ {
+ /* Branch if signed 64-bit integers are not equal */
+ if(VM_STK_LONG1 != VM_STK_LONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LLT):
+ {
+ /* Branch if signed 64-bit integers are less than */
+ if(VM_STK_LONG1 < VM_STK_LONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LLT_UN):
+ {
+ /* Branch if unsigned 64-bit integers are less than */
+ if(VM_STK_ULONG1 < VM_STK_ULONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LLE):
+ {
+ /* Branch if signed 64-bit integers are less than or equal */
+ if(VM_STK_LONG1 <= VM_STK_LONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LLE_UN):
+ {
+ /* Branch if unsigned 64-bit integers are less than or equal */
+ if(VM_STK_ULONG1 <= VM_STK_ULONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LGT):
+ {
+ /* Branch if signed 64-bit integers are greater than */
+ if(VM_STK_LONG1 > VM_STK_LONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LGT_UN):
+ {
+ /* Branch if unsigned 64-bit integers are greater than */
+ if(VM_STK_ULONG1 > VM_STK_ULONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LGE):
+ {
+ /* Branch if signed 64-bit integers are greater than or equal */
+ if(VM_STK_LONG1 >= VM_STK_LONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_LGE_UN):
+ {
+ /* Branch if unsigned 64-bit integers are greater than or equal */
+ if(VM_STK_ULONG1 >= VM_STK_ULONG0)
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FEQ):
+ {
+ /* Branch if 32-bit floats are equal */
+ if(jit_float32_eq(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FNE):
+ {
+ /* Branch if 32-bit floats are not equal */
+ if(jit_float32_ne(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FLT):
+ {
+ /* Branch if 32-bit floats are less than */
+ if(jit_float32_lt(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FLE):
+ {
+ /* Branch if 32-bit floats are less than or equal */
+ if(jit_float32_le(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FGT):
+ {
+ /* Branch if 32-bit floats are greater than */
+ if(jit_float32_gt(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FGE):
+ {
+ /* Branch if 32-bit floats are greater than or equal */
+ if(jit_float32_ge(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FEQ_INV):
+ {
+ /* Branch if 32-bit floats are equal; invert nan test */
+ if(!jit_float32_ne(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FNE_INV):
+ {
+ /* Branch if 32-bit floats are not equal; invert nan test */
+ if(!jit_float32_eq(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FLT_INV):
+ {
+ /* Branch if 32-bit floats are less than; invert nan test */
+ if(!jit_float32_ge(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FLE_INV):
+ {
+ /* Branch if 32-bit floats are less or equal; invert nan test */
+ if(!jit_float32_gt(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FGT_INV):
+ {
+ /* Branch if 32-bit floats are greater than; invert nan test */
+ if(!jit_float32_le(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_FGE_INV):
+ {
+ /* Branch if 32-bit floats are greater or equal; invert nan test */
+ if(!jit_float32_lt(VM_STK_FLOAT321, VM_STK_FLOAT320))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DEQ):
+ {
+ /* Branch if 64-bit floats are equal */
+ if(jit_float64_eq(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DNE):
+ {
+ /* Branch if 64-bit floats are not equal */
+ if(jit_float64_ne(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DLT):
+ {
+ /* Branch if 64-bit floats are less than */
+ if(jit_float64_lt(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DLE):
+ {
+ /* Branch if 64-bit floats are less than or equal */
+ if(jit_float64_le(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DGT):
+ {
+ /* Branch if 64-bit floats are greater than */
+ if(jit_float64_gt(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DGE):
+ {
+ /* Branch if 64-bit floats are greater than or equal */
+ if(jit_float64_ge(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DEQ_INV):
+ {
+ /* Branch if 64-bit floats are equal; invert nan test */
+ if(!jit_float64_ne(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DNE_INV):
+ {
+ /* Branch if 64-bit floats are not equal; invert nan test */
+ if(!jit_float64_eq(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DLT_INV):
+ {
+ /* Branch if 64-bit floats are less than; invert nan test */
+ if(!jit_float64_ge(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DLE_INV):
+ {
+ /* Branch if 64-bit floats are less or equal; invert nan test */
+ if(!jit_float64_gt(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DGT_INV):
+ {
+ /* Branch if 64-bit floats are greater than; invert nan test */
+ if(!jit_float64_le(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_DGE_INV):
+ {
+ /* Branch if 64-bit floats are greater or equal; invert nan test */
+ if(!jit_float64_lt(VM_STK_FLOAT641, VM_STK_FLOAT640))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFEQ):
+ {
+ /* Branch if native floats are equal */
+ if(jit_nfloat_eq(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFNE):
+ {
+ /* Branch if native floats are not equal */
+ if(jit_nfloat_ne(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFLT):
+ {
+ /* Branch if native floats are less than */
+ if(jit_nfloat_lt(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFLE):
+ {
+ /* Branch if native floats are less than or equal */
+ if(jit_nfloat_le(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFGT):
+ {
+ /* Branch if native floats are greater than */
+ if(jit_nfloat_gt(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFGE):
+ {
+ /* Branch if native floats are greater than or equal */
+ if(jit_nfloat_ge(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFEQ_INV):
+ {
+ /* Branch if native floats are equal; invert nan test */
+ if(!jit_nfloat_ne(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFNE_INV):
+ {
+ /* Branch if native floats are not equal; invert nan test */
+ if(!jit_nfloat_eq(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFLT_INV):
+ {
+ /* Branch if native floats are less than; invert nan test */
+ if(!jit_nfloat_ge(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFLE_INV):
+ {
+ /* Branch if native floats are less or equal; invert nan test */
+ if(!jit_nfloat_gt(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFGT_INV):
+ {
+ /* Branch if native floats are greater than; invert nan test */
+ if(!jit_nfloat_le(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_BR_NFGE_INV):
+ {
+ /* Branch if native floats are greater or equal; invert nan test */
+ if(!jit_nfloat_lt(VM_STK_NFLOAT1, VM_STK_NFLOAT0))
+ {
+ pc = VM_BR_TARGET;
+ VM_MODIFY_STACK(2);
+ }
+ else
+ {
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Comparison opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_ICMP):
+ {
+ /* Compare signed 32-bit integers */
+ VM_STK_INT1 = jit_int_cmp(VM_STK_INT1, VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ICMP_UN):
+ {
+ /* Compare unsigned 32-bit integers */
+ VM_STK_UINT1 = jit_uint_cmp(VM_STK_UINT1, VM_STK_UINT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LCMP):
+ {
+ /* Compare signed 64-bit integers */
+ VM_STK_INT1 = jit_long_cmp(VM_STK_LONG1, VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LCMP_UN):
+ {
+ /* Compare unsigned 64-bit integers */
+ VM_STK_INT1 = jit_long_cmp(VM_STK_ULONG1, VM_STK_ULONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FCMPL):
+ {
+ /* Compare 32-bit floats, with less nan */
+ VM_STK_INT1 = jit_float32_cmpl(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FCMPG):
+ {
+ /* Compare 32-bit floats, with greater nan */
+ VM_STK_INT1 = jit_float32_cmpg(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DCMPL):
+ {
+ /* Compare 64-bit floats, with less nan */
+ VM_STK_INT1 = jit_float64_cmpl(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DCMPG):
+ {
+ /* Compare 64-bit floats, with greater nan */
+ VM_STK_INT1 = jit_float64_cmpg(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFCMPL):
+ {
+ /* Compare native floats, with less nan */
+ VM_STK_INT1 = jit_float64_cmpl(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFCMPG):
+ {
+ /* Compare native floats, with greater nan */
+ VM_STK_INT1 = jit_float64_cmpg(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IEQ):
+ {
+ /* Compare signed 32-bit integers for equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_INT1 == VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_INE):
+ {
+ /* Compare signed 32-bit integers for not equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_INT1 != VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ILT):
+ {
+ /* Compare signed 32-bit integers for less than */
+ VM_STK_INT1 = (jit_int)(VM_STK_INT1 < VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ILT_UN):
+ {
+ /* Compare unsigned 32-bit integers for less than */
+ VM_STK_INT1 = (jit_int)(VM_STK_UINT1 < VM_STK_UINT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ILE):
+ {
+ /* Compare signed 32-bit integers for less than or equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_INT1 <= VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ILE_UN):
+ {
+ /* Compare unsigned 32-bit integers for less than or equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_UINT1 <= VM_STK_UINT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IGT):
+ {
+ /* Compare signed 32-bit integers for greater than */
+ VM_STK_INT1 = (jit_int)(VM_STK_INT1 > VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IGT_UN):
+ {
+ /* Compare unsigned 32-bit integers for greater than */
+ VM_STK_INT1 = (jit_int)(VM_STK_UINT1 > VM_STK_UINT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IGE):
+ {
+ /* Compare signed 32-bit integers for greater than or equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_INT1 >= VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IGE_UN):
+ {
+ /* Compare unsigned 32-bit integers for greater than or equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_UINT1 >= VM_STK_UINT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LEQ):
+ {
+ /* Compare signed 64-bit integers for equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_LONG1 == VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LNE):
+ {
+ /* Compare signed 64-bit integers for not equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_LONG1 != VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LLT):
+ {
+ /* Compare signed 64-bit integers for less than */
+ VM_STK_INT1 = (jit_int)(VM_STK_LONG1 < VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LLT_UN):
+ {
+ /* Compare unsigned 64-bit integers for less than */
+ VM_STK_INT1 = (jit_int)(VM_STK_ULONG1 < VM_STK_ULONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LLE):
+ {
+ /* Compare signed 64-bit integers for less than or equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_LONG1 <= VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LLE_UN):
+ {
+ /* Compare unsigned 64-bit integers for less than or equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_ULONG1 <= VM_STK_ULONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LGT):
+ {
+ /* Compare signed 64-bit integers for greater than */
+ VM_STK_INT1 = (jit_int)(VM_STK_LONG1 > VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LGT_UN):
+ {
+ /* Compare unsigned 64-bit integers for greater than */
+ VM_STK_INT1 = (jit_int)(VM_STK_ULONG1 > VM_STK_ULONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LGE):
+ {
+ /* Compare signed 64-bit integers for greater than or equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_LONG1 >= VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LGE_UN):
+ {
+ /* Compare unsigned 64-bit integers for greater than or equal */
+ VM_STK_INT1 = (jit_int)(VM_STK_ULONG1 >= VM_STK_ULONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FEQ):
+ {
+ /* Compare 32-bit floats for equal */
+ VM_STK_INT1 = jit_float32_eq(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FNE):
+ {
+ /* Compare 32-bit floats for not equal */
+ VM_STK_INT1 = jit_float32_ne(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FLT):
+ {
+ /* Compare 32-bit floats for less than */
+ VM_STK_INT1 = jit_float32_lt(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FLE):
+ {
+ /* Compare 32-bit floats for less than or equal */
+ VM_STK_INT1 = jit_float32_le(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FGT):
+ {
+ /* Compare 32-bit floats for greater than */
+ VM_STK_INT1 = jit_float32_gt(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FGE):
+ {
+ /* Compare 32-bit floats for greater than or equal */
+ VM_STK_INT1 = jit_float32_ge(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FEQ_INV):
+ {
+ /* Compare 32-bit floats for equal; invert nan test */
+ VM_STK_INT1 = !jit_float32_ne(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FNE_INV):
+ {
+ /* Compare 32-bit floats for not equal; invert nan test */
+ VM_STK_INT1 = !jit_float32_eq(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FLT_INV):
+ {
+ /* Compare 32-bit floats for less than; invert nan test */
+ VM_STK_INT1 = !jit_float32_ge(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FLE_INV):
+ {
+ /* Compare 32-bit floats for less than or equal; invert nan test */
+ VM_STK_INT1 = !jit_float32_gt(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FGT_INV):
+ {
+ /* Compare 32-bit floats for greater than; invert nan test */
+ VM_STK_INT1 = !jit_float32_le(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FGE_INV):
+ {
+ /* Compare 32-bit floats for greater or equal; invert nan test */
+ VM_STK_INT1 = !jit_float32_lt(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DEQ):
+ {
+ /* Compare 64-bit floats for equal */
+ VM_STK_INT1 = jit_float64_eq(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DNE):
+ {
+ /* Compare 64-bit floats for not equal */
+ VM_STK_INT1 = jit_float64_ne(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DLT):
+ {
+ /* Compare 64-bit floats for less than */
+ VM_STK_INT1 = jit_float64_lt(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DLE):
+ {
+ /* Compare 64-bit floats for less than or equal */
+ VM_STK_INT1 = jit_float64_le(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DGT):
+ {
+ /* Compare 64-bit floats for greater than */
+ VM_STK_INT1 = jit_float64_gt(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DGE):
+ {
+ /* Compare 64-bit floats for greater than or equal */
+ VM_STK_INT1 = jit_float64_ge(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DEQ_INV):
+ {
+ /* Compare 64-bit floats for equal; invert nan test */
+ VM_STK_INT1 = !jit_float64_ne(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DNE_INV):
+ {
+ /* Compare 64-bit floats for equal; invert nan test */
+ VM_STK_INT1 = !jit_float64_eq(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DLT_INV):
+ {
+ /* Compare 64-bit floats for equal; invert nan test */
+ VM_STK_INT1 = !jit_float64_ge(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DLE_INV):
+ {
+ /* Compare 64-bit floats for equal; invert nan test */
+ VM_STK_INT1 = !jit_float64_gt(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DGT_INV):
+ {
+ /* Compare 64-bit floats for equal; invert nan test */
+ VM_STK_INT1 = !jit_float64_le(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DGE_INV):
+ {
+ /* Compare 64-bit floats for equal; invert nan test */
+ VM_STK_INT1 = !jit_float64_lt(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFEQ):
+ {
+ /* Compare native floats for equal */
+ VM_STK_INT1 = jit_nfloat_eq(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFNE):
+ {
+ /* Compare native floats for not equal */
+ VM_STK_INT1 = jit_nfloat_ne(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLT):
+ {
+ /* Compare native floats for less than */
+ VM_STK_INT1 = jit_nfloat_lt(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLE):
+ {
+ /* Compare native floats for less than or equal */
+ VM_STK_INT1 = jit_nfloat_le(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFGT):
+ {
+ /* Compare native floats for greater than */
+ VM_STK_INT1 = jit_nfloat_gt(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFGE):
+ {
+ /* Compare native floats for greater than or equal */
+ VM_STK_INT1 = jit_nfloat_ge(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFEQ_INV):
+ {
+ /* Compare native floats for equal; invert nan test */
+ VM_STK_INT1 = !jit_nfloat_ne(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFNE_INV):
+ {
+ /* Compare native floats for not equal; invert nan test */
+ VM_STK_INT1 = !jit_nfloat_eq(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLT_INV):
+ {
+ /* Compare native floats for less than; invert nan test */
+ VM_STK_INT1 = !jit_nfloat_ge(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLE_INV):
+ {
+ /* Compare native floats for less than or equal; invert nan test */
+ VM_STK_INT1 = !jit_nfloat_gt(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFGT_INV):
+ {
+ /* Compare native floats for greater than; invert nan test */
+ VM_STK_INT1 = !jit_nfloat_le(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFGE_INV):
+ {
+ /* Compare native floats for greater or equal; invert nan test */
+ VM_STK_INT1 = !jit_nfloat_lt(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_FNAN):
+ {
+ /* Check a 32-bit float for "not a number" */
+ VM_STK_INT0 = jit_float32_is_nan(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_FINF):
+ {
+ /* Check a 32-bit float for "infinity" */
+ VM_STK_INT0 = jit_float32_is_inf(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_FFINITE):
+ {
+ /* Check a 32-bit float for "finite" */
+ VM_STK_INT0 = jit_float32_is_finite(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_DNAN):
+ {
+ /* Check a 64-bit float for "not a number" */
+ VM_STK_INT0 = jit_float64_is_nan(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_DINF):
+ {
+ /* Check a 64-bit float for "infinity" */
+ VM_STK_INT0 = jit_float64_is_inf(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_DFINITE):
+ {
+ /* Check a 64-bit float for "finite" */
+ VM_STK_INT0 = jit_float64_is_finite(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_NFNAN):
+ {
+ /* Check a native float for "not a number" */
+ VM_STK_INT0 = jit_nfloat_is_nan(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_NFINF):
+ {
+ /* Check a native float for "infinity" */
+ VM_STK_INT0 = jit_nfloat_is_inf(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IS_NFFINITE):
+ {
+ /* Check a native float for "finite" */
+ VM_STK_INT0 = jit_nfloat_is_finite(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Mathematical functions.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_FACOS):
+ {
+ /* Compute 32-bit float "acos" */
+ VM_STK_FLOAT320 = jit_float32_acos(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FASIN):
+ {
+ /* Compute 32-bit float "asin" */
+ VM_STK_FLOAT320 = jit_float32_asin(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FATAN):
+ {
+ /* Compute 32-bit float "atan" */
+ VM_STK_FLOAT320 = jit_float32_atan(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FATAN2):
+ {
+ /* Compute 32-bit float "atan2" */
+ VM_STK_FLOAT321 = jit_float32_atan2
+ (VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FCEIL):
+ {
+ /* Compute 32-bit float "ceil" */
+ VM_STK_FLOAT320 = jit_float32_ceil(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FCOS):
+ {
+ /* Compute 32-bit float "cos" */
+ VM_STK_FLOAT320 = jit_float32_cos(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FCOSH):
+ {
+ /* Compute 32-bit float "cosh" */
+ VM_STK_FLOAT320 = jit_float32_cosh(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FEXP):
+ {
+ /* Compute 32-bit float "exp" */
+ VM_STK_FLOAT320 = jit_float32_exp(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FFLOOR):
+ {
+ /* Compute 32-bit float "floor" */
+ VM_STK_FLOAT320 = jit_float32_floor(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FLOG):
+ {
+ /* Compute 32-bit float "log" */
+ VM_STK_FLOAT320 = jit_float32_log(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FLOG10):
+ {
+ /* Compute 32-bit float "log10" */
+ VM_STK_FLOAT320 = jit_float32_log10(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FPOW):
+ {
+ /* Compute 32-bit float "pow" */
+ VM_STK_FLOAT321 = jit_float32_pow
+ (VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FRINT):
+ {
+ /* Compute 32-bit float "rint" */
+ VM_STK_FLOAT320 = jit_float32_rint(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FROUND):
+ {
+ /* Compute 32-bit float "round" */
+ VM_STK_FLOAT320 = jit_float32_round(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FSIN):
+ {
+ /* Compute 32-bit float "sin" */
+ VM_STK_FLOAT320 = jit_float32_sin(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FSINH):
+ {
+ /* Compute 32-bit float "sinh" */
+ VM_STK_FLOAT320 = jit_float32_sinh(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FSQRT):
+ {
+ /* Compute 32-bit float "sqrt" */
+ VM_STK_FLOAT320 = jit_float32_sqrt(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FTAN):
+ {
+ /* Compute 32-bit float "tan" */
+ VM_STK_FLOAT320 = jit_float32_tan(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FTANH):
+ {
+ /* Compute 32-bit float "tanh" */
+ VM_STK_FLOAT320 = jit_float32_tanh(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DACOS):
+ {
+ /* Compute 64-bit float "acos" */
+ VM_STK_FLOAT640 = jit_float64_acos(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DASIN):
+ {
+ /* Compute 64-bit float "asin" */
+ VM_STK_FLOAT640 = jit_float64_asin(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DATAN):
+ {
+ /* Compute 64-bit float "atan" */
+ VM_STK_FLOAT640 = jit_float64_atan(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DATAN2):
+ {
+ /* Compute 64-bit float "atan2" */
+ VM_STK_FLOAT641 = jit_float64_atan2
+ (VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DCEIL):
+ {
+ /* Compute 64-bit float "ceil" */
+ VM_STK_FLOAT640 = jit_float64_ceil(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DCOS):
+ {
+ /* Compute 64-bit float "cos" */
+ VM_STK_FLOAT640 = jit_float64_cos(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DCOSH):
+ {
+ /* Compute 64-bit float "cosh" */
+ VM_STK_FLOAT640 = jit_float64_cosh(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DEXP):
+ {
+ /* Compute 64-bit float "exp" */
+ VM_STK_FLOAT640 = jit_float64_exp(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DFLOOR):
+ {
+ /* Compute 64-bit float "floor" */
+ VM_STK_FLOAT640 = jit_float64_floor(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DLOG):
+ {
+ /* Compute 64-bit float "log" */
+ VM_STK_FLOAT640 = jit_float64_log(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DLOG10):
+ {
+ /* Compute 64-bit float "log10" */
+ VM_STK_FLOAT640 = jit_float64_log10(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DPOW):
+ {
+ /* Compute 64-bit float "pow" */
+ VM_STK_FLOAT641 = jit_float64_pow
+ (VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DRINT):
+ {
+ /* Compute 64-bit float "rint" */
+ VM_STK_FLOAT640 = jit_float64_rint(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DROUND):
+ {
+ /* Compute 64-bit float "round" */
+ VM_STK_FLOAT640 = jit_float64_round(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DSIN):
+ {
+ /* Compute 64-bit float "sin" */
+ VM_STK_FLOAT640 = jit_float64_sin(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DSINH):
+ {
+ /* Compute 64-bit float "sinh" */
+ VM_STK_FLOAT640 = jit_float64_sinh(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DSQRT):
+ {
+ /* Compute 64-bit float "sqrt" */
+ VM_STK_FLOAT640 = jit_float64_sqrt(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DTAN):
+ {
+ /* Compute 64-bit float "tan" */
+ VM_STK_FLOAT640 = jit_float64_tan(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DTANH):
+ {
+ /* Compute 64-bit float "tanh" */
+ VM_STK_FLOAT640 = jit_float64_tanh(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFACOS):
+ {
+ /* Compute native float "acos" */
+ VM_STK_NFLOAT0 = jit_nfloat_acos(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFASIN):
+ {
+ /* Compute native float "asin" */
+ VM_STK_NFLOAT0 = jit_nfloat_asin(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFATAN):
+ {
+ /* Compute native float "atan" */
+ VM_STK_NFLOAT0 = jit_nfloat_atan(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFATAN2):
+ {
+ /* Compute native float "atan2" */
+ VM_STK_NFLOAT1 = jit_nfloat_atan2
+ (VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFCEIL):
+ {
+ /* Compute native float "ceil" */
+ VM_STK_NFLOAT0 = jit_nfloat_ceil(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFCOS):
+ {
+ /* Compute native float "cos" */
+ VM_STK_NFLOAT0 = jit_nfloat_cos(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFCOSH):
+ {
+ /* Compute native float "cosh" */
+ VM_STK_NFLOAT0 = jit_nfloat_cosh(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFEXP):
+ {
+ /* Compute native float "exp" */
+ VM_STK_NFLOAT0 = jit_nfloat_exp(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFFLOOR):
+ {
+ /* Compute native float "floor" */
+ VM_STK_NFLOAT0 = jit_nfloat_floor(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLOG):
+ {
+ /* Compute native float "log" */
+ VM_STK_NFLOAT0 = jit_nfloat_log(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFLOG10):
+ {
+ /* Compute native float "log10" */
+ VM_STK_NFLOAT0 = jit_nfloat_log10(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFPOW):
+ {
+ /* Compute native float "pow" */
+ VM_STK_NFLOAT1 = jit_nfloat_pow
+ (VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFRINT):
+ {
+ /* Compute native float "rint" */
+ VM_STK_NFLOAT0 = jit_nfloat_rint(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFROUND):
+ {
+ /* Compute native float "round" */
+ VM_STK_NFLOAT0 = jit_nfloat_round(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFSIN):
+ {
+ /* Compute native float "sin" */
+ VM_STK_NFLOAT0 = jit_nfloat_sin(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFSINH):
+ {
+ /* Compute native float "sinh" */
+ VM_STK_NFLOAT0 = jit_nfloat_sinh(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFSQRT):
+ {
+ /* Compute native float "sqrt" */
+ VM_STK_NFLOAT0 = jit_nfloat_sqrt(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFTAN):
+ {
+ /* Compute native float "tan" */
+ VM_STK_NFLOAT0 = jit_nfloat_tan(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFTANH):
+ {
+ /* Compute native float "tanh" */
+ VM_STK_NFLOAT0 = jit_nfloat_tanh(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Absolute, minimum, maximum, and sign.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_IABS):
+ {
+ /* Compute the absolute value of a signed 32-bit integer value */
+ VM_STK_INT0 = jit_int_abs(VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LABS):
+ {
+ /* Compute the absolute value of a signed 64-bit integer value */
+ VM_STK_LONG0 = jit_long_abs(VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FABS):
+ {
+ /* Compute the absolute value of a 32-bit float value */
+ VM_STK_FLOAT320 = jit_float32_abs(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DABS):
+ {
+ /* Compute the absolute value of a 64-bit float value */
+ VM_STK_FLOAT640 = jit_float64_abs(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFABS):
+ {
+ /* Compute the absolute value of a native float value */
+ VM_STK_NFLOAT0 = jit_nfloat_abs(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMIN):
+ {
+ /* Compute the minimum of two signed 32-bit integer values */
+ VM_STK_INT1 = jit_int_min(VM_STK_INT1, VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMIN_UN):
+ {
+ /* Compute the minimum of two unsigned 32-bit integer values */
+ VM_STK_UINT1 = jit_uint_min(VM_STK_UINT1, VM_STK_UINT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LMIN):
+ {
+ /* Compute the minimum of two signed 64-bit integer values */
+ VM_STK_LONG1 = jit_long_min(VM_STK_LONG1, VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LMIN_UN):
+ {
+ /* Compute the minimum of two unsigned 64-bit integer values */
+ VM_STK_ULONG1 = jit_ulong_min(VM_STK_ULONG1, VM_STK_ULONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FMIN):
+ {
+ /* Compute the minimum of two 32-bit float values */
+ VM_STK_FLOAT321 = jit_float32_min(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DMIN):
+ {
+ /* Compute the minimum of two 64-bit float values */
+ VM_STK_FLOAT641 = jit_float64_min(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFMIN):
+ {
+ /* Compute the minimum of two native float values */
+ VM_STK_NFLOAT1 = jit_nfloat_min(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMAX):
+ {
+ /* Compute the maximum of two signed 32-bit integer values */
+ VM_STK_INT1 = jit_int_max(VM_STK_INT1, VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMAX_UN):
+ {
+ /* Compute the maximum of two unsigned 32-bit integer values */
+ VM_STK_UINT1 = jit_uint_max(VM_STK_UINT1, VM_STK_UINT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LMAX):
+ {
+ /* Compute the maximum of two signed 64-bit integer values */
+ VM_STK_LONG1 = jit_long_max(VM_STK_LONG1, VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LMAX_UN):
+ {
+ /* Compute the maximum of two unsigned 64-bit integer values */
+ VM_STK_ULONG1 = jit_ulong_max(VM_STK_ULONG1, VM_STK_ULONG0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FMAX):
+ {
+ /* Compute the maximum of two 32-bit float values */
+ VM_STK_FLOAT321 = jit_float32_max(VM_STK_FLOAT321, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DMAX):
+ {
+ /* Compute the maximum of two 64-bit float values */
+ VM_STK_FLOAT641 = jit_float64_max(VM_STK_FLOAT641, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFMAX):
+ {
+ /* Compute the maximum of two native float values */
+ VM_STK_NFLOAT1 = jit_nfloat_max(VM_STK_NFLOAT1, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ISIGN):
+ {
+ /* Compute the sign of a signed 32-bit integer value */
+ VM_STK_INT0 = jit_int_sign(VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LSIGN):
+ {
+ /* Compute the sign of a signed 64-bit integer value */
+ VM_STK_INT0 = jit_long_sign(VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_FSIGN):
+ {
+ /* Compute the sign of a 32-bit float value */
+ VM_STK_INT0 = jit_float32_sign(VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_DSIGN):
+ {
+ /* Compute the sign of a 64-bit float value */
+ VM_STK_INT0 = jit_float64_sign(VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_NFSIGN):
+ {
+ /* Compute the sign of a native float value */
+ VM_STK_INT0 = jit_nfloat_sign(VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Pointer check opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_CHECK_NULL):
+ {
+ /* Check the top of stack to see if it is null */
+ if(!VM_STK_PTR0)
+ {
+ VM_BUILTIN(JIT_RESULT_NULL_REFERENCE);
+ }
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CHECK_NULL_N):
+ {
+ /* Check a pointer for null "n" items down the stack.
+ This opcode is specific to the interpreter */
+ if(!(stacktop[VM_NINT_ARG].ptr_value))
+ {
+ VM_BUILTIN(JIT_RESULT_NULL_REFERENCE);
+ }
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Function calls.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_CALL):
+ VMCASE(JIT_OP_CALL_TAIL):
+ {
+ /* Call a function that is under the control of the JIT */
+ call_func = (jit_function_t)VM_NINT_ARG;
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ entry = call_func->entry_point;
+ _jit_backtrace_push(&call_trace, pc, 0, 0);
+ if(!entry)
+ {
+ entry = _jit_function_compile_on_demand(call_func);
+ }
+ _jit_run_function((jit_function_interp_t)entry, stacktop,
+ return_area);
+ _jit_backtrace_pop();
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CALL_INDIRECT):
+ {
+ /* Call a native function via an indirect pointer */
+ tempptr = (void *)VM_NINT_ARG;
+ temparg = VM_NINT_ARG2;
+ VM_MODIFY_PC_AND_STACK(3, 2);
+ _jit_backtrace_push(&call_trace, pc, 0, 0);
+ apply_from_interpreter((jit_type_t)tempptr,
+ (void *)VM_STK_PTRP2,
+ stacktop,
+ (unsigned int)temparg,
+ VM_STK_PTRP);
+ _jit_backtrace_pop();
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CALL_VTABLE_PTR):
+ {
+ /* Call a JIT-managed function via an indirect vtable pointer */
+ call_func = (jit_function_t)(VM_STK_PTR0);
+ if(!call_func)
+ {
+ VM_BUILTIN(JIT_RESULT_NULL_FUNCTION);
+ }
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ entry = call_func->entry_point;
+ _jit_backtrace_push(&call_trace, pc, 0, 0);
+ if(!entry)
+ {
+ entry = _jit_function_compile_on_demand(call_func);
+ }
+ _jit_run_function((jit_function_interp_t)entry, stacktop,
+ return_area);
+ _jit_backtrace_pop();
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CALL_EXTERNAL):
+ {
+ /* Call an external native function */
+ tempptr = (void *)VM_NINT_ARG;
+ tempptr2 = (void *)VM_NINT_ARG2;
+ temparg = VM_NINT_ARG3;
+ VM_MODIFY_PC_AND_STACK(4, 1);
+ _jit_backtrace_push(&call_trace, pc, 0, 0);
+ apply_from_interpreter((jit_type_t)tempptr,
+ (void *)tempptr2,
+ stacktop,
+ (unsigned int)temparg,
+ VM_STK_PTRP);
+ _jit_backtrace_pop();
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_RETURN):
+ {
+ /* Return from the current function, with no result */
+ if(jbuf)
+ {
+ _jit_unwind_pop_setjmp();
+ }
+ return;
+ }
+ /* Not reached */
+
+ VMCASE(JIT_OP_RETURN_INT):
+ {
+ /* Return from the current function, with an integer result */
+ return_area->int_value = VM_STK_INT0;
+ if(jbuf)
+ {
+ _jit_unwind_pop_setjmp();
+ }
+ return;
+ }
+ /* Not reached */
+
+ VMCASE(JIT_OP_RETURN_LONG):
+ {
+ /* Return from the current function, with a long result */
+ return_area->long_value = VM_STK_LONG0;
+ if(jbuf)
+ {
+ _jit_unwind_pop_setjmp();
+ }
+ return;
+ }
+ /* Not reached */
+
+ VMCASE(JIT_OP_RETURN_FLOAT32):
+ {
+ /* Return from the current function, with a 32-bit float result */
+ return_area->float32_value = VM_STK_FLOAT320;
+ if(jbuf)
+ {
+ _jit_unwind_pop_setjmp();
+ }
+ return;
+ }
+ /* Not reached */
+
+ VMCASE(JIT_OP_RETURN_FLOAT64):
+ {
+ /* Return from the current function, with a 64-bit float result */
+ return_area->float64_value = VM_STK_FLOAT640;
+ if(jbuf)
+ {
+ _jit_unwind_pop_setjmp();
+ }
+ return;
+ }
+ /* Not reached */
+
+ VMCASE(JIT_OP_RETURN_NFLOAT):
+ {
+ /* Return from the current function, with a native float result */
+ return_area->nfloat_value = VM_STK_NFLOAT0;
+ if(jbuf)
+ {
+ _jit_unwind_pop_setjmp();
+ }
+ return;
+ }
+ /* Not reached */
+
+ VMCASE(JIT_OP_RETURN_SMALL_STRUCT):
+ {
+ /* Return from the current function, with a small structure */
+ #if JIT_APPLY_MAX_STRUCT_IN_REG != 0
+ jit_memcpy(return_area->struct_value, VM_STK_PTR0,
+ (unsigned int)VM_NINT_ARG);
+ #endif
+ if(jbuf)
+ {
+ _jit_unwind_pop_setjmp();
+ }
+ return;
+ }
+ /* Not reached */
+
+ VMCASE(JIT_OP_SETUP_FOR_NESTED):
+ {
+ /* Set up to call a nested function who is our child */
+ stacktop[-1].ptr_value = args;
+ stacktop[-2].ptr_value = frame;
+ VM_MODIFY_PC_AND_STACK(1, -2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_SETUP_FOR_SIBLING):
+ {
+ /* Set up to call a nested function who is our sibling, a sibling
+ of one of our ancestors, or one of our ancestors directly */
+ temparg = VM_NINT_ARG;
+ tempptr = &(args[0]);
+ while(temparg > 0)
+ {
+ tempptr = (((jit_item *)tempptr)[1]).ptr_value;
+ --temparg;
+ }
+ stacktop[-1].ptr_value = (((jit_item *)tempptr)[1]).ptr_value;
+ stacktop[-2].ptr_value = (((jit_item *)tempptr)[0]).ptr_value;
+ VM_MODIFY_PC_AND_STACK(1, -2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMPORT_LOCAL):
+ {
+ /* Import the address of a local variable from an outer scope */
+ temparg = VM_NINT_ARG2;
+ tempptr = args[0].ptr_value;
+ tempptr2 = args[1].ptr_value;
+ while(temparg > 1)
+ {
+ tempptr = ((jit_item *)tempptr2)[0].ptr_value;
+ tempptr2 = ((jit_item *)tempptr2)[1].ptr_value;
+ --temparg;
+ }
+ VM_STK_PTRP = ((jit_item *)tempptr) + VM_NINT_ARG;
+ VM_MODIFY_PC_AND_STACK(3, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_IMPORT_ARG):
+ {
+ /* Import the address of an argument from an outer scope */
+ temparg = VM_NINT_ARG2;
+ tempptr = args[1].ptr_value;
+ while(temparg > 1)
+ {
+ tempptr = ((jit_item *)tempptr)[1].ptr_value;
+ --temparg;
+ }
+ VM_STK_PTRP = ((jit_item *)tempptr) + VM_NINT_ARG;
+ VM_MODIFY_PC_AND_STACK(3, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_STRUCT):
+ {
+ /* Push a structure value onto the stack, given a pointer to it */
+ tempptr = VM_STK_PTR0;
+ temparg = VM_NINT_ARG;
+ stacktop -= (JIT_NUM_ITEMS_IN_STRUCT(temparg) - 1);
+ jit_memcpy(stacktop, tempptr, (unsigned int)temparg);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Exception handling.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_THROW):
+ {
+ /* Throw an exception, which may be handled in this function */
+ exception_object = VM_STK_PTR0;
+ handle_exception:
+ if(jit_function_from_pc(func->func->context, pc, &handler)
+ == func->func && handler != 0)
+ {
+ /* We have an appropriate "catch" handler in this function */
+ pc = (void **)handler;
+ stacktop = frame - 1;
+ stacktop->ptr_value = exception_object;
+ }
+ else
+ {
+ /* Throw the exception up to the next level */
+ _jit_unwind_pop_setjmp();
+ jit_exception_throw(exception_object);
+ }
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_PC):
+ {
+ /* Load the current program counter onto the stack */
+ VM_STK_PTRP = (void *)pc;
+ VM_MODIFY_PC_AND_STACK(1, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LEAVE_FINALLY):
+ {
+ /* Return from a "finally" handler */
+ pc = (void **)VM_STK_PTR0;
+ VM_MODIFY_STACK(1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LEAVE_FILTER):
+ {
+ /* Return from a "filter" handler: pc and value on stack */
+ pc = (void **)(stacktop[1].ptr_value);
+ stacktop[1] = stacktop[0];
+ VM_MODIFY_STACK(1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CALL_FILTER):
+ {
+ /* Call a "filter" handler with pc and value on stack */
+ stacktop[-1] = stacktop[0];
+ stacktop[0].ptr_value = (void *)(pc + 2);
+ VM_MODIFY_STACK(-1);
+ pc = VM_BR_TARGET;
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_CALL_FINALLY):
+ {
+ /* Call a "finally" handler */
+ VM_STK_PTRP = (void *)(pc + 2);
+ VM_MODIFY_STACK(-1);
+ pc = VM_BR_TARGET;
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Pointer-relative loads and stores.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_SBYTE):
+ {
+ /* Load a signed 8-bit integer from a relative pointer */
+ VM_STK_INT0 = *VM_REL(jit_sbyte, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_UBYTE):
+ {
+ /* Load an unsigned 8-bit integer from a relative pointer */
+ VM_STK_INT0 = *VM_REL(jit_ubyte, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_SHORT):
+ {
+ /* Load a signed 16-bit integer from a relative pointer */
+ VM_STK_INT0 = *VM_REL(jit_short, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_USHORT):
+ {
+ /* Load an unsigned 16-bit integer from a relative pointer */
+ VM_STK_INT0 = *VM_REL(jit_ushort, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_INT):
+ {
+ /* Load a 32-bit integer from a relative pointer */
+ VM_STK_INT0 = *VM_REL(jit_int, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_LONG):
+ {
+ /* Load a 64-bit integer from a relative pointer */
+ VM_STK_LONG0 = *VM_REL(jit_long, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_FLOAT32):
+ {
+ /* Load a 32-bit float from a relative pointer */
+ VM_STK_FLOAT320 = *VM_REL(jit_float32, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_FLOAT64):
+ {
+ /* Load a 64-bit float from a relative pointer */
+ VM_STK_FLOAT640 = *VM_REL(jit_float64, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_NFLOAT):
+ {
+ /* Load a native float from a relative pointer */
+ VM_STK_NFLOAT0 = *VM_REL(jit_nfloat, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_RELATIVE_STRUCT):
+ {
+ /* Load a structure from a relative pointer */
+ tempptr = VM_REL(void, VM_STK_PTR0);
+ temparg = VM_NINT_ARG2;
+ stacktop -= (JIT_NUM_ITEMS_IN_STRUCT(temparg) - 1);
+ jit_memcpy(stacktop, tempptr, temparg);
+ VM_MODIFY_PC_AND_STACK(3, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_RELATIVE_BYTE):
+ {
+ /* Store an 8-bit integer value to a relative pointer */
+ *VM_REL(jit_sbyte, VM_STK_PTR1) = (jit_sbyte)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_RELATIVE_SHORT):
+ {
+ /* Store a 16-bit integer value to a relative pointer */
+ *VM_REL(jit_short, VM_STK_PTR1) = (jit_short)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_RELATIVE_INT):
+ {
+ /* Store a 32-bit integer value to a relative pointer */
+ *VM_REL(jit_int, VM_STK_PTR1) = VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_RELATIVE_LONG):
+ {
+ /* Store a 64-bit integer value to a relative pointer */
+ *VM_REL(jit_long, VM_STK_PTR1) = VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_RELATIVE_FLOAT32):
+ {
+ /* Store a 32-bit float value to a relative pointer */
+ *VM_REL(jit_float32, VM_STK_PTR1) = VM_STK_FLOAT320;
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_RELATIVE_FLOAT64):
+ {
+ /* Store a 64-bit float value to a relative pointer */
+ *VM_REL(jit_float64, VM_STK_PTR1) = VM_STK_FLOAT640;
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_RELATIVE_NFLOAT):
+ {
+ /* Store a native float value to a relative pointer */
+ *VM_REL(jit_nfloat, VM_STK_PTR1) = VM_STK_NFLOAT0;
+ VM_MODIFY_PC_AND_STACK(2, 2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_RELATIVE_STRUCT):
+ {
+ /* Store a structure value to a relative pointer */
+ temparg = VM_NINT_ARG2;
+ tempptr = stacktop;
+ stacktop += JIT_NUM_ITEMS_IN_STRUCT(temparg);
+ jit_memcpy(VM_REL(void, VM_STK_PTR0), tempptr, temparg);
+ VM_MODIFY_PC_AND_STACK(3, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_ADD_RELATIVE):
+ {
+ /* Add a relative offset to a pointer */
+ VM_STK_PTR0 = VM_REL(void, VM_STK_PTR0);
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Array element loads and stores.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_SBYTE):
+ {
+ /* Load a signed 8-bit integer value from an array */
+ VM_STK_INT1 = VM_LOAD_ELEM(jit_sbyte);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_UBYTE):
+ {
+ /* Load an unsigned 8-bit integer value from an array */
+ VM_STK_INT1 = VM_LOAD_ELEM(jit_ubyte);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_SHORT):
+ {
+ /* Load a signed 16-bit integer value from an array */
+ VM_STK_INT1 = VM_LOAD_ELEM(jit_short);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_USHORT):
+ {
+ /* Load an unsigned 16-bit integer value from an array */
+ VM_STK_INT1 = VM_LOAD_ELEM(jit_ushort);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_INT):
+ {
+ /* Load a signed 32-bit integer value from an array */
+ VM_STK_INT1 = VM_LOAD_ELEM(jit_int);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_UINT):
+ {
+ /* Load an unsigned 32-bit integer value from an array */
+ VM_STK_UINT1 = VM_LOAD_ELEM(jit_uint);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_LONG):
+ {
+ /* Load a signed 64-bit integer value from an array */
+ VM_STK_LONG1 = VM_LOAD_ELEM(jit_long);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_ULONG):
+ {
+ /* Load an unsigned 64-bit integer value from an array */
+ VM_STK_ULONG1 = VM_LOAD_ELEM(jit_ulong);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_FLOAT32):
+ {
+ /* Load a 32-bit float value from an array */
+ VM_STK_FLOAT321 = VM_LOAD_ELEM(jit_float32);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_FLOAT64):
+ {
+ /* Load a 64-bit float value from an array */
+ VM_STK_FLOAT641 = VM_LOAD_ELEM(jit_float64);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LOAD_ELEMENT_NFLOAT):
+ {
+ /* Load a native float value from an array */
+ VM_STK_NFLOAT1 = VM_LOAD_ELEM(jit_nfloat);
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_ELEMENT_BYTE):
+ {
+ /* Store a 8-bit integer value to an array */
+ VM_STORE_ELEM(jit_sbyte, VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_ELEMENT_SHORT):
+ {
+ /* Store a 16-bit integer value to an array */
+ VM_STORE_ELEM(jit_short, VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_ELEMENT_INT):
+ {
+ /* Store a 32-bit integer value to an array */
+ VM_STORE_ELEM(jit_int, VM_STK_INT0);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_ELEMENT_LONG):
+ {
+ /* Store a 64-bit integer value to an array */
+ VM_STORE_ELEM(jit_long, VM_STK_LONG0);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_ELEMENT_FLOAT32):
+ {
+ /* Store a 32-bit float value to an array */
+ VM_STORE_ELEM(jit_float32, VM_STK_FLOAT320);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_ELEMENT_FLOAT64):
+ {
+ /* Store a 64-bit float value to an array */
+ VM_STORE_ELEM(jit_float64, VM_STK_FLOAT640);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STORE_ELEMENT_NFLOAT):
+ {
+ /* Store a native float value to an array */
+ VM_STORE_ELEM(jit_nfloat, VM_STK_NFLOAT0);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Block operations.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_MEMCPY):
+ {
+ /* Copy a block of memory */
+ jit_memcpy(VM_STK_PTR2, VM_STK_PTR1, VM_STK_NUINT0);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_MEMMOVE):
+ {
+ /* Move a block of memory */
+ jit_memmove(VM_STK_PTR2, VM_STK_PTR1, VM_STK_NUINT0);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_MEMSET):
+ {
+ /* Set a block of memory to a value */
+ jit_memset(VM_STK_PTR2, (int)VM_STK_INT1, VM_STK_NUINT0);
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Argument variable access opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_LDARG_SBYTE):
+ {
+ /* Load a signed 8-bit integer argument onto the stack */
+ VM_STK_INTP = *VM_ARG(jit_sbyte);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_UBYTE):
+ {
+ /* Load an unsigned 8-bit integer argument onto the stack */
+ VM_STK_INTP = *VM_ARG(jit_ubyte);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_SHORT):
+ {
+ /* Load a signed 16-bit integer argument onto the stack */
+ VM_STK_INTP = *VM_ARG(jit_short);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_USHORT):
+ {
+ /* Load an unsigned 16-bit integer argument onto the stack */
+ VM_STK_INTP = *VM_ARG(jit_ushort);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_INT):
+ {
+ /* Load a 32-bit integer argument onto the stack */
+ VM_STK_INTP = *VM_ARG(jit_int);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_LONG):
+ {
+ /* Load a 64-bit integer argument onto the stack */
+ VM_STK_LONGP = *VM_ARG(jit_long);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_FLOAT32):
+ {
+ /* Load a 32-bit float argument onto the stack */
+ VM_STK_FLOAT32P = *VM_ARG(jit_float32);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_FLOAT64):
+ {
+ /* Load a 64-bit float argument onto the stack */
+ VM_STK_FLOAT64P = *VM_ARG(jit_float64);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_NFLOAT):
+ {
+ /* Load a native float argument onto the stack */
+ VM_STK_NFLOATP = *VM_ARG(jit_nfloat);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARG_STRUCT):
+ {
+ /* Load a structure argument onto the stack */
+ temparg = VM_NINT_ARG2;
+ stacktop -= JIT_NUM_ITEMS_IN_STRUCT(temparg);
+ jit_memcpy(stacktop, VM_ARG(void), temparg);
+ VM_MODIFY_PC_AND_STACK(3, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDARGA):
+ {
+ /* Load the address of an argument onto the stack */
+ VM_STK_PTRP = VM_ARG(void);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STARG_BYTE):
+ {
+ /* Store an 8-bit integer into a stack argument */
+ *VM_ARG(jit_sbyte) = (jit_sbyte)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STARG_SHORT):
+ {
+ /* Store a 16-bit integer into a stack argument */
+ *VM_ARG(jit_short) = (jit_short)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STARG_INT):
+ {
+ /* Store a 32-bit integer into a stack argument */
+ *VM_ARG(jit_int) = VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STARG_LONG):
+ {
+ /* Store a 64-bit integer into a stack argument */
+ *VM_ARG(jit_long) = VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STARG_FLOAT32):
+ {
+ /* Store a 32-bit float into a stack argument */
+ *VM_ARG(jit_float32) = VM_STK_FLOAT320;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STARG_FLOAT64):
+ {
+ /* Store a 64-bit float into a stack argument */
+ *VM_ARG(jit_float64) = VM_STK_FLOAT640;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STARG_NFLOAT):
+ {
+ /* Store a native float into a stack argument */
+ *VM_ARG(jit_nfloat) = VM_STK_NFLOAT0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STARG_STRUCT):
+ {
+ /* Store a structure value into a stack argument */
+ temparg = VM_NINT_ARG2;
+ jit_memcpy(VM_ARG(void), stacktop, temparg);
+ stacktop += JIT_NUM_ITEMS_IN_STRUCT(temparg);
+ VM_MODIFY_PC_AND_STACK(3, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Local variable frame access opcodes.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_LDLOC_SBYTE):
+ {
+ /* Load a signed 8-bit integer local onto the stack */
+ VM_STK_INTP = *VM_LOC(jit_sbyte);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_UBYTE):
+ {
+ /* Load an unsigned 8-bit integer local onto the stack */
+ VM_STK_INTP = *VM_LOC(jit_ubyte);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_SHORT):
+ {
+ /* Load a signed 16-bit integer local onto the stack */
+ VM_STK_INTP = *VM_LOC(jit_short);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_USHORT):
+ {
+ /* Load an unsigned 16-bit integer local onto the stack */
+ VM_STK_INTP = *VM_LOC(jit_ushort);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_INT):
+ {
+ /* Load a 32-bit integer local onto the stack */
+ VM_STK_INTP = *VM_LOC(jit_int);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_LONG):
+ {
+ /* Load a 64-bit integer local onto the stack */
+ VM_STK_LONGP = *VM_LOC(jit_long);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_FLOAT32):
+ {
+ /* Load a 32-bit float local onto the stack */
+ VM_STK_FLOAT32P = *VM_LOC(jit_float32);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_FLOAT64):
+ {
+ /* Load a 64-bit float local onto the stack */
+ VM_STK_FLOAT64P = *VM_LOC(jit_float64);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_NFLOAT):
+ {
+ /* Load a native float local onto the stack */
+ VM_STK_NFLOATP = *VM_LOC(jit_nfloat);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOC_STRUCT):
+ {
+ /* Load a structure local onto the stack */
+ temparg = VM_NINT_ARG2;
+ stacktop -= JIT_NUM_ITEMS_IN_STRUCT(temparg);
+ jit_memcpy(stacktop, VM_LOC(void), temparg);
+ VM_MODIFY_PC_AND_STACK(3, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_LDLOCA):
+ {
+ /* Load the address of an local onto the stack */
+ VM_STK_PTRP = VM_LOC(void);
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STLOC_BYTE):
+ {
+ /* Store an 8-bit integer into a stack local */
+ *VM_LOC(jit_sbyte) = (jit_sbyte)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STLOC_SHORT):
+ {
+ /* Store a 16-bit integer into a stack local */
+ *VM_LOC(jit_short) = (jit_short)VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STLOC_INT):
+ {
+ /* Store a 32-bit integer into a stack local */
+ *VM_LOC(jit_int) = VM_STK_INT0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STLOC_LONG):
+ {
+ /* Store a 64-bit integer into a stack local */
+ *VM_LOC(jit_long) = VM_STK_LONG0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STLOC_FLOAT32):
+ {
+ /* Store a 32-bit float into a stack local */
+ *VM_LOC(jit_float32) = VM_STK_FLOAT320;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STLOC_FLOAT64):
+ {
+ /* Store a 64-bit float into a stack local */
+ *VM_LOC(jit_float64) = VM_STK_FLOAT640;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STLOC_NFLOAT):
+ {
+ /* Store a native float into a stack local */
+ *VM_LOC(jit_nfloat) = VM_STK_NFLOAT0;
+ VM_MODIFY_PC_AND_STACK(2, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_STLOC_STRUCT):
+ {
+ /* Store a structure value into a stack local */
+ temparg = VM_NINT_ARG2;
+ jit_memcpy(VM_LOC(void), stacktop, temparg);
+ stacktop += JIT_NUM_ITEMS_IN_STRUCT(temparg);
+ VM_MODIFY_PC_AND_STACK(3, 0);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Stack management
+ ******************************************************************/
+
+ VMCASE(JIT_OP_POP_STACK):
+ {
+ /* Pop a specific number of items from the stack */
+ temparg = VM_NINT_ARG;
+ VM_MODIFY_PC_AND_STACK(2, temparg);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_POP):
+ {
+ /* Pop a single item from the stack */
+ VM_MODIFY_PC_AND_STACK(1, 1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_POP_2):
+ {
+ /* Pop two items from the stack */
+ VM_MODIFY_PC_AND_STACK(1, 2);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_POP_3):
+ {
+ /* Pop three items from the stack */
+ VM_MODIFY_PC_AND_STACK(1, 3);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_RETURN_INT):
+ {
+ /* Push an integer return value back onto the stack */
+ VM_STK_INTP = return_area->int_value;
+ VM_MODIFY_PC_AND_STACK(1, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_RETURN_LONG):
+ {
+ /* Push a long integer return value back onto the stack */
+ VM_STK_LONGP = return_area->long_value;
+ VM_MODIFY_PC_AND_STACK(1, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_RETURN_FLOAT32):
+ {
+ /* Push a 32-bit float return value back onto the stack */
+ VM_STK_FLOAT32P = return_area->float32_value;
+ VM_MODIFY_PC_AND_STACK(1, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_RETURN_FLOAT64):
+ {
+ /* Push a 64-bit float return value back onto the stack */
+ VM_STK_FLOAT64P = return_area->float64_value;
+ VM_MODIFY_PC_AND_STACK(1, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_RETURN_NFLOAT):
+ {
+ /* Push a native float return value back onto the stack */
+ VM_STK_NFLOATP = return_area->nfloat_value;
+ VM_MODIFY_PC_AND_STACK(1, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_RETURN_SMALL_STRUCT):
+ {
+ /* Push a small structure return value back onto the stack */
+ temparg = VM_NINT_ARG;
+ stacktop -= JIT_NUM_ITEMS_IN_STRUCT(temparg);
+ #if JIT_APPLY_MAX_STRUCT_IN_REG != 0
+ jit_memcpy(stacktop, return_area->struct_value, temparg);
+ #endif
+ VM_MODIFY_PC_AND_STACK(2, 0);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_RETURN_AREA_PTR):
+ {
+ /* Push the address of "return_area" for an external call */
+ VM_STK_PTRP = return_area;
+ VM_MODIFY_PC_AND_STACK(1, -1);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Stack management
+ ******************************************************************/
+
+ VMCASE(JIT_OP_PUSH_CONST_INT):
+ {
+ /* Push an integer constant onto the stack */
+ VM_STK_INTP = (jit_int)VM_NINT_ARG;
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_CONST_LONG):
+ {
+ /* Push a long constant onto the stack */
+ #ifdef JIT_NATIVE_INT64
+ VM_STK_LONGP = (jit_long)VM_NINT_ARG;
+ VM_MODIFY_PC_AND_STACK(2, -1);
+ #else
+ jit_memcpy(stacktop - 1, pc + 1, sizeof(jit_long));
+ VM_MODIFY_PC_AND_STACK
+ (1 + (sizeof(jit_long) / sizeof(void *)), -1);
+ #endif
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_CONST_FLOAT32):
+ {
+ /* Push a 32-bit float constant onto the stack */
+ jit_memcpy(stacktop - 1, pc + 1, sizeof(jit_float32));
+ VM_MODIFY_PC_AND_STACK
+ (1 + (sizeof(jit_float32) / sizeof(void *)), -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_CONST_FLOAT64):
+ {
+ /* Push a 64-bit float constant onto the stack */
+ jit_memcpy(stacktop - 1, pc + 1, sizeof(jit_float64));
+ VM_MODIFY_PC_AND_STACK
+ (1 + (sizeof(jit_float64) / sizeof(void *)), -1);
+ }
+ VMBREAK;
+
+ VMCASE(JIT_OP_PUSH_CONST_NFLOAT):
+ {
+ /* Push a native float constant onto the stack */
+ jit_memcpy(stacktop - 1, pc + 1, sizeof(jit_nfloat));
+ VM_MODIFY_PC_AND_STACK
+ (1 + (sizeof(jit_nfloat) / sizeof(void *)), -1);
+ }
+ VMBREAK;
+
+ /******************************************************************
+ * Opcodes that aren't used by the interpreter. These are replaced
+ * by more specific instructions during function compilation.
+ ******************************************************************/
+
+ VMCASE(JIT_OP_IMPORT):
+ VMCASE(JIT_OP_COPY_LOAD_SBYTE):
+ VMCASE(JIT_OP_COPY_LOAD_UBYTE):
+ VMCASE(JIT_OP_COPY_LOAD_SHORT):
+ VMCASE(JIT_OP_COPY_LOAD_USHORT):
+ VMCASE(JIT_OP_COPY_INT):
+ VMCASE(JIT_OP_COPY_LONG):
+ VMCASE(JIT_OP_COPY_FLOAT32):
+ VMCASE(JIT_OP_COPY_FLOAT64):
+ VMCASE(JIT_OP_COPY_NFLOAT):
+ VMCASE(JIT_OP_COPY_STRUCT):
+ VMCASE(JIT_OP_COPY_STORE_BYTE):
+ VMCASE(JIT_OP_COPY_STORE_SHORT):
+ VMCASE(JIT_OP_ADDRESS_OF):
+ VMCASE(JIT_OP_INCOMING_REG):
+ VMCASE(JIT_OP_INCOMING_FRAME_POSN):
+ VMCASE(JIT_OP_OUTGOING_REG):
+ VMCASE(JIT_OP_RETURN_REG):
+ VMCASE(JIT_OP_PUSH_INT):
+ VMCASE(JIT_OP_PUSH_LONG):
+ VMCASE(JIT_OP_PUSH_FLOAT32):
+ VMCASE(JIT_OP_PUSH_FLOAT64):
+ VMCASE(JIT_OP_PUSH_NFLOAT):
+ VMCASE(JIT_OP_FLUSH_SMALL_STRUCT):
+ VMCASE(JIT_OP_END_MARKER):
+ VMCASE(JIT_OP_ENTER_CATCH):
+ VMCASE(JIT_OP_ENTER_FINALLY):
+ VMCASE(JIT_OP_ENTER_FILTER):
+ VMCASE(JIT_OP_CALL_FILTER_RETURN):
+ VMCASE(JIT_OP_PREPARE_FOR_LEAVE):
+ VMCASE(JIT_OP_PREPARE_FOR_RETURN):
+ {
+ /* Shouldn't happen, but skip the instruction anyway */
+ VM_MODIFY_PC_AND_STACK(1, 0);
+ }
+ VMBREAK;
+
+ }
+ VMSWITCHEND
+
+handle_builtin: ;
+ jit_exception_builtin(builtin_exception);
+}
+
+int jit_function_apply
+ (jit_function_t func, void **args, void *return_area)
+{
+ if(func)
+ {
+ return jit_function_apply_vararg
+ (func, func->signature, args, return_area);
+ }
+ else
+ {
+ return jit_function_apply_vararg(func, 0, args, return_area);
+ }
+}
+
+/* Imported from "jit-rules-interp.c" */
+unsigned int _jit_interp_calculate_arg_size
+ (jit_function_t func, jit_type_t signature);
+
+int jit_function_apply_vararg
+ (jit_function_t func, jit_type_t signature, void **args, void *return_area)
+{
+ struct jit_backtrace call_trace;
+ jit_function_interp_t entry;
+ jit_item interp_return_area;
+ jit_item *arg_buffer;
+ jit_item *temp_arg;
+ jit_type_t type;
+ unsigned int num_params;
+ unsigned int param;
+ jit_jmp_buf jbuf;
+
+ /* Push a "setjmp" context onto the stack, so that we can catch
+ any exceptions that are thrown up to this level and prevent
+ them from propagating further */
+ _jit_unwind_push_setjmp(&jbuf);
+ if(setjmp(jbuf.buf))
+ {
+ _jit_unwind_pop_setjmp();
+ return 1;
+ }
+
+ /* Initialize the backtrace information */
+ _jit_backtrace_push(&call_trace, 0, 0, 0);
+
+ /* Clear the exception context */
+ jit_exception_clear_last();
+
+ /* Bail out if the function is NULL */
+ if(!func)
+ {
+ jit_exception_builtin(JIT_RESULT_NULL_FUNCTION);
+ }
+
+ /* Make sure that the function is compiled */
+ if(func->is_compiled)
+ {
+ entry = (jit_function_interp_t)(func->entry_point);
+ }
+ else
+ {
+ entry = (jit_function_interp_t)
+ _jit_function_compile_on_demand(func);
+ }
+
+ /* Populate the low-level argument buffer */
+ if(!signature)
+ {
+ signature = func->signature;
+ arg_buffer = (jit_item *)alloca(entry->args_size);
+ }
+ else if(signature == func->signature)
+ {
+ arg_buffer = (jit_item *)alloca(entry->args_size);
+ }
+ else
+ {
+ arg_buffer = (jit_item *)alloca
+ (_jit_interp_calculate_arg_size(func, signature));
+ }
+ temp_arg = arg_buffer;
+ if(func->nested_parent)
+ {
+ jit_exception_builtin(JIT_RESULT_CALLED_NESTED);
+ }
+ type = jit_type_get_return(signature);
+ if(jit_type_return_via_pointer(type))
+ {
+ if(!return_area)
+ {
+ return_area = alloca(jit_type_get_size(type));
+ }
+ temp_arg->ptr_value = return_area;
+ ++temp_arg;
+ }
+ num_params = jit_type_num_params(signature);
+ for(param = 0; param < num_params; ++param)
+ {
+ type = jit_type_normalize
+ (jit_type_get_param(signature, param));
+ if(!(args[param]))
+ {
+ jit_exception_builtin(JIT_RESULT_NULL_REFERENCE);
+ }
+ switch(type->kind)
+ {
+ case JIT_TYPE_SBYTE:
+ {
+ temp_arg->int_value = *((jit_sbyte *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_UBYTE:
+ {
+ temp_arg->int_value = *((jit_ubyte *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_SHORT:
+ {
+ temp_arg->int_value = *((jit_short *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_USHORT:
+ {
+ temp_arg->int_value = *((jit_ushort *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_INT:
+ case JIT_TYPE_UINT:
+ {
+ temp_arg->int_value = *((jit_int *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_LONG:
+ case JIT_TYPE_ULONG:
+ {
+ temp_arg->long_value = *((jit_long *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_FLOAT32:
+ {
+ temp_arg->float32_value =
+ *((jit_float32 *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_FLOAT64:
+ {
+ temp_arg->float64_value =
+ *((jit_float64 *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_NFLOAT:
+ {
+ temp_arg->nfloat_value =
+ *((jit_nfloat *)(args[param]));
+ ++temp_arg;
+ }
+ break;
+
+ case JIT_TYPE_STRUCT:
+ case JIT_TYPE_UNION:
+ {
+ jit_memcpy(temp_arg, args[param],
+ jit_type_get_size(type));
+ temp_arg += JIT_NUM_ITEMS_IN_STRUCT
+ (jit_type_get_size(type));
+ }
+ break;
+ }
+ }
+
+ /* Run the function */
+ _jit_run_function(entry, arg_buffer, &interp_return_area);
+
+ /* Copy the return value into place, if it isn't already there */
+ if(return_area)
+ {
+ type = jit_type_normalize(jit_type_get_return(signature));
+ if(type && type != jit_type_void)
+ {
+ switch(type->kind)
+ {
+ case JIT_TYPE_SBYTE:
+ case JIT_TYPE_UBYTE:
+ {
+ *((jit_sbyte *)return_area) =
+ (jit_sbyte)(interp_return_area.int_value);
+ }
+ break;
+
+ case JIT_TYPE_SHORT:
+ case JIT_TYPE_USHORT:
+ {
+ *((jit_short *)return_area) =
+ (jit_short)(interp_return_area.int_value);
+ }
+ break;
+
+ case JIT_TYPE_INT:
+ case JIT_TYPE_UINT:
+ {
+ *((jit_int *)return_area) =
+ interp_return_area.int_value;
+ }
+ break;
+
+ case JIT_TYPE_LONG:
+ case JIT_TYPE_ULONG:
+ {
+ *((jit_long *)return_area) =
+ interp_return_area.long_value;
+ }
+ break;
+
+ case JIT_TYPE_FLOAT32:
+ {
+ *((jit_float32 *)return_area) =
+ interp_return_area.float32_value;
+ }
+ break;
+
+ case JIT_TYPE_FLOAT64:
+ {
+ *((jit_float64 *)return_area) =
+ interp_return_area.float64_value;
+ }
+ break;
+
+ case JIT_TYPE_NFLOAT:
+ {
+ *((jit_nfloat *)return_area) =
+ interp_return_area.nfloat_value;
+ }
+ break;
+
+ case JIT_TYPE_STRUCT:
+ case JIT_TYPE_UNION:
+ {
+ if(!jit_type_return_via_pointer(type))
+ {
+ jit_memcpy(return_area, &interp_return_area,
+ jit_type_get_size(type));
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ /* Pop the "setjmp" context and exit */
+ _jit_unwind_pop_setjmp();
+ return 1;
+}
+
+#endif /* JIT_BACKEND_INTERP */
generated by cgit v1.2.3 (git 2.25.1) at 2025年09月16日 23:02:41 +0000

AltStyle によって変換されたページ (->オリジナル) /