@@ -200,10 +200,8 @@ public enum AtomicOrdering: Comparable {
200
200
. sequentiallyConsistent: LLVMAtomicOrderingSequentiallyConsistent,
201
201
]
202
202
203
- public static func == ( lhs: AtomicOrdering , rhs: AtomicOrdering ) -> Bool {
204
- return lhs. llvm == rhs. llvm
205
- }
206
-
203
+ /// Returns whether the left atomic ordering is strictly weaker than the
204
+ /// right atomic order.
207
205
public static func < ( lhs: AtomicOrdering , rhs: AtomicOrdering ) -> Bool {
208
206
return lhs. llvm. rawValue < rhs. llvm. rawValue
209
207
}
@@ -1094,25 +1092,40 @@ public class IRBuilder {
1094
1092
return LLVMBuildAlloca ( llvm, type. asLLVM ( ) , name)
1095
1093
}
1096
1094
1097
- /// Build a store instruction that stores the first value into the location
1095
+ /// Builds a store instruction that stores the first value into the location
1098
1096
/// given in the second value.
1099
1097
///
1098
+ /// - parameter val: The source value.
1099
+ /// - parameter ptr: The destination pointer to store into.
1100
+ /// - parameter ordering: The ordering effect of the fence for this store,
1101
+ /// if any. Defaults to a nonatomic store.
1102
+ /// - parameter volatile: Whether this is a store to a volatile memory location.
1103
+ ///
1100
1104
/// - returns: A value representing `void`.
1101
1105
@discardableResult
1102
- public func buildStore( _ val: IRValue , to ptr: IRValue ) -> IRValue {
1103
- return LLVMBuildStore ( llvm, val. asLLVM ( ) , ptr. asLLVM ( ) )
1106
+ public func buildStore( _ val: IRValue , to ptr: IRValue , ordering: AtomicOrdering = . notAtomic, volatile: Bool = false ) -> IRValue {
1107
+ let storeInst = LLVMBuildStore ( llvm, val. asLLVM ( ) , ptr. asLLVM ( ) ) !
1108
+ LLVMSetOrdering ( storeInst, ordering. llvm)
1109
+ LLVMSetVolatile ( storeInst, volatile. llvm)
1110
+ return storeInst
1104
1111
}
1105
1112
1106
1113
/// Builds a load instruction that loads a value from the location in the
1107
1114
/// given value.
1108
1115
///
1109
1116
/// - parameter ptr: The pointer value to load from.
1117
+ /// - parameter ordering: The ordering effect of the fence for this load,
1118
+ /// if any. Defaults to a nonatomic load.
1119
+ /// - parameter volatile: Whether this is a load from a volatile memory location.
1110
1120
/// - parameter name: The name for the newly inserted instruction.
1111
1121
///
1112
1122
/// - returns: A value representing the result of a load from the given
1113
1123
/// pointer value.
1114
- public func buildLoad( _ ptr: IRValue , name: String = " " ) -> IRValue {
1115
- return LLVMBuildLoad ( llvm, ptr. asLLVM ( ) , name)
1124
+ public func buildLoad( _ ptr: IRValue , ordering: AtomicOrdering = . notAtomic, volatile: Bool = false , name: String = " " ) -> IRValue {
1125
+ let loadInst = LLVMBuildLoad ( llvm, ptr. asLLVM ( ) , name) !
1126
+ LLVMSetOrdering ( loadInst, ordering. llvm)
1127
+ LLVMSetVolatile ( loadInst, volatile. llvm)
1128
+ return loadInst
1116
1129
}
1117
1130
1118
1131
/// Builds a `GEP` (Get Element Pointer) instruction with a resultant value
@@ -1706,6 +1719,48 @@ public class IRBuilder {
1706
1719
return Alias ( llvm: LLVMAddAlias ( module. llvm, type. asLLVM ( ) , aliasee. asLLVM ( ) , name) )
1707
1720
}
1708
1721
1722
+ // MARK: Inline Assembly
1723
+
1724
+ /// Builds a value representing an inline assembly expression (as opposed to
1725
+ /// module-level inline assembly).
1726
+ ///
1727
+ /// LLVM represents inline assembler as a template string (containing the
1728
+ /// instructions to emit), a list of operand constraints (stored as a string),
1729
+ /// and some flags.
1730
+ ///
1731
+ /// The template string supports argument substitution of the operands using
1732
+ /// "$" followed by a number, to indicate substitution of the given
1733
+ /// register/memory location, as specified by the constraint string.
1734
+ /// "${NUM:MODIFIER}" may also be used, where MODIFIER is a target-specific
1735
+ /// annotation for how to print the operand (see [Asm Template Argument
1736
+ /// Modifiers](https://llvm.org/docs/LangRef.html#inline-asm-modifiers)).
1737
+ ///
1738
+ /// LLVM’s support for inline asm is modeled closely on the requirements of
1739
+ /// Clang’s GCC-compatible inline-asm support. Thus, the feature-set and the
1740
+ /// constraint and modifier codes are similar or identical to those in GCC’s
1741
+ /// inline asm support.
1742
+ ///
1743
+ /// However, the syntax of the template and constraint strings is not the
1744
+ /// same as the syntax accepted by GCC and Clang, and, while most constraint
1745
+ /// letters are passed through as-is by Clang, some get translated to other
1746
+ /// codes when converting from the C source to the LLVM assembly.
1747
+ ///
1748
+ /// - parameter asm: The inline assembly expression template string.
1749
+ /// - parameter type: The type of the parameters and return value of the
1750
+ /// assembly expression string.
1751
+ /// - parameter constraints: A comma-separated string, each element containing
1752
+ /// one or more constraint codes.
1753
+ /// - parameter hasSideEffects: Whether this inline asm expression has
1754
+ /// side effects. Defaults to `false`.
1755
+ /// - parameter needsAlignedStack: Whether the function containing the
1756
+ /// asm needs to align its stack conservatively. Defaults to `true`.
1757
+ ///
1758
+ /// - returns: A representation of the newly created inline assembly
1759
+ /// expression.
1760
+ public func buildInlineAssembly( _ asm: String , type: FunctionType , constraints: String = " " , hasSideEffects: Bool = true , needsAlignedStack: Bool = true ) -> IRValue {
1761
+ return LLVMConstInlineAsm ( type. asLLVM ( ) , asm, constraints, hasSideEffects. llvm, needsAlignedStack. llvm)
1762
+ }
1763
+
1709
1764
deinit {
1710
1765
LLVMDisposeBuilder ( llvm)
1711
1766
}
0 commit comments