#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"
}
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++;
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;
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: {
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: {
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;
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);
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);