dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (l


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET Just In Time compiler (libjit) branch, master, updated. e60c55a7468143eaf47946fa9518d74a71b27b3b
Date: Tue, 21 Sep 2010 17:42:30 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET Just In Time compiler (libjit)".

The branch, master has been updated
       via  e60c55a7468143eaf47946fa9518d74a71b27b3b (commit)
      from  935c651b7a9e328f77abb068b34cf0fc8cdcd95e (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/libjit.git/commit/?id=e60c55a7468143eaf47946fa9518d74a71b27b3b

commit e60c55a7468143eaf47946fa9518d74a71b27b3b
Author: Klaus Treichel <address@hidden>
Date:   Tue Sep 21 19:42:01 2010 +0200

    Add support for applying an opcode to one or two constant values.

diff --git a/ChangeLog b/ChangeLog
index e051067..45765e2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2010-09-21  Klaus Treichel  <address@hidden>
+
+       * 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  <address@hidden>
 
        * config/jit-opcodes.ops: Remove the *eq_inv and *ne_inv float
diff --git a/config/jit-opcodes.ops b/config/jit-opcodes.ops
index 527b374..d54e628 100644
--- a/config/jit-opcodes.ops
+++ b/config/jit-opcodes.ops
@@ -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.
         */
diff --git a/jit/Makefile.am b/jit/Makefile.am
index ef2af91..965afe9 100644
--- a/jit/Makefile.am
+++ b/jit/Makefile.am
@@ -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 \
diff --git a/jit/jit-internal.h b/jit/jit-internal.h
index 35961ab..83d0bb4 100644
--- a/jit/jit-internal.h
+++ b/jit/jit-internal.h
@@ -758,6 +758,103 @@ 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.
  */
 #define        JIT_CALL_NATIVE         (1 << 14)
diff --git a/jit/jit-opcode-apply.c b/jit/jit-opcode-apply.c
new file mode 100644
index 0000000..494436b
--- /dev/null
+++ b/jit/jit-opcode-apply.c
@@ -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;
+}
+
diff --git a/tools/gen-ops-parser.y b/tools/gen-ops-parser.y
index 35dc051..a6ac448 100644
--- a/tools/gen-ops-parser.y
+++ b/tools/gen-ops-parser.y
@@ -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
@@ -100,14 +101,59 @@ extern char yytext[];
 #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;
 };
 
 /*
@@ -141,6 +188,12 @@ 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.
  */
 static const char *start_code_block = 0;
@@ -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;
 }
@@ -510,6 +569,220 @@ genops_output_value_flags(const char *prefix, int flags, 
int 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.
  */
 static char *
@@ -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,9 +871,18 @@ 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;
                int             oper;
@@ -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);
+               }
+       ;
+
 %%
 
 /*
@@ -1053,6 +1529,49 @@ genops_output_ops(void)
 }
 
 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)
 {
        printf("/%c Automatically generated from %s - DO NOT EDIT %c/\n",
@@ -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);
diff --git a/tools/gen-ops-scanner.l b/tools/gen-ops-scanner.l
index 25af607..27b428e 100644
--- a/tools/gen-ops-scanner.l
+++ b/tools/gen-ops-scanner.l
@@ -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);

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog               |   17 +
 config/jit-opcodes.ops  |  930 +++++++++++++++++++++++++++++++----------------
 jit/Makefile.am         |    1 +
 jit/jit-internal.h      |   97 +++++
 jit/jit-opcode-apply.c  |  887 ++++++++++++++++++++++++++++++++++++++++++++
 tools/gen-ops-parser.y  |  546 +++++++++++++++++++++++++++-
 tools/gen-ops-scanner.l |   35 ++
 7 files changed, 2193 insertions(+), 320 deletions(-)
 create mode 100644 jit/jit-opcode-apply.c


hooks/post-receive
-- 
DotGNU Portable.NET Just In Time compiler (libjit)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]