Skip to content

Commit d28f438

Browse files
committed
Finish up the builder's instructions
1 parent 52bf103 commit d28f438

File tree

1 file changed

+181
-1
lines changed

1 file changed

+181
-1
lines changed

Sources/LLVM/IRBuilder.swift

Lines changed: 181 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,111 @@ public enum AtomicOrdering: Comparable {
214214
}
215215
}
216216

217+
/// `BinaryOperation` enumerates the subset of opcodes that are binary operations.
218+
public enum BinaryOperation {
219+
/// The `add` instruction.
220+
case add
221+
/// The `fadd` instruction.
222+
case fadd
223+
/// The `sub` instruction.
224+
case sub
225+
/// The `fsub` instruction.
226+
case fsub
227+
/// The `mul` instruction.
228+
case mul
229+
/// The `fmul` instruction.
230+
case fmul
231+
/// The `udiv` instruction.
232+
case udiv
233+
/// The `sdiv` instruction.
234+
case sdiv
235+
/// The `fdiv` instruction.
236+
case fdiv
237+
/// The `urem` instruction.
238+
case urem
239+
/// The `srem` instruction.
240+
case srem
241+
/// The `frem` instruction.
242+
case frem
243+
244+
/// The `shl` instruction.
245+
case shl
246+
/// The `lshr` instruction.
247+
case lshr
248+
/// The `ashr` instruction.
249+
case ashr
250+
/// The `and` instruction.
251+
case and
252+
/// The `or` instruction.
253+
case or
254+
/// The `xor` instruction.
255+
case xor
256+
257+
static let binaryOperationMap: [BinaryOperation: LLVMOpcode] = [
258+
.add: LLVMAdd, .fadd: LLVMFAdd, .sub: LLVMSub, .fsub: LLVMFSub,
259+
.mul: LLVMMul, .fmul: LLVMFMul, .udiv: LLVMUDiv, .sdiv: LLVMSDiv,
260+
.fdiv: LLVMFDiv, .urem: LLVMURem, .srem: LLVMSRem, .frem: LLVMFRem,
261+
.shl: LLVMShl, .lshr: LLVMLShr, .ashr: LLVMAShr, .and: LLVMAnd,
262+
.or: LLVMOr, .xor: LLVMXor,
263+
]
264+
265+
/// Retrieves the corresponding `LLVMOpcode`.
266+
public var llvm: LLVMOpcode {
267+
return BinaryOperation.binaryOperationMap[self]!
268+
}
269+
}
270+
271+
/// `CastOperation` enumerates the subset of opcodes that are cast operations.
272+
public enum CastOperation {
273+
/// The `trunc` instruction.
274+
case trunc
275+
/// The `zext` instruction.
276+
case zext
277+
/// The `sext` instruction.
278+
case sext
279+
/// The `fpToUI` instruction.
280+
case fpToUI
281+
/// The `fpToSI` instruction.
282+
case fpToSI
283+
/// The `uiToFP` instruction.
284+
case uiToFP
285+
/// The `siToFP` instruction.
286+
case siToFP
287+
/// The `fpTrunc` instruction.
288+
case fpTrunc
289+
/// The `fpext` instruction.
290+
case fpext
291+
/// The `ptrToInt` instruction.
292+
case ptrToInt
293+
/// The `intToPtr` instruction.
294+
case intToPtr
295+
/// The `bitCast` instruction.
296+
case bitCast
297+
/// The `addrSpaceCast` instruction.
298+
case addrSpaceCast
299+
300+
static let castOperationMap: [CastOperation: LLVMOpcode] = [
301+
.trunc: LLVMTrunc,
302+
.zext: LLVMZExt,
303+
.sext: LLVMSExt,
304+
.fpToUI: LLVMFPToUI,
305+
.fpToSI: LLVMFPToSI,
306+
.uiToFP: LLVMUIToFP,
307+
.siToFP: LLVMSIToFP,
308+
.fpTrunc: LLVMFPTrunc,
309+
.fpext: LLVMFPExt,
310+
.ptrToInt: LLVMPtrToInt,
311+
.intToPtr: LLVMIntToPtr,
312+
.bitCast: LLVMBitCast,
313+
.addrSpaceCast: LLVMAddrSpaceCast,
314+
]
315+
316+
/// Retrieves the corresponding `LLVMOpcode`.
317+
public var llvm: LLVMOpcode {
318+
return CastOperation.castOperationMap[self]!
319+
}
320+
}
321+
217322
/// `AtomicReadModifyWriteOperation` enumerates the kinds of supported atomic
218323
/// read-write-modify operations.
219324
public enum AtomicReadModifyWriteOperation {
@@ -421,6 +526,35 @@ public class IRBuilder {
421526
}
422527
}
423528

529+
// MARK: Convenience Instructions
530+
531+
/// Builds the specified binary operation instruction with the given arguments.
532+
///
533+
/// - parameter op: The operation to build.
534+
/// - parameter lhs: The first operand.
535+
/// - parameter rhs: The second operand.
536+
/// - parameter name: The name for the newly inserted instruction.
537+
///
538+
/// - returns: A value representing the result of perfomring the given binary
539+
/// operation with the given values as arguments.
540+
public func buildBinaryOperation(_ op: BinaryOperation, _ lhs: IRValue, _ rhs: IRValue, name: String = "") -> IRValue {
541+
return LLVMBuildBinOp(llvm, op.llvm, lhs.asLLVM(), rhs.asLLVM(), name)
542+
}
543+
544+
/// Builds the specified cast operation instruction with the given value and
545+
/// destination type.
546+
///
547+
/// - parameter op: The cast operation to build.
548+
/// - parameter value: The value to cast.
549+
/// - parameter type: The destination type to cast to.
550+
/// - parameter name: The name for the newly inserted instruction.
551+
///
552+
/// - returns: A value representing the result of casting the given value to
553+
/// the given destination type using the given operation.
554+
public func buildCast(_ op: CastOperation, value: IRValue, type: IRType, name: String = "") -> IRValue {
555+
return LLVMBuildCast(llvm, op.llvm, value.asLLVM(), type.asLLVM(), name)
556+
}
557+
424558
// MARK: Arithmetic Instructions
425559

426560
/// Builds a negation instruction with the given value as an operand.
@@ -432,7 +566,7 @@ public class IRBuilder {
432566
/// - parameter value: The value to negate.
433567
/// - parameter overflowBehavior: Should overflow occur, specifies the
434568
/// behavior of the program.
435-
/// - name: The name for the newly inserted instruction.
569+
/// - parameter name: The name for the newly inserted instruction.
436570
///
437571
/// - returns: A value representing the negation of the given value.
438572
public func buildNeg(_ value: IRValue,
@@ -1035,6 +1169,21 @@ public class IRBuilder {
10351169
public func buildResume(_ val: IRValue) -> IRValue {
10361170
return LLVMBuildResume(llvm, val.asLLVM())
10371171
}
1172+
1173+
/// Build a `va_arg` instruction to access arguments passed through the
1174+
/// "variable argument" area of a function call.
1175+
///
1176+
/// This instruction is used to implement the `va_arg` macro in C.
1177+
///
1178+
/// - parameter list: A value of type `va_list*`
1179+
/// - parameter type: THe type of values in the variable argument area.
1180+
/// - parameter name: The name for the newly inserted instruction.
1181+
///
1182+
/// - returns: A value of the specified argument type. In addition, the
1183+
/// `va_list` pointer is incremented to point to the next argument.
1184+
public func buildVAArg(_ list: IRValue, type: IRType, name: String = "") -> IRValue {
1185+
return LLVMBuildVAArg(llvm, list.asLLVM(), type.asLLVM(), name)
1186+
}
10381187

10391188
// MARK: Memory Access Instructions
10401189

@@ -1191,6 +1340,19 @@ public class IRBuilder {
11911340
return LLVMBuildTruncOrBitCast(llvm, val.asLLVM(), type.asLLVM(), name)
11921341
}
11931342

1343+
/// Builds an instruction that either performs a zero extension or a bitcast of
1344+
/// the given value to a value of the given type with a wider width.
1345+
///
1346+
/// - parameter val: The value to zero extend.
1347+
/// - parameter type: The destination type.
1348+
/// - parameter name: The name for the newly inserted instruction.
1349+
///
1350+
/// - returns: A value representing the result of zero extending or bitcasting
1351+
/// the given value to fit the given type.
1352+
public func buildZExtOrBitCast(_ val: IRValue, type: IRType, name: String = "") -> IRValue {
1353+
return LLVMBuildZExtOrBitCast(llvm, val.asLLVM(), type.asLLVM(), name)
1354+
}
1355+
11941356
/// Builds a bitcast instruction to convert the given value to a value of the
11951357
/// given type by just copying the bit pattern.
11961358
///
@@ -1552,6 +1714,24 @@ public class IRBuilder {
15521714
return LLVMBuildExtractElement(llvm, vector.asLLVM(), index.asLLVM(), name)
15531715
}
15541716

1717+
/// Builds a vector shuffle instruction to construct a permutation of elements
1718+
/// from the two given input vectors, returning a vector with the same element
1719+
/// type as the inputs and length that is the same as the shuffle mask.
1720+
///
1721+
/// - parameter vector1: The first vector to shuffle.
1722+
/// - parameter vector2: The second vector to shuffle.
1723+
/// - parameter mask: A constant vector of `i32` values that acts as a mask
1724+
/// for the shuffled vectors.
1725+
///
1726+
/// - returns: A value representing a vector with the same element type as the
1727+
/// inputs and length that is the same as the shuffle mask.
1728+
public func buildShuffleVector(_ vector1: IRValue, and vector2: IRValue, mask: IRValue, name: String = "") -> IRValue {
1729+
guard let maskTy = mask.type as? VectorType, maskTy.elementType is IntType else {
1730+
fatalError("Vector shuffle mask's elements must be 32-bit integers")
1731+
}
1732+
return LLVMBuildShuffleVector(llvm, vector1.asLLVM(), vector2.asLLVM(), mask.asLLVM(), name)
1733+
}
1734+
15551735
// MARK: Global Variable Instructions
15561736

15571737
/// Build a named global of the given type.

0 commit comments

Comments
 (0)