/* * jit-opcode.c - Information about all of the JIT opcodes. * * 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 */ #include "jit-internal.h" #include "jit-rules.h" #define F_(dest,src1,src2) \ (JIT_OPCODE_DEST_##dest | JIT_OPCODE_SRC1_##src1 | JIT_OPCODE_SRC2_##src2) #define O_(dest,src1,src2,oper) \ (JIT_OPCODE_DEST_##dest | JIT_OPCODE_SRC1_##src1 | \ JIT_OPCODE_SRC2_##src2 | JIT_OPCODE_OPER_##oper) #define B_(src1,src2) \ (JIT_OPCODE_IS_BRANCH | JIT_OPCODE_SRC1_##src1 | JIT_OPCODE_SRC2_##src2) #define A_(src1,src2,oper) \ (JIT_OPCODE_IS_BRANCH | JIT_OPCODE_SRC1_##src1 | \ JIT_OPCODE_SRC2_##src2 | JIT_OPCODE_OPER_##oper) #if defined(JIT_BACKEND_INTERP) #define NINT_ARG JIT_OPCODE_NINT_ARG #define NINT_ARG_TWO JIT_OPCODE_NINT_ARG_TWO #define INDIRECT_ARGS JIT_OPCODE_CALL_INDIRECT_ARGS #else #define NINT_ARG 0 #define NINT_ARG_TWO 0 #define INDIRECT_ARGS 0 #endif jit_opcode_info_t const jit_opcodes[JIT_OP_NUM_OPCODES] = { /* * Simple opcodes. */ {"nop", F_(EMPTY, EMPTY, EMPTY)}, /* * Conversion opcodes. */ {"trunc_sbyte", F_(INT, INT, EMPTY)}, {"trunc_ubyte", F_(INT, INT, EMPTY)}, {"trunc_short", F_(INT, INT, EMPTY)}, {"trunc_ushort", F_(INT, INT, EMPTY)}, {"trunc_int", F_(INT, INT, EMPTY)}, {"trunc_uint", F_(INT, INT, EMPTY)}, {"check_sbyte", F_(INT, INT, EMPTY)}, {"check_ubyte", F_(INT, INT, EMPTY)}, {"check_short", F_(INT, INT, EMPTY)}, {"check_ushort", F_(INT, INT, EMPTY)}, {"check_int", F_(INT, INT, EMPTY)}, {"check_uint", F_(INT, INT, EMPTY)}, {"low_word", F_(INT, LONG, EMPTY)}, {"expand_int", F_(LONG, INT, EMPTY)}, {"expand_uint", F_(LONG, INT, EMPTY)}, {"check_low_word", F_(INT, LONG, EMPTY)}, {"check_signed_low_word", F_(INT, LONG, EMPTY)}, {"check_long", F_(LONG, LONG, EMPTY)}, {"check_ulong", F_(LONG, LONG, EMPTY)}, {"nfloat_to_int", F_(INT, NFLOAT, EMPTY)}, {"nfloat_to_uint", F_(INT, NFLOAT, EMPTY)}, {"nfloat_to_long", F_(LONG, NFLOAT, EMPTY)}, {"nfloat_to_ulong", F_(LONG, NFLOAT, EMPTY)}, {"check_nfloat_to_int", F_(INT, NFLOAT, EMPTY)}, {"check_nfloat_to_uint", F_(INT, NFLOAT, EMPTY)}, {"check_nfloat_to_long", F_(LONG, NFLOAT, EMPTY)}, {"check_nfloat_to_ulong", F_(LONG, NFLOAT, EMPTY)}, {"int_to_nfloat", F_(NFLOAT, INT, EMPTY)}, {"uint_to_nfloat", F_(NFLOAT, INT, EMPTY)}, {"long_to_nfloat", F_(NFLOAT, LONG, EMPTY)}, {"ulong_to_nfloat", F_(NFLOAT, LONG, EMPTY)}, {"nfloat_to_float32", F_(FLOAT32, NFLOAT, EMPTY)}, {"nfloat_to_float64", F_(FLOAT64, NFLOAT, EMPTY)}, {"float32_to_nfloat", F_(NFLOAT, FLOAT32, EMPTY)}, {"float64_to_nfloat", F_(NFLOAT, FLOAT64, EMPTY)}, /* * Arithmetic opcodes. */ {"iadd", O_(INT, INT, INT, ADD)}, {"iadd_ovf", F_(INT, INT, INT)}, {"iadd_ovf_un", F_(INT, INT, INT)}, {"isub", O_(INT, INT, INT, SUB)}, {"isub_ovf", F_(INT, INT, INT)}, {"isub_ovf_un", F_(INT, INT, INT)}, {"imul", O_(INT, INT, INT, MUL)}, {"imul_ovf", F_(INT, INT, INT)}, {"imul_ovf_un", F_(INT, INT, INT)}, {"idiv", O_(INT, INT, INT, DIV)}, {"idiv_un", F_(INT, INT, INT)}, {"irem", O_(INT, INT, INT, REM)}, {"irem_un", F_(INT, INT, INT)}, {"ineg", O_(INT, INT, EMPTY, NEG)}, {"ladd", O_(LONG, LONG, LONG, ADD)}, {"ladd_ovf", F_(LONG, LONG, LONG)}, {"ladd_ovf_un", F_(LONG, LONG, LONG)}, {"lsub", O_(LONG, LONG, LONG, SUB)}, {"lsub_ovf", F_(LONG, LONG, LONG)}, {"lsub_ovf_un", F_(LONG, LONG, LONG)}, {"lmul", O_(LONG, LONG, LONG, MUL)}, {"lmul_ovf", F_(LONG, LONG, LONG)}, {"lmul_ovf_un", F_(LONG, LONG, LONG)}, {"ldiv", O_(LONG, LONG, LONG, DIV)}, {"ldiv_un", F_(LONG, LONG, LONG)}, {"lrem", O_(LONG, LONG, LONG, REM)}, {"lrem_un", F_(LONG, LONG, LONG)}, {"lneg", O_(LONG, LONG, EMPTY, NEG)}, {"fadd", O_(FLOAT32, FLOAT32, FLOAT32, ADD)}, {"fsub", O_(FLOAT32, FLOAT32, FLOAT32, SUB)}, {"fmul", O_(FLOAT32, FLOAT32, FLOAT32, MUL)}, {"fdiv", O_(FLOAT32, FLOAT32, FLOAT32, DIV)}, {"frem", O_(FLOAT32, FLOAT32, FLOAT32, REM)}, {"frem_ieee", F_(FLOAT32, FLOAT32, FLOAT32)}, {"fneg", O_(FLOAT32, FLOAT32, EMPTY, NEG)}, {"dadd", O_(FLOAT64, FLOAT64, FLOAT64, ADD)}, {"dsub", O_(FLOAT64, FLOAT64, FLOAT64, SUB)}, {"dmul", O_(FLOAT64, FLOAT64, FLOAT64, MUL)}, {"ddiv", O_(FLOAT64, FLOAT64, FLOAT64, DIV)}, {"drem", O_(FLOAT64, FLOAT64, FLOAT64, REM)}, {"drem_ieee", F_(FLOAT64, FLOAT64, FLOAT64)}, {"dneg", O_(FLOAT64, FLOAT64, EMPTY, NEG)}, {"nfadd", O_(NFLOAT, NFLOAT, NFLOAT, ADD)}, {"nfsub", O_(NFLOAT, NFLOAT, NFLOAT, SUB)}, {"nfmul", O_(NFLOAT, NFLOAT, NFLOAT, MUL)}, {"nfdiv", O_(NFLOAT, NFLOAT, NFLOAT, DIV)}, {"nfrem", O_(NFLOAT, NFLOAT, NFLOAT, REM)}, {"nfrem_ieee", F_(NFLOAT, NFLOAT, NFLOAT)}, {"nfneg", O_(NFLOAT, NFLOAT, EMPTY, NEG)}, /* * Bitwise opcodes. */ {"iand", O_(INT, INT, INT, AND)}, {"ior", O_(INT, INT, INT, OR)}, {"ixor", O_(INT, INT, INT, XOR)}, {"inot", O_(INT, INT, EMPTY, NOT)}, {"ishl", O_(INT, INT, INT, SHL)}, {"ishr", O_(INT, INT, INT, SHR)}, {"ishr_un", O_(INT, INT, INT, SHR_UN)}, {"land", O_(LONG, LONG, LONG, AND)}, {"lor", O_(LONG, LONG, LONG, OR)}, {"lxor", O_(LONG, LONG, LONG, XOR)}, {"lnot", O_(LONG, LONG, EMPTY, NOT)}, {"lshl", O_(LONG, LONG, INT, SHL)}, {"lshr", O_(LONG, LONG, INT, SHR)}, {"lshr_un", O_(LONG, LONG, INT, SHR_UN)}, /* * Branch opcodes. */ {"br", B_(EMPTY, EMPTY)}, {"br_ifalse", B_(INT, EMPTY)}, {"br_itrue", B_(INT, EMPTY)}, {"br_ieq", A_(INT, INT, EQ)}, {"br_ine", A_(INT, INT, NE)}, {"br_ilt", A_(INT, INT, LT)}, {"br_ilt_un", B_(INT, INT)}, {"br_ile", A_(INT, INT, LE)}, {"br_ile_un", B_(INT, INT)}, {"br_igt", A_(INT, INT, GT)}, {"br_igt_un", B_(INT, INT)}, {"br_ige", A_(INT, INT, GE)}, {"br_ige_un", B_(INT, INT)}, {"br_lfalse", B_(LONG, EMPTY)}, {"br_ltrue", B_(LONG, EMPTY)}, {"br_leq", A_(LONG, LONG, EQ)}, {"br_lne", A_(LONG, LONG, NE)}, {"br_llt", A_(LONG, LONG, LT)}, {"br_llt_un", B_(LONG, LONG)}, {"br_lle", A_(LONG, LONG, LE)}, {"br_lle_un", B_(LONG, LONG)}, {"br_lgt", A_(LONG, LONG, GT)}, {"br_lgt_un", B_(LONG, LONG)}, {"br_lge", A_(LONG, LONG, GE)}, {"br_lge_un", B_(LONG, LONG)}, {"br_feq", A_(FLOAT32, FLOAT32, EQ)}, {"br_fne", A_(FLOAT32, FLOAT32, NE)}, {"br_flt", A_(FLOAT32, FLOAT32, LT)}, {"br_fle", A_(FLOAT32, FLOAT32, LE)}, {"br_fgt", A_(FLOAT32, FLOAT32, GT)}, {"br_fge", A_(FLOAT32, FLOAT32, GE)}, {"br_feq_inv", B_(FLOAT32, FLOAT32)}, {"br_fne_inv", B_(FLOAT32, FLOAT32)}, {"br_flt_inv", B_(FLOAT32, FLOAT32)}, {"br_fle_inv", B_(FLOAT32, FLOAT32)}, {"br_fgt_inv", B_(FLOAT32, FLOAT32)}, {"br_fge_inv", B_(FLOAT32, FLOAT32)}, {"br_deq", A_(FLOAT64, FLOAT64, EQ)}, {"br_dne", A_(FLOAT64, FLOAT64, NE)}, {"br_dlt", A_(FLOAT64, FLOAT64, LT)}, {"br_dle", A_(FLOAT64, FLOAT64, LE)}, {"br_dgt", A_(FLOAT64, FLOAT64, GT)}, {"br_dge", A_(FLOAT64, FLOAT64, GE)}, {"br_deq_inv", B_(FLOAT64, FLOAT64)}, {"br_dne_inv", B_(FLOAT64, FLOAT64)}, {"br_dlt_inv", B_(FLOAT64, FLOAT64)}, {"br_dle_inv", B_(FLOAT64, FLOAT64)}, {"br_dgt_inv", B_(FLOAT64, FLOAT64)}, {"br_dge_inv", B_(FLOAT64, FLOAT64)}, {"br_nfeq", A_(NFLOAT, NFLOAT, EQ)}, {"br_nfne", A_(NFLOAT, NFLOAT, NE)}, {"br_nflt", A_(NFLOAT, NFLOAT, LT)}, {"br_nfle", A_(NFLOAT, NFLOAT, LE)}, {"br_nfgt", A_(NFLOAT, NFLOAT, GT)}, {"br_nfge", A_(NFLOAT, NFLOAT, GE)}, {"br_nfeq_inv", B_(NFLOAT, NFLOAT)}, {"br_nfne_inv", B_(NFLOAT, NFLOAT)}, {"br_nflt_inv", B_(NFLOAT, NFLOAT)}, {"br_nfle_inv", B_(NFLOAT, NFLOAT)}, {"br_nfgt_inv", B_(NFLOAT, NFLOAT)}, {"br_nfge_inv", B_(NFLOAT, NFLOAT)}, /* * Comparison opcodes. */ {"icmp", F_(INT, INT, INT)}, {"icmp_un", F_(INT, INT, INT)}, {"lcmp", F_(INT, LONG, LONG)}, {"lcmp_un", F_(INT, LONG, LONG)}, {"fcmpl", F_(INT, FLOAT32, FLOAT32)}, {"fcmpg", F_(INT, FLOAT32, FLOAT32)}, {"dcmpl", F_(INT, FLOAT64, FLOAT64)}, {"dcmpg", F_(INT, FLOAT64, FLOAT64)}, {"nfcmpl", F_(INT, NFLOAT, NFLOAT)}, {"nfcmpg", F_(INT, NFLOAT, NFLOAT)}, {"ieq", O_(INT, INT, INT, EQ)}, {"ine", O_(INT, INT, INT, NE)}, {"ilt", O_(INT, INT, INT, LT)}, {"ilt_un", F_(INT, INT, INT)}, {"ile", O_(INT, INT, INT, LE)}, {"ile_un", F_(INT, INT, INT)}, {"igt", O_(INT, INT, INT, GT)}, {"igt_un", F_(INT, INT, INT)}, {"ige", O_(INT, INT, INT, GE)}, {"ige_un", F_(INT, INT, INT)}, {"leq", O_(INT, LONG, LONG, EQ)}, {"lne", O_(INT, LONG, LONG, NE)}, {"llt", O_(INT, LONG, LONG, LT)}, {"llt_un", F_(INT, LONG, LONG)}, {"lle", O_(INT, LONG, LONG, LE)}, {"lle_un", F_(INT, LONG, LONG)}, {"lgt", O_(INT, LONG, LONG, GT)}, {"lgt_un", F_(INT, LONG, LONG)}, {"lge", O_(INT, LONG, LONG, GE)}, {"lge_un", F_(INT, LONG, LONG)}, {"feq", O_(INT, FLOAT32, FLOAT32, EQ)}, {"fne", O_(INT, FLOAT32, FLOAT32, NE)}, {"flt", O_(INT, FLOAT32, FLOAT32, LT)}, {"fle", O_(INT, FLOAT32, FLOAT32, LE)}, {"fgt", O_(INT, FLOAT32, FLOAT32, GT)}, {"fge", O_(INT, FLOAT32, FLOAT32, GE)}, {"feq_inv", F_(INT, FLOAT32, FLOAT32)}, {"fne_inv", F_(INT, FLOAT32, FLOAT32)}, {"flt_inv", F_(INT, FLOAT32, FLOAT32)}, {"fle_inv", F_(INT, FLOAT32, FLOAT32)}, {"fgt_inv", F_(INT, FLOAT32, FLOAT32)}, {"fge_inv", F_(INT, FLOAT32, FLOAT32)}, {"deq", O_(INT, FLOAT64, FLOAT64, EQ)}, {"dne", O_(INT, FLOAT64, FLOAT64, NE)}, {"dlt", O_(INT, FLOAT64, FLOAT64, LT)}, {"dle", O_(INT, FLOAT64, FLOAT64, LE)}, {"dgt", O_(INT, FLOAT64, FLOAT64, GT)}, {"dge", O_(INT, FLOAT64, FLOAT64, GE)}, {"deq_inv", F_(INT, FLOAT64, FLOAT64)}, {"dne_inv", F_(INT, FLOAT64, FLOAT64)}, {"dlt_inv", F_(INT, FLOAT64, FLOAT64)}, {"dle_inv", F_(INT, FLOAT64, FLOAT64)}, {"dgt_inv", F_(INT, FLOAT64, FLOAT64)}, {"dge_inv", F_(INT, FLOAT64, FLOAT64)}, {"nfeq", O_(INT, NFLOAT, NFLOAT, EQ)}, {"nfne", O_(INT, NFLOAT, NFLOAT, NE)}, {"nflt", O_(INT, NFLOAT, NFLOAT, LT)}, {"nfle", O_(INT, NFLOAT, NFLOAT, LE)}, {"nfgt", O_(INT, NFLOAT, NFLOAT, GT)}, {"nfge", O_(INT, NFLOAT, NFLOAT, GE)}, {"nfeq_inv", F_(INT, NFLOAT, NFLOAT)}, {"nfne_inv", F_(INT, NFLOAT, NFLOAT)}, {"nflt_inv", F_(INT, NFLOAT, NFLOAT)}, {"nfle_inv", F_(INT, NFLOAT, NFLOAT)}, {"nfgt_inv", F_(INT, NFLOAT, NFLOAT)}, {"nfge_inv", F_(INT, NFLOAT, NFLOAT)}, {"is_fnan", F_(INT, FLOAT32, EMPTY)}, {"is_finf", F_(INT, FLOAT32, EMPTY)}, {"is_ffinite", F_(INT, FLOAT32, EMPTY)}, {"is_dnan", F_(INT, FLOAT64, EMPTY)}, {"is_dinf", F_(INT, FLOAT64, EMPTY)}, {"is_dfinite", F_(INT, FLOAT64, EMPTY)}, {"is_nfnan", F_(INT, NFLOAT, EMPTY)}, {"is_nfinf", F_(INT, NFLOAT, EMPTY)}, {"is_nffinite", F_(INT, NFLOAT, EMPTY)}, /* * Mathematical functions. */ {"facos", F_(FLOAT32, FLOAT32, EMPTY)}, {"fasin", F_(FLOAT32, FLOAT32, EMPTY)}, {"fatan", F_(FLOAT32, FLOAT32, EMPTY)}, {"fatan2", F_(FLOAT32, FLOAT32, FLOAT32)}, {"fceil", F_(FLOAT32, FLOAT32, EMPTY)}, {"fcos", F_(FLOAT32, FLOAT32, EMPTY)}, {"fcosh", F_(FLOAT32, FLOAT32, EMPTY)}, {"fexp", F_(FLOAT32, FLOAT32, EMPTY)}, {"ffloor", F_(FLOAT32, FLOAT32, EMPTY)}, {"flog", F_(FLOAT32, FLOAT32, EMPTY)}, {"flog10", F_(FLOAT32, FLOAT32, EMPTY)}, {"fpow", F_(FLOAT32, FLOAT32, FLOAT32)}, {"frint", F_(FLOAT32, FLOAT32, EMPTY)}, {"fround", F_(FLOAT32, FLOAT32, EMPTY)}, {"fsin", F_(FLOAT32, FLOAT32, EMPTY)}, {"fsinh", F_(FLOAT32, FLOAT32, EMPTY)}, {"fsqrt", F_(FLOAT32, FLOAT32, EMPTY)}, {"ftan", F_(FLOAT32, FLOAT32, EMPTY)}, {"ftanh", F_(FLOAT32, FLOAT32, EMPTY)}, {"dacos", F_(FLOAT64, FLOAT64, EMPTY)}, {"dasin", F_(FLOAT64, FLOAT64, EMPTY)}, {"datan", F_(FLOAT64, FLOAT64, EMPTY)}, {"datan2", F_(FLOAT64, FLOAT64, FLOAT64)}, {"dceil", F_(FLOAT64, FLOAT64, EMPTY)}, {"dcos", F_(FLOAT64, FLOAT64, EMPTY)}, {"dcosh", F_(FLOAT64, FLOAT64, EMPTY)}, {"dexp", F_(FLOAT64, FLOAT64, EMPTY)}, {"dfloor", F_(FLOAT64, FLOAT64, EMPTY)}, {"dlog", F_(FLOAT64, FLOAT64, EMPTY)}, {"dlog10", F_(FLOAT64, FLOAT64, EMPTY)}, {"dpow", F_(FLOAT64, FLOAT64, FLOAT64)}, {"drint", F_(FLOAT64, FLOAT64, EMPTY)}, {"dround", F_(FLOAT64, FLOAT64, EMPTY)}, {"dsin", F_(FLOAT64, FLOAT64, EMPTY)}, {"dsinh", F_(FLOAT64, FLOAT64, EMPTY)}, {"dsqrt", F_(FLOAT64, FLOAT64, EMPTY)}, {"dtan", F_(FLOAT64, FLOAT64, EMPTY)}, {"dtanh", F_(FLOAT64, FLOAT64, EMPTY)}, {"nfacos", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfasin", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfatan", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfatan2", F_(NFLOAT, NFLOAT, NFLOAT)}, {"nfceil", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfcos", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfcosh", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfexp", F_(NFLOAT, NFLOAT, EMPTY)}, {"nffloor", F_(NFLOAT, NFLOAT, EMPTY)}, {"nflog", F_(NFLOAT, NFLOAT, EMPTY)}, {"nflog10", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfpow", F_(NFLOAT, NFLOAT, NFLOAT)}, {"nfrint", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfround", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfsin", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfsinh", F_(NFLOAT, NFLOAT, EMPTY)}, {"nfsqrt", F_(NFLOAT, NFLOAT, EMPTY)}, {"nftan", F_(NFLOAT, NFLOAT, EMPTY)}, {"nftanh", F_(NFLOAT, NFLOAT, EMPTY)}, /* * Absolute, minimum, maximum, and sign. */ {"iabs", F_(INT, INT, EMPTY)}, {"labs", F_(LONG, LONG, EMPTY)}, {"fabs", F_(FLOAT32, FLOAT32, EMPTY)}, {"dabs", F_(FLOAT64, FLOAT64, EMPTY)}, {"nfabs", F_(NFLOAT, NFLOAT, EMPTY)}, {"imin", F_(INT, INT, INT)}, {"imin_un", F_(INT, INT, INT)}, {"lmin", F_(LONG, LONG, LONG)}, {"lmin_un", F_(LONG, LONG, LONG)}, {"fmin", F_(FLOAT32, FLOAT32, FLOAT32)}, {"dmin", F_(FLOAT64, FLOAT64, FLOAT64)}, {"nfmin", F_(NFLOAT, NFLOAT, NFLOAT)}, {"imax", F_(INT, INT, INT)}, {"imax_un", F_(INT, INT, INT)}, {"lmax", F_(LONG, LONG, LONG)}, {"lmax_un", F_(LONG, LONG, LONG)}, {"fmax", F_(FLOAT32, FLOAT32, FLOAT32)}, {"dmax", F_(FLOAT64, FLOAT64, FLOAT64)}, {"nfmax", F_(NFLOAT, NFLOAT, NFLOAT)}, {"isign", F_(INT, INT, EMPTY)}, {"lsign", F_(INT, LONG, EMPTY)}, {"fsign", F_(INT, FLOAT32, EMPTY)}, {"dsign", F_(INT, FLOAT64, EMPTY)}, {"nfsign", F_(INT, NFLOAT, EMPTY)}, /* * Pointer check opcodes. */ {"check_null", F_(EMPTY, PTR, EMPTY)}, /* * Function calls. */ {"call", JIT_OPCODE_IS_CALL}, {"call_tail", JIT_OPCODE_IS_CALL}, {"call_indirect", F_(EMPTY, PTR, EMPTY) | INDIRECT_ARGS}, {"call_indirect_tail", F_(EMPTY, PTR, EMPTY) | INDIRECT_ARGS}, {"call_vtable_ptr", F_(EMPTY, PTR, EMPTY)}, {"call_vtable_ptr_tail", F_(EMPTY, PTR, EMPTY)}, {"call_external", JIT_OPCODE_IS_CALL_EXTERNAL}, {"call_external_tail", JIT_OPCODE_IS_CALL_EXTERNAL}, {"return", F_(EMPTY, EMPTY, EMPTY)}, {"return_int", F_(EMPTY, INT, EMPTY)}, {"return_long", F_(EMPTY, LONG, EMPTY)}, {"return_float32", F_(EMPTY, FLOAT32, EMPTY)}, {"return_float64", F_(EMPTY, FLOAT64, EMPTY)}, {"return_nfloat", F_(EMPTY, NFLOAT, EMPTY)}, {"return_small_struct", F_(EMPTY, PTR, PTR)}, {"setup_for_nested", F_(EMPTY, INT, EMPTY)}, {"setup_for_sibling", F_(EMPTY, INT, INT) | NINT_ARG}, {"import", F_(PTR, ANY, INT)}, /* * Exception handling. */ {"throw", F_(EMPTY, PTR, EMPTY)}, {"rethrow", F_(EMPTY, PTR, EMPTY)}, {"load_pc", F_(PTR, EMPTY, EMPTY)}, {"load_exception_pc", F_(PTR, EMPTY, EMPTY)}, {"enter_finally", F_(EMPTY, EMPTY, EMPTY)}, {"leave_finally", F_(EMPTY, EMPTY, EMPTY)}, {"call_finally", B_(EMPTY, EMPTY)}, {"enter_filter", F_(ANY, EMPTY, EMPTY)}, {"leave_filter", F_(EMPTY, ANY, EMPTY)}, {"call_filter", B_(ANY, EMPTY)}, {"call_filter_return", F_(ANY, EMPTY, EMPTY)}, {"address_of_label", JIT_OPCODE_IS_ADDROF_LABEL}, /* * Data manipulation. */ {"copy_load_sbyte", F_(INT, INT, EMPTY)}, {"copy_load_ubyte", F_(INT, INT, EMPTY)}, {"copy_load_short", F_(INT, INT, EMPTY)}, {"copy_load_ushort", F_(INT, INT, EMPTY)}, {"copy_int", O_(INT, INT, EMPTY, COPY)}, {"copy_long", O_(LONG, LONG, EMPTY, COPY)}, {"copy_float32", O_(FLOAT32, FLOAT32, EMPTY, COPY)}, {"copy_float64", O_(FLOAT64, FLOAT64, EMPTY, COPY)}, {"copy_nfloat", O_(NFLOAT, NFLOAT, EMPTY, COPY)}, {"copy_struct", O_(PTR, PTR, EMPTY, COPY)}, {"copy_store_byte", F_(INT, INT, EMPTY)}, {"copy_store_short", F_(INT, INT, EMPTY)}, {"address_of", O_(PTR, ANY, EMPTY, ADDRESS_OF)}, /* * Incoming registers, outgoing registers, and stack pushes. */ {"incoming_reg", JIT_OPCODE_IS_REG}, {"incoming_frame_posn", F_(EMPTY, ANY, INT)}, {"outgoing_reg", JIT_OPCODE_IS_REG}, {"outgoing_frame_posn", F_(EMPTY, ANY, INT)}, {"return_reg", JIT_OPCODE_IS_REG}, {"push_int", F_(EMPTY, INT, EMPTY)}, {"push_long", F_(EMPTY, LONG, EMPTY)}, {"push_float32", F_(EMPTY, FLOAT32, EMPTY)}, {"push_float64", F_(EMPTY, FLOAT64, EMPTY)}, {"push_nfloat", F_(EMPTY, NFLOAT, EMPTY)}, {"push_struct", F_(EMPTY, ANY, PTR) | NINT_ARG}, {"pop_stack", F_(EMPTY, INT, EMPTY) | NINT_ARG}, {"flush_small_struct", F_(EMPTY, ANY, EMPTY)}, {"set_param_int", F_(EMPTY, INT, PTR)}, {"set_param_long", F_(EMPTY, LONG, PTR)}, {"set_param_float32", F_(EMPTY, FLOAT32, PTR)}, {"set_param_float64", F_(EMPTY, FLOAT64, PTR)}, {"set_param_nfloat", F_(EMPTY, NFLOAT, PTR)}, {"set_param_struct", F_(PTR, PTR, PTR)}, {"push_return_area_ptr", F_(EMPTY, EMPTY, EMPTY)}, /* * Pointer-relative loads and stores. */ {"load_relative_sbyte", F_(INT, PTR, INT) | NINT_ARG}, {"load_relative_ubyte", F_(INT, PTR, INT) | NINT_ARG}, {"load_relative_short", F_(INT, PTR, INT) | NINT_ARG}, {"load_relative_ushort", F_(INT, PTR, INT) | NINT_ARG}, {"load_relative_int", F_(INT, PTR, INT) | NINT_ARG}, {"load_relative_long", F_(LONG, PTR, INT) | NINT_ARG}, {"load_relative_float32", F_(FLOAT32, PTR, INT) | NINT_ARG}, {"load_relative_float64", F_(FLOAT64, PTR, INT) | NINT_ARG}, {"load_relative_nfloat", F_(NFLOAT, PTR, INT) | NINT_ARG}, {"load_relative_struct", F_(ANY, PTR, INT) | NINT_ARG_TWO}, {"store_relative_byte", F_(PTR, INT, INT) | NINT_ARG}, {"store_relative_short", F_(PTR, INT, INT) | NINT_ARG}, {"store_relative_int", F_(PTR, INT, INT) | NINT_ARG}, {"store_relative_long", F_(PTR, LONG, INT) | NINT_ARG}, {"store_relative_float32", F_(PTR, FLOAT32, INT) | NINT_ARG}, {"store_relative_float64", F_(PTR, FLOAT64, INT) | NINT_ARG}, {"store_relative_nfloat", F_(PTR, NFLOAT, INT) | NINT_ARG}, {"store_relative_struct", F_(PTR, ANY, INT) | NINT_ARG_TWO}, {"add_relative", F_(PTR, PTR, INT) | NINT_ARG}, /* * Array element loads and stores. */ {"load_element_sbyte", F_(INT, PTR, INT)}, {"load_element_ubyte", F_(INT, PTR, INT)}, {"load_element_short", F_(INT, PTR, INT)}, {"load_element_ushort", F_(INT, PTR, INT)}, {"load_element_int", F_(INT, PTR, INT)}, {"load_element_long", F_(LONG, PTR, INT)}, {"load_element_float32", F_(FLOAT32, PTR, INT)}, {"load_element_float64", F_(FLOAT64, PTR, INT)}, {"load_element_nfloat", F_(NFLOAT, PTR, INT)}, {"store_element_byte", F_(PTR, INT, INT)}, {"store_element_short", F_(PTR, INT, INT)}, {"store_element_int", F_(PTR, INT, INT)}, {"store_element_long", F_(PTR, INT, LONG)}, {"store_element_float32", F_(PTR, INT, FLOAT32)}, {"store_element_float64", F_(PTR, INT, FLOAT64)}, {"store_element_nfloat", F_(PTR, INT, NFLOAT)}, /* * Block operations. */ {"memcpy", F_(PTR, PTR, PTR)}, {"memmove", F_(PTR, PTR, PTR)}, {"memset", F_(PTR, INT, PTR)}, /* * Allocate memory from the stack. */ {"alloca", F_(PTR, PTR, EMPTY)}, /* * Debugging support. */ {"mark_offset", F_(EMPTY, INT, EMPTY)}, {"mark_breakpoint", F_(EMPTY, PTR, PTR)}, /* * Switch statement support. */ {"jump_table", F_(PTR, PTR, INT)}, }; #if defined(JIT_BACKEND_INTERP) jit_opcode_info_t const _jit_interp_opcodes[JIT_OP_NUM_INTERP_OPCODES] = { /* * Argument variable access opcodes. */ {"ldarg_sbyte", JIT_OPCODE_NINT_ARG}, {"ldarg_ubyte", JIT_OPCODE_NINT_ARG}, {"ldarg_short", JIT_OPCODE_NINT_ARG}, {"ldarg_ushort", JIT_OPCODE_NINT_ARG}, {"ldarg_int", JIT_OPCODE_NINT_ARG}, {"ldarg_long", JIT_OPCODE_NINT_ARG}, {"ldarg_float32", JIT_OPCODE_NINT_ARG}, {"ldarg_float64", JIT_OPCODE_NINT_ARG}, {"ldarg_nfloat", JIT_OPCODE_NINT_ARG}, {"ldarg_struct", JIT_OPCODE_NINT_ARG_TWO}, {"ldarga", JIT_OPCODE_NINT_ARG}, {"starg_byte", JIT_OPCODE_NINT_ARG}, {"starg_short", JIT_OPCODE_NINT_ARG}, {"starg_int", JIT_OPCODE_NINT_ARG}, {"starg_long", JIT_OPCODE_NINT_ARG}, {"starg_float32", JIT_OPCODE_NINT_ARG}, {"starg_float64", JIT_OPCODE_NINT_ARG}, {"starg_nfloat", JIT_OPCODE_NINT_ARG}, {"starg_struct", JIT_OPCODE_NINT_ARG_TWO}, /* * Local variable frame access opcodes. */ {"ldloc_sbyte", JIT_OPCODE_NINT_ARG}, {"ldloc_ubyte", JIT_OPCODE_NINT_ARG}, {"ldloc_short", JIT_OPCODE_NINT_ARG}, {"ldloc_ushort", JIT_OPCODE_NINT_ARG}, {"ldloc_int", JIT_OPCODE_NINT_ARG}, {"ldloc_long", JIT_OPCODE_NINT_ARG}, {"ldloc_float32", JIT_OPCODE_NINT_ARG}, {"ldloc_float64", JIT_OPCODE_NINT_ARG}, {"ldloc_nfloat", JIT_OPCODE_NINT_ARG}, {"ldloc_struct", JIT_OPCODE_NINT_ARG_TWO}, {"ldloca", JIT_OPCODE_NINT_ARG}, {"stloc_byte", JIT_OPCODE_NINT_ARG}, {"stloc_short", JIT_OPCODE_NINT_ARG}, {"stloc_int", JIT_OPCODE_NINT_ARG}, {"stloc_long", JIT_OPCODE_NINT_ARG}, {"stloc_float32", JIT_OPCODE_NINT_ARG}, {"stloc_float64", JIT_OPCODE_NINT_ARG}, {"stloc_nfloat", JIT_OPCODE_NINT_ARG}, {"stloc_struct", JIT_OPCODE_NINT_ARG_TWO}, /* * Pointer check opcodes (interpreter only). */ {"check_null_n", JIT_OPCODE_NINT_ARG}, /* * Stack management. */ {"pop", 0}, {"pop_2", 0}, {"pop_3", 0}, {"push_return_int", 0}, {"push_return_long", 0}, {"push_return_float32", 0}, {"push_return_float64", 0}, {"push_return_nfloat", 0}, {"push_return_small_struct", JIT_OPCODE_NINT_ARG}, /* * Nested function call handling. */ {"import_local", JIT_OPCODE_NINT_ARG_TWO}, {"import_arg", JIT_OPCODE_NINT_ARG_TWO}, /* * Push constant values onto the stack. */ {"push_const_int", JIT_OPCODE_NINT_ARG}, {"push_const_long", JIT_OPCODE_CONST_LONG}, {"push_const_float32", JIT_OPCODE_CONST_FLOAT32}, {"push_const_float64", JIT_OPCODE_CONST_FLOAT64}, {"push_const_nfloat", JIT_OPCODE_CONST_NFLOAT}, /* * Marker opcode for the end of a function. */ {"end_marker", 0}, }; #endif /* JIT_BACKEND_INTERP */