Merge pull request #5428 from kumpera/wasm-support-p2
[mono.git] / mono / mini / mini-s390x.c
index a0dddf7aa8a8782236178e614370b8a28a4cbbd0..584813cc4db9caa812d9b5f4c9d75382cb6358f0 100644 (file)
@@ -331,6 +331,7 @@ if (ins->inst_true_bb->native_offset) {                                     \
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/unlocked.h>
 
 #include "mini-s390x.h"
 #include "cpu-s390x.h"
@@ -2216,14 +2217,6 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                                }
                                break;
                        }
-#if 0
-                       if ((sig->call_convention == MONO_CALL_VARARG) && 
-                           (cinfo->args[iParm].regtype != RegTypeGeneral) &&
-                           (iParm < sig->sentinelpos)) 
-                               cfg->sig_cookie += size;
-printf("%s %4d cookine %x\n",__FUNCTION__,__LINE__,cfg->sig_cookie);
-#endif
-
                        offset += MAX(size, 8);
                }
                curinst++;
@@ -2554,27 +2547,6 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                                ins->inst_destbasereg = STK_BASE;
                                ins->inst_offset = ainfo->offset;
                                ins->sreg1 = in->dreg;
-
-#if 0
-                               /* This is needed by MonoTypedRef->value to point to the correct data */
-                               if ((sig->call_convention == MONO_CALL_VARARG) &&
-                                       (i >= sig->sentinelpos)) {
-                                       switch (ainfo->size) {
-                                       case 1:
-                                               ins->opcode = OP_STOREI1_MEMBASE_REG;
-                                               break;
-                                       case 2:
-                                               ins->opcode = OP_STOREI2_MEMBASE_REG;
-                                               break;
-                                       case 4:
-                                               ins->opcode = OP_STOREI4_MEMBASE_REG;
-                                               break;
-                                       default:
-                                               break;
-                                       }
-                               }
-#endif
-
                                MONO_ADD_INS (cfg->cbb, ins);
                        }
                        break;
@@ -3745,33 +3717,43 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (ins->dreg != ins->sreg1) {
                                s390_lgr  (code, ins->dreg, ins->sreg1);
                        }
-                       if (s390_is_imm16 (ins->inst_imm)) {
-                               s390_lghi (code, s390_r13, ins->inst_imm);
-                       } else if (s390_is_imm32 (ins->inst_imm)) {
-                               s390_lgfi (code, s390_r13, ins->inst_imm);
+                       if ((mono_hwcap_s390x_has_gie) &&
+                           (s390_is_imm32 (ins->inst_imm))) {
+                               s390_msgfi (code, ins->dreg, ins->inst_imm);
                        } else {
-                               S390_SET (code, s390_r13, ins->inst_imm);
+                               if (s390_is_imm16 (ins->inst_imm)) {
+                                       s390_lghi (code, s390_r13, ins->inst_imm);
+                               } else if (s390_is_imm32 (ins->inst_imm)) {
+                                       s390_lgfi (code, s390_r13, ins->inst_imm);
+                               } else {
+                                       S390_SET (code, s390_r13, ins->inst_imm);
+                               }
+                               s390_msgr (code, ins->dreg, s390_r13);
                        }
-                       s390_msgr (code, ins->dreg, s390_r13);
                }
                        break;
                case OP_LMUL_OVF: {
                        short int *o[2];
-                       s390_ltgr (code, s390_r1, ins->sreg1);
-                       s390_jz   (code, 0); CODEPTR(code, o[0]);
-                       s390_ltgr (code, s390_r0, ins->sreg2);
-                       s390_jnz  (code, 6);
-                       s390_lghi (code, s390_r1, 0);
-                       s390_j    (code, 0); CODEPTR(code, o[1]);
-                       s390_xgr  (code, s390_r0, s390_r1);
-                       s390_msgr (code, s390_r1, ins->sreg2);
-                       s390_xgr  (code, s390_r0, s390_r1);
-                       s390_srlg (code, s390_r0, s390_r0, 0, 63);
-                       s390_ltgr (code, s390_r0, s390_r0);
-                       EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NZ, "OverflowException");
-                       PTRSLOT   (code, o[0]); 
-                       PTRSLOT   (code, o[1]);
-                       s390_lgr  (code, ins->dreg, s390_r1);
+                       if (mono_hwcap_s390x_has_mie2) {
+                               s390_msgrkc (code, ins->dreg, ins->sreg1, ins->sreg2);
+                               EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
+                       } else {
+                               s390_ltgr (code, s390_r1, ins->sreg1);
+                               s390_jz   (code, 0); CODEPTR(code, o[0]);
+                               s390_ltgr (code, s390_r0, ins->sreg2);
+                               s390_jnz  (code, 6);
+                               s390_lghi (code, s390_r1, 0);
+                               s390_j    (code, 0); CODEPTR(code, o[1]);
+                               s390_xgr  (code, s390_r0, s390_r1);
+                               s390_msgr (code, s390_r1, ins->sreg2);
+                               s390_xgr  (code, s390_r0, s390_r1);
+                               s390_srlg (code, s390_r0, s390_r0, 0, 63);
+                               s390_ltgr (code, s390_r0, s390_r0);
+                               EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NZ, "OverflowException");
+                               PTRSLOT   (code, o[0]); 
+                               PTRSLOT   (code, o[1]);
+                               s390_lgr  (code, ins->dreg, s390_r1);
+                       }
                }
                        break;
                case OP_LMUL_OVF_UN: {
@@ -3826,26 +3808,42 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_LADD_OVF:
                case OP_S390_LADD_OVF: {
-                       CHECK_SRCDST_COM;
-                       s390_agr    (code, ins->dreg, src2);
+                       if (mono_hwcap_s390x_has_mlt) {
+                               s390_agrk (code, ins->dreg, ins->sreg1, ins->sreg2);
+                       } else { 
+                               CHECK_SRCDST_COM;
+                               s390_agr    (code, ins->dreg, src2);
+                       }
                        EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
                }
                        break;
                case OP_LADD_OVF_UN:
                case OP_S390_LADD_OVF_UN: {
-                       CHECK_SRCDST_COM;
-                       s390_algr  (code, ins->dreg, src2);
+                       if (mono_hwcap_s390x_has_mlt) {
+                               s390_algrk (code, ins->dreg, ins->sreg1, ins->sreg2);
+                       } else { 
+                               CHECK_SRCDST_COM;
+                               s390_algr  (code, ins->dreg, src2);
+                       }
                        EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, "OverflowException");
                }
                        break;
                case OP_ISUBCC: {
-                       CHECK_SRCDST_NCOM_I;
-                       s390_slgr (code, ins->dreg, src2);
+                       if (mono_hwcap_s390x_has_mlt) {
+                               s390_slgrk (code, ins->dreg, ins->sreg1, ins->sreg2);
+                       } else {
+                               CHECK_SRCDST_NCOM_I;
+                               s390_slgr (code, ins->dreg, src2);
+                       }
                }
                        break;
                case OP_ISUB: {
-                       CHECK_SRCDST_NCOM_I;
-                       s390_sgr  (code, ins->dreg, src2);
+                       if (mono_hwcap_s390x_has_mlt) {
+                               s390_sgrk (code, ins->dreg, ins->sreg1, ins->sreg2);
+                       } else {
+                               CHECK_SRCDST_NCOM_I;
+                               s390_sgr  (code, ins->dreg, src2);
+                       }
                }
                        break;
                case OP_ISBB: {
@@ -3871,24 +3869,37 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_ISUB_OVF:
                case OP_S390_ISUB_OVF: {
-                       CHECK_SRCDST_NCOM;
-                       s390_sr   (code, ins->dreg, src2);
-                       EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
-                       s390_lgfr (code, ins->dreg, ins->dreg);
+                       if (mono_hwcap_s390x_has_mlt) {
+                               s390_srk (code, ins->dreg, ins->sreg1, ins->sreg2);
+                               EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
+                       } else { 
+                               CHECK_SRCDST_NCOM;
+                               s390_sr   (code, ins->dreg, src2);
+                               EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
+                               s390_lgfr (code, ins->dreg, ins->dreg);
+                       }
                }
                        break;
                case OP_ISUB_OVF_UN:
                case OP_S390_ISUB_OVF_UN: {
-                       CHECK_SRCDST_NCOM;
-                       s390_slr  (code, ins->dreg, src2);
+                       if (mono_hwcap_s390x_has_mlt) {
+                               s390_slrk  (code, ins->dreg, ins->sreg1, ins->sreg2);
+                       } else {
+                               CHECK_SRCDST_NCOM;
+                               s390_slr  (code, ins->dreg, src2);
+                       }
                        EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NC, "OverflowException");
                        s390_llgfr(code, ins->dreg, ins->dreg);
                }
                        break;
                case OP_LSUB_OVF:
                case OP_S390_LSUB_OVF: {
-                       CHECK_SRCDST_NCOM;
-                       s390_sgr   (code, ins->dreg, src2);
+                       if (mono_hwcap_s390x_has_mlt) {
+                               s390_sgrk  (code, ins->dreg, ins->sreg1, ins->sreg2);
+                       } else {
+                               CHECK_SRCDST_NCOM;
+                               s390_sgr   (code, ins->dreg, src2);
+                       }
                        EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
                }
                        break;
@@ -5999,14 +6010,6 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        mono_emit_unwind_op_offset (cfg, code, s390_r14, S390_RET_ADDR_OFFSET);
        mini_gc_set_slot_type_from_cfa (cfg, S390_RET_ADDR_OFFSET, SLOT_NOREF);
 
-#if 0
-if ((strcmp(method->klass->name, "Tests") == 0) && 
-    (strcmp(method->name,"test_5_jmp") == 0)) {
-printf("Found!\n"); fflush(stdout);
-s390_j (code, 0);
-}
-#endif
-
        if (cfg->arch.bkchain_reg != -1)
                s390_lgr (code, cfg->arch.bkchain_reg, STK_BASE);
 
@@ -7068,7 +7071,7 @@ mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain,
        mono_arch_flush_icache ((guint8*)start, (code - start));
 
        if (!fail_tramp) 
-               mono_stats.imt_trampolines_size += (code - start);
+               UnlockedAdd (&mono_stats.imt_trampolines_size, code - start);
 
        g_assert (code - start <= size);