Skip to content

Commit

Permalink
[mono] Support LLVM inline assembly. (#62558)
Browse files Browse the repository at this point in the history
This change adds a convenience function, named `mono_llvm_inline_asm`,
that wraps `LLVMGetInlineAsm` and `LLVMBuildCall2`.

Inline assembly isn't used right now for normal code generation. But
this can be used to ease debugging and development by inserting
easy-to-find markers in the generated code. Towards that end, this
change also adds a convenience `LLVMTypeRef`, named `void_func_t`, that
denotes a function type that takes no parameters and does not return a
value.

Example:

    mono_llvm_inline_asm (builder, void_func_t, "int $$0x3", "", LLVM_ASM_SIDE_EFFECT, NULL, 0, "");
  • Loading branch information
imhameed authored Dec 9, 2021
1 parent 6f46a09 commit 6331df3
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/mono/mono/mini/mini-llvm-cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,3 +755,26 @@ unsigned int
mono_llvm_get_prim_size_bits (LLVMTypeRef type) {
return unwrap (type)->getPrimitiveSizeInBits ();
}

/*
* Inserts a call to a fragment of inline assembly.
*
* Return values correspond to output constraints. Parameter values correspond
* to input constraints. Example of use:
* mono_llvm_inline_asm (builder, void_func_t, "int $$0x3", "", LLVM_ASM_SIDE_EFFECT, NULL, 0, "");
*/
LLVMValueRef
mono_llvm_inline_asm (LLVMBuilderRef builder, LLVMTypeRef type,
const char *asmstr, const char *constraints,
MonoLLVMAsmFlags flags, LLVMValueRef *args, unsigned num_args,
const char *name)
{
const auto asmstr_len = strlen (asmstr);
const auto constraints_len = strlen (constraints);
const auto asmval = LLVMGetInlineAsm (type,
const_cast<char *>(asmstr), asmstr_len,
const_cast<char *>(constraints), constraints_len,
(flags & LLVM_ASM_SIDE_EFFECT) != 0, (flags & LLVM_ASM_ALIGN_STACK) != 0,
LLVMInlineAsmDialectATT);
return LLVMBuildCall2 (builder, type, asmval, args, num_args, name);
}
11 changes: 11 additions & 0 deletions src/mono/mono/mini/mini-llvm-cpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,17 @@ mono_llvm_register_overloaded_intrinsic (LLVMModuleRef module, IntrinsicId id, L
unsigned int
mono_llvm_get_prim_size_bits (LLVMTypeRef type);

typedef enum {
LLVM_ASM_SIDE_EFFECT = 1 << 0,
LLVM_ASM_ALIGN_STACK = 1 << 1,
} MonoLLVMAsmFlags;

LLVMValueRef
mono_llvm_inline_asm (LLVMBuilderRef builder, LLVMTypeRef type,
const char *asmstr, const char *constraints,
MonoLLVMAsmFlags flags, LLVMValueRef *args, unsigned num_args,
const char *name);

G_END_DECLS

#endif /* __MONO_MINI_LLVM_CPP_H__ */
4 changes: 4 additions & 0 deletions src/mono/mono/mini/mini-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,8 @@ static LLVMTypeRef sse_i1_t, sse_i2_t, sse_i4_t, sse_i8_t, sse_r4_t, sse_r8_t;
static LLVMTypeRef v64_i1_t, v64_i2_t, v64_i4_t, v64_i8_t, v64_r4_t, v64_r8_t;
static LLVMTypeRef v128_i1_t, v128_i2_t, v128_i4_t, v128_i8_t, v128_r4_t, v128_r8_t;

static LLVMTypeRef void_func_t;

static MonoLLVMModule *init_jit_module (void);

static void emit_dbg_loc (EmitContext *ctx, LLVMBuilderRef builder, const unsigned char *cil_code);
Expand Down Expand Up @@ -12404,6 +12406,8 @@ mono_llvm_init (gboolean enable_jit)

intrins_id_to_intrins = g_hash_table_new (NULL, NULL);

void_func_t = LLVMFunctionType0 (LLVMVoidType (), FALSE);

if (enable_jit)
mono_llvm_jit_init ();
}
Expand Down

0 comments on commit 6331df3

Please sign in to comment.