|
@@ -405,7 +405,7 @@ static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsign
|
|
|
static void emit_default_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder);
|
|
static void emit_default_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder);
|
|
|
static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
|
|
static LLVMValueRef emit_dbg_subprogram (EmitContext *ctx, MonoCompile *cfg, LLVMValueRef method, const char *name);
|
|
|
static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
|
|
static void emit_dbg_info (MonoLLVMModule *module, const char *filename, const char *cu_name);
|
|
|
-static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp);
|
|
|
|
|
|
|
+static void emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp, gboolean force_explicit);
|
|
|
static LLVMValueRef get_intrins_by_name (EmitContext *ctx, const char *name);
|
|
static LLVMValueRef get_intrins_by_name (EmitContext *ctx, const char *name);
|
|
|
static LLVMValueRef get_intrins (EmitContext *ctx, int id);
|
|
static LLVMValueRef get_intrins (EmitContext *ctx, int id);
|
|
|
static LLVMValueRef get_intrins_from_module (LLVMModuleRef lmodule, int id);
|
|
static LLVMValueRef get_intrins_from_module (LLVMModuleRef lmodule, int id);
|
|
@@ -2299,58 +2299,36 @@ emit_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, LL
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static LLVMValueRef
|
|
static LLVMValueRef
|
|
|
-emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, BarrierKind barrier)
|
|
|
|
|
|
|
+emit_load (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef addr, LLVMValueRef base, const char *name, gboolean is_faulting, gboolean is_volatile, BarrierKind barrier)
|
|
|
{
|
|
{
|
|
|
LLVMValueRef res;
|
|
LLVMValueRef res;
|
|
|
|
|
|
|
|
- if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
|
|
|
|
|
- /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
|
|
|
|
|
- LLVMValueRef cmp;
|
|
|
|
|
-
|
|
|
|
|
- cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
|
|
|
|
|
- emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
|
|
|
|
|
- *builder_ref = ctx->builder;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
/*
|
|
/*
|
|
|
* We emit volatile loads for loads which can fault, because otherwise
|
|
* We emit volatile loads for loads which can fault, because otherwise
|
|
|
* LLVM will generate invalid code when encountering a load from a
|
|
* LLVM will generate invalid code when encountering a load from a
|
|
|
* NULL address.
|
|
* NULL address.
|
|
|
*/
|
|
*/
|
|
|
if (barrier != LLVM_BARRIER_NONE)
|
|
if (barrier != LLVM_BARRIER_NONE)
|
|
|
- res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_faulting, size, barrier);
|
|
|
|
|
|
|
+ res = mono_llvm_build_atomic_load (*builder_ref, addr, name, is_volatile, size, barrier);
|
|
|
else
|
|
else
|
|
|
- res = mono_llvm_build_load (*builder_ref, addr, name, is_faulting);
|
|
|
|
|
-
|
|
|
|
|
- /* Mark it with a custom metadata */
|
|
|
|
|
- /*
|
|
|
|
|
- if (is_faulting)
|
|
|
|
|
- set_metadata_flag (res, "mono.faulting.load");
|
|
|
|
|
- */
|
|
|
|
|
|
|
+ res = mono_llvm_build_load (*builder_ref, addr, name, is_volatile);
|
|
|
|
|
|
|
|
return res;
|
|
return res;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
static void
|
|
|
-emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, BarrierKind barrier)
|
|
|
|
|
|
|
+emit_store_general (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, gboolean is_volatile, BarrierKind barrier)
|
|
|
{
|
|
{
|
|
|
- if (is_faulting && bb->region != -1 && !ctx->cfg->llvm_only) {
|
|
|
|
|
- /* The llvm.mono.load/store intrinsics are not supported by this llvm version, emit an explicit null check instead */
|
|
|
|
|
- LLVMValueRef cmp = LLVMBuildICmp (*builder_ref, LLVMIntEQ, base, LLVMConstNull (LLVMTypeOf (base)), "");
|
|
|
|
|
- emit_cond_system_exception (ctx, bb, "NullReferenceException", cmp);
|
|
|
|
|
- *builder_ref = ctx->builder;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (barrier != LLVM_BARRIER_NONE)
|
|
if (barrier != LLVM_BARRIER_NONE)
|
|
|
mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
|
|
mono_llvm_build_aligned_store (*builder_ref, value, addr, barrier, size);
|
|
|
else
|
|
else
|
|
|
- mono_llvm_build_store (*builder_ref, value, addr, is_faulting, barrier);
|
|
|
|
|
|
|
+ mono_llvm_build_store (*builder_ref, value, addr, is_volatile, barrier);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
static void
|
|
|
-emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting)
|
|
|
|
|
|
|
+emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, int size, LLVMValueRef value, LLVMValueRef addr, LLVMValueRef base, gboolean is_faulting, gboolean is_volatile)
|
|
|
{
|
|
{
|
|
|
- emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, LLVM_BARRIER_NONE);
|
|
|
|
|
|
|
+ emit_store_general (ctx, bb, builder_ref, size, value, addr, base, is_faulting, is_volatile, LLVM_BARRIER_NONE);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -2360,7 +2338,7 @@ emit_store (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, i
|
|
|
* Might set the ctx exception.
|
|
* Might set the ctx exception.
|
|
|
*/
|
|
*/
|
|
|
static void
|
|
static void
|
|
|
-emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp)
|
|
|
|
|
|
|
+emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *exc_type, LLVMValueRef cmp, gboolean force_explicit)
|
|
|
{
|
|
{
|
|
|
LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
|
|
LLVMBasicBlockRef ex_bb, ex2_bb = NULL, noex_bb;
|
|
|
LLVMBuilderRef builder;
|
|
LLVMBuilderRef builder;
|
|
@@ -2384,7 +2362,10 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
|
|
|
ex2_bb = gen_bb (ctx, "EX2_BB");
|
|
ex2_bb = gen_bb (ctx, "EX2_BB");
|
|
|
noex_bb = gen_bb (ctx, "NOEX_BB");
|
|
noex_bb = gen_bb (ctx, "NOEX_BB");
|
|
|
|
|
|
|
|
- LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
|
|
|
|
|
|
|
+ LLVMValueRef branch = LLVMBuildCondBr (ctx->builder, cmp, ex_bb, noex_bb);
|
|
|
|
|
+ if (exc_id == MONO_EXC_NULL_REF && !ctx->cfg->disable_llvm_implicit_null_checks && !force_explicit) {
|
|
|
|
|
+ mono_llvm_set_implicit_branch (ctx->builder, branch);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
/* Emit exception throwing code */
|
|
/* Emit exception throwing code */
|
|
|
ctx->builder = builder = create_builder (ctx);
|
|
ctx->builder = builder = create_builder (ctx);
|
|
@@ -3284,7 +3265,7 @@ emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, Mo
|
|
|
ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
|
|
ins->opcode == OP_IDIV_IMM || ins->opcode == OP_LDIV_IMM || ins->opcode == OP_IREM_IMM || ins->opcode == OP_LREM_IMM);
|
|
|
|
|
|
|
|
cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
|
|
cmp = LLVMBuildICmp (builder, LLVMIntEQ, rhs, LLVMConstInt (LLVMTypeOf (rhs), 0, FALSE), "");
|
|
|
- emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp);
|
|
|
|
|
|
|
+ emit_cond_system_exception (ctx, bb, "DivideByZeroException", cmp, FALSE);
|
|
|
if (!ctx_ok (ctx))
|
|
if (!ctx_ok (ctx))
|
|
|
break;
|
|
break;
|
|
|
builder = ctx->builder;
|
|
builder = ctx->builder;
|
|
@@ -3296,7 +3277,7 @@ emit_div_check (EmitContext *ctx, LLVMBuilderRef builder, MonoBasicBlock *bb, Mo
|
|
|
LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
|
|
LLVMValueRef cond2 = LLVMBuildICmp (builder, LLVMIntEQ, lhs, c, "");
|
|
|
|
|
|
|
|
cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
|
|
cmp = LLVMBuildICmp (builder, LLVMIntEQ, LLVMBuildAnd (builder, cond1, cond2, ""), LLVMConstInt (LLVMInt1Type (), 1, FALSE), "");
|
|
|
- emit_cond_system_exception (ctx, bb, "OverflowException", cmp);
|
|
|
|
|
|
|
+ emit_cond_system_exception (ctx, bb, "OverflowException", cmp, FALSE);
|
|
|
if (!ctx_ok (ctx))
|
|
if (!ctx_ok (ctx))
|
|
|
break;
|
|
break;
|
|
|
builder = ctx->builder;
|
|
builder = ctx->builder;
|
|
@@ -5211,7 +5192,14 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
/* Add stores for volatile variables */
|
|
/* Add stores for volatile variables */
|
|
|
emit_volatile_store (ctx, ins->next->dreg);
|
|
emit_volatile_store (ctx, ins->next->dreg);
|
|
|
} else if (MONO_IS_COND_EXC (ins->next)) {
|
|
} else if (MONO_IS_COND_EXC (ins->next)) {
|
|
|
- emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp);
|
|
|
|
|
|
|
+ gboolean force_explicit_branch = FALSE;
|
|
|
|
|
+ if (bb->region != -1) {
|
|
|
|
|
+ /* Don't tag null check branches in exception-handling
|
|
|
|
|
+ * regions with `make.implicit`.
|
|
|
|
|
+ */
|
|
|
|
|
+ force_explicit_branch = TRUE;
|
|
|
|
|
+ }
|
|
|
|
|
+ emit_cond_system_exception (ctx, bb, (const char*)ins->next->inst_p1, cmp, force_explicit_branch);
|
|
|
if (!ctx_ok (ctx))
|
|
if (!ctx_ok (ctx))
|
|
|
break;
|
|
break;
|
|
|
builder = ctx->builder;
|
|
builder = ctx->builder;
|
|
@@ -5758,7 +5746,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
LLVMValueRef base, index, addr;
|
|
LLVMValueRef base, index, addr;
|
|
|
LLVMTypeRef t;
|
|
LLVMTypeRef t;
|
|
|
gboolean sext = FALSE, zext = FALSE;
|
|
gboolean sext = FALSE, zext = FALSE;
|
|
|
- gboolean is_volatile = (ins->flags & (MONO_INST_FAULT | MONO_INST_VOLATILE)) != 0;
|
|
|
|
|
|
|
+ gboolean is_faulting = (ins->flags & MONO_INST_FAULT) != 0;
|
|
|
|
|
+ gboolean is_volatile = (ins->flags & MONO_INST_VOLATILE) != 0;
|
|
|
|
|
|
|
|
t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
|
|
t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
|
|
|
|
|
|
|
@@ -5786,9 +5775,9 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
|
|
|
|
|
addr = convert (ctx, addr, LLVMPointerType (t, 0));
|
|
addr = convert (ctx, addr, LLVMPointerType (t, 0));
|
|
|
|
|
|
|
|
- values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, base, dname, is_volatile, LLVM_BARRIER_NONE);
|
|
|
|
|
|
|
+ values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, base, dname, is_faulting, is_volatile, LLVM_BARRIER_NONE);
|
|
|
|
|
|
|
|
- if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
|
|
|
|
|
|
|
+ if (!(is_faulting || is_volatile) && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
|
|
|
/*
|
|
/*
|
|
|
* These will signal LLVM that these loads do not alias any stores, and
|
|
* These will signal LLVM that these loads do not alias any stores, and
|
|
|
* they can't fail, allowing them to be hoisted out of loops.
|
|
* they can't fail, allowing them to be hoisted out of loops.
|
|
@@ -5816,7 +5805,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
LLVMValueRef index, addr, base;
|
|
LLVMValueRef index, addr, base;
|
|
|
LLVMTypeRef t;
|
|
LLVMTypeRef t;
|
|
|
gboolean sext = FALSE, zext = FALSE;
|
|
gboolean sext = FALSE, zext = FALSE;
|
|
|
- gboolean is_volatile = (ins->flags & (MONO_INST_FAULT | MONO_INST_VOLATILE)) != 0;
|
|
|
|
|
|
|
+ gboolean is_faulting = (ins->flags & MONO_INST_FAULT) != 0;
|
|
|
|
|
+ gboolean is_volatile = (ins->flags & MONO_INST_VOLATILE) != 0;
|
|
|
|
|
|
|
|
if (!values [ins->inst_destbasereg]) {
|
|
if (!values [ins->inst_destbasereg]) {
|
|
|
set_failure (ctx, "inst_destbasereg");
|
|
set_failure (ctx, "inst_destbasereg");
|
|
@@ -5837,7 +5827,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
if (is_volatile && LLVMGetInstructionOpcode (base) == LLVMAlloca && !(ins->flags & MONO_INST_VOLATILE))
|
|
if (is_volatile && LLVMGetInstructionOpcode (base) == LLVMAlloca && !(ins->flags & MONO_INST_VOLATILE))
|
|
|
/* Storing to an alloca cannot fail */
|
|
/* Storing to an alloca cannot fail */
|
|
|
is_volatile = FALSE;
|
|
is_volatile = FALSE;
|
|
|
- emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
|
|
|
|
|
|
|
+ emit_store (ctx, bb, &builder, size, convert (ctx, values [ins->sreg1], t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_faulting, is_volatile);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -5850,7 +5840,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
LLVMValueRef index, addr, base;
|
|
LLVMValueRef index, addr, base;
|
|
|
LLVMTypeRef t;
|
|
LLVMTypeRef t;
|
|
|
gboolean sext = FALSE, zext = FALSE;
|
|
gboolean sext = FALSE, zext = FALSE;
|
|
|
- gboolean is_volatile = (ins->flags & (MONO_INST_FAULT | MONO_INST_VOLATILE)) != 0;
|
|
|
|
|
|
|
+ gboolean is_faulting = (ins->flags & MONO_INST_FAULT) != 0;
|
|
|
|
|
+ gboolean is_volatile = (ins->flags & MONO_INST_VOLATILE) != 0;
|
|
|
|
|
|
|
|
t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
|
|
t = load_store_to_llvm_type (ins->opcode, &size, &sext, &zext);
|
|
|
|
|
|
|
@@ -5863,12 +5854,12 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
|
|
index = LLVMConstInt (LLVMInt32Type (), ins->inst_offset / size, FALSE);
|
|
|
addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
|
|
addr = LLVMBuildGEP (builder, convert (ctx, base, LLVMPointerType (t, 0)), &index, 1, "");
|
|
|
}
|
|
}
|
|
|
- emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_volatile);
|
|
|
|
|
|
|
+ emit_store (ctx, bb, &builder, size, convert (ctx, LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), t), convert (ctx, addr, LLVMPointerType (t, 0)), base, is_faulting, is_volatile);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
case OP_CHECK_THIS:
|
|
case OP_CHECK_THIS:
|
|
|
- emit_load (ctx, bb, &builder, TARGET_SIZEOF_VOID_P, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, LLVM_BARRIER_NONE);
|
|
|
|
|
|
|
+ emit_load (ctx, bb, &builder, TARGET_SIZEOF_VOID_P, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), lhs, "", TRUE, FALSE, LLVM_BARRIER_NONE);
|
|
|
break;
|
|
break;
|
|
|
case OP_OUTARG_VTRETADDR:
|
|
case OP_OUTARG_VTRETADDR:
|
|
|
break;
|
|
break;
|
|
@@ -6344,7 +6335,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
int size;
|
|
int size;
|
|
|
gboolean sext, zext;
|
|
gboolean sext, zext;
|
|
|
LLVMTypeRef t;
|
|
LLVMTypeRef t;
|
|
|
- gboolean is_volatile = (ins->flags & (MONO_INST_FAULT | MONO_INST_VOLATILE)) != 0;
|
|
|
|
|
|
|
+ gboolean is_faulting = (ins->flags & MONO_INST_FAULT) != 0;
|
|
|
|
|
+ gboolean is_volatile = (ins->flags & MONO_INST_VOLATILE) != 0;
|
|
|
BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
|
|
BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
|
|
|
LLVMValueRef index, addr;
|
|
LLVMValueRef index, addr;
|
|
|
|
|
|
|
@@ -6363,7 +6355,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
addr = convert (ctx, addr, LLVMPointerType (t, 0));
|
|
addr = convert (ctx, addr, LLVMPointerType (t, 0));
|
|
|
|
|
|
|
|
ARM64_ATOMIC_FENCE_FIX;
|
|
ARM64_ATOMIC_FENCE_FIX;
|
|
|
- values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, lhs, dname, is_volatile, barrier);
|
|
|
|
|
|
|
+ values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, lhs, dname, is_faulting, is_volatile, barrier);
|
|
|
ARM64_ATOMIC_FENCE_FIX;
|
|
ARM64_ATOMIC_FENCE_FIX;
|
|
|
|
|
|
|
|
if (sext)
|
|
if (sext)
|
|
@@ -6385,7 +6377,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
int size;
|
|
int size;
|
|
|
gboolean sext, zext;
|
|
gboolean sext, zext;
|
|
|
LLVMTypeRef t;
|
|
LLVMTypeRef t;
|
|
|
- gboolean is_volatile = (ins->flags & (MONO_INST_FAULT | MONO_INST_VOLATILE)) != 0;
|
|
|
|
|
|
|
+ gboolean is_faulting = (ins->flags & MONO_INST_FAULT) != 0;
|
|
|
|
|
+ gboolean is_volatile = (ins->flags & MONO_INST_VOLATILE) != 0;
|
|
|
BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
|
|
BarrierKind barrier = (BarrierKind) ins->backend.memory_barrier_kind;
|
|
|
LLVMValueRef index, addr, value, base;
|
|
LLVMValueRef index, addr, value, base;
|
|
|
|
|
|
|
@@ -6402,7 +6395,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
value = convert (ctx, values [ins->sreg1], t);
|
|
value = convert (ctx, values [ins->sreg1], t);
|
|
|
|
|
|
|
|
ARM64_ATOMIC_FENCE_FIX;
|
|
ARM64_ATOMIC_FENCE_FIX;
|
|
|
- emit_store_general (ctx, bb, &builder, size, value, addr, base, is_volatile, barrier);
|
|
|
|
|
|
|
+ emit_store_general (ctx, bb, &builder, size, value, addr, base, is_faulting, is_volatile, barrier);
|
|
|
ARM64_ATOMIC_FENCE_FIX;
|
|
ARM64_ATOMIC_FENCE_FIX;
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
@@ -6520,7 +6513,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
|
|
|
val = LLVMBuildCall (builder, func, args, 2, "");
|
|
val = LLVMBuildCall (builder, func, args, 2, "");
|
|
|
values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
|
|
values [ins->dreg] = LLVMBuildExtractValue (builder, val, 0, dname);
|
|
|
ovf = LLVMBuildExtractValue (builder, val, 1, "");
|
|
ovf = LLVMBuildExtractValue (builder, val, 1, "");
|
|
|
- emit_cond_system_exception (ctx, bb, "OverflowException", ovf);
|
|
|
|
|
|
|
+ emit_cond_system_exception (ctx, bb, "OverflowException", ovf, FALSE);
|
|
|
if (!ctx_ok (ctx))
|
|
if (!ctx_ok (ctx))
|
|
|
break;
|
|
break;
|
|
|
builder = ctx->builder;
|
|
builder = ctx->builder;
|