]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
Add support for applying an opcode to one or two constant values.
authorKlaus Treichel <ktreichel@web.de>
Tue, 21 Sep 2010 17:42:01 +0000 (19:42 +0200)
committerKlaus Treichel <ktreichel@web.de>
Tue, 21 Sep 2010 17:42:01 +0000 (19:42 +0200)
ChangeLog
config/jit-opcodes.ops
jit/Makefile.am
jit/jit-internal.h
jit/jit-opcode-apply.c [new file with mode: 0644]
tools/gen-ops-parser.y
tools/gen-ops-scanner.l

index e051067fe2930bb8d7c686f629a97b4e1f8b6bc3..45765e272b6c53fb221f391a333d25faa42d8d78 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2010-09-21  Klaus Treichel  <ktreichel@web.de>
+
+       * config/jit-opcodes.ops: Add definitions for the opcode's
+       intrinsics.
+
+       * jit/Makefile.am: Add jit-opcode-apply.c to the sources.
+
+       * jit/jit-internal.h (enum _jit_intrinsic_signature): Declare the
+       various intrinsic signatures.
+       (struct _jit_intrinsic_info): Declare structure to hold the intrinsic
+       information for an opcode.
+
+       * jit/jit-opcode-apply.c: Add support for constant folding.
+
+       * tools/gen-ops-parset.y, tools/gen-ops-scanner.l: Add support for
+       generating the opcode intrinsic table.
+
 2010-09-12  Klaus Treichel  <ktreichel@web.de>
 
        * config/jit-opcodes.ops: Remove the *eq_inv and *ne_inv float
index 527b37498dadface61a1f1b64e135495c230ddce..d54e62831253d43438868c2c3cddcc083bc748b9 100644 (file)
@@ -68,362 +68,674 @@ extern    "C" {
 
 %]
 
+%option gen_intrinsic_table = yes
+%option intrinsic_table_decl = "_jit_intrinsic_info_t const _jit_intrinsics[JIT_OP_NUM_OPCODES]"
+
 opcodes(JIT_OP_, "jit_opcode_info_t const jit_opcodes[JIT_OP_NUM_OPCODES]")
 {
        op_def("nop") { }
        /*
         * Conversion opcodes
         */
-       op_def("trunc_sbyte") { op_values(int, int) }
-       op_def("trunc_ubyte") { op_values(int, int) }
-       op_def("trunc_short") { op_values(int, int) }
-       op_def("trunc_ushort") { op_values(int, int) }
-       op_def("trunc_int") { op_values(int, int) }
-       op_def("trunc_uint") { op_values(int, int) }
+       op_def("trunc_sbyte") { op_values(int, int),
+                               op_intrinsic(conv) }
+       op_def("trunc_ubyte") { op_values(int, int),
+                               op_intrinsic(conv) }
+       op_def("trunc_short") { op_values(int, int),
+                               op_intrinsic(conv) }
+       op_def("trunc_ushort") { op_values(int, int),
+                                op_intrinsic(conv) }
+       op_def("trunc_int") { op_values(int, int),
+                             op_intrinsic(conv) }
+       op_def("trunc_uint") { op_values(int, int),
+                              op_intrinsic(conv) }
        op_def("check_sbyte") { op_values(int, int) }
        op_def("check_ubyte") { op_values(int, int) }
        op_def("check_short") { op_values(int, int) }
        op_def("check_ushort") { op_values(int, int) }
        op_def("check_int") { op_values(int, int) }
        op_def("check_uint") { op_values(int, int) }
-       op_def("low_word") { op_values(int, long) }
-       op_def("expand_int") { op_values(long, int) }
-       op_def("expand_uint") { op_values(long, int) }
+       op_def("low_word") { op_values(int, long),
+                            op_intrinsic(conv) }
+       op_def("expand_int") { op_values(long, int),
+                              op_intrinsic(conv) }
+       op_def("expand_uint") { op_values(long, int),
+                               op_intrinsic(conv) }
        op_def("check_low_word") { op_values(int, long) }
        op_def("check_signed_low_word") { op_values(int, long) }
        op_def("check_long") { op_values(long, long) }
        op_def("check_ulong") { op_values(long, long) }
-       op_def("float32_to_int") { op_values(int, float32) }
-       op_def("float32_to_uint") { op_values(int, float32) }
-       op_def("float32_to_long") { op_values(long, float32) }
-       op_def("float32_to_ulong") { op_values(long, float32) }
+       op_def("float32_to_int") { op_values(int, float32),
+                                  op_intrinsic(conv) }
+       op_def("float32_to_uint") { op_values(int, float32),
+                                   op_intrinsic(conv) }
+       op_def("float32_to_long") { op_values(long, float32),
+                                   op_intrinsic(conv) }
+       op_def("float32_to_ulong") { op_values(long, float32),
+                                    op_intrinsic(conv) }
        op_def("check_float32_to_int") { op_values(int, float32) }
        op_def("check_float32_to_uint") { op_values(int, float32) }
        op_def("check_float32_to_long") { op_values(long, float32) }
        op_def("check_float32_to_ulong") { op_values(long, float32) }
-       op_def("int_to_float32") { op_values(float32, int) }
-       op_def("uint_to_float32") { op_values(float32, int) }
-       op_def("long_to_float32") { op_values(float32, long) }
-       op_def("ulong_to_float32") { op_values(float32, long) }
-       op_def("float32_to_float64") { op_values(float64, float32) }
-       op_def("float64_to_int") { op_values(int, float64) }
-       op_def("float64_to_uint") { op_values(int, float64) }
-       op_def("float64_to_long") { op_values(long, float64) }
-       op_def("float64_to_ulong") { op_values(long, float64) }
+       op_def("int_to_float32") { op_values(float32, int),
+                                  op_intrinsic(conv) }
+       op_def("uint_to_float32") { op_values(float32, int),
+                                   op_intrinsic(conv) }
+       op_def("long_to_float32") { op_values(float32, long),
+                                   op_intrinsic(conv) }
+       op_def("ulong_to_float32") { op_values(float32, long),
+                                    op_intrinsic(conv) }
+       op_def("float32_to_float64") { op_values(float64, float32),
+                                      op_intrinsic(conv) }
+       op_def("float64_to_int") { op_values(int, float64),
+                                  op_intrinsic(conv) }
+       op_def("float64_to_uint") { op_values(int, float64),
+                                   op_intrinsic(conv) }
+       op_def("float64_to_long") { op_values(long, float64),
+                                   op_intrinsic(conv) }
+       op_def("float64_to_ulong") { op_values(long, float64),
+                                    op_intrinsic(conv) }
        op_def("check_float64_to_int") { op_values(int, float64) }
        op_def("check_float64_to_uint") { op_values(int, float64) }
        op_def("check_float64_to_long") { op_values(long, float64) }
        op_def("check_float64_to_ulong") { op_values(long, float64) }
-       op_def("int_to_float64") { op_values(float64, int) }
-       op_def("uint_to_float64") { op_values(float64, int) }
-       op_def("long_to_float64") { op_values(float64, long) }
-       op_def("ulong_to_float64") { op_values(float64, long) }
-       op_def("float64_to_float32") { op_values(float32, float64) }
-       op_def("nfloat_to_int") { op_values(int, nfloat) }
-       op_def("nfloat_to_uint") { op_values(int, nfloat) }
-       op_def("nfloat_to_long") { op_values(long, nfloat) }
-       op_def("nfloat_to_ulong") { op_values(long, nfloat) }
+       op_def("int_to_float64") { op_values(float64, int),
+                                  op_intrinsic(conv) }
+       op_def("uint_to_float64") { op_values(float64, int),
+                                   op_intrinsic(conv) }
+       op_def("long_to_float64") { op_values(float64, long),
+                                   op_intrinsic(conv) }
+       op_def("ulong_to_float64") { op_values(float64, long),
+                                    op_intrinsic(conv) }
+       op_def("float64_to_float32") { op_values(float32, float64),
+                                      op_intrinsic(conv) }
+       op_def("nfloat_to_int") { op_values(int, nfloat),
+                                 op_intrinsic(conv) }
+       op_def("nfloat_to_uint") { op_values(int, nfloat),
+                                  op_intrinsic(conv) }
+       op_def("nfloat_to_long") { op_values(long, nfloat),
+                                  op_intrinsic(conv) }
+       op_def("nfloat_to_ulong") { op_values(long, nfloat),
+                                   op_intrinsic(conv) }
        op_def("check_nfloat_to_int") { op_values(int, nfloat) }
        op_def("check_nfloat_to_uint") { op_values(int, nfloat) }
        op_def("check_nfloat_to_long") { op_values(long, nfloat) }
        op_def("check_nfloat_to_ulong") { op_values(long, nfloat) }
-       op_def("int_to_nfloat") { op_values(nfloat, int) }
-       op_def("uint_to_nfloat") { op_values(nfloat, int) }
-       op_def("long_to_nfloat") { op_values(nfloat, long) }
-       op_def("ulong_to_nfloat") { op_values(nfloat, long) }
-       op_def("nfloat_to_float32") { op_values(float32, nfloat) }
-       op_def("nfloat_to_float64") { op_values(float64, nfloat) }
-       op_def("float32_to_nfloat") { op_values(nfloat, float32) }
-       op_def("float64_to_nfloat") { op_values(nfloat, float64) }
+       op_def("int_to_nfloat") { op_values(nfloat, int),
+                                 op_intrinsic(conv) }
+       op_def("uint_to_nfloat") { op_values(nfloat, int),
+                                  op_intrinsic(conv) }
+       op_def("long_to_nfloat") { op_values(nfloat, long),
+                                  op_intrinsic(conv) }
+       op_def("ulong_to_nfloat") { op_values(nfloat, long),
+                                   op_intrinsic(conv) }
+       op_def("nfloat_to_float32") { op_values(float32, nfloat),
+                                     op_intrinsic(conv) }
+       op_def("nfloat_to_float64") { op_values(float64, nfloat),
+                                     op_intrinsic(conv) }
+       op_def("float32_to_nfloat") { op_values(nfloat, float32),
+                                     op_intrinsic(conv) }
+       op_def("float64_to_nfloat") { op_values(nfloat, float64),
+                                     op_intrinsic(conv) }
        /*
         * Arithmetic opcodes.
         */
-       op_def("iadd", +) { op_values(int, int, int) }
-       op_def("iadd_ovf") { op_values(int, int, int) }
-       op_def("iadd_ovf_un") { op_values(int, int, int) }
-       op_def("isub", -) { op_values(int, int, int) }
-       op_def("isub_ovf") { op_values(int, int, int) }
-       op_def("isub_ovf_un") { op_values(int, int, int) }
-       op_def("imul", *) { op_values(int, int, int) }
-       op_def("imul_ovf") { op_values(int, int, int) }
-       op_def("imul_ovf_un") { op_values(int, int, int) }
-       op_def("idiv", /) { op_values(int, int, int) }
-       op_def("idiv_un") { op_values(int, int, int) }
-       op_def("irem", %) { op_values(int, int, int) }
-       op_def("irem_un") { op_values(int, int, int) }
-       op_def("ineg", neg) { op_values(int, int) }
-       op_def("ladd", +) { op_values(long, long, long) }
-       op_def("ladd_ovf") { op_values(long, long, long) }
-       op_def("ladd_ovf_un") { op_values(long, long, long) }
-       op_def("lsub", -) { op_values(long, long, long) }
-       op_def("lsub_ovf") { op_values(long, long, long) }
-       op_def("lsub_ovf_un") { op_values(long, long, long) }
-       op_def("lmul", *) { op_values(long, long, long) }
-       op_def("lmul_ovf") { op_values(long, long, long) }
-       op_def("lmul_ovf_un") { op_values(long, long, long) }
-       op_def("ldiv", /) { op_values(long, long, long) }
-       op_def("ldiv_un") { op_values(long, long, long) }
-       op_def("lrem", %) { op_values(long, long, long) }
-       op_def("lrem_un") { op_values(long, long, long) }
-       op_def("lneg", neg) { op_values(long, long) }
-       op_def("fadd", +) { op_values(float32, float32, float32) }
-       op_def("fsub", -) { op_values( float32, float32, float32) }
-       op_def("fmul", *) { op_values(float32, float32, float32) }
-       op_def("fdiv", /) { op_values(float32, float32, float32) }
-       op_def("frem", %) { op_values(float32, float32, float32) }
-       op_def("frem_ieee") { op_values(float32, float32, float32) }
-       op_def("fneg", neg) { op_values(float32, float32) }
-       op_def("dadd", +) { op_values(float64, float64, float64) }
-       op_def("dsub", -) { op_values(float64, float64, float64) }
-       op_def("dmul", *) { op_values(float64, float64, float64) }
-       op_def("ddiv", /) { op_values(float64, float64, float64) }
-       op_def("drem", %) { op_values(float64, float64, float64) }
-       op_def("drem_ieee") { op_values(float64, float64, float64) }
-       op_def("dneg", neg) { op_values(float64, float64) }
-       op_def("nfadd", +) { op_values(nfloat, nfloat, nfloat) }
-       op_def("nfsub", -) { op_values(nfloat, nfloat, nfloat) }
-       op_def("nfmul", *) { op_values(nfloat, nfloat, nfloat) }
-       op_def("nfdiv", /) { op_values(nfloat, nfloat, nfloat) }
-       op_def("nfrem", %) { op_values(nfloat, nfloat, nfloat) }
-       op_def("nfrem_ieee") { op_values(nfloat, nfloat, nfloat) }
-       op_def("nfneg", neg) { op_values(nfloat, nfloat) }
+       op_def("iadd", +) { op_values(int, int, int),
+                           op_intrinsic(jit_int_add, i_ii) }
+       op_def("iadd_ovf") { op_values(int, int, int),
+                            op_intrinsic(jit_int_add_ovf, i_piii) }
+       op_def("iadd_ovf_un") { op_values(int, int, int),
+                               op_intrinsic(jit_uint_add_ovf, i_pIII) }
+       op_def("isub", -) { op_values(int, int, int),
+                           op_intrinsic(jit_int_sub, i_ii) }
+       op_def("isub_ovf") { op_values(int, int, int),
+                            op_intrinsic(jit_int_sub_ovf, i_piii) }
+       op_def("isub_ovf_un") { op_values(int, int, int),
+                               op_intrinsic(jit_uint_sub_ovf, i_pIII) }
+       op_def("imul", *) { op_values(int, int, int),
+                           op_intrinsic(jit_int_mul, i_ii) }
+       op_def("imul_ovf") { op_values(int, int, int),
+                            op_intrinsic(jit_int_mul_ovf, i_piii) }
+       op_def("imul_ovf_un") { op_values(int, int, int),
+                               op_intrinsic(jit_uint_mul_ovf, i_pIII) }
+       op_def("idiv", /) { op_values(int, int, int),
+                           op_intrinsic(jit_int_div, i_piii) }
+       op_def("idiv_un") { op_values(int, int, int),
+                           op_intrinsic(jit_uint_div, i_pIII) }
+       op_def("irem", %) { op_values(int, int, int),
+                           op_intrinsic(jit_int_rem, i_piii) }
+       op_def("irem_un") { op_values(int, int, int),
+                           op_intrinsic(jit_uint_rem, i_pIII) }
+       op_def("ineg", neg) { op_values(int, int),
+                             op_intrinsic(jit_int_neg, i_i) }
+       op_def("ladd", +) { op_values(long, long, long),
+                           op_intrinsic(jit_long_add, l_ll) }
+       op_def("ladd_ovf") { op_values(long, long, long),
+                            op_intrinsic(jit_long_add_ovf, i_plll) }
+       op_def("ladd_ovf_un") { op_values(long, long, long),
+                               op_intrinsic(jit_ulong_add_ovf, i_pLLL) }
+       op_def("lsub", -) { op_values(long, long, long),
+                           op_intrinsic(jit_long_sub, l_ll) }
+       op_def("lsub_ovf") { op_values(long, long, long),
+                            op_intrinsic(jit_long_sub_ovf, i_plll) }
+       op_def("lsub_ovf_un") { op_values(long, long, long),
+                               op_intrinsic(jit_ulong_sub_ovf, i_pLLL) }
+       op_def("lmul", *) { op_values(long, long, long),
+                           op_intrinsic(jit_long_mul, l_ll) }
+       op_def("lmul_ovf") { op_values(long, long, long),
+                            op_intrinsic(jit_long_mul_ovf, i_plll) }
+       op_def("lmul_ovf_un") { op_values(long, long, long),
+                               op_intrinsic(jit_ulong_mul_ovf, i_pLLL) }
+       op_def("ldiv", /) { op_values(long, long, long),
+                           op_intrinsic(jit_long_div, i_plll) }
+       op_def("ldiv_un") { op_values(long, long, long),
+                           op_intrinsic(jit_ulong_div, i_pLLL) }
+       op_def("lrem", %) { op_values(long, long, long),
+                           op_intrinsic(jit_long_rem, i_plll) }
+       op_def("lrem_un") { op_values(long, long, long),
+                           op_intrinsic(jit_ulong_rem, i_pLLL) }
+       op_def("lneg", neg) { op_values(long, long),
+                             op_intrinsic(jit_long_neg, l_l) }
+       op_def("fadd", +) { op_values(float32, float32, float32),
+                           op_intrinsic(jit_float32_add, f_ff) }
+       op_def("fsub", -) { op_values( float32, float32, float32),
+                           op_intrinsic(jit_float32_sub, f_ff) }
+       op_def("fmul", *) { op_values(float32, float32, float32),
+                           op_intrinsic(jit_float32_mul, f_ff) }
+       op_def("fdiv", /) { op_values(float32, float32, float32),
+                           op_intrinsic(jit_float32_div, f_ff) }
+       op_def("frem", %) { op_values(float32, float32, float32),
+                           op_intrinsic(jit_float32_rem, f_ff) }
+       op_def("frem_ieee") { op_values(float32, float32, float32),
+                             op_intrinsic(jit_float32_ieee_rem, f_ff) }
+       op_def("fneg", neg) { op_values(float32, float32),
+                             op_intrinsic(jit_float32_neg, f_f) }
+       op_def("dadd", +) { op_values(float64, float64, float64),
+                           op_intrinsic(jit_float64_add, d_dd) }
+       op_def("dsub", -) { op_values(float64, float64, float64),
+                           op_intrinsic(jit_float64_sub, d_dd) }
+       op_def("dmul", *) { op_values(float64, float64, float64),
+                           op_intrinsic(jit_float64_mul, d_dd) }
+       op_def("ddiv", /) { op_values(float64, float64, float64),
+                           op_intrinsic(jit_float64_div, d_dd) }
+       op_def("drem", %) { op_values(float64, float64, float64),
+                           op_intrinsic(jit_float64_rem, d_dd) }
+       op_def("drem_ieee") { op_values(float64, float64, float64),
+                             op_intrinsic(jit_float64_ieee_rem, d_dd) }
+       op_def("dneg", neg) { op_values(float64, float64),
+                             op_intrinsic(jit_float64_neg, d_d) }
+       op_def("nfadd", +) { op_values(nfloat, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_add, D_DD) }
+       op_def("nfsub", -) { op_values(nfloat, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_sub, D_DD) }
+       op_def("nfmul", *) { op_values(nfloat, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_mul, D_DD) }
+       op_def("nfdiv", /) { op_values(nfloat, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_div, D_DD) }
+       op_def("nfrem", %) { op_values(nfloat, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_rem, D_DD) }
+       op_def("nfrem_ieee") { op_values(nfloat, nfloat, nfloat),
+                              op_intrinsic(jit_nfloat_ieee_rem, D_DD) }
+       op_def("nfneg", neg) { op_values(nfloat, nfloat),
+                              op_intrinsic(jit_nfloat_neg, D_D) }
        /*
         * Bitwise opcodes.
         */
-       op_def("iand", &) { op_values(int, int, int) }
-       op_def("ior", |) { op_values(int, int, int) }
-       op_def("ixor", ^) { op_values(int, int, int) }
-       op_def("inot", ~) { op_values(int, int) }
-       op_def("ishl", <<) { op_values(int, int, int) }
-       op_def("ishr", >>) { op_values(int, int, int) }
-       op_def("ishr_un", shr_un) { op_values(int, int, int) }
-       op_def("land", &) { op_values(long, long, long) }
-       op_def("lor", |) { op_values(long, long, long) }
-       op_def("lxor", ^) { op_values(long, long, long) }
-       op_def("lnot", ~) { op_values(long, long) }
-       op_def("lshl", <<) { op_values(long, long, int) }
-       op_def("lshr", >>) { op_values(long, long, int) }
-       op_def("lshr_un", shr_un) { op_values(long, long, int) }
+       op_def("iand", &) { op_values(int, int, int),
+                           op_intrinsic(jit_int_and, i_ii) }
+       op_def("ior", |) { op_values(int, int, int),
+                          op_intrinsic(jit_int_or, i_ii) }
+       op_def("ixor", ^) { op_values(int, int, int),
+                           op_intrinsic(jit_int_xor, i_ii) }
+       op_def("inot", ~) { op_values(int, int),
+                           op_intrinsic(jit_int_not, i_i) }
+       op_def("ishl", <<) { op_values(int, int, int),
+                            op_intrinsic(jit_int_shl, i_iI) }
+       op_def("ishr", >>) { op_values(int, int, int),
+                            op_intrinsic(jit_int_shr, i_iI) }
+       op_def("ishr_un", shr_un) { op_values(int, int, int),
+                                   op_intrinsic(jit_uint_shr, i_iI) }
+       op_def("land", &) { op_values(long, long, long),
+                           op_intrinsic(jit_long_and, l_ll) }
+       op_def("lor", |) { op_values(long, long, long),
+                          op_intrinsic(jit_long_or, l_ll) }
+       op_def("lxor", ^) { op_values(long, long, long),
+                           op_intrinsic(jit_long_xor, l_ll) }
+       op_def("lnot", ~) { op_values(long, long),
+                           op_intrinsic(jit_long_not, l_l) }
+       op_def("lshl", <<) { op_values(long, long, int),
+                            op_intrinsic(jit_long_shl, l_lI) }
+       op_def("lshr", >>) { op_values(long, long, int),
+                            op_intrinsic(jit_long_shr, l_lI) }
+       op_def("lshr_un", shr_un) { op_values(long, long, int),
+                                   op_intrinsic(jit_ulong_shr, L_LI) }
        /*
         * Branch opcodes.
         */
        op_def("br") { op_type(branch) }
-       op_def("br_ifalse") { op_type(branch), op_values(empty, int) }
-       op_def("br_itrue") { op_type(branch), op_values(empty, int) }
-       op_def("br_ieq", ==) { op_type(branch), op_values(empty, int, int) }
-       op_def("br_ine", !=) { op_type(branch), op_values(empty, int, int) }
-       op_def("br_ilt", <) { op_type(branch), op_values(empty, int, int) }
-       op_def("br_ilt_un") { op_type(branch), op_values(empty, int, int) }
-       op_def("br_ile", <=) { op_type(branch), op_values(empty, int, int) }
-       op_def("br_ile_un") { op_type(branch), op_values(empty, int, int) }
-       op_def("br_igt", >) { op_type(branch), op_values(empty, int, int) }
-       op_def("br_igt_un") { op_type(branch), op_values(empty, int, int) }
-       op_def("br_ige", >=) { op_type(branch), op_values(empty, int, int) }
-       op_def("br_ige_un") { op_type(branch), op_values(empty, int, int) }
-       op_def("br_lfalse") { op_type(branch), op_values(empty, long) }
-       op_def("br_ltrue") { op_type(branch), op_values(empty, long) }
-       op_def("br_leq", ==) { op_type(branch), op_values(empty, long, long) }
-       op_def("br_lne", !=) { op_type(branch), op_values(empty, long, long) }
-       op_def("br_llt", <) { op_type(branch), op_values(empty, long, long) }
-       op_def("br_llt_un") { op_type(branch), op_values(empty, long, long) }
-       op_def("br_lle", <=) { op_type(branch), op_values(empty, long, long) }
-       op_def("br_lle_un") { op_type(branch), op_values(empty, long, long) }
-       op_def("br_lgt", >) { op_type(branch), op_values(empty, long, long) }
-       op_def("br_lgt_un") { op_type(branch), op_values(empty, long, long) }
-       op_def("br_lge", >=) { op_type(branch), op_values(empty, long, long) }
-       op_def("br_lge_un") { op_type(branch), op_values(empty, long, long) }
-       op_def("br_feq", ==) { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_fne", !=) { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_flt", <) { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_fle", <=) { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_fgt", >) { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_fge", >=) { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_flt_inv") { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_fle_inv") { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_fgt_inv") { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_fge_inv") { op_type(branch), op_values(empty, float32, float32) }
-       op_def("br_deq", ==) { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dne", !=) { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dlt", <) { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dle", <=) { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dgt", >) { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dge", >=) { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dlt_inv") { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dle_inv") { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dgt_inv") { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_dge_inv") { op_type(branch), op_values(empty, float64, float64) }
-       op_def("br_nfeq", ==) { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nfne", !=) { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nflt", <) { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nfle", <=) { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nfgt", >) { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nfge", >=) { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nflt_inv") { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nfle_inv") { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nfgt_inv") { op_type(branch), op_values(empty, nfloat, nfloat) }
-       op_def("br_nfge_inv") { op_type(branch), op_values(empty, nfloat, nfloat) }
+       op_def("br_ifalse") { op_type(branch), op_values(empty, int),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH_UNARY | _JIT_INTRINSIC_FLAG_IFALSE") }
+       op_def("br_itrue") { op_type(branch), op_values(empty, int),
+                            op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH_UNARY | _JIT_INTRINSIC_FLAG_ITRUE") }
+       op_def("br_ieq", ==) { op_type(branch), op_values(empty, int, int),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_IEQ") }
+       op_def("br_ine", !=) { op_type(branch), op_values(empty, int, int),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_INE") }
+       op_def("br_ilt", <) { op_type(branch), op_values(empty, int, int),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_ILT") }
+       op_def("br_ilt_un") { op_type(branch), op_values(empty, int, int),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_ILT_UN") }
+       op_def("br_ile", <=) { op_type(branch), op_values(empty, int, int),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_ILE") }
+       op_def("br_ile_un") { op_type(branch), op_values(empty, int, int),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_ILE_UN") }
+       op_def("br_igt", >) { op_type(branch), op_values(empty, int, int),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_IGT") }
+       op_def("br_igt_un") { op_type(branch), op_values(empty, int, int),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_IGT_UN") }
+       op_def("br_ige", >=) { op_type(branch), op_values(empty, int, int),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_IGE") }
+       op_def("br_ige_un") { op_type(branch), op_values(empty, int, int),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_IGE_UN") }
+       op_def("br_lfalse") { op_type(branch), op_values(empty, long),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH_UNARY | _JIT_INTRINSIC_FLAG_LFALSE") }
+       op_def("br_ltrue") { op_type(branch), op_values(empty, long),
+                            op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH_UNARY | _JIT_INTRINSIC_FLAG_LTRUE") }
+       op_def("br_leq", ==) { op_type(branch), op_values(empty, long, long),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LEQ") }
+       op_def("br_lne", !=) { op_type(branch), op_values(empty, long, long),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LNE") }
+       op_def("br_llt", <) { op_type(branch), op_values(empty, long, long),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LLT") }
+       op_def("br_llt_un") { op_type(branch), op_values(empty, long, long),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LLT_UN") }
+       op_def("br_lle", <=) { op_type(branch), op_values(empty, long, long),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LLE") }
+       op_def("br_lle_un") { op_type(branch), op_values(empty, long, long),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LLE_UN") }
+       op_def("br_lgt", >) { op_type(branch), op_values(empty, long, long),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LGT") }
+       op_def("br_lgt_un") { op_type(branch), op_values(empty, long, long),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LGT_UN") }
+       op_def("br_lge", >=) { op_type(branch), op_values(empty, long, long),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LGE") }
+       op_def("br_lge_un") { op_type(branch), op_values(empty, long, long),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_LGE_UN") }
+       op_def("br_feq", ==) { op_type(branch), op_values(empty, float32, float32),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FEQ") }
+       op_def("br_fne", !=) { op_type(branch), op_values(empty, float32, float32),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FNE") }
+       op_def("br_flt", <) { op_type(branch), op_values(empty, float32, float32),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FLT") }
+       op_def("br_fle", <=) { op_type(branch), op_values(empty, float32, float32),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FLE") }
+       op_def("br_fgt", >) { op_type(branch), op_values(empty, float32, float32),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FGT") }
+       op_def("br_fge", >=) { op_type(branch), op_values(empty, float32, float32),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FGE") }
+       op_def("br_flt_inv") { op_type(branch), op_values(empty, float32, float32),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FLT_INV") }
+       op_def("br_fle_inv") { op_type(branch), op_values(empty, float32, float32),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FLE_INV") }
+       op_def("br_fgt_inv") { op_type(branch), op_values(empty, float32, float32),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FGT_INV") }
+       op_def("br_fge_inv") { op_type(branch), op_values(empty, float32, float32),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_FGE_INV") }
+       op_def("br_deq", ==) { op_type(branch), op_values(empty, float64, float64),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DEQ") }
+       op_def("br_dne", !=) { op_type(branch), op_values(empty, float64, float64),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DNE") }
+       op_def("br_dlt", <) { op_type(branch), op_values(empty, float64, float64),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DLT") }
+       op_def("br_dle", <=) { op_type(branch), op_values(empty, float64, float64),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DLE") }
+       op_def("br_dgt", >) { op_type(branch), op_values(empty, float64, float64),
+                             op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DGT") }
+       op_def("br_dge", >=) { op_type(branch), op_values(empty, float64, float64),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DGE") }
+       op_def("br_dlt_inv") { op_type(branch), op_values(empty, float64, float64),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DLT_INV") }
+       op_def("br_dle_inv") { op_type(branch), op_values(empty, float64, float64),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DLE_INV") }
+       op_def("br_dgt_inv") { op_type(branch), op_values(empty, float64, float64),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DGT_INV") }
+       op_def("br_dge_inv") { op_type(branch), op_values(empty, float64, float64),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_DGE_INV") }
+       op_def("br_nfeq", ==) { op_type(branch), op_values(empty, nfloat, nfloat),
+                               op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFEQ") }
+       op_def("br_nfne", !=) { op_type(branch), op_values(empty, nfloat, nfloat),
+                               op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFNE") }
+       op_def("br_nflt", <) { op_type(branch), op_values(empty, nfloat, nfloat),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFLT") }
+       op_def("br_nfle", <=) { op_type(branch), op_values(empty, nfloat, nfloat),
+                               op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFLE") }
+       op_def("br_nfgt", >) { op_type(branch), op_values(empty, nfloat, nfloat),
+                              op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFGT") }
+       op_def("br_nfge", >=) { op_type(branch), op_values(empty, nfloat, nfloat),
+                               op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFGE") }
+       op_def("br_nflt_inv") { op_type(branch), op_values(empty, nfloat, nfloat),
+                               op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFLT_INV") }
+       op_def("br_nfle_inv") { op_type(branch), op_values(empty, nfloat, nfloat),
+                               op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFLE_INV") }
+       op_def("br_nfgt_inv") { op_type(branch), op_values(empty, nfloat, nfloat),
+                               op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFGT_INV") }
+       op_def("br_nfge_inv") { op_type(branch), op_values(empty, nfloat, nfloat),
+                               op_intrinsic("_JIT_INTRINSIC_FLAG_BRANCH | JIT_OP_NFGE_INV") }
        /*
         * Comparison opcodes.
         */
-       op_def("icmp") { op_values(int, int, int) }
-       op_def("icmp_un") { op_values(int, int, int) }
-       op_def("lcmp") { op_values(int, long, long) }
-       op_def("lcmp_un") { op_values(int, long, long) }
-       op_def("fcmpl") { op_values(int, float32, float32) }
-       op_def("fcmpg") { op_values(int, float32, float32) }
-       op_def("dcmpl") { op_values(int, float64, float64) }
-       op_def("dcmpg") { op_values(int, float64, float64) }
-       op_def("nfcmpl") { op_values(int, nfloat, nfloat) }
-       op_def("nfcmpg") { op_values(int, nfloat, nfloat) }
-       op_def("ieq", ==) { op_values(int, int, int) }
-       op_def("ine", !=) { op_values(int, int, int) }
-       op_def("ilt", <) { op_values(int, int, int) }
-       op_def("ilt_un") { op_values(int, int, int) }
-       op_def("ile", <=) { op_values(int, int, int) }
-       op_def("ile_un") { op_values(int, int, int) }
-       op_def("igt", >) { op_values(int, int, int) }
-       op_def("igt_un") { op_values(int, int, int) }
-       op_def("ige", >=) { op_values(int, int, int) }
-       op_def("ige_un") { op_values(int, int, int) }
-       op_def("leq", ==) { op_values(int, long, long) }
-       op_def("lne", !=) { op_values(int, long, long) }
-       op_def("llt", <) { op_values(int, long, long) }
-       op_def("llt_un") { op_values(int, long, long) }
-       op_def("lle", <=) { op_values(int, long, long) }
-       op_def("lle_un") { op_values(int, long, long) }
-       op_def("lgt", >) { op_values(int, long, long) }
-       op_def("lgt_un") { op_values(int, long, long) }
-       op_def("lge", >=) { op_values(int, long, long) }
-       op_def("lge_un") { op_values(int, long, long) }
-       op_def("feq", ==) { op_values(int, float32, float32) }
-       op_def("fne", !=) { op_values(int, float32, float32) }
-       op_def("flt", <) { op_values(int, float32, float32) }
-       op_def("fle", <=) { op_values(int, float32, float32) }
-       op_def("fgt", >) { op_values(int, float32, float32) }
-       op_def("fge", >=) { op_values(int, float32, float32) }
-       op_def("flt_inv") { op_values(int, float32, float32) }
-       op_def("fle_inv") { op_values(int, float32, float32) }
-       op_def("fgt_inv") { op_values(int, float32, float32) }
-       op_def("fge_inv") { op_values(int, float32, float32) }
-       op_def("deq", ==) { op_values(int, float64, float64) }
-       op_def("dne", !=) { op_values(int, float64, float64) }
-       op_def("dlt", <) { op_values(int, float64, float64) }
-       op_def("dle", <=) { op_values(int, float64, float64) }
-       op_def("dgt", >) { op_values(int, float64, float64) }
-       op_def("dge", >=) { op_values(int, float64, float64) }
-       op_def("dlt_inv") { op_values(int, float64, float64) }
-       op_def("dle_inv") { op_values(int, float64, float64) }
-       op_def("dgt_inv") { op_values(int, float64, float64) }
-       op_def("dge_inv") { op_values(int, float64, float64) }
-       op_def("nfeq", ==) { op_values(int, nfloat, nfloat) }
-       op_def("nfne", !=) { op_values(int, nfloat, nfloat) }
-       op_def("nflt", <) { op_values(int, nfloat, nfloat) }
-       op_def("nfle", <=) { op_values(int, nfloat, nfloat) }
-       op_def("nfgt", >) { op_values(int, nfloat, nfloat) }
-       op_def("nfge", >=) { op_values(int, nfloat, nfloat) }
-       op_def("nflt_inv") { op_values(int, nfloat, nfloat) }
-       op_def("nfle_inv") { op_values(int, nfloat, nfloat) }
-       op_def("nfgt_inv") { op_values(int, nfloat, nfloat) }
-       op_def("nfge_inv") { op_values(int, nfloat, nfloat) }
-       op_def("is_fnan") { op_values(int, float32) }
-       op_def("is_finf") { op_values(int, float32) }
-       op_def("is_ffinite") { op_values(int, float32) }
-       op_def("is_dnan") { op_values(int, float64) }
-       op_def("is_dinf") { op_values(int, float64) }
-       op_def("is_dfinite") { op_values(int, float64) }
-       op_def("is_nfnan") { op_values(int, nfloat) }
-       op_def("is_nfinf") { op_values(int, nfloat) }
-       op_def("is_nffinite") { op_values(int, nfloat) }
+       op_def("icmp") { op_values(int, int, int),
+                        op_intrinsic(jit_int_cmp, i_ii) }
+       op_def("icmp_un") { op_values(int, int, int),
+                           op_intrinsic(jit_uint_cmp, i_II) }
+       op_def("lcmp") { op_values(int, long, long),
+                        op_intrinsic(jit_long_cmp, i_ll) }
+       op_def("lcmp_un") { op_values(int, long, long),
+                           op_intrinsic(jit_ulong_cmp, i_LL) }
+       op_def("fcmpl") { op_values(int, float32, float32),
+                         op_intrinsic(jit_float32_cmpl, i_ff) }
+       op_def("fcmpg") { op_values(int, float32, float32),
+                         op_intrinsic(jit_float32_cmpg, i_ff) }
+       op_def("dcmpl") { op_values(int, float64, float64),
+                         op_intrinsic(jit_float64_cmpl, i_dd) }
+       op_def("dcmpg") { op_values(int, float64, float64),
+                         op_intrinsic(jit_float64_cmpg, i_dd) }
+       op_def("nfcmpl") { op_values(int, nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_cmpl, i_DD) }
+       op_def("nfcmpg") { op_values(int, nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_cmpg, i_DD) }
+       op_def("ieq", ==) { op_values(int, int, int),
+                           op_intrinsic(jit_int_eq, i_ii) }
+       op_def("ine", !=) { op_values(int, int, int),
+                           op_intrinsic(jit_int_ne, i_ii) }
+       op_def("ilt", <) { op_values(int, int, int),
+                          op_intrinsic(jit_int_lt, i_ii) }
+       op_def("ilt_un") { op_values(int, int, int),
+                          op_intrinsic(jit_uint_lt, i_II) }
+       op_def("ile", <=) { op_values(int, int, int),
+                           op_intrinsic(jit_int_le, i_ii) }
+       op_def("ile_un") { op_values(int, int, int),
+                          op_intrinsic(jit_uint_le, i_II) }
+       op_def("igt", >) { op_values(int, int, int),
+                          op_intrinsic(jit_int_gt, i_ii) }
+       op_def("igt_un") { op_values(int, int, int),
+                          op_intrinsic(jit_uint_gt, i_II) }
+       op_def("ige", >=) { op_values(int, int, int),
+                           op_intrinsic(jit_int_ge, i_ii) }
+       op_def("ige_un") { op_values(int, int, int),
+                          op_intrinsic(jit_uint_ge, i_II) }
+       op_def("leq", ==) { op_values(int, long, long),
+                           op_intrinsic(jit_long_eq, i_ll) }
+       op_def("lne", !=) { op_values(int, long, long),
+                           op_intrinsic(jit_long_ne, i_ll) }
+       op_def("llt", <) { op_values(int, long, long),
+                          op_intrinsic(jit_long_lt, i_ll) }
+       op_def("llt_un") { op_values(int, long, long),
+                          op_intrinsic(jit_ulong_lt, i_LL) }
+       op_def("lle", <=) { op_values(int, long, long),
+                           op_intrinsic(jit_long_le, i_ll) }
+       op_def("lle_un") { op_values(int, long, long),
+                          op_intrinsic(jit_ulong_le, i_LL) }
+       op_def("lgt", >) { op_values(int, long, long),
+                          op_intrinsic(jit_long_gt, i_ll) }
+       op_def("lgt_un") { op_values(int, long, long),
+                          op_intrinsic(jit_ulong_gt, i_LL) }
+       op_def("lge", >=) { op_values(int, long, long),
+                           op_intrinsic(jit_long_ge, i_ll) }
+       op_def("lge_un") { op_values(int, long, long),
+                          op_intrinsic(jit_ulong_ge, i_LL) }
+       op_def("feq", ==) { op_values(int, float32, float32),
+                           op_intrinsic(jit_float32_eq, i_ff) }
+       op_def("fne", !=) { op_values(int, float32, float32),
+                           op_intrinsic(jit_float32_ne, i_ff) }
+       op_def("flt", <) { op_values(int, float32, float32),
+                          op_intrinsic(jit_float32_lt, i_ff) }
+       op_def("fle", <=) { op_values(int, float32, float32),
+                           op_intrinsic(jit_float32_le, i_ff) }
+       op_def("fgt", >) { op_values(int, float32, float32),
+                          op_intrinsic(jit_float32_gt, i_ff) }
+       op_def("fge", >=) { op_values(int, float32, float32),
+                           op_intrinsic(jit_float32_ge, i_ff) }
+       op_def("flt_inv") { op_values(int, float32, float32),
+                           op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_FGE") }
+       op_def("fle_inv") { op_values(int, float32, float32),
+                           op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_FGT") }
+       op_def("fgt_inv") { op_values(int, float32, float32),
+                           op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_FLE") }
+       op_def("fge_inv") { op_values(int, float32, float32),
+                           op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_FLT") }
+       op_def("deq", ==) { op_values(int, float64, float64),
+                           op_intrinsic(jit_float64_eq, i_dd) }
+       op_def("dne", !=) { op_values(int, float64, float64),
+                           op_intrinsic(jit_float64_ne, i_dd) }
+       op_def("dlt", <) { op_values(int, float64, float64),
+                          op_intrinsic(jit_float64_lt, i_dd) }
+       op_def("dle", <=) { op_values(int, float64, float64),
+                           op_intrinsic(jit_float64_le, i_dd) }
+       op_def("dgt", >) { op_values(int, float64, float64),
+                          op_intrinsic(jit_float64_gt, i_dd) }
+       op_def("dge", >=) { op_values(int, float64, float64),
+                           op_intrinsic(jit_float64_ge, i_dd) }
+       op_def("dlt_inv") { op_values(int, float64, float64),
+                           op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_DGE") }
+       op_def("dle_inv") { op_values(int, float64, float64),
+                           op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_DGT") }
+       op_def("dgt_inv") { op_values(int, float64, float64),
+                           op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_DLE") }
+       op_def("dge_inv") { op_values(int, float64, float64),
+                           op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_DLT") }
+       op_def("nfeq", ==) { op_values(int, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_eq, i_DD) }
+       op_def("nfne", !=) { op_values(int, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_ne, i_DD) }
+       op_def("nflt", <) { op_values(int, nfloat, nfloat),
+                           op_intrinsic(jit_nfloat_lt, i_DD) }
+       op_def("nfle", <=) { op_values(int, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_le, i_DD) }
+       op_def("nfgt", >) { op_values(int, nfloat, nfloat),
+                           op_intrinsic(jit_nfloat_gt, i_DD) }
+       op_def("nfge", >=) { op_values(int, nfloat, nfloat),
+                            op_intrinsic(jit_nfloat_ge, i_DD) }
+       op_def("nflt_inv") { op_values(int, nfloat, nfloat),
+                            op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_NFGE") }
+       op_def("nfle_inv") { op_values(int, nfloat, nfloat),
+                            op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_NFGT") }
+       op_def("nfgt_inv") { op_values(int, nfloat, nfloat),
+                            op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_NFLE") }
+       op_def("nfge_inv") { op_values(int, nfloat, nfloat),
+                            op_intrinsic("_JIT_INTRINSIC_FLAG_NOT | JIT_OP_NFLT") }
+       op_def("is_fnan") { op_values(int, float32),
+                           op_intrinsic(jit_float32_is_nan, i_f) }
+       op_def("is_finf") { op_values(int, float32),
+                           op_intrinsic(jit_float32_is_inf, i_f) }
+       op_def("is_ffinite") { op_values(int, float32),
+                              op_intrinsic(jit_float32_is_finite, i_f) }
+       op_def("is_dnan") { op_values(int, float64),
+                           op_intrinsic(jit_float64_is_nan, i_d) }
+       op_def("is_dinf") { op_values(int, float64),
+                           op_intrinsic(jit_float64_is_inf, i_d) }
+       op_def("is_dfinite") { op_values(int, float64),
+                              op_intrinsic(jit_float64_is_finite, i_d) }
+       op_def("is_nfnan") { op_values(int, nfloat),
+                            op_intrinsic(jit_nfloat_is_nan, i_D) }
+       op_def("is_nfinf") { op_values(int, nfloat),
+                            op_intrinsic(jit_nfloat_is_inf, i_D) }
+       op_def("is_nffinite") { op_values(int, nfloat),
+                               op_intrinsic(jit_nfloat_is_finite, i_D) }
        /*
         * Mathematical functions.
         */
-       op_def("facos") { op_values(float32, float32) }
-       op_def("fasin") { op_values(float32, float32) }
-       op_def("fatan") { op_values(float32, float32) }
-       op_def("fatan2") { op_values(float32, float32, float32) }
-       op_def("fceil") { op_values(float32, float32) }
-       op_def("fcos") { op_values(float32, float32) }
-       op_def("fcosh") { op_values(float32, float32) }
-       op_def("fexp") { op_values(float32, float32) }
-       op_def("ffloor") { op_values(float32, float32) }
-       op_def("flog") { op_values(float32, float32) }
-       op_def("flog10") { op_values(float32, float32) }
-       op_def("fpow") { op_values(float32, float32, float32) }
-       op_def("frint") { op_values(float32, float32) }
-       op_def("fround") { op_values(float32, float32) }
-       op_def("fsin") { op_values(float32, float32) }
-       op_def("fsinh") { op_values(float32, float32) }
-       op_def("fsqrt") { op_values(float32, float32) }
-       op_def("ftan") { op_values(float32, float32) }
-       op_def("ftanh") { op_values(float32, float32) }
-       op_def("ftrunc") { op_values(float32, float32) }
-       op_def("dacos") { op_values(float64, float64) }
-       op_def("dasin") { op_values(float64, float64) }
-       op_def("datan") { op_values(float64, float64) }
-       op_def("datan2") { op_values(float64, float64, float64)}
-       op_def("dceil") { op_values(float64, float64) }
-       op_def("dcos") { op_values(float64, float64) }
-       op_def("dcosh") { op_values(float64, float64) }
-       op_def("dexp") { op_values(float64, float64) }
-       op_def("dfloor") { op_values(float64, float64) }
-       op_def("dlog") { op_values(float64, float64) }
-       op_def("dlog10") { op_values(float64, float64) }
-       op_def("dpow") { op_values(float64, float64, float64) }
-       op_def("drint") { op_values(float64, float64) }
-       op_def("dround") { op_values(float64, float64) }
-       op_def("dsin") { op_values(float64, float64) }
-       op_def("dsinh") { op_values(float64, float64) }
-       op_def("dsqrt") { op_values(float64, float64) }
-       op_def("dtan") { op_values(float64, float64) }
-       op_def("dtanh") { op_values(float64, float64) }
-       op_def("dtrunc") { op_values(float64, float64) }
-       op_def("nfacos") { op_values(nfloat, nfloat) }
-       op_def("nfasin") { op_values(nfloat, nfloat) }
-       op_def("nfatan") { op_values(nfloat, nfloat) }
-       op_def("nfatan2") { op_values(nfloat, nfloat, nfloat) }
-       op_def("nfceil") { op_values(nfloat, nfloat) }
-       op_def("nfcos") { op_values(nfloat, nfloat) }
-       op_def("nfcosh") { op_values(nfloat, nfloat) }
-       op_def("nfexp") { op_values(nfloat, nfloat) }
-       op_def("nffloor") { op_values(nfloat, nfloat) }
-       op_def("nflog") { op_values(nfloat, nfloat) }
-       op_def("nflog10") { op_values(nfloat, nfloat) }
-       op_def("nfpow") { op_values(nfloat, nfloat, nfloat) }
-       op_def("nfrint") { op_values(nfloat, nfloat) }
-       op_def("nfround") { op_values(nfloat, nfloat) }
-       op_def("nfsin") { op_values(nfloat, nfloat) }
-       op_def("nfsinh") { op_values(nfloat, nfloat) }
-       op_def("nfsqrt") { op_values(nfloat, nfloat) }
-       op_def("nftan") { op_values(nfloat, nfloat) }
-       op_def("nftanh") { op_values(nfloat, nfloat) }
-       op_def("nftrunc") { op_values(nfloat, nfloat) }
+       op_def("facos") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_acos, f_f) }
+       op_def("fasin") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_asin, f_f) }
+       op_def("fatan") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_atan, f_f) }
+       op_def("fatan2") { op_values(float32, float32, float32),
+                          op_intrinsic(jit_float32_atan2, f_ff) }
+       op_def("fceil") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_ceil, f_f) }
+       op_def("fcos") { op_values(float32, float32),
+                        op_intrinsic(jit_float32_cos, f_f) }
+       op_def("fcosh") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_cosh, f_f) }
+       op_def("fexp") { op_values(float32, float32),
+                        op_intrinsic(jit_float32_exp, f_f) }
+       op_def("ffloor") { op_values(float32, float32),
+                          op_intrinsic(jit_float32_floor, f_f) }
+       op_def("flog") { op_values(float32, float32),
+                        op_intrinsic(jit_float32_log, f_f) }
+       op_def("flog10") { op_values(float32, float32),
+                          op_intrinsic(jit_float32_log10, f_f) }
+       op_def("fpow") { op_values(float32, float32, float32),
+                        op_intrinsic(jit_float32_pow, f_ff) }
+       op_def("frint") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_rint, f_f) }
+       op_def("fround") { op_values(float32, float32),
+                          op_intrinsic(jit_float32_round, f_f) }
+       op_def("fsin") { op_values(float32, float32),
+                        op_intrinsic(jit_float32_sin, f_f) }
+       op_def("fsinh") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_sinh, f_f) }
+       op_def("fsqrt") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_sqrt, f_f) }
+       op_def("ftan") { op_values(float32, float32),
+                        op_intrinsic(jit_float32_tan, f_f) }
+       op_def("ftanh") { op_values(float32, float32),
+                         op_intrinsic(jit_float32_tanh, f_f) }
+       op_def("ftrunc") { op_values(float32, float32),
+                          op_intrinsic(jit_float32_trunc, f_f) }
+       op_def("dacos") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_acos, d_d) }
+       op_def("dasin") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_asin, d_d) }
+       op_def("datan") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_atan, d_d) }
+       op_def("datan2") { op_values(float64, float64, float64),
+                          op_intrinsic(jit_float64_atan2, d_dd) }
+       op_def("dceil") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_ceil, d_d) }
+       op_def("dcos") { op_values(float64, float64),
+                        op_intrinsic(jit_float64_cos, d_d) }
+       op_def("dcosh") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_cosh, d_d) }
+       op_def("dexp") { op_values(float64, float64),
+                        op_intrinsic(jit_float64_exp, d_d) }
+       op_def("dfloor") { op_values(float64, float64),
+                          op_intrinsic(jit_float64_floor, d_d) }
+       op_def("dlog") { op_values(float64, float64),
+                        op_intrinsic(jit_float64_log, d_d) }
+       op_def("dlog10") { op_values(float64, float64),
+                          op_intrinsic(jit_float64_log10, d_d) }
+       op_def("dpow") { op_values(float64, float64, float64),
+                        op_intrinsic(jit_float64_pow, d_dd) }
+       op_def("drint") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_rint, d_d) }
+       op_def("dround") { op_values(float64, float64),
+                          op_intrinsic(jit_float64_round, d_d) }
+       op_def("dsin") { op_values(float64, float64),
+                        op_intrinsic(jit_float64_sin, d_d) }
+       op_def("dsinh") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_sinh, d_d) }
+       op_def("dsqrt") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_sqrt, d_d) }
+       op_def("dtan") { op_values(float64, float64),
+                        op_intrinsic(jit_float64_tan, d_d) }
+       op_def("dtanh") { op_values(float64, float64),
+                         op_intrinsic(jit_float64_tanh, d_d) }
+       op_def("dtrunc") { op_values(float64, float64),
+                          op_intrinsic(jit_float64_trunc, d_d) }
+       op_def("nfacos") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_acos, D_D) }
+       op_def("nfasin") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_asin, D_D) }
+       op_def("nfatan") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_atan, D_D) }
+       op_def("nfatan2") { op_values(nfloat, nfloat, nfloat),
+                           op_intrinsic(jit_nfloat_atan2, D_DD) }
+       op_def("nfceil") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_ceil, D_D) }
+       op_def("nfcos") { op_values(nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_cos, D_D) }
+       op_def("nfcosh") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_cosh, D_D) }
+       op_def("nfexp") { op_values(nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_exp, D_D) }
+       op_def("nffloor") { op_values(nfloat, nfloat),
+                           op_intrinsic(jit_nfloat_floor, D_D) }
+       op_def("nflog") { op_values(nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_log, D_D) }
+       op_def("nflog10") { op_values(nfloat, nfloat),
+                           op_intrinsic(jit_nfloat_log10, D_D) }
+       op_def("nfpow") { op_values(nfloat, nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_pow, D_DD) }
+       op_def("nfrint") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_rint, D_D) }
+       op_def("nfround") { op_values(nfloat, nfloat),
+                           op_intrinsic(jit_nfloat_round, D_D) }
+       op_def("nfsin") { op_values(nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_sin, D_D) }
+       op_def("nfsinh") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_sinh, D_D) }
+       op_def("nfsqrt") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_sqrt, D_D) }
+       op_def("nftan") { op_values(nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_tan, D_D) }
+       op_def("nftanh") { op_values(nfloat, nfloat),
+                          op_intrinsic(jit_nfloat_tanh, D_D) }
+       op_def("nftrunc") { op_values(nfloat, nfloat),
+                           op_intrinsic(jit_nfloat_trunc, D_D) }
        /*
         * Absolute, minimum, maximum, and sign.
         */
-       op_def("iabs") { op_values(int, int) }
-       op_def("labs") { op_values(long, long) }
-       op_def("fabs") { op_values(float32, float32) }
-       op_def("dabs") { op_values(float64, float64) }
-       op_def("nfabs") { op_values(nfloat, nfloat) }
-       op_def("imin") { op_values(int, int, int) }
-       op_def("imin_un") { op_values(int, int, int) }
-       op_def("lmin") { op_values(long, long, long) }
-       op_def("lmin_un") { op_values(long, long, long) }
-       op_def("fmin") { op_values(float32, float32, float32) }
-       op_def("dmin") { op_values(float64, float64, float64) }
-       op_def("nfmin") { op_values(nfloat, nfloat, nfloat) }
-       op_def("imax") { op_values(int, int, int) }
-       op_def("imax_un") { op_values(int, int, int) }
-       op_def("lmax") { op_values(long, long, long) }
-       op_def("lmax_un") { op_values(long, long, long) }
-       op_def("fmax") { op_values(float32, float32, float32) }
-       op_def("dmax") { op_values(float64, float64, float64) }
-       op_def("nfmax") { op_values(nfloat, nfloat, nfloat) }
-       op_def("isign") { op_values(int, int) }
-       op_def("lsign") { op_values(int, long) }
-       op_def("fsign") { op_values(int, float32) }
-       op_def("dsign") { op_values(int, float64) }
-       op_def("nfsign") { op_values(int, nfloat) }
+       op_def("iabs") { op_values(int, int),
+                        op_intrinsic(jit_int_abs, i_i) }
+       op_def("labs") { op_values(long, long),
+                        op_intrinsic(jit_long_abs, l_l) }
+       op_def("fabs") { op_values(float32, float32),
+                        op_intrinsic(jit_float32_abs, f_f) }
+       op_def("dabs") { op_values(float64, float64),
+                        op_intrinsic(jit_float64_abs, d_d) }
+       op_def("nfabs") { op_values(nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_abs, D_D) }
+       op_def("imin") { op_values(int, int, int),
+                        op_intrinsic(jit_int_min, i_ii) }
+       op_def("imin_un") { op_values(int, int, int),
+                           op_intrinsic(jit_uint_min, I_II) }
+       op_def("lmin") { op_values(long, long, long),
+                        op_intrinsic(jit_long_min, l_ll) }
+       op_def("lmin_un") { op_values(long, long, long),
+                           op_intrinsic(jit_ulong_min, L_LL) }
+       op_def("fmin") { op_values(float32, float32, float32),
+                        op_intrinsic(jit_float32_min, f_ff) }
+       op_def("dmin") { op_values(float64, float64, float64),
+                        op_intrinsic(jit_float64_min, d_dd) }
+       op_def("nfmin") { op_values(nfloat, nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_min, D_DD) }
+       op_def("imax") { op_values(int, int, int),
+                        op_intrinsic(jit_int_max, i_ii) }
+       op_def("imax_un") { op_values(int, int, int),
+                           op_intrinsic(jit_uint_max, I_II) }
+       op_def("lmax") { op_values(long, long, long),
+                        op_intrinsic(jit_long_max, l_ll) }
+       op_def("lmax_un") { op_values(long, long, long),
+                           op_intrinsic(jit_ulong_max, L_LL) }
+       op_def("fmax") { op_values(float32, float32, float32),
+                        op_intrinsic(jit_float32_max, f_ff) }
+       op_def("dmax") { op_values(float64, float64, float64),
+                        op_intrinsic(jit_float64_max, d_dd) }
+       op_def("nfmax") { op_values(nfloat, nfloat, nfloat),
+                         op_intrinsic(jit_nfloat_max, D_DD) }
+       op_def("isign") { op_values(int, int),
+                         op_intrinsic(jit_int_sign, i_i) }
+       op_def("lsign") { op_values(int, long),
+                         op_intrinsic(jit_long_sign, i_l) }
+       op_def("fsign") { op_values(int, float32),
+                         op_intrinsic(jit_float32_sign, i_f) }
+       op_def("dsign") { op_values(int, float64),
+                         op_intrinsic(jit_float64_sign, i_d) }
+       op_def("nfsign") { op_values(int, nfloat),
+                          op_intrinsic(jit_nfloat_sign, i_D) }
        /*
         * Pointer check opcodes.
         */
index ef2af91d84f59e15e2293547e87704d7eee5014e..965afe9c17c4ef237ec31424ef3271aff3c4a754 100644 (file)
@@ -47,6 +47,7 @@ libjit_la_SOURCES = \
        jit-memory.c \
        jit-memory.h \
        jit-meta.c \
+       jit-opcode-apply.c \
        jit-objmodel.c \
        jit-opcode.c \
        jit-pool.c \
index 35961ab65d858ecf329e7896c68b75959748b39b..83d0bb48cfb977533b688ba39bec216d1e903f05 100644 (file)
@@ -757,6 +757,103 @@ extern struct _jit_type const _jit_type_float64_def;
 extern struct _jit_type const _jit_type_nfloat_def;
 extern struct _jit_type const _jit_type_void_ptr_def;
 
+/*
+ * Intrinsic signatures.
+ *
+ * Naming convention is return type folowed by an underscore and the
+ * argument types.
+ *
+ * jit_int     -> i  (lower case I)
+ * jit_uint    -> I
+ * jit_long    -> l  (lower case L)
+ * jit_ulong   -> L
+ * jit_float32 -> f
+ * jit_float64 -> d
+ * jit_nflloat -> D
+ *
+ * pointer     -> p  followed by the type
+ *
+ * Special signatures are conv and conv_ovf for type conversions without
+ * and with overflow checks.
+ */
+enum
+{
+       JIT_SIG_NONE    = 0,
+       JIT_SIG_i_i     = 1,
+       JIT_SIG_i_ii    = 2,
+       JIT_SIG_i_piii  = 3,
+       JIT_SIG_i_iI    = 4,
+       JIT_SIG_i_II    = 5,
+       JIT_SIG_I_I     = 6,
+       JIT_SIG_I_II    = 7,
+       JIT_SIG_i_pIII  = 8,
+       JIT_SIG_l_l     = 9,
+       JIT_SIG_l_ll    = 10,
+       JIT_SIG_i_plll  = 11,
+       JIT_SIG_i_l     = 12,
+       JIT_SIG_i_ll    = 13,
+       JIT_SIG_l_lI    = 14,
+       JIT_SIG_L_L     = 15,
+       JIT_SIG_L_LL    = 16,
+       JIT_SIG_i_pLLL  = 17,
+       JIT_SIG_i_LL    = 18,
+       JIT_SIG_L_LI    = 19,
+       JIT_SIG_f_f     = 20,
+       JIT_SIG_f_ff    = 21,
+       JIT_SIG_i_f     = 22,
+       JIT_SIG_i_ff    = 23,
+       JIT_SIG_d_d     = 24,
+       JIT_SIG_d_dd    = 25,
+       JIT_SIG_i_d     = 26,
+       JIT_SIG_i_dd    = 27,
+       JIT_SIG_D_D     = 28,
+       JIT_SIG_D_DD    = 29,
+       JIT_SIG_i_D     = 30,
+       JIT_SIG_i_DD    = 31,
+       JIT_SIG_conv    = 32,
+       JIT_SIG_conv_ovf= 33
+} _jit_intrinsic_signature;
+
+/*
+ * Flags for the instinsic info.
+ */
+#define _JIT_INTRINSIC_FLAG_NONE               0x0000
+#define _JIT_INTRINSIC_FLAG_BRANCH             0x8000
+#define _JIT_INTRINSIC_FLAG_BRANCH_UNARY       0xC000
+#define _JIT_INTRINSIC_FLAG_NOT                        0x4000
+#define _JIT_INTRINSIC_FLAG_MASK               0xC000
+
+/*
+ * Addititional intrinsic flags for the unary branches.
+ */
+#define _JIT_INTRINSIC_FLAG_IFALSE             0x0000
+#define _JIT_INTRINSIC_FLAG_ITRUE              0x0001
+#define _JIT_INTRINSIC_FLAG_LFALSE             0x0002
+#define _JIT_INTRINSIC_FLAG_LTRUE              0x0003
+
+/*
+ * Descriprion for the implementation of an opcode by an intrinsic.
+ */
+typedef struct _jit_intrinsic_info _jit_intrinsic_info_t;
+struct _jit_intrinsic_info
+{
+       jit_short       flags;
+       jit_short       signature;
+       void            *intrinsic;
+};
+
+extern _jit_intrinsic_info_t const _jit_intrinsics[JIT_OP_NUM_OPCODES];
+
+/*
+ * Apply an opcode to one or two constant values.
+ * Returns the constant result value on success and NULL otherwise.
+ * NOTE: dest_type MUST be either the correct destination type for the
+ * opcode or a tagged type of the correct destination type.
+ */
+jit_value_t
+_jit_opcode_apply(jit_function_t func, jit_uint opcode, jit_type_t dest_type,
+                 jit_value_t value1, jit_value_t value2);
+
 /*
  * Extra call flags for internal use.
  */
diff --git a/jit/jit-opcode-apply.c b/jit/jit-opcode-apply.c
new file mode 100644 (file)
index 0000000..494436b
--- /dev/null
@@ -0,0 +1,887 @@
+/*
+ * jit-opcode-apply.c - Constant folding.
+ *
+ * Copyright (C) 2008  Southern Storm Software, Pty Ltd.
+ *
+ * This file is part of the libjit library.
+ *
+ * The libjit library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The libjit library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the libjit library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include "jit-internal.h"
+#include "jit-rules.h"
+
+/*
+ * Signatures for the different intrinsics
+ */
+typedef jit_int (*jit_cf_i_i_func)(jit_int value);
+typedef jit_int (*jit_cf_i_ii_func)(jit_int value1, jit_int value2);
+typedef jit_int (*jit_cf_i_piii_func)(jit_int *result, jit_int value1, jit_int value2);
+typedef jit_int (*jit_cf_i_iI_func)(jit_int value1, jit_uint value2);
+typedef jit_int (*jit_cf_i_II_func)(jit_uint value1, jit_uint value2);
+typedef jit_uint (*jit_cf_I_I_func)(jit_uint value);
+typedef jit_uint (*jit_cf_I_II_func)(jit_uint value1, jit_uint value2);
+typedef jit_int (*jit_cf_i_pIII_func)(jit_uint *result, jit_uint value1, jit_uint value2);
+typedef jit_long (*jit_cf_l_l_func)(jit_long value);
+typedef jit_long (*jit_cf_l_ll_func)(jit_long value1, jit_long value2);
+typedef jit_int (*jit_cf_i_plll_func)(jit_long *result, jit_long value1, jit_long value2);
+typedef jit_int (*jit_cf_i_l_func)(jit_long value);
+typedef jit_int (*jit_cf_i_ll_func)(jit_long value1, jit_long value2);
+typedef jit_long (*jit_cf_l_lI_func)(jit_long value1, jit_uint value2);
+typedef jit_ulong (*jit_cf_L_L_func)(jit_ulong value);
+typedef jit_ulong (*jit_cf_L_LL_func)(jit_ulong value1, jit_ulong value2);
+typedef jit_int (*jit_cf_i_pLLL_func)(jit_ulong *result, jit_ulong value1, jit_ulong value2);
+typedef jit_int (*jit_cf_i_LL_func)(jit_ulong value1, jit_ulong value2);
+typedef jit_ulong (*jit_cf_L_LI_func)(jit_ulong value1, jit_uint value2);
+typedef jit_float32 (*jit_cf_f_f_func)(jit_float32 value);
+typedef jit_float32 (*jit_cf_f_ff_func)(jit_float32 value1, jit_float32 value2);
+typedef jit_int (*jit_cf_i_f_func)(jit_float32 value);
+typedef jit_int (*jit_cf_i_ff_func)(jit_float32 value1, jit_float32 value2);
+typedef jit_float64 (*jit_cf_d_d_func)(jit_float64 value);
+typedef jit_float64 (*jit_cf_d_dd_func)(jit_float64 value1, jit_float64 value2);
+typedef jit_int (*jit_cf_i_d_func)(jit_float64 value);
+typedef jit_int (*jit_cf_i_dd_func)(jit_float64 value1, jit_float64 value2);
+typedef jit_nfloat (*jit_cf_D_D_func)(jit_nfloat value);
+typedef jit_nfloat (*jit_cf_D_DD_func)(jit_nfloat value1, jit_nfloat value2);
+typedef jit_int (*jit_cf_i_D_func)(jit_nfloat value);
+typedef jit_int (*jit_cf_i_DD_func)(jit_nfloat value1, jit_nfloat value2);
+
+/*
+ * NOTE: The result type is already set in const_result.
+ */
+static int
+apply_conv(jit_constant_t *const_result, jit_value_t value, int overflow_check)
+{
+       jit_type_t srctype;
+       jit_constant_t const_value;
+
+       srctype = jit_type_promote_int(jit_type_normalize(value->type));
+       if(!srctype)
+       {
+               return 0;
+       }
+       const_value.type = srctype;
+       switch(srctype->kind)
+       {
+               case JIT_TYPE_INT:
+               {
+                       const_value.un.int_value = value->address;
+               }
+               break;
+
+               case JIT_TYPE_UINT:
+               {
+                       const_value.un.uint_value = value->address;
+               }
+               break;
+
+               case JIT_TYPE_LONG:
+               {
+#ifdef JIT_NATIVE_INT64
+                       const_value.un.long_value = value->address;
+#else
+                       const_value.un.long_value = *(jit_long *)(value->address);
+#endif
+               }
+               break;
+
+               case JIT_TYPE_ULONG:
+               {
+#ifdef JIT_NATIVE_INT64
+                       const_value.un.ulong_value = value->address;
+#else
+                       const_value.un.ulong_value = *(jit_ulong *)(value->address);
+#endif
+               }
+               break;
+
+               case JIT_TYPE_FLOAT32:
+               {
+                       const_value.un.float32_value = *(jit_float32 *)(value->address);
+               }
+               break;
+
+               case JIT_TYPE_FLOAT64:
+               {
+                       const_value.un.float64_value = *(jit_float64 *)(value->address);
+               }
+               break;
+
+               case JIT_TYPE_NFLOAT:
+               {
+                       const_value.un.nfloat_value = *(jit_nfloat *)(value->address);
+               }
+               break;
+
+               default:
+               {
+                       return 0;
+               }
+       }
+       return jit_constant_convert(const_result, &const_value,
+                                   const_result->type, overflow_check);
+}
+
+/*
+ * NOTE: value1 is guaranteed to be valid and a constant n entry of each
+ * of the apply_* functions.
+ * This is checked on entry of the public _jit_opcode_apply function.
+ */
+static int
+apply_i_i(jit_constant_t *const_result, jit_value_t value1,
+         jit_cf_i_i_func intrinsic)
+{
+       if(value1->is_nint_constant)
+       {
+               const_result->un.int_value = (*intrinsic)(value1->address);
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_ii(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_i_ii_func intrinsic)
+{
+       if(value1->is_nint_constant && value2 && value2->is_nint_constant)
+       {
+               const_result->un.int_value = (*intrinsic)(value1->address,
+                                                         value2->address);
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_piii(jit_constant_t *const_result,
+            jit_value_t value1, jit_value_t value2,
+            jit_cf_i_piii_func intrinsic)
+{
+       if(value1->is_nint_constant && value2 && value2->is_nint_constant)
+       {
+               return (*intrinsic)(&(const_result->un.int_value),
+                                   value1->address, value2->address);
+       }
+       return 0;
+}
+
+static int
+apply_i_iI(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_i_iI_func intrinsic)
+{
+       if(value1->is_nint_constant && value2 && value2->is_nint_constant)
+       {
+               const_result->un.int_value = (*intrinsic)(value1->address,
+                                                         value2->address);
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_II(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_i_II_func intrinsic)
+{
+       if(value1->is_nint_constant && value2 && value2->is_nint_constant)
+       {
+               const_result->un.int_value = (*intrinsic)(value1->address, value2->address);
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_I_I(jit_constant_t *const_result, jit_value_t value1,
+         jit_cf_I_I_func intrinsic)
+{
+       if(value1->is_nint_constant)
+       {
+               const_result->un.uint_value = (*intrinsic)(value1->address);
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_I_II(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_I_II_func intrinsic)
+{
+       if(value1->is_nint_constant && value2 && value2->is_nint_constant)
+       {
+               const_result->un.uint_value = (*intrinsic)(value1->address, value2->address);
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_pIII(jit_constant_t *const_result,
+            jit_value_t value1, jit_value_t value2,
+            jit_cf_i_pIII_func intrinsic)
+{
+       if(value1->is_nint_constant && value2 && value2->is_nint_constant)
+       {
+               return (*intrinsic)(&(const_result->un.uint_value),
+                                   value1->address, value2->address);
+       }
+       return 0;
+}
+
+static int
+apply_l_l(jit_constant_t *const_result, jit_value_t value1,
+         jit_cf_l_l_func intrinsic)
+{
+#ifdef JIT_NATIVE_INT64
+       const_result->un.long_value = (*intrinsic)(value1->address);
+#else
+       const_result->un.long_value = (*intrinsic)(*(jit_long *)(value1->address));
+#endif
+       return 1;
+}
+
+static int
+apply_l_ll(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_l_ll_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+#ifdef JIT_NATIVE_INT64
+               const_result->un.long_value = (*intrinsic)(value1->address,
+                                                          value2->address);
+#else
+               const_result->un.long_value = (*intrinsic)(*(jit_long *)(value1->address),
+                                                          *(jit_long *)(value2->address));
+#endif
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_plll(jit_constant_t *const_result,
+            jit_value_t value1, jit_value_t value2,
+            jit_cf_i_plll_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+#ifdef JIT_NATIVE_INT64
+               return (*intrinsic)(&(const_result->un.long_value),
+                                   value1->address, value2->address);
+#else
+               return (*intrinsic)(&(const_result->un.long_value),
+                                   *(jit_long *)(value1->address),
+                                   *(jit_long *)(value2->address)))
+#endif
+       }
+       return 0;
+}
+
+static int
+apply_i_l(jit_constant_t *const_result,
+         jit_value_t value, jit_cf_i_l_func intrinsic)
+{
+#ifdef JIT_NATIVE_INT64
+       const_result->un.int_value = (*intrinsic)(value->address);
+#else
+       const_result->un.int_value = (*intrinsic)(*(jit_long *)(value->address));
+#endif
+       return 1;
+}
+
+static int
+apply_i_ll(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_i_ll_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+#ifdef JIT_NATIVE_INT64
+               const_result->un.int_value = (*intrinsic)(value1->address,
+                                                         value2->address);
+#else
+               const_result->un.int_value = (*intrinsic)(*(jit_long *)(value1->address),
+                                                         *(jit_long *)(value2->address));
+#endif
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_l_lI(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_l_lI_func intrinsic)
+{
+       if(value2 && value2->is_nint_constant)
+       {
+#ifdef JIT_NATIVE_INT64
+               const_result->un.long_value = (*intrinsic)(value1->address,
+                                                          value2->address);
+#else
+               const_result->un.long_value = (*intrinsic)(*(jit_long *)(value1->address),
+                                                          value2->address);
+#endif
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_L_L(jit_constant_t *const_result, jit_value_t value,
+         jit_cf_L_L_func intrinsic)
+{
+#ifdef JIT_NATIVE_INT64
+       const_result->un.ulong_value = (*intrinsic)(value->address);
+#else
+       const_result->un.ulong_value = (*intrinsic)(*(jit_ulong *)(value->address));
+#endif
+       return 1;
+}
+
+static int
+apply_L_LL(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_L_LL_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+#ifdef JIT_NATIVE_INT64
+               const_result->un.ulong_value = (*intrinsic)(value1->address,
+                                                           value2->address);
+#else
+               const_result->un.ulong_value = (*intrinsic)(*(jit_ulong *)(value1->address),
+                                                           *(jit_ulong *)(value2->address));
+#endif
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_pLLL(jit_constant_t *const_result,
+            jit_value_t value1, jit_value_t value2,
+            jit_cf_i_pLLL_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+#ifdef JIT_NATIVE_INT64
+               return (*intrinsic)(&(const_result->un.ulong_value),
+                                   value1->address, value2->address);
+#else
+               return (*intrinsic)(&(const_result->un.ulong_value),
+                                   *(jit_ulong *)(value1->address),
+                                   *(jit_ulong *)(value2->address));
+#endif
+       }
+       return 0;
+}
+
+static int
+apply_i_LL(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_i_LL_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+#ifdef JIT_NATIVE_INT64
+               const_result->un.int_value = (*intrinsic)(value1->address,
+                                                         value2->address);
+#else
+               const_result->un.int_value = (*intrinsic)(*(jit_ulong *)(value1->address),
+                                                         *(jit_ulong *)(value2->address));
+#endif
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_L_LI(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_L_LI_func intrinsic)
+{
+       if(value2 && value2->is_nint_constant)
+       {
+#ifdef JIT_NATIVE_INT64
+               const_result->un.ulong_value = (*intrinsic)(value1->address,
+                                                           value2->address);
+#else
+               const_result->un.ulong_value = (*intrinsic)(*(jit_ulong *)(value1->address),
+                                                           value2->address);
+#endif
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_f_f(jit_constant_t *const_result, jit_value_t value,
+         jit_cf_f_f_func intrinsic)
+{
+       const_result->un.float32_value = (*intrinsic)(*(jit_float32 *)(value->address));
+       return 1;
+}
+
+static int
+apply_f_ff(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_f_ff_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+               const_result->un.float32_value = (*intrinsic)(*(jit_float32 *)(value1->address),
+                                                             *(jit_float32 *)(value2->address));
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_f(jit_constant_t *const_result, jit_value_t value,
+         jit_cf_i_f_func intrinsic)
+{
+       const_result->un.int_value = (*intrinsic)(*(jit_float32 *)(value->address));
+       return 1;
+}
+
+static int
+apply_i_ff(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_i_ff_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+               const_result->un.int_value = (*intrinsic)(*(jit_float32 *)(value1->address),
+                                                         *(jit_float32 *)(value2->address));
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_d_d(jit_constant_t *const_result, jit_value_t value,
+         jit_cf_d_d_func intrinsic)
+{
+       const_result->un.float64_value = (*intrinsic)(*(jit_float64 *)(value->address));
+       return 1;
+}
+
+static int
+apply_d_dd(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_d_dd_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+               const_result->un.float64_value = (*intrinsic)(*(jit_float64 *)(value1->address),
+                                                             *(jit_float64 *)(value2->address));
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_d(jit_constant_t *const_result, jit_value_t value,
+         jit_cf_i_d_func intrinsic)
+{
+       const_result->un.int_value = (*intrinsic)(*(jit_float64 *)(value->address));
+       return 1;
+}
+
+static int
+apply_i_dd(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_i_dd_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+               const_result->un.int_value = (*intrinsic)(*(jit_float64 *)(value1->address),
+                                                         *(jit_float64 *)(value2->address));
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_D_D(jit_constant_t *const_result, jit_value_t value,
+         jit_cf_D_D_func intrinsic)
+{
+       const_result->un.nfloat_value = (*intrinsic)(*(jit_nfloat *)(value->address));
+       return 1;
+}
+
+static int
+apply_D_DD(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_D_DD_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+               const_result->un.nfloat_value = (*intrinsic)(*(jit_nfloat *)(value1->address),
+                                                            *(jit_nfloat *)(value2->address));
+               return 1;
+       }
+       return 0;
+}
+
+static int
+apply_i_D(jit_constant_t *const_result,
+         jit_value_t value, jit_cf_i_D_func intrinsic)
+{
+       const_result->un.int_value = (*intrinsic)(*(jit_nfloat *)(value->address));
+       return 1;
+}
+
+static int
+apply_i_DD(jit_constant_t *const_result,
+          jit_value_t value1, jit_value_t value2,
+          jit_cf_i_DD_func intrinsic)
+{
+       if(value2 && value2->is_constant)
+       {
+               const_result->un.int_value = (*intrinsic)(*(jit_nfloat *)(value1->address),
+                                                         *(jit_nfloat *)(value2->address));
+               return 1;
+       }
+       return 0;
+}
+
+static jit_value_t
+apply_opcode(jit_function_t func, const _jit_intrinsic_info_t *opcode_info,
+            jit_type_t dest_type, jit_value_t value1, jit_value_t value2)
+{
+       jit_constant_t const_result;
+       int result = 0;
+
+       const_result.type = dest_type;
+       switch(opcode_info->signature)
+       {
+               case JIT_SIG_i_i:
+               {
+                       result = apply_i_i
+                                (&const_result, value1,
+                                (jit_cf_i_i_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_ii:
+               {
+                       result = apply_i_ii
+                                (&const_result, value1, value2,
+                                (jit_cf_i_ii_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_piii:
+               {
+                       result = apply_i_piii
+                                (&const_result, value1, value2,
+                                (jit_cf_i_piii_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_iI:
+               {
+                       result = apply_i_iI
+                                (&const_result, value1, value2,
+                                (jit_cf_i_iI_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_II:
+               {
+                       result = apply_i_II
+                                (&const_result, value1, value2,
+                                (jit_cf_i_II_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_I_I:
+               {
+                       result = apply_I_I
+                                (&const_result, value1,
+                                (jit_cf_I_I_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_I_II:
+               {
+                       result = apply_I_II
+                                (&const_result, value1, value2,
+                                (jit_cf_I_II_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_pIII:
+               {
+                       result = apply_i_pIII
+                                (&const_result, value1, value2,
+                                (jit_cf_i_pIII_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_l_l:
+               {
+                       result = apply_l_l
+                                (&const_result, value1,
+                                (jit_cf_l_l_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_l_ll:
+               {
+                       result = apply_l_ll
+                                (&const_result, value1, value2,
+                                (jit_cf_l_ll_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_plll:
+               {
+                       result = apply_i_plll
+                                (&const_result, value1, value2,
+                                (jit_cf_i_plll_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_l:
+               {
+                       result = apply_i_l
+                                (&const_result, value1,
+                                (jit_cf_i_l_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_ll:
+               {
+                       result = apply_i_ll
+                                (&const_result, value1, value2,
+                                (jit_cf_i_ll_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_l_lI:
+               {
+                       result = apply_l_lI
+                                (&const_result, value1, value2,
+                                (jit_cf_l_lI_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_L_L:
+               {
+                       result = apply_L_L
+                                (&const_result, value1,
+                                (jit_cf_L_L_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_L_LL:
+               {
+                       result = apply_L_LL
+                                (&const_result, value1, value2,
+                                (jit_cf_L_LL_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_pLLL:
+               {
+                       result = apply_i_pLLL
+                                (&const_result, value1, value2,
+                                (jit_cf_i_pLLL_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_LL:
+               {
+                       result = apply_i_LL
+                                (&const_result, value1, value2,
+                                (jit_cf_i_LL_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_L_LI:
+               {
+                       result = apply_L_LI
+                                (&const_result, value1, value2,
+                                (jit_cf_L_LI_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_f_f:
+               {
+                       result = apply_f_f
+                                (&const_result, value1,
+                                (jit_cf_f_f_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_f_ff:
+               {
+                       result = apply_f_ff
+                                (&const_result, value1, value2,
+                                (jit_cf_f_ff_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_f:
+               {
+                       result = apply_i_f
+                                (&const_result, value1,
+                                (jit_cf_i_f_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_ff:
+               {
+                       result = apply_i_ff
+                                (&const_result, value1, value2,
+                                (jit_cf_i_ff_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_d_d:
+               {
+                       result = apply_d_d
+                                (&const_result, value1,
+                                (jit_cf_d_d_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_d_dd:
+               {
+                       result = apply_d_dd
+                                (&const_result, value1, value2,
+                                (jit_cf_d_dd_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_d:
+               {
+                       result = apply_i_d
+                                (&const_result, value1,
+                                (jit_cf_i_d_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_dd:
+               {
+                       result = apply_i_dd
+                                (&const_result, value1, value2,
+                                (jit_cf_i_dd_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_D_D:
+               {
+                       result = apply_D_D
+                                (&const_result, value1,
+                                (jit_cf_D_D_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_D_DD:
+               {
+                       result = apply_D_DD
+                                (&const_result, value1, value2,
+                                (jit_cf_D_DD_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_D:
+               {
+                       result = apply_i_D
+                                (&const_result, value1,
+                                (jit_cf_i_D_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_i_DD:
+               {
+                       result = apply_i_DD
+                                (&const_result, value1, value2,
+                                (jit_cf_i_DD_func)opcode_info->intrinsic);
+               }
+               break;
+
+               case JIT_SIG_conv:
+               {
+                       result = apply_conv(&const_result, value1, 0);
+               }
+               break;
+
+               case JIT_SIG_conv_ovf:
+               {
+                       result = apply_conv(&const_result, value1, 1);
+               }
+               break;
+       }
+       if(result)
+       {
+               return jit_value_create_constant(func, &const_result);
+       }
+       return 0;
+}
+
+jit_value_t
+_jit_opcode_apply(jit_function_t func, jit_uint opcode, jit_type_t dest_type,
+                 jit_value_t value1, jit_value_t value2)
+{
+       const _jit_intrinsic_info_t *opcode_info;
+
+       if(!func || opcode >= JIT_OP_NUM_OPCODES)
+       {
+               return 0;
+       }
+       if((value1 == 0) || !(value1->is_constant))
+       {
+               return 0;
+       }
+       opcode_info = &(_jit_intrinsics[opcode]);
+       if((opcode_info->flags & _JIT_INTRINSIC_FLAG_MASK) ==
+          _JIT_INTRINSIC_FLAG_NOT)
+       {
+               jit_value_t value;
+               
+               opcode = opcode_info->flags & ~_JIT_INTRINSIC_FLAG_MASK;
+               if(opcode >= JIT_OP_NUM_OPCODES)
+               {
+                       return 0;
+               }
+               opcode_info = &(_jit_intrinsics[opcode]);
+               value = apply_opcode(func, opcode_info, dest_type, value1, value2);
+               if(value)
+               {
+                       /*
+                        * We have to apply a logical not to the constant
+                        * jit_int result value.
+                        */
+                       value->address = !(value->address);
+                       return value;
+               }
+       }
+       else if((opcode_info->flags & _JIT_INTRINSIC_FLAG_MASK) ==
+             _JIT_INTRINSIC_FLAG_NONE)
+       {
+               return apply_opcode(func, opcode_info, dest_type, value1, value2);
+       }
+       return 0;
+}
+
index 35dc0512eaebb33437cd97e97f6852bbbe5268f3..a6ac448e5ba45c94b41e33f89f299382e1cbd162 100644 (file)
@@ -50,6 +50,7 @@ extern char yytext[];
 #define TASK_GEN_NONE          0
 #define TASK_GEN_HEADER                1
 #define TASK_GEN_TABLE         2
+#define TASK_GEN_CF_TABLE      3
  
 /*
  * Value Flags
@@ -99,15 +100,60 @@ extern char yytext[];
 #define        OP_COPY                 0x14
 #define        OP_ADDRESS_OF           0x15
 
+/*
+ * Intrinisc signatures
+ */
+#define SIG_NONE       0
+#define SIG_i_i                1
+#define SIG_i_ii       2
+#define SIG_i_piii     3
+#define SIG_i_iI       4
+#define SIG_i_II       5
+#define SIG_I_I                6
+#define SIG_I_II       7
+#define SIG_i_pIII     8
+#define SIG_l_l                9
+#define SIG_l_ll       10
+#define SIG_i_plll     11
+#define SIG_i_l                12
+#define SIG_i_ll       13
+#define SIG_l_lI       14
+#define SIG_L_L                15
+#define SIG_L_LL       16
+#define SIG_i_pLLL     17
+#define SIG_i_LL       18
+#define SIG_L_LI       19
+#define SIG_f_f                20
+#define SIG_f_ff       21
+#define SIG_i_f                22
+#define SIG_i_ff       23
+#define SIG_d_d                24
+#define SIG_d_dd       25
+#define SIG_i_d                26
+#define SIG_i_dd       27
+#define SIG_D_D                28
+#define SIG_D_DD       29
+#define SIG_i_D                30
+#define SIG_i_DD       31
+#define SIG_conv       32
+#define SIG_conv_ovf   33
+
 /*
  * Current file and line number.
  */
 extern char *genops_filename;
 extern long genops_linenum;
 
+struct intrinsic_info
+{
+       const char             *flags;
+       int                     signature;
+       const char             *intrinsic;
+};
+
 struct genops_opcode
 {
-       struct genops_opcode   *next;
+       struct genops_opcode     *next;
        const char             *name;
        int                     type;
        int                     oper;
@@ -115,6 +161,7 @@ struct genops_opcode
        int                     input1_flags;
        int                     input2_flags;
        const char             *expression;
+       struct intrinsic_info   intrinsic_info;
 };
 
 /*
@@ -140,6 +187,12 @@ static int genops_task = TASK_GEN_NONE;
 static FILE *genops_file = 0;
 static int genops_file_needs_close = 0;
 
+/*
+ * options
+ */
+static int genops_gen_intrinsic_table = 0;
+static const char *genops_intrinsic_decl = 0;
+
 /*
  * Blocks coppied to the resulting file.
  */
@@ -201,7 +254,10 @@ genops_create_opcode_header(const char *define_start, const char *declaration,
  * Create an opcode entry
  */
 static struct genops_opcode *
-genops_add_opcode(const char *name, int type, int oper, int dest_flags, int input1_flags, int input2_flags, const char *expression)
+genops_add_opcode(const char *name, int type, int oper, int dest_flags,
+                 int input1_flags, int input2_flags, const char *expression,
+                 const char *intrinsic_flags, int signature,
+                 const char *intrinsic)
 {
        struct genops_opcode *opcode;
 
@@ -229,6 +285,9 @@ genops_add_opcode(const char *name, int type, int oper, int dest_flags, int inpu
        opcode->input1_flags= input1_flags;
        opcode->input2_flags= input2_flags;
        opcode->expression = expression;
+       opcode->intrinsic_info.flags = intrinsic_flags;
+       opcode->intrinsic_info.signature = signature;
+       opcode->intrinsic_info.intrinsic = intrinsic;
 
        return opcode;
 }
@@ -509,6 +568,220 @@ genops_output_value_flags(const char *prefix, int flags, int needs_or)
        return needs_or;
 }
 
+/*
+ *
+ */
+static void
+genops_output_signature(int signature)
+{
+       switch(signature)
+       {
+               case SIG_NONE:
+               {
+                       printf("JIT_SIG_NONE");
+               }
+               break;
+
+               case SIG_i_i:
+               {
+                       printf("JIT_SIG_i_i");
+               }
+               break;
+
+               case SIG_i_ii:
+               {
+                       printf("JIT_SIG_i_ii");
+               }
+               break;
+
+               case SIG_i_piii:
+               {
+                       printf("JIT_SIG_i_piii");
+               }
+               break;
+
+               case SIG_i_iI:
+               {
+                       printf("JIT_SIG_i_iI");
+               }
+               break;
+
+               case SIG_i_II:
+               {
+                       printf("JIT_SIG_i_II");
+               }
+               break;
+
+               case SIG_I_I:
+               {
+                       printf("JIT_SIG_I_I");
+               }
+               break;
+
+               case SIG_I_II:
+               {
+                       printf("JIT_SIG_I_II");
+               }
+               break;
+
+               case SIG_i_pIII:
+               {
+                       printf("JIT_SIG_i_pIII");
+               }
+               break;
+
+               case SIG_l_l:
+               {
+                       printf("JIT_SIG_l_l");
+               }
+               break;
+
+               case SIG_l_ll:
+               {
+                       printf("JIT_SIG_l_ll");
+               }
+               break;
+
+               case SIG_i_plll:
+               {
+                       printf("JIT_SIG_i_plll");
+               }
+               break;
+
+               case SIG_i_l:
+               {
+                       printf("JIT_SIG_i_l");
+               }
+               break;
+
+               case SIG_i_ll:
+               {
+                       printf("JIT_SIG_i_ll");
+               }
+               break;
+
+               case SIG_l_lI:
+               {
+                       printf("JIT_SIG_l_lI");
+               }
+               break;
+
+               case SIG_L_L:
+               {
+                       printf("JIT_SIG_L_L");
+               }
+               break;
+
+               case SIG_L_LL:
+               {
+                       printf("JIT_SIG_L_LL");
+               }
+               break;
+
+               case SIG_i_pLLL:
+               {
+                       printf("JIT_SIG_i_pLLL");
+               }
+               break;
+
+               case SIG_i_LL:
+               {
+                       printf("JIT_SIG_i_LL");
+               }
+               break;
+
+               case SIG_L_LI:
+               {
+                       printf("JIT_SIG_L_LI");
+               }
+               break;
+
+               case SIG_f_f:
+               {
+                       printf("JIT_SIG_f_f");
+               }
+               break;
+
+               case SIG_f_ff:
+               {
+                       printf("JIT_SIG_f_ff");
+               }
+               break;
+
+               case SIG_i_f:
+               {
+                       printf("JIT_SIG_i_f");
+               }
+               break;
+
+               case SIG_i_ff:
+               {
+                       printf("JIT_SIG_i_ff");
+               }
+               break;
+
+               case SIG_d_d:
+               {
+                       printf("JIT_SIG_d_d");
+               }
+               break;
+
+               case SIG_d_dd:
+               {
+                       printf("JIT_SIG_d_dd");
+               }
+               break;
+
+               case SIG_i_d:
+               {
+                       printf("JIT_SIG_i_d");
+               }
+               break;
+
+               case SIG_i_dd:
+               {
+                       printf("JIT_SIG_i_dd");
+               }
+               break;
+
+               case SIG_D_D:
+               {
+                       printf("JIT_SIG_D_D");
+               }
+               break;
+
+               case SIG_D_DD:
+               {
+                       printf("JIT_SIG_D_DD");
+               }
+               break;
+
+               case SIG_i_D:
+               {
+                       printf("JIT_SIG_i_D");
+               }
+               break;
+
+               case SIG_i_DD:
+               {
+                       printf("JIT_SIG_i_DD");
+               }
+               break;
+
+               case SIG_conv:
+               {
+                       printf("JIT_SIG_conv");
+               }
+               break;
+
+               case SIG_conv_ovf:
+               {
+                       printf("JIT_SIG_conv_ovf");
+               }
+               break;
+       }
+}
+
 /*
  * Create an upper-case copy of a string.
  */
@@ -530,6 +803,37 @@ genops_string_upper(const char *string)
        return 0;
 }
 
+static int
+genops_set_option(const char *option, const char *value)
+{
+       if(!strcmp(option, "gen_intrinsic_table"))
+       {
+               if(!strcmp(value, "yes"))
+               {
+                       genops_gen_intrinsic_table = 1;
+               }
+               else if(!strcmp(value, "no"))
+               {
+                       genops_gen_intrinsic_table = 0;
+               }
+               else
+               {
+                       yyerror("Invalid boolean value for the option. Allowed values: yes | no");
+                       return 0;
+               }
+       }
+       else if(!strcmp(option, "intrinsic_table_decl"))
+       {
+               genops_intrinsic_decl = value;
+       }
+       else
+       {
+               yyerror("Invalid option");
+               return 0;
+       }
+       return 1;
+}
+
 %}
 
 /*
@@ -567,8 +871,17 @@ genops_string_upper(const char *string)
                int             input1_flags;
                int             input2_flags;
                const char     *expression;
+               const char     *intrinsic_flags;
+               int             signature;
+               const char     *intrinsic;
        } opcode_properties;
        struct
+       {
+               const char     *intrinsic_flags;
+               int             signature;
+               const char     *intrinsic;
+       } intrinsic_info;
+       struct
        {
                const char     *name;
                int             type;
@@ -577,6 +890,9 @@ genops_string_upper(const char *string)
                int             input1_flags;
                int             input2_flags;
                const char     *expression;
+               const char     *intrinsic_flags;
+               int             signature;
+               const char     *intrinsic;
        } opcode;
 }
 
@@ -592,8 +908,8 @@ genops_string_upper(const char *string)
 %token K_INT                   "int"
 %token K_LONG                  "long"
 %token K_PTR                   "ptr"
-%token K_FLOAT32               "float32"
-%token K_FLOAT64               "float64"
+%token K_FLOAT32                       "float32"
+%token K_FLOAT64                       "float64"
 %token K_NFLOAT                        "nfloat"
 %token K_NEG                   "neg"
 %token K_EQ                    "=="
@@ -612,10 +928,45 @@ genops_string_upper(const char *string)
 %token K_CALL_EXTERNAL         "call_external"
 %token K_JUMP_TABLE            "jump_table"
 %token K_OP_DEF                        "op_def"
-%token K_OP_TYPE               "op_type"
+%token K_OP_INTRINSIC          "op_intrinsic"
+%token K_OP_TYPE                       "op_type"
 %token K_OP_VALUES             "op_values"
-%token K_OPCODES               "opcodes"
+%token K_OPCODES                       "opcodes"
 %token K_REG                   "reg"
+%token K_POPTION                       "%option"
+%token K_i_i                   "i_i"
+%token K_i_ii                  "i_ii"
+%token K_i_piii                        "i_piii"
+%token K_i_iI                  "i_iI"
+%token K_i_II                  "i_II"
+%token K_I_I                   "I_I"
+%token K_I_II                  "I_II"
+%token K_i_pIII                        "i_pIII"
+%token K_l_l                   "l_l"
+%token K_l_ll                  "l_ll"
+%token K_i_plll                        "i_plll"
+%token K_i_l                   "i_l"
+%token K_i_ll                  "i_ll"
+%token K_l_lI                  "l_lI"
+%token K_L_L                   "L_L"
+%token K_L_LL                  "L_LL"
+%token K_i_pLLL                        "i_pLLL"
+%token K_i_LL                  "i_LL"
+%token K_L_LI                  "L_LI"
+%token K_f_f                   "f_f"
+%token K_f_ff                  "f_ff"
+%token K_i_f                   "i_f"
+%token K_i_ff                  "i_ff"
+%token K_d_d                   "d_d"
+%token K_d_dd                  "d_dd"
+%token K_i_d                   "i_d"
+%token K_i_dd                  "i_dd"
+%token K_D_D                   "D_D"
+%token K_D_DD                  "D_DD"
+%token K_i_D                   "i_D"
+%token K_i_DD                  "i_DD"
+%token K_CONV                  "conv"
+%token K_CONV_OVF              "conv_ovf"
 
 /*
  * Define the yylval types of the various non-terminals.
@@ -626,11 +977,13 @@ genops_string_upper(const char *string)
 %type <opcode_list_header>     OpcodeListHeader
 %type <value>                  ValueFlag Op
 %type <value>                  OpcodeType OpcodeTypeFlag
+%type <value>                  Signature
 %type <name>                   OpcodeExpression
 %type <opcode>                 Opcode
 %type <opcode_header>          OpcodeHeader
 %type <opcode_properties>      OpcodeProperties
 %type <opcode_values>          OpcodeValues
+%type <intrinsic_info>         OpcodeIntrinsicInfo
 
 %expect 0
 
@@ -640,11 +993,11 @@ genops_string_upper(const char *string)
 %%
 
 Start
-       : Blocks OpcodeDeclarations Blocks      {
+       : Blocks OptOptions OpcodeDeclarations Blocks   {
                        start_code_block = ($1).code;
                        start_header_block = ($1).header;
-                       end_code_block = ($3).code;;
-                       end_header_block = ($3).header;
+                       end_code_block = ($4).code;;
+                       end_header_block = ($4).header;
                }
        ;
 
@@ -690,14 +1043,20 @@ Opcodes
                                          ($1).oper, ($1).dest_flags,
                                          ($1).input1_flags,
                                          ($1).input2_flags,
-                                         ($1).expression);
+                                         ($1).expression,
+                                         ($1).intrinsic_flags,
+                                         ($1).signature,
+                                         ($1).intrinsic);
                }
        | Opcodes Opcode        {
                        genops_add_opcode(($2).name, ($2).type,
                                          ($2).oper, ($2).dest_flags,
                                          ($2).input1_flags,
                                          ($2).input2_flags,
-                                         ($2).expression);
+                                         ($2).expression,
+                                         ($2).intrinsic_flags,
+                                         ($2).signature,
+                                         ($2).intrinsic);
                }
        ;
 
@@ -710,6 +1069,9 @@ Opcode
                        ($$).input1_flags = VALUE_FLAG_EMPTY;
                        ($$).input2_flags = VALUE_FLAG_EMPTY;
                        ($$).expression = 0;
+                       ($$).intrinsic_flags = 0;
+                       ($$).signature = SIG_NONE;
+                       ($$).intrinsic = 0;;
                }
        | OpcodeHeader '{' OpcodeProperties '}' {
                        ($$).name = ($1).name;
@@ -719,6 +1081,9 @@ Opcode
                        ($$).input1_flags = ($3).input1_flags;
                        ($$).input2_flags = ($3).input2_flags;
                        ($$).expression = ($3).expression;
+                       ($$).intrinsic_flags = ($3).intrinsic_flags;
+                       ($$).signature = ($3).signature;
+                       ($$).intrinsic = ($3).intrinsic;;
                }
        ;
 
@@ -740,6 +1105,9 @@ OpcodeProperties
                        ($$).input1_flags = VALUE_FLAG_EMPTY;
                        ($$).input2_flags = VALUE_FLAG_EMPTY;
                        ($$).expression = 0;
+                       ($$).intrinsic_flags = 0;
+                       ($$).signature = SIG_NONE;
+                       ($$).intrinsic = 0;;
                }
        | OpcodeValues                  {
                        ($$).type = 0;
@@ -747,6 +1115,9 @@ OpcodeProperties
                        ($$).input1_flags = ($1).input1_flags;
                        ($$).input2_flags = ($1).input2_flags;
                        ($$).expression = 0;
+                       ($$).intrinsic_flags = 0;
+                       ($$).signature = SIG_NONE;
+                       ($$).intrinsic = 0;;
                }
        | OpcodeExpression              {
                        ($$).type = 0;
@@ -754,6 +1125,19 @@ OpcodeProperties
                        ($$).input1_flags = VALUE_FLAG_EMPTY;
                        ($$).input2_flags = VALUE_FLAG_EMPTY;
                        ($$).expression = $1;
+                       ($$).intrinsic_flags = 0;
+                       ($$).signature = SIG_NONE;
+                       ($$).intrinsic = 0;;
+               }
+       | OpcodeIntrinsicInfo           {
+                       ($$).type = 0;
+                       ($$).dest_flags = VALUE_FLAG_EMPTY;
+                       ($$).input1_flags = VALUE_FLAG_EMPTY;
+                       ($$).input2_flags = VALUE_FLAG_EMPTY;
+                       ($$).expression = 0;
+                       ($$).intrinsic_flags = ($1).intrinsic_flags;
+                       ($$).signature = ($1).signature;
+                       ($$).intrinsic = ($1).intrinsic;;
                }
        | OpcodeProperties ',' OpcodeType       {
                        ($$).type = $3;
@@ -761,6 +1145,9 @@ OpcodeProperties
                        ($$).input1_flags = ($1).input1_flags;
                        ($$).input2_flags = ($1).input2_flags;
                        ($$).expression = ($1).expression;
+                       ($$).intrinsic_flags = ($1).intrinsic_flags;
+                       ($$).signature = ($1).signature;
+                       ($$).intrinsic = ($1).intrinsic;;
                }
        | OpcodeProperties ',' OpcodeValues     {
                        ($$).type = ($1).type;
@@ -768,6 +1155,9 @@ OpcodeProperties
                        ($$).input1_flags = ($3).input1_flags;
                        ($$).input2_flags = ($3).input2_flags;
                        ($$).expression = ($1).expression;
+                       ($$).intrinsic_flags = ($1).intrinsic_flags;
+                       ($$).signature = ($1).signature;
+                       ($$).intrinsic = ($1).intrinsic;;
                }
        | OpcodeProperties ',' OpcodeExpression {
                        ($$).type = ($1).type;
@@ -775,6 +1165,19 @@ OpcodeProperties
                        ($$).input1_flags = ($1).input1_flags;
                        ($$).input2_flags = ($1).input2_flags;
                        ($$).expression = $3;
+                       ($$).intrinsic_flags = ($1).intrinsic_flags;
+                       ($$).signature = ($1).signature;
+                       ($$).intrinsic = ($1).intrinsic;;
+               }
+       | OpcodeProperties ',' OpcodeIntrinsicInfo      {
+                       ($$).type = ($1).type;
+                       ($$).dest_flags = ($1).dest_flags;
+                       ($$).input1_flags = ($1).input1_flags;
+                       ($$).input2_flags = ($1).input2_flags;
+                       ($$).expression = ($1).expression;
+                       ($$).intrinsic_flags = ($3).intrinsic_flags;
+                       ($$).signature = ($3).signature;
+                       ($$).intrinsic = ($3).intrinsic;;
                }
        ;
 
@@ -849,6 +1252,60 @@ ValueFlag
        | K_ANY                         { $$ = VALUE_FLAG_ANY; }
        ;
 
+OpcodeIntrinsicInfo
+       : K_OP_INTRINSIC '(' Literal ')'        {
+                       ($$).intrinsic_flags = $3;
+                       ($$).signature = SIG_NONE;
+                       ($$).intrinsic = 0;;
+               }
+       | K_OP_INTRINSIC '(' Signature ')'      {
+                       ($$).intrinsic_flags = 0;
+                       ($$).signature = $3;
+                       ($$).intrinsic = 0;
+               }
+       | K_OP_INTRINSIC '(' IDENTIFIER ',' Signature ')'       {
+                       ($$).intrinsic_flags = 0;
+                       ($$).signature = $5;
+                       ($$).intrinsic = $3;
+               }
+       ;
+
+Signature
+       : K_i_i                         { $$ = SIG_i_i; }
+       | K_i_ii                        { $$ = SIG_i_ii; }
+       | K_i_piii                      { $$ = SIG_i_piii; }
+       | K_i_iI                        { $$ = SIG_i_iI; }
+       | K_i_II                        { $$ = SIG_i_II; }
+       | K_I_I                         { $$ = SIG_I_I; }
+       | K_I_II                        { $$ = SIG_I_II; }
+       | K_i_pIII                      { $$ = SIG_i_pIII; }
+       | K_l_l                         { $$ = SIG_l_l; }
+       | K_l_ll                        { $$ = SIG_l_ll; }
+       | K_i_plll                      { $$ = SIG_i_plll; }
+       | K_i_l                         { $$ = SIG_i_l; }
+       | K_i_ll                        { $$ = SIG_i_ll; }
+       | K_l_lI                        { $$ = SIG_l_lI; }
+       | K_L_L                         { $$ = SIG_L_L; }
+       | K_L_LL                        { $$ = SIG_L_LL; }
+       | K_i_pLLL                      { $$ = SIG_i_pLLL; }
+       | K_i_LL                        { $$ = SIG_i_LL; }
+       | K_L_LI                        { $$ = SIG_L_LI; }
+       | K_f_f                         { $$ = SIG_f_f; }
+       | K_f_ff                        { $$ = SIG_f_ff; }
+       | K_i_f                         { $$ = SIG_i_f; }
+       | K_i_ff                        { $$ = SIG_i_ff; }
+       | K_d_d                         { $$ = SIG_d_d; }
+       | K_d_dd                        { $$ = SIG_d_dd; }
+       | K_i_d                         { $$ = SIG_i_d; }
+       | K_i_dd                        { $$ = SIG_i_dd; }
+       | K_D_D                         { $$ = SIG_D_D; }
+       | K_D_DD                        { $$ = SIG_D_DD; }
+       | K_i_D                         { $$ = SIG_i_D; }
+       | K_i_DD                        { $$ = SIG_i_DD; }
+       | K_CONV                        { $$ = SIG_conv; }
+       | K_CONV_OVF                    { $$ = SIG_conv_ovf; }
+       ;
+
 Literal
        : LITERAL                       { $$ = $1; }
        | Literal LITERAL               {
@@ -865,6 +1322,25 @@ Literal
                }
        ;
 
+OptOptions
+       : /* None */                    { }
+       | Options
+       ;
+
+Options
+       : Option
+       | Options Option
+       ;
+
+Option
+       : K_POPTION IDENTIFIER '=' IDENTIFIER   {
+                       genops_set_option($2, $4);
+               }
+       | K_POPTION IDENTIFIER '=' Literal      {
+                       genops_set_option($2, $4);
+               }
+       ;
+
 %%
 
 /*
@@ -1052,6 +1528,49 @@ genops_output_ops(void)
        printf("};\n");
 }
 
+static void
+genops_output_intrinsic_table(const char *define_start)
+{
+       struct genops_opcode *current;
+
+       printf("%s = {\n", genops_intrinsic_decl);
+       current = opcode_header->first_opcode;
+       while(current)
+       {
+               printf("\t{");
+               if(current->intrinsic_info.flags)
+               {
+                       printf("%s", current->intrinsic_info.flags);
+               }
+               else
+               {
+                       printf("%i", 0);
+               }
+               printf(", ");
+               genops_output_signature(current->intrinsic_info.signature);
+               printf(", ");
+               if(current->intrinsic_info.intrinsic)
+               {
+                       printf("%s", current->intrinsic_info.intrinsic);
+               }
+               else
+               {
+                       printf("0");
+               }
+               printf("}");
+               current = current->next;
+               if(current)
+               {
+                       printf(",\n");
+               }
+               else
+               {
+                       printf("\n");
+               }
+       }
+       printf("};\n");
+}
+
 static void
 genops_output_opcode_table(const char *filename)
 {
@@ -1062,6 +1581,11 @@ genops_output_opcode_table(const char *filename)
                printf("%s", start_code_block);
        }
        genops_output_ops();
+       if(genops_gen_intrinsic_table)
+       {
+               printf("\n");
+               genops_output_intrinsic_table(opcode_header->define_start);
+       }
        if(end_code_block)
        {
                printf("%s", end_code_block);
index 25af607868883a025edb7f2bf28b9cf081fc1239..27b428eabde4ca18aef3af03eae4261332b66ba1 100644 (file)
@@ -112,10 +112,45 @@ WHITE                     [ \t\v\r\f]
 "call_external"                { RETURNTOK(K_CALL_EXTERNAL); }
 "jump_table"           { RETURNTOK(K_JUMP_TABLE); }
 "op_def"               { RETURNTOK(K_OP_DEF); }
+"op_intrinsic"         { RETURNTOK(K_OP_INTRINSIC); }
 "op_type"              { RETURNTOK(K_OP_TYPE); }
 "op_values"            { RETURNTOK(K_OP_VALUES); }
 "opcodes"              { RETURNTOK(K_OPCODES); }
 "reg"                  { RETURNTOK(K_REG); }
+"%option"              { RETURNTOK(K_POPTION); }
+"i_i"                  { RETURNTOK(K_i_i); }
+"i_ii"                 { RETURNTOK(K_i_ii); }
+"i_piii"               { RETURNTOK(K_i_piii); }
+"i_iI"                 { RETURNTOK(K_i_iI); }
+"i_II"                 { RETURNTOK(K_i_II); }
+"I_I"                  { RETURNTOK(K_I_I); }
+"I_II"                 { RETURNTOK(K_I_II); }
+"i_pIII"               { RETURNTOK(K_i_pIII); }
+"l_l"                  { RETURNTOK(K_l_l); }
+"l_ll"                 { RETURNTOK(K_l_ll); }
+"i_plll"               { RETURNTOK(K_i_plll); }
+"i_l"                  { RETURNTOK(K_i_l); }
+"i_ll"                 { RETURNTOK(K_i_ll); }
+"l_lI"                 { RETURNTOK(K_l_lI); }
+"L_L"                  { RETURNTOK(K_L_L); }
+"L_LL"                 { RETURNTOK(K_L_LL); }
+"i_pLLL"               { RETURNTOK(K_i_pLLL); }
+"i_LL"                 { RETURNTOK(K_i_LL); }
+"L_LI"                 { RETURNTOK(K_L_LI); }
+"f_f"                  { RETURNTOK(K_f_f); }
+"f_ff"                 { RETURNTOK(K_f_ff); }
+"i_f"                  { RETURNTOK(K_i_f); }
+"i_ff"                 { RETURNTOK(K_i_ff); }
+"d_d"                  { RETURNTOK(K_d_d); }
+"d_dd"                 { RETURNTOK(K_d_dd); }
+"i_d"                  { RETURNTOK(K_i_d); }
+"i_dd"                 { RETURNTOK(K_i_dd); }
+"D_D"                  { RETURNTOK(K_D_D); }
+"D_DD"                 { RETURNTOK(K_D_DD); }
+"i_D"                  { RETURNTOK(K_i_D); }
+"i_DD"                 { RETURNTOK(K_i_DD); }
+"conv"                 { RETURNTOK(K_CONV); }
+"conv_ovf"             { RETURNTOK(K_CONV_OVF); }
 
 "!"?{IDALPHA}({DIGIT}|{IDALPHA})*      {
                        yylval.name = genops_strdup(yytext);