Merge pull request #5668 from kumpera/wasm-work-p4
[mono.git] / mono / mini / mini-ops.h
index 59011ebccd36cfed480fa6707ca1f8f92d8a4d09..32ad106ab571ce0b975e13a92e824ddbec7afc56 100644 (file)
@@ -1,7 +1,9 @@
-/*
+/**
+ * \file
  * Copyright 2003 Ximian, Inc
  * Copyright 2003-2011 Novell Inc
  * Copyright 2011 Xamarin Inc
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 MINI_OP(OP_LOAD,       "load", NONE, NONE, NONE)
 MINI_OP(OP_LDADDR,     "ldaddr", IREG, NONE, NONE)
@@ -15,6 +17,7 @@ MINI_OP(OP_VPHI,      "vphi", VREG, NONE, NONE)
 MINI_OP(OP_COMPARE,    "compare", NONE, IREG, IREG)
 MINI_OP(OP_COMPARE_IMM,        "compare_imm", NONE, IREG, NONE)
 MINI_OP(OP_FCOMPARE,   "fcompare", NONE, FREG, FREG)
+MINI_OP(OP_RCOMPARE,   "rcompare", NONE, FREG, FREG)
 MINI_OP(OP_LCOMPARE,   "lcompare", NONE, LREG, LREG)
 MINI_OP(OP_ICOMPARE,   "icompare", NONE, IREG, IREG)
 MINI_OP(OP_ICOMPARE_IMM,       "icompare_imm", NONE, IREG, NONE)
@@ -37,8 +40,10 @@ MINI_OP(OP_LOCALLOC, "localloc", IREG, IREG, NONE)
 MINI_OP(OP_LOCALLOC_IMM, "localloc_imm", IREG, NONE, NONE)
 MINI_OP(OP_CHECK_THIS, "checkthis", NONE, IREG, NONE)
 MINI_OP(OP_SEQ_POINT, "seq_point", NONE, NONE, NONE)
+MINI_OP(OP_IL_SEQ_POINT, "il_seq_point", NONE, NONE, NONE)
 MINI_OP(OP_IMPLICIT_EXCEPTION, "implicit_exception", NONE, NONE, NONE)
 
+/* CALL opcodes need to stay together, see MONO_IS_CALL macro */
 MINI_OP(OP_VOIDCALL,   "voidcall", NONE, NONE, NONE)
 MINI_OP(OP_VOIDCALL_REG,       "voidcall_reg", NONE, IREG, NONE)
 MINI_OP(OP_VOIDCALL_MEMBASE,   "voidcall_membase", NONE, IREG, NONE)
@@ -48,6 +53,9 @@ MINI_OP(OP_CALL_MEMBASE,      "call_membase", IREG, IREG, NONE)
 MINI_OP(OP_FCALL,      "fcall", FREG, NONE, NONE)
 MINI_OP(OP_FCALL_REG,  "fcall_reg", FREG, IREG, NONE)
 MINI_OP(OP_FCALL_MEMBASE,      "fcall_membase", FREG, IREG, NONE)
+MINI_OP(OP_RCALL,      "rcall", FREG, NONE, NONE)
+MINI_OP(OP_RCALL_REG,  "rcall_reg", FREG, IREG, NONE)
+MINI_OP(OP_RCALL_MEMBASE,      "rcall_membase", FREG, IREG, NONE)
 MINI_OP(OP_LCALL,      "lcall", LREG, NONE, NONE)
 MINI_OP(OP_LCALL_REG,  "lcall_reg", LREG, IREG, NONE)
 MINI_OP(OP_LCALL_MEMBASE,      "lcall_membase", LREG, IREG, NONE)
@@ -67,6 +75,7 @@ MINI_OP(OP_R8CONST,   "r8const", FREG, NONE, NONE)
 MINI_OP(OP_DUMMY_ICONST, "dummy_iconst", IREG, NONE, NONE)
 MINI_OP(OP_DUMMY_I8CONST, "dummy_i8const", LREG, NONE, NONE)
 MINI_OP(OP_DUMMY_R8CONST, "dummy_r8const", FREG, NONE, NONE)
+MINI_OP(OP_DUMMY_R4CONST, "dummy_r4const", FREG, NONE, NONE)
 MINI_OP(OP_DUMMY_VZERO, "dummy_vzero", VREG, NONE, NONE)
 MINI_OP(OP_REGVAR,     "regvar", NONE, NONE, NONE)
 MINI_OP(OP_REGOFFSET,  "regoffset", NONE, NONE, NONE)
@@ -166,9 +175,20 @@ MINI_OP(OP_LOADI8_MEM,"loadi8_mem", IREG, NONE, NONE)
 MINI_OP(OP_STORE_MEM_IMM, "store_mem_imm", NONE, NONE, NONE)
 
 MINI_OP(OP_MOVE,       "move", IREG, IREG, NONE)
-MINI_OP(OP_LMOVE,      "lmove", IREG, IREG, NONE)
+MINI_OP(OP_LMOVE,      "lmove", LREG, LREG, NONE)
 MINI_OP(OP_FMOVE,      "fmove", FREG, FREG, NONE)
 MINI_OP(OP_VMOVE,   "vmove", VREG, VREG, NONE)
+MINI_OP(OP_RMOVE,      "rmove", FREG, FREG, NONE)
+
+/*
+ * All 4 of these are only available when soft float isn't active. They
+ * perform no conversions; they simply move values back and forth.
+ */
+MINI_OP(OP_MOVE_F_TO_I4, "move_f_to_i4", IREG, FREG, NONE)
+MINI_OP(OP_MOVE_I4_TO_F, "move_i4_to_f", FREG, IREG, NONE)
+/* These 2 are only available on 64-bit targets. */
+MINI_OP(OP_MOVE_F_TO_I8, "move_f_to_i8", IREG, FREG, NONE)
+MINI_OP(OP_MOVE_I8_TO_F, "move_i8_to_f", FREG, IREG, NONE)
 
 MINI_OP(OP_VZERO,   "vzero", VREG, NONE, NONE)
 
@@ -292,11 +312,11 @@ MINI_OP(OP_LCONV_TO_OVF_I8,"long_conv_to_ovf_i8", LREG, LREG, NONE)
 MINI_OP(OP_LCONV_TO_OVF_U8,"long_conv_to_ovf_u8", LREG, LREG, NONE)
 
 /* mono_decompose_long_opts () depends on the order here */
-MINI_OP(OP_LCEQ,   "long_ceq", LREG, NONE, NONE)
-MINI_OP(OP_LCGT,   "long_cgt", LREG, NONE, NONE)
-MINI_OP(OP_LCGT_UN,"long_cgt_un", LREG, NONE, NONE)
-MINI_OP(OP_LCLT,   "long_clt", LREG, NONE, NONE)
-MINI_OP(OP_LCLT_UN,"long_clt_un", LREG, NONE, NONE)
+MINI_OP(OP_LCEQ,   "long_ceq", IREG, NONE, NONE)
+MINI_OP(OP_LCGT,   "long_cgt", IREG, NONE, NONE)
+MINI_OP(OP_LCGT_UN,"long_cgt_un", IREG, NONE, NONE)
+MINI_OP(OP_LCLT,   "long_clt", IREG, NONE, NONE)
+MINI_OP(OP_LCLT_UN,"long_clt_un", IREG, NONE, NONE)
 
 MINI_OP(OP_LCONV_TO_R_UN,"long_conv_to_r_un", FREG, LREG, NONE)
 MINI_OP(OP_LCONV_TO_U,   "long_conv_to_u", IREG, LREG, NONE)
@@ -354,7 +374,7 @@ MINI_OP(OP_INOT,       "int_not", IREG, IREG, NONE)
 MINI_OP(OP_ICONV_TO_I1,"int_conv_to_i1", IREG, IREG, NONE)
 MINI_OP(OP_ICONV_TO_I2,"int_conv_to_i2", IREG, IREG, NONE)
 MINI_OP(OP_ICONV_TO_I4,"int_conv_to_i4", IREG, IREG, NONE)
-MINI_OP(OP_ICONV_TO_I8,"int_conv_to_i8", IREG, IREG, NONE)
+MINI_OP(OP_ICONV_TO_I8,"int_conv_to_i8", LREG, IREG, NONE)
 MINI_OP(OP_ICONV_TO_R4,"int_conv_to_r4", FREG, IREG, NONE)
 MINI_OP(OP_ICONV_TO_R8,"int_conv_to_r8", FREG, IREG, NONE)
 MINI_OP(OP_ICONV_TO_U4,"int_conv_to_u4", IREG, IREG, NONE)
@@ -453,6 +473,17 @@ MINI_OP(OP_FBGT_UN, "float_bgt_un", NONE, NONE, NONE)
 MINI_OP(OP_FBLE_UN, "float_ble_un", NONE, NONE, NONE)
 MINI_OP(OP_FBLT_UN, "float_blt_un", NONE, NONE, NONE)
 
+MINI_OP(OP_RBEQ,    "r4_beq", NONE, NONE, NONE)
+MINI_OP(OP_RBGE,    "r4_bge", NONE, NONE, NONE)
+MINI_OP(OP_RBGT,    "r4_bgt", NONE, NONE, NONE)
+MINI_OP(OP_RBLE,    "r4_ble", NONE, NONE, NONE)
+MINI_OP(OP_RBLT,    "r4_blt", NONE, NONE, NONE)
+MINI_OP(OP_RBNE_UN, "r4_bne_un", NONE, NONE, NONE)
+MINI_OP(OP_RBGE_UN, "r4_bge_un", NONE, NONE, NONE)
+MINI_OP(OP_RBGT_UN, "r4_bgt_un", NONE, NONE, NONE)
+MINI_OP(OP_RBLE_UN, "r4_ble_un", NONE, NONE, NONE)
+MINI_OP(OP_RBLT_UN, "r4_blt_un", NONE, NONE, NONE)
+
 /* float opcodes: must be in the same order as the matching CEE_ opcodes: binops_op_map */
 MINI_OP(OP_FADD,   "float_add", FREG, FREG, FREG)
 MINI_OP(OP_FSUB,   "float_sub", FREG, FREG, FREG)
@@ -462,6 +493,15 @@ MINI_OP(OP_FDIV_UN,"float_div_un", FREG, FREG, FREG)
 MINI_OP(OP_FREM,   "float_rem", FREG, FREG, FREG)
 MINI_OP(OP_FREM_UN,"float_rem_un", FREG, FREG, FREG)
 
+/* r4 opcodes: must be in the same order as the matching CEE_ opcodes: binops_op_map */
+MINI_OP(OP_RADD,   "r4_add", FREG, FREG, FREG)
+MINI_OP(OP_RSUB,   "r4_sub", FREG, FREG, FREG)
+MINI_OP(OP_RMUL,   "r4_mul", FREG, FREG, FREG)
+MINI_OP(OP_RDIV,   "r4_div", FREG, FREG, FREG)
+MINI_OP(OP_RDIV_UN,"r4_div_un", FREG, FREG, FREG)
+MINI_OP(OP_RREM,   "r4_rem", FREG, FREG, FREG)
+MINI_OP(OP_RREM_UN,"r4_rem_un", FREG, FREG, FREG)
+
 /* float opcodes: must be in the same order as the matching CEE_ opcodes: unops_op_map */
 MINI_OP(OP_FNEG,       "float_neg", FREG, FREG, NONE)
 MINI_OP(OP_FNOT,       "float_not", FREG, FREG, NONE)
@@ -474,12 +514,25 @@ MINI_OP(OP_FCONV_TO_R8,"float_conv_to_r8", FREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_U4,"float_conv_to_u4", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_U8,"float_conv_to_u8", LREG, FREG, NONE)
 
+MINI_OP(OP_RNEG,       "r4_neg", FREG, FREG, NONE)
+MINI_OP(OP_RNOT,       "r4_not", FREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_I1,"r4_conv_to_i1", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_I2,"r4_conv_to_i2", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_I4,"r4_conv_to_i4", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_I8,"r4_conv_to_i8", LREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_R4,"r4_conv_to_r4", FREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_R8,"r4_conv_to_r8", FREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_U4,"r4_conv_to_u4", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_U8,"r4_conv_to_u8", LREG, FREG, NONE)
+
+/* float opcodes: must be in the same order as the matching CEE_ opcodes: ovfops_op_map */
 MINI_OP(OP_FCONV_TO_U2,   "float_conv_to_u2", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_U1,   "float_conv_to_u1", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_I,    "float_conv_to_i", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_I,"float_conv_to_ovf_i", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_U,"float_conv_to_ovd_u", IREG, FREG, NONE)
 
+/* float opcodes: must be in the same order as the matching CEE_ opcodes: ovfops_op_map */
 MINI_OP(OP_FADD_OVF,      "float_add_ovf", FREG, FREG, FREG)
 MINI_OP(OP_FADD_OVF_UN,   "float_add_ovf_un", FREG, FREG, FREG)
 MINI_OP(OP_FMUL_OVF,      "float_mul_ovf", FREG, FREG, FREG)
@@ -490,11 +543,11 @@ MINI_OP(OP_FSUB_OVF_UN,   "float_sub_ovf_un", FREG, FREG, FREG)
 MINI_OP(OP_FCONV_TO_OVF_I1_UN,"float_conv_to_ovf_i1_un", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_I2_UN,"float_conv_to_ovf_i2_un", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_I4_UN,"float_conv_to_ovf_i4_un", IREG, FREG, NONE)
-MINI_OP(OP_FCONV_TO_OVF_I8_UN,"float_conv_to_ovf_i8_un", IREG, FREG, NONE)
+MINI_OP(OP_FCONV_TO_OVF_I8_UN,"float_conv_to_ovf_i8_un", LREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_U1_UN,"float_conv_to_ovf_u1_un", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_U2_UN,"float_conv_to_ovf_u2_un", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_U4_UN,"float_conv_to_ovf_u4_un", IREG, FREG, NONE)
-MINI_OP(OP_FCONV_TO_OVF_U8_UN,"float_conv_to_ovf_u8_un", IREG, FREG, NONE)
+MINI_OP(OP_FCONV_TO_OVF_U8_UN,"float_conv_to_ovf_u8_un", LREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_I_UN, "float_conv_to_ovf_i_un", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_U_UN, "float_conv_to_ovf_u_un", IREG, FREG, NONE)
 
@@ -504,8 +557,8 @@ MINI_OP(OP_FCONV_TO_OVF_I2,"float_conv_to_ovf_i2", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_U2,"float_conv_to_ovf_u2", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_I4,"float_conv_to_ovf_i4", IREG, FREG, NONE)
 MINI_OP(OP_FCONV_TO_OVF_U4,"float_conv_to_ovf_u4", IREG, FREG, NONE)
-MINI_OP(OP_FCONV_TO_OVF_I8,"float_conv_to_ovf_i8", IREG, FREG, NONE)
-MINI_OP(OP_FCONV_TO_OVF_U8,"float_conv_to_ovf_u8", IREG, FREG, NONE)
+MINI_OP(OP_FCONV_TO_OVF_I8,"float_conv_to_ovf_i8", LREG, FREG, NONE)
+MINI_OP(OP_FCONV_TO_OVF_U8,"float_conv_to_ovf_u8", LREG, FREG, NONE)
 
 /* These do the comparison too */
 MINI_OP(OP_FCEQ,   "float_ceq", IREG, FREG, FREG)
@@ -527,6 +580,52 @@ MINI_OP(OP_FCLT_UN_MEMBASE,"float_clt_un_membase", IREG, FREG, IREG)
 MINI_OP(OP_FCONV_TO_U, "float_conv_to_u", IREG, FREG, NONE)
 MINI_OP(OP_CKFINITE, "ckfinite", FREG, FREG, NONE)
 
+/* r4 opcodes: must be in the same order as the matching CEE_ opcodes: ovfops_op_map */
+MINI_OP(OP_RCONV_TO_U2,   "r4_conv_to_u2", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_U1,   "r4_conv_to_u1", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_I,    "r4_conv_to_i", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_I,"r4_conv_to_ovf_i", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U,"r4_conv_to_ovd_u", IREG, FREG, NONE)
+
+/* r4 opcodes: must be in the same order as the matching CEE_ opcodes: ovfops_op_map */
+MINI_OP(OP_RADD_OVF,      "r4_add_ovf", FREG, FREG, FREG)
+MINI_OP(OP_RADD_OVF_UN,   "r4_add_ovf_un", FREG, FREG, FREG)
+MINI_OP(OP_RMUL_OVF,      "r4_mul_ovf", FREG, FREG, FREG)
+MINI_OP(OP_RMUL_OVF_UN,   "r4_mul_ovf_un", FREG, FREG, FREG)
+MINI_OP(OP_RSUB_OVF,      "r4_sub_ovf", FREG, FREG, FREG)
+MINI_OP(OP_RSUB_OVF_UN,   "r4_sub_ovf_un", FREG, FREG, FREG)
+
+MINI_OP(OP_RCONV_TO_OVF_I1_UN,"r4_conv_to_ovf_i1_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_I2_UN,"r4_conv_to_ovf_i2_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_I4_UN,"r4_conv_to_ovf_i4_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_I8_UN,"r4_conv_to_ovf_i8_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U1_UN,"r4_conv_to_ovf_u1_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U2_UN,"r4_conv_to_ovf_u2_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U4_UN,"r4_conv_to_ovf_u4_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U8_UN,"r4_conv_to_ovf_u8_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_I_UN, "r4_conv_to_ovf_i_un", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U_UN, "r4_conv_to_ovf_u_un", IREG, FREG, NONE)
+
+MINI_OP(OP_RCONV_TO_OVF_I1,"r4_conv_to_ovf_i1", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U1,"r4_conv_to_ovf_u1", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_I2,"r4_conv_to_ovf_i2", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U2,"r4_conv_to_ovf_u2", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_I4,"r4_conv_to_ovf_i4", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U4,"r4_conv_to_ovf_u4", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_I8,"r4_conv_to_ovf_i8", IREG, FREG, NONE)
+MINI_OP(OP_RCONV_TO_OVF_U8,"r4_conv_to_ovf_u8", IREG, FREG, NONE)
+
+/* r4 opcodes: must be in the same order as the matching CEE_ opcodes: ceqops_op_map */
+MINI_OP(OP_RCEQ,   "r4_ceq", IREG, FREG, FREG)
+MINI_OP(OP_RCGT,   "r4_cgt", IREG, FREG, FREG)
+MINI_OP(OP_RCGT_UN,"r4_cgt_un", IREG, FREG, FREG)
+MINI_OP(OP_RCLT,   "r4_clt", IREG, FREG, FREG)
+MINI_OP(OP_RCLT_UN,"r4_clt_un", IREG, FREG, FREG)
+
+MINI_OP(OP_RCNEQ,  "r4_cneq", IREG, FREG, FREG)
+MINI_OP(OP_RCGE,   "r4_cge", IREG, FREG, FREG)
+MINI_OP(OP_RCLE,   "r4_cle", IREG, FREG, FREG)
+
 /* Return the low 32 bits of a double vreg */
 MINI_OP(OP_FGETLOW32, "float_getlow32", IREG, FREG, NONE)
 /* Return the high 32 bits of a double vreg */
@@ -544,6 +643,11 @@ MINI_OP(OP_CALL_HANDLER  , "call_handler", NONE, NONE, NONE)
 MINI_OP(OP_START_HANDLER  , "start_handler", NONE, NONE, NONE)
 MINI_OP(OP_ENDFILTER,  "endfilter", NONE, IREG, NONE)
 MINI_OP(OP_ENDFINALLY,  "endfinally", NONE, NONE, NONE)
+/*
+ * Returns the exception object passed to catch clauses in
+ * by the EH code in a register.
+ */
+MINI_OP(OP_GET_EX_OBJ, "get_ex_obj", IREG, NONE, NONE)
 
 /* inline (long)int * (long)int */
 MINI_OP(OP_BIGMUL, "bigmul", LREG, IREG, IREG)
@@ -603,6 +707,9 @@ MINI_OP(OP_STRLEN, "strlen", IREG, IREG, NONE)
 MINI_OP(OP_NEWARR, "newarr", IREG, IREG, NONE)
 MINI_OP(OP_LDLEN, "ldlen", IREG, IREG, NONE)
 MINI_OP(OP_BOUNDS_CHECK, "bounds_check", NONE, IREG, IREG)
+/* type checks */
+MINI_OP(OP_ISINST, "isinst", IREG, IREG, NONE)
+MINI_OP(OP_CASTCLASS, "castclass", IREG, IREG, NONE)
 /* get adress of element in a 2D array */
 MINI_OP(OP_LDELEMA2D, "getldelema2", NONE, NONE, NONE)
 /* inlined small memcpy with constant length */
@@ -758,6 +865,7 @@ MINI_OP(OP_PSUBW_SAT_UN, "psubw_sat_un", XREG, XREG, XREG)
 
 MINI_OP(OP_PMULW, "pmulw", XREG, XREG, XREG)
 MINI_OP(OP_PMULD, "pmuld", XREG, XREG, XREG)
+/* Multiplies two 32 bit numbers into a 64 bit one */
 MINI_OP(OP_PMULQ, "pmulq", XREG, XREG, XREG)
 
 MINI_OP(OP_PMULW_HIGH_UN, "pmul_high_un", XREG, XREG, XREG)
@@ -789,7 +897,7 @@ MINI_OP(OP_PSHLQ, "pshlq", XREG, XREG, NONE)
 MINI_OP(OP_PSHLQ_REG, "pshlq_reg", XREG, XREG, XREG)
 
 MINI_OP(OP_EXTRACT_I4, "extract_i4", IREG, XREG, NONE)
-MINI_OP(OP_ICONV_TO_R8_RAW, "iconv_to_r8_raw", FREG, IREG, NONE)
+MINI_OP(OP_ICONV_TO_R4_RAW, "iconv_to_r4_raw", FREG, IREG, NONE)
 
 MINI_OP(OP_EXTRACT_I2, "extract_i2", IREG, XREG, NONE)
 MINI_OP(OP_EXTRACT_U2, "extract_u2", IREG, XREG, NONE)
@@ -841,35 +949,69 @@ MINI_OP(OP_CVTPS2PD, "cvtps2pd", XREG, XREG, NONE)
 MINI_OP(OP_CVTTPD2DQ, "cvttpd2dq", XREG, XREG, NONE)
 MINI_OP(OP_CVTTPS2DQ, "cvttps2dq", XREG, XREG, NONE)
 
+/* r4 dot product */
+/* multiply all 4 single precision float elements, add them together, and store the result to the lowest element */
+MINI_OP(OP_DPPS, "dpps", XREG, XREG, XREG)
+
 #endif
 
 MINI_OP(OP_XMOVE,   "xmove", XREG, XREG, NONE)
 MINI_OP(OP_XZERO,   "xzero", XREG, NONE, NONE)
+MINI_OP(OP_XONES,   "xones", XREG, NONE, NONE)
 MINI_OP(OP_XPHI,       "xphi", XREG, NONE, NONE)
 
-/* Atomic specific
+/*
+ * These are used for efficient implementation of the
+ * atomic methods on Interlocked, Volatile, and Thread.
+ * This is done only on architectures that support it,
+ * as per mono_arch_opcode_supported ().
+ *
+ * Note that while the 32-bit variants are used on
+ * both 32-bit and 64-bit systems, the 64-bit variants
+ * are only used if the system is 64-bit. If that is
+ * not the case, the fallback code in the runtime is
+ * used instead. This is done because decomposing the
+ * 64-bit variants to instructions operating on 32-bit
+ * registers is very complicated on some architectures.
+ *
+ * For memory_barrier and load/store instructions, the
+ * inst.backend.memory_barrier_kind field indicates
+ * which semantics to use.
+ *
+ * Where relevant, all of these return the new value at
+ * the given memory location after performing the
+ * operation.
+ */
+
+MINI_OP(OP_MEMORY_BARRIER, "memory_barrier", NONE, NONE, NONE)
 
-       Note, OP_ATOMIC_ADD_IMM_NEW_I4 and
-       OP_ATOMIC_ADD_NEW_I4 returns the new
-       value compared to OP_ATOMIC_ADD_I4 that
-       returns the old value.
+MINI_OP(OP_ATOMIC_LOAD_I1, "atomic_load_i1", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_I2, "atomic_load_i2", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_I4, "atomic_load_i4", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_I8, "atomic_load_i8", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_U1, "atomic_load_u1", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_U2, "atomic_load_u2", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_U4, "atomic_load_u4", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_U8, "atomic_load_u8", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_R4, "atomic_load_r4", FREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_LOAD_R8, "atomic_load_r8", FREG, IREG, NONE)
+
+MINI_OP(OP_ATOMIC_STORE_I1, "atomic_store_i1", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_I2, "atomic_store_i2", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_I4, "atomic_store_i4", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_I8, "atomic_store_i8", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_U1, "atomic_store_u1", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_U2, "atomic_store_u2", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_U4, "atomic_store_u4", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_U8, "atomic_store_u8", IREG, IREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_R4, "atomic_store_r4", IREG, FREG, NONE)
+MINI_OP(OP_ATOMIC_STORE_R8, "atomic_store_r8", IREG, FREG, NONE)
 
-       OP_ATOMIC_ADD_NEW_I4 is used by
-       Interlocked::Increment and Interlocked:Decrement
-       and atomic_add_i4 by Interlocked::Add
-*/
 MINI_OP(OP_ATOMIC_ADD_I4, "atomic_add_i4", IREG, IREG, IREG)
-MINI_OP(OP_ATOMIC_ADD_NEW_I4, "atomic_add_new_i4", IREG, IREG, IREG)
-MINI_OP(OP_ATOMIC_ADD_IMM_I4, "atomic_add_imm_i4", IREG, IREG, NONE)
-MINI_OP(OP_ATOMIC_ADD_IMM_NEW_I4, "atomic_add_imm_new_i4", IREG, IREG, NONE)
-MINI_OP(OP_ATOMIC_EXCHANGE_I4, "atomic_exchange_i4", IREG, IREG, IREG)
-
 MINI_OP(OP_ATOMIC_ADD_I8, "atomic_add_i8", IREG, IREG, IREG)
-MINI_OP(OP_ATOMIC_ADD_NEW_I8, "atomic_add_new_i8", IREG, IREG, IREG)
-MINI_OP(OP_ATOMIC_ADD_IMM_I8, "atomic_add_imm_i8", IREG, IREG, NONE)
-MINI_OP(OP_ATOMIC_ADD_IMM_NEW_I8, "atomic_add_imm_new_i8", IREG, IREG, NONE)
+
+MINI_OP(OP_ATOMIC_EXCHANGE_I4, "atomic_exchange_i4", IREG, IREG, IREG)
 MINI_OP(OP_ATOMIC_EXCHANGE_I8, "atomic_exchange_i8", IREG, IREG, IREG)
-MINI_OP(OP_MEMORY_BARRIER, "memory_barrier", NONE, NONE, NONE)
 
 MINI_OP3(OP_ATOMIC_CAS_I4, "atomic_cas_i4", IREG, IREG, IREG, IREG)
 MINI_OP3(OP_ATOMIC_CAS_I8, "atomic_cas_i8", IREG, IREG, IREG, IREG)
@@ -937,14 +1079,17 @@ MINI_OP(OP_GC_SPILL_SLOT_LIVENESS_DEF, "gc_spill_slot_liveness_def", NONE, NONE,
  */
 MINI_OP(OP_GC_PARAM_SLOT_LIVENESS_DEF, "gc_param_slot_liveness_def", NONE, NONE, NONE)
 
-/* Arch specific opcodes */
-/* #if defined(__native_client_codegen__) || defined(__native_client__) */
-/* We have to define these in terms of the TARGET defines, not NaCl defines */
-/* because genmdesc.pl doesn't have multiple defines per platform.          */
-#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM)
-MINI_OP(OP_NACL_GC_SAFE_POINT,     "nacl_gc_safe_point", IREG, NONE, NONE)
-#endif
+MINI_OP(OP_GC_SAFE_POINT, "gc_safe_point", NONE, IREG, NONE)
 
+/*
+ * Check if the class given by sreg1 was inited, if not, call
+ * mono_generic_class_init_trampoline () though a trampoline.
+ * Since the trampoline saves all registers, this doesn't clobber
+ * any registers.
+ */
+MINI_OP(OP_GENERIC_CLASS_INIT, "generic_class_init", NONE, IREG, NONE)
+
+/* Arch specific opcodes */
 #if defined(TARGET_X86) || defined(TARGET_AMD64)
 MINI_OP(OP_X86_TEST_NULL,          "x86_test_null", NONE, IREG, NONE)
 MINI_OP(OP_X86_COMPARE_MEMBASE_REG,"x86_compare_membase_reg", NONE, IREG, IREG)
@@ -1033,9 +1178,11 @@ MINI_OP(OP_PPC_SUBFZE,             "ppc_subfze", IREG, IREG, NONE)
 MINI_OP(OP_CHECK_FINITE,           "ppc_check_finite", NONE, IREG, NONE)
 #endif
 
-#if defined(TARGET_ARM)
+#if defined(TARGET_ARM) || defined(TARGET_ARM64)
 MINI_OP(OP_ARM_RSBS_IMM,            "arm_rsbs_imm", IREG, IREG, NONE)
 MINI_OP(OP_ARM_RSC_IMM,             "arm_rsc_imm", IREG, IREG, NONE)
+/* Set dreg to an r4 value */
+MINI_OP(OP_ARM_SETFREG_R4,             "arm_setfreg_r4", FREG, FREG, NONE)
 #endif
 
 #if defined(__sparc__) || defined(sparc)
@@ -1072,104 +1219,14 @@ MINI_OP(OP_S390_IADD_OVF,       "s390_int_add_ovf", IREG, IREG, IREG)
 MINI_OP(OP_S390_IADD_OVF_UN,    "s390_int_add_ovf_un", IREG, IREG, IREG)
 MINI_OP(OP_S390_ISUB_OVF,       "s390_int_sub_ovf", IREG, IREG, IREG)
 MINI_OP(OP_S390_ISUB_OVF_UN,    "s390_int_sub_ovf_un", IREG, IREG, IREG)
-#endif
-
-#if defined(__ia64__)
-MINI_OP(OP_IA64_LOAD,          "ia64_load", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADI1,        "ia64_loadi1", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADU1,        "ia64_loadu1", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADI2,        "ia64_loadi2", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADU2,        "ia64_loadu2", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADI4,        "ia64_loadi4", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADU4,        "ia64_loadu4", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADI8,        "ia64_loadi8", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADU8,        "ia64_loadu8", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADR4,        "ia64_loadr4", NONE, NONE, NONE)
-MINI_OP(OP_IA64_LOADR8,        "ia64_loadr8", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STORE,          "ia64_store", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STOREI1,        "ia64_storei1", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STOREU1,        "ia64_storeu1", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STOREI2,        "ia64_storei2", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STOREU2,        "ia64_storeu2", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STOREI4,        "ia64_storei4", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STOREU4,        "ia64_storeu4", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STOREI8,        "ia64_storei8", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STOREU8,        "ia64_storeu8", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STORER4,        "ia64_storer4", NONE, NONE, NONE)
-MINI_OP(OP_IA64_STORER8,        "ia64_storer8", NONE, NONE, NONE)
-
-MINI_OP(OP_IA64_CMP4_EQ,        "ia64_cmp4_eq", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_NE,        "ia64_cmp4_ne", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_LE,        "ia64_cmp4_le", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_LT,        "ia64_cmp4_lt", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_GE,        "ia64_cmp4_ge", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_GT,        "ia64_cmp4_gt", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_LE_UN,     "ia64_cmp4_le_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_LT_UN,     "ia64_cmp4_lt_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_GE_UN,     "ia64_cmp4_ge_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP4_GT_UN,     "ia64_cmp4_gt_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_EQ,         "ia64_cmp_eq", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_NE,         "ia64_cmp_ne", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_LE,         "ia64_cmp_le", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_LT,         "ia64_cmp_lt", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_GE,         "ia64_cmp_ge", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_GT,         "ia64_cmp_gt", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_LT_UN,      "ia64_cmp_lt_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_GT_UN,      "ia64_cmp_gt_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_GE_UN,      "ia64_cmp_ge_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_CMP_LE_UN,      "ia64_cmp_le_un", NONE, IREG, IREG)
-
-MINI_OP(OP_IA64_CMP4_EQ_IMM,        "ia64_cmp4_eq_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_NE_IMM,        "ia64_cmp4_ne_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_LE_IMM,        "ia64_cmp4_le_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_LT_IMM,        "ia64_cmp4_lt_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_GE_IMM,        "ia64_cmp4_ge_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_GT_IMM,        "ia64_cmp4_gt_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_LE_UN_IMM,     "ia64_cmp4_le_un_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_LT_UN_IMM,     "ia64_cmp4_lt_un_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_GE_UN_IMM,     "ia64_cmp4_ge_un_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP4_GT_UN_IMM,     "ia64_cmp4_gt_un_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_EQ_IMM,         "ia64_cmp_eq_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_NE_IMM,         "ia64_cmp_ne_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_LE_IMM,         "ia64_cmp_le_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_LT_IMM,         "ia64_cmp_lt_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_GE_IMM,         "ia64_cmp_ge_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_GT_IMM,         "ia64_cmp_gt_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_LT_UN_IMM,      "ia64_cmp_lt_un_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_GT_UN_IMM,      "ia64_cmp_gt_un_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_GE_UN_IMM,      "ia64_cmp_ge_un_imm", NONE, NONE, IREG)
-MINI_OP(OP_IA64_CMP_LE_UN_IMM,      "ia64_cmp_le_un_imm", NONE, NONE, IREG)
-
-MINI_OP(OP_IA64_FCMP_EQ,         "ia64_fcmp_eq", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_NE,         "ia64_fcmp_ne", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_LE,         "ia64_fcmp_le", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_LT,         "ia64_fcmp_lt", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_GE,         "ia64_fcmp_ge", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_GT,         "ia64_fcmp_gt", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_LT_UN,      "ia64_fcmp_lt_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_GT_UN,      "ia64_fcmp_gt_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_GE_UN,      "ia64_fcmp_ge_un", NONE, IREG, IREG)
-MINI_OP(OP_IA64_FCMP_LE_UN,      "ia64_fcmp_le_un", NONE, IREG, IREG)
-
-MINI_OP(OP_IA64_BR_COND,        "ia64_br_cond", NONE, NONE, NONE)
-MINI_OP(OP_IA64_COND_EXC,       "ia64_cond_exc", NONE, NONE, NONE)
-MINI_OP(OP_IA64_CSET,           "ia64_cset", IREG, NONE, NONE)
-
-MINI_OP(OP_IA64_STOREI1_MEMBASE_INC_REG, "ia64_storei1_membase_inc_reg", IREG, IREG, NONE)
-MINI_OP(OP_IA64_STOREI2_MEMBASE_INC_REG, "ia64_storei2_membase_inc_reg", IREG, IREG, NONE)
-MINI_OP(OP_IA64_STOREI4_MEMBASE_INC_REG, "ia64_storei4_membase_inc_reg", IREG, IREG, NONE)
-MINI_OP(OP_IA64_STOREI8_MEMBASE_INC_REG, "ia64_storei8_membase_inc_reg", IREG, IREG, NONE)
-MINI_OP(OP_IA64_STORER4_MEMBASE_INC_REG, "ia64_storer4_membase_inc_reg", IREG, IREG, NONE)
-MINI_OP(OP_IA64_STORER8_MEMBASE_INC_REG, "ia64_storer8_membase_inc_reg", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADI1_MEMBASE_INC,"ia64_loadi1_membase_inc", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADU1_MEMBASE_INC,"ia64_loadu1_membase_inc", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADI2_MEMBASE_INC,"ia64_loadi2_membase_inc", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADU2_MEMBASE_INC,"ia64_loadu2_membase_inc", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADI4_MEMBASE_INC,"ia64_loadi4_membase_inc", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADU4_MEMBASE_INC,"ia64_loadu4_membase_inc", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADI8_MEMBASE_INC,"ia64_loadi8_membase_inc", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADR4_MEMBASE_INC,"ia64_loadr4_membase_inc", IREG, IREG, NONE)
-MINI_OP(OP_IA64_LOADR8_MEMBASE_INC,"ia64_loadr8_membase_inc", IREG, IREG, NONE)
+MINI_OP(OP_S390_CRJ,            "s390_crj", IREG, IREG, IREG)
+MINI_OP(OP_S390_CLRJ,           "s390_crj_un", IREG, IREG, IREG)
+MINI_OP(OP_S390_CGRJ,           "s390_cgrj", LREG, LREG, IREG)
+MINI_OP(OP_S390_CLGRJ,          "s390_cgrj_un", LREG, LREG, IREG)
+MINI_OP(OP_S390_CIJ,            "s390_cij", IREG, NONE, NONE)
+MINI_OP(OP_S390_CLIJ,           "s390_cij_un", IREG, IREG, NONE)
+MINI_OP(OP_S390_CGIJ,           "s390_cgij", LREG, NONE, NONE)
+MINI_OP(OP_S390_CLGIJ,          "s390_cgij_un", LREG, NONE, NONE)
 #endif
 
 #if defined(__mips__)
@@ -1238,13 +1295,28 @@ MINI_OP(OP_MIPS_COND_EXC_INC, "mips_cond_exc_inc", NONE, IREG, IREG)
 
 #endif
 
+#if defined(TARGET_ARM64)
+/* Branch if sreg1 == 0 */
+MINI_OP(OP_ARM64_CBZW, "arm64_cbzw", NONE, IREG, NONE)
+MINI_OP(OP_ARM64_CBZX, "arm64_cbzx", NONE, IREG, NONE)
+/* Branch if sreg1 != 0 */
+MINI_OP(OP_ARM64_CBNZW, "arm64_cbnzw", NONE, IREG, NONE)
+MINI_OP(OP_ARM64_CBNZX, "arm64_cbnzx", NONE, IREG, NONE)
+#endif
+
 /* Same as OUTARG_VT, but has a dreg */
-#ifdef ENABLE_LLVM
 MINI_OP(OP_LLVM_OUTARG_VT,     "llvm_outarg_vt", IREG, VREG, NONE)
-#endif
 
 MINI_OP(OP_OBJC_GET_SELECTOR, "objc_get_selector", IREG, NONE, NONE)
 
 MINI_OP(OP_GET_SP, "get_sp", IREG, NONE, NONE)
 MINI_OP(OP_SET_SP, "set_sp", NONE, IREG, NONE)
 
+MINI_OP(OP_GET_LAST_ERROR, "get_last_error", IREG, NONE, NONE)
+
+/*
+ * Fill out a MonoContext contained in a MonoProfilerCallContext. This only
+ * stores the stack pointer, frame pointer, and callee-saved registers. This
+ * should be enough to locate arguments and variables.
+ */
+MINI_OP(OP_FILL_PROF_CALL_CTX, "fill_prof_call_ctx", NONE, IREG, NONE)