Skip to content

Commit 6894d18

Browse files
committed
feat: add support for calling into inline asm
1 parent c38c6cd commit 6894d18

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

src/context.rs

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
//! A `Context` is an opaque owner and manager of core global data.
22
3-
use llvm_sys::core::{LLVMAppendBasicBlockInContext, LLVMContextCreate, LLVMContextDispose, LLVMCreateBuilderInContext, LLVMDoubleTypeInContext, LLVMFloatTypeInContext, LLVMFP128TypeInContext, LLVMInsertBasicBlockInContext, LLVMInt16TypeInContext, LLVMInt1TypeInContext, LLVMInt32TypeInContext, LLVMInt64TypeInContext, LLVMInt8TypeInContext, LLVMIntTypeInContext, LLVMModuleCreateWithNameInContext, LLVMStructCreateNamed, LLVMStructTypeInContext, LLVMVoidTypeInContext, LLVMHalfTypeInContext, LLVMGetGlobalContext, LLVMPPCFP128TypeInContext, LLVMConstStructInContext, LLVMMDNodeInContext, LLVMMDStringInContext, LLVMGetMDKindIDInContext, LLVMX86FP80TypeInContext, LLVMConstStringInContext, LLVMContextSetDiagnosticHandler};
3+
use llvm_sys::core::{LLVMAppendBasicBlockInContext, LLVMContextCreate, LLVMContextDispose, LLVMCreateBuilderInContext, LLVMDoubleTypeInContext, LLVMFloatTypeInContext, LLVMFP128TypeInContext, LLVMInsertBasicBlockInContext, LLVMInt16TypeInContext, LLVMInt1TypeInContext, LLVMInt32TypeInContext, LLVMInt64TypeInContext, LLVMInt8TypeInContext, LLVMIntTypeInContext, LLVMModuleCreateWithNameInContext, LLVMStructCreateNamed, LLVMStructTypeInContext, LLVMVoidTypeInContext, LLVMHalfTypeInContext, LLVMGetGlobalContext, LLVMPPCFP128TypeInContext, LLVMConstStructInContext, LLVMMDNodeInContext, LLVMMDStringInContext, LLVMGetMDKindIDInContext, LLVMX86FP80TypeInContext, LLVMConstStringInContext, LLVMContextSetDiagnosticHandler, LLVMGetInlineAsm};
44
#[llvm_versions(4.0..=latest)]
5-
use llvm_sys::core::{LLVMCreateEnumAttribute, LLVMCreateStringAttribute};
5+
use llvm_sys::core::{LLVMCreateEnumAttribute, LLVMCreateStringAttribute, LLVMGetTypeKind, LLVMTypeOf, LLVMGetElementType};
66
use llvm_sys::prelude::{LLVMContextRef, LLVMTypeRef, LLVMValueRef, LLVMDiagnosticInfoRef};
77
use llvm_sys::ir_reader::LLVMParseIRInContext;
88
use llvm_sys::target::{LLVMIntPtrTypeForASInContext, LLVMIntPtrTypeInContext};
99
use libc::c_void;
1010
use once_cell::sync::Lazy;
1111
use parking_lot::{Mutex, MutexGuard};
1212

13-
use crate::AddressSpace;
13+
use crate::{AddressSpace, InlineAsmDialect};
1414
#[llvm_versions(4.0..=latest)]
1515
use crate::attributes::Attribute;
1616
use crate::basic_block::BasicBlock;
@@ -19,8 +19,8 @@ use crate::memory_buffer::MemoryBuffer;
1919
use crate::module::Module;
2020
use crate::support::{to_c_str, LLVMString};
2121
use crate::targets::TargetData;
22-
use crate::types::{BasicTypeEnum, FloatType, IntType, StructType, VoidType, AsTypeRef};
23-
use crate::values::{AsValueRef, BasicMetadataValueEnum, BasicValueEnum, FunctionValue, StructValue, MetadataValue, VectorValue};
22+
use crate::types::{BasicTypeEnum, FloatType, IntType, StructType, VoidType, AsTypeRef, AnyTypeEnum, FunctionType};
23+
use crate::values::{AsValueRef, BasicMetadataValueEnum, BasicValueEnum, FunctionValue, StructValue, MetadataValue, VectorValue, PointerValue};
2424

2525
use std::marker::PhantomData;
2626
use std::mem::{forget, ManuallyDrop};
@@ -191,6 +191,42 @@ impl Context {
191191
Err(LLVMString::new(err_str))
192192
}
193193

194+
/// Creates a inline asm function pointer.
195+
///
196+
/// # Example
197+
/// ```no_run
198+
/// use inkwell::context::Context;
199+
///
200+
/// let context = Context::create();
201+
/// let module = context.create_module("my_module");
202+
/// let builder = context.create_builder();
203+
/// let void_type = context.void_type();
204+
/// let fn_type = void_type.fn_type(&[], false);
205+
/// let fn_val = module.add_function("my_fn", fn_type, None);
206+
/// let basic_block = context.append_basic_block(fn_val, "entry");
207+
///
208+
/// builder.position_at_end(basic_block);
209+
/// let asm_fn = context.i64_type().fn_type(&[context.i64_type().into(), context.i64_type().into()], false);
210+
/// let asm = context.create_inline_asm(asm_fn, "syscall", "=r,{rax},{rdi}", true, false, None);
211+
/// let params = &[context.i64_type().const_int(60).into(), context.i64_type().const_int(1).into()];
212+
/// builder.build_call(asm, params, "exit");
213+
/// builder.build_return(None);
214+
pub fn create_inline_asm(&self, ty: FunctionType, mut assembly: String, mut constraints: String, sideeffects: bool, alignstack: bool, dialect: Option<InlineAsmDialect>) -> PointerValue {
215+
let value = unsafe {
216+
LLVMGetInlineAsm(
217+
ty.as_type_ref(),
218+
assembly.as_mut_ptr() as *mut ::libc::c_char,
219+
assembly.len(),
220+
constraints.as_mut_ptr() as *mut ::libc::c_char,
221+
constraints.len(),
222+
sideeffects as i32,
223+
alignstack as i32,
224+
dialect.unwrap_or(InlineAsmDialect::ATT).into()
225+
)
226+
};
227+
PointerValue::new(value)
228+
}
229+
194230
/// Gets the `VoidType`. It will be assigned the current context.
195231
///
196232
/// # Example

src/lib.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ pub mod targets;
3939
pub mod types;
4040
pub mod values;
4141

42-
use llvm_sys::{LLVMIntPredicate, LLVMRealPredicate, LLVMVisibility, LLVMThreadLocalMode, LLVMDLLStorageClass, LLVMAtomicOrdering, LLVMAtomicRMWBinOp};
42+
use llvm_sys::{LLVMIntPredicate, LLVMRealPredicate, LLVMVisibility, LLVMThreadLocalMode, LLVMDLLStorageClass, LLVMAtomicOrdering, LLVMAtomicRMWBinOp, LLVMInlineAsmDialect};
4343

4444
use std::convert::TryFrom;
4545

@@ -385,3 +385,12 @@ impl Default for DLLStorageClass {
385385
DLLStorageClass::Default
386386
}
387387
}
388+
389+
#[llvm_enum(LLVMInlineAsmDialect)]
390+
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
391+
pub enum InlineAsmDialect {
392+
#[llvm_variant(LLVMInlineAsmDialectATT)]
393+
ATT,
394+
#[llvm_variant(LLVMInlineAsmDialectIntel)]
395+
Intel,
396+
}

0 commit comments

Comments
 (0)