#endif
break;
}
+ case OP_GC_SAFE_POINT: {
+ LLVMValueRef val, cmp, callee;
+ LLVMBasicBlockRef poll_bb, cont_bb;
+ static LLVMTypeRef sig;
+ const char *icall_name = "mono_threads_state_poll";
+
+ if (!sig)
+ sig = LLVMFunctionType0 (LLVMVoidType (), FALSE);
+
+ /*
+ * if (!*sreg1)
+ * mono_threads_state_poll ();
+ * FIXME: Use a preserveall wrapper
+ */
+ val = mono_llvm_build_load (builder, convert (ctx, lhs, LLVMPointerType (IntPtrType (), 0)), "", TRUE, LLVM_BARRIER_NONE);
+ cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstNull (LLVMTypeOf (val)), "");
+ poll_bb = gen_bb (ctx, "POLL_BB");
+ cont_bb = gen_bb (ctx, "CONT_BB");
+ LLVMBuildCondBr (builder, cmp, cont_bb, poll_bb);
+
+ ctx->builder = builder = create_builder (ctx);
+ LLVMPositionBuilderAtEnd (builder, poll_bb);
+
+ if (ctx->cfg->compile_aot) {
+ callee = get_callee (ctx, sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
+ } else {
+ gpointer target = resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
+ callee = emit_jit_callee (ctx, icall_name, sig, target);
+ }
+ LLVMBuildCall (builder, callee, NULL, 0, "");
+ LLVMBuildBr (builder, cont_bb);
+
+ ctx->builder = builder = create_builder (ctx);
+ LLVMPositionBuilderAtEnd (builder, cont_bb);
+ ctx->bblocks [bb->block_num].end_bblock = cont_bb;
+ break;
+ }
/*
* Overflow opcodes.