Skip to content

Commit 215cb8e

Browse files
committed
More arithmetic
# Conflicts: # Sources/LLVM/IntType.swift
1 parent 40e877f commit 215cb8e

File tree

1 file changed

+80
-13
lines changed

1 file changed

+80
-13
lines changed

Sources/LLVM/Constant.swift

Lines changed: 80 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ import cllvm
33
#endif
44

55
public protocol ConstantRepresentation {}
6-
public enum Unsigned: ConstantRepresentation {}
7-
public enum Signed: ConstantRepresentation {}
8-
public enum Floating: ConstantRepresentation {}
6+
public protocol IntegralConstantRepresentation: ConstantRepresentation {}
7+
public protocol RealConstantRepresentation: ConstantRepresentation {}
8+
public enum Unsigned: IntegralConstantRepresentation {}
9+
public enum Signed: IntegralConstantRepresentation {}
10+
public enum Floating: RealConstantRepresentation {}
11+
12+
internal enum InternalConstantRepresentation {
13+
case unsigned
14+
case signed
15+
case floating
16+
}
917

1018
public struct Constant<Repr: ConstantRepresentation>: IRValue {
11-
internal enum Representation {
12-
case unsigned
13-
case signed
14-
case floating
15-
}
16-
1719
internal let llvm: LLVMValueRef
18-
internal let repr: Representation
20+
internal let repr: InternalConstantRepresentation
1921

2022
/// Retrieves the underlying LLVM constant object.
2123
public func asLLVM() -> LLVMValueRef {
@@ -25,17 +27,28 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
2527
public init(llvm: LLVMValueRef!) {
2628
self.llvm = llvm
2729

28-
if ObjectIdentifier(Repr.self) == ObjectIdentifier(Unsigned.self) {
30+
let reprID = ObjectIdentifier(Repr.self)
31+
if reprID == ObjectIdentifier(Unsigned.self) {
2932
self.repr = .unsigned
30-
} else if ObjectIdentifier(Repr.self) == ObjectIdentifier(Signed.self) {
33+
} else if reprID == ObjectIdentifier(Signed.self) {
3134
self.repr = .signed
32-
} else if ObjectIdentifier(Repr.self) == ObjectIdentifier(Floating.self) {
35+
} else if reprID == ObjectIdentifier(Floating.self) {
3336
self.repr = .floating
3437
} else {
3538
fatalError("Invalid representation \(type(of: Repr.self))")
3639
}
3740
}
3841

42+
public static prefix func -(lhs: Constant<Signed>) -> Constant<Signed> {
43+
precondition(lhs.repr == .signed, "Invalid representation")
44+
return Constant<Signed>(llvm: LLVMConstNeg(lhs.llvm))
45+
}
46+
47+
public static prefix func -(lhs: Constant<Floating>) -> Constant<Floating> {
48+
precondition(lhs.repr == .floating, "Invalid representation")
49+
return Constant<Floating>(llvm: LLVMConstFNeg(lhs.llvm))
50+
}
51+
3952
public static func +(lhs: Constant, rhs: Constant) -> Constant {
4053
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
4154

@@ -85,6 +98,19 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
8598
}
8699
}
87100

101+
public static func %(lhs: Constant, rhs: Constant) -> Constant {
102+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
103+
104+
switch lhs.repr {
105+
case .signed:
106+
return Constant(llvm: LLVMConstSRem(lhs.llvm, rhs.llvm))
107+
case .unsigned:
108+
return Constant(llvm: LLVMConstURem(lhs.llvm, rhs.llvm))
109+
case .floating:
110+
return Constant(llvm: LLVMConstFRem(lhs.llvm, rhs.llvm))
111+
}
112+
}
113+
88114
public static func ==(lhs: Constant, rhs: Constant) -> Constant {
89115
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
90116

@@ -142,4 +168,45 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
142168
return Constant(llvm: LLVMConstFCmp(RealPredicate.oge.llvm, lhs.llvm, rhs.llvm))
143169
}
144170
}
171+
172+
public static prefix func ! <T: IntegralConstantRepresentation>(lhs: Constant<T>) -> Constant<T> {
173+
precondition(lhs.repr == .signed || lhs.repr == .unsigned, "Invalid representation")
174+
return Constant<T>(llvm: LLVMConstNeg(lhs.llvm))
175+
}
176+
177+
public static func &&(lhs: Constant, rhs: Constant) -> Constant {
178+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
179+
180+
return Constant(llvm: LLVMConstAnd(lhs.llvm, rhs.llvm))
181+
}
182+
183+
public static func ||(lhs: Constant, rhs: Constant) -> Constant {
184+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
185+
186+
return Constant(llvm: LLVMConstOr(lhs.llvm, rhs.llvm))
187+
}
188+
189+
public static func ^(lhs: Constant, rhs: Constant) -> Constant {
190+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
191+
192+
return Constant(llvm: LLVMConstXor(lhs.llvm, rhs.llvm))
193+
}
194+
195+
public static func >> <T: IntegralConstantRepresentation, U: IntegralConstantRepresentation>(lhs: Constant<T>, rhs: Constant<U>) -> Constant<T> {
196+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
197+
198+
return Constant<T>(llvm: LLVMConstAShr(lhs.llvm, rhs.llvm))
199+
}
200+
201+
// public static func >>> <T: IntegralConstantRepresentation, U: IntegralConstantRepresentation>(lhs: Constant<T>, rhs: Constant<U>) -> Constant<T> {
202+
// precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
203+
//
204+
// return Constant<T>(llvm: LLVMConstLShr(lhs.llvm, rhs.llvm))
205+
// }
206+
207+
public static func << <T: IntegralConstantRepresentation, U: IntegralConstantRepresentation>(lhs: Constant<T>, rhs: Constant<U>) -> Constant<T> {
208+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
209+
210+
return Constant<T>(llvm: LLVMConstShl(lhs.llvm, rhs.llvm))
211+
}
145212
}

0 commit comments

Comments
 (0)