Skip to content

Commit bbe4b40

Browse files
committed
Add named equivalents of operators for overflow behavior specification
1 parent 937f05d commit bbe4b40

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed

Sources/LLVM/Constant.swift

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,22 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
3939
}
4040
}
4141

42+
// MARK: Arithmetic Operations
43+
44+
public static func neg(_ lhs: Constant<Signed>, overflowBehavior: OverflowBehavior = .default) -> Constant<Signed> {
45+
precondition(lhs.repr == .signed, "Invalid representation")
46+
47+
let lhsVal = lhs.asLLVM()
48+
switch overflowBehavior {
49+
case .noSignedWrap:
50+
return Constant<Signed>(llvm: LLVMConstNSWNeg(lhsVal))
51+
case .noUnsignedWrap:
52+
return Constant<Signed>(llvm: LLVMConstNUWNeg(lhsVal))
53+
case .default:
54+
return Constant<Signed>(llvm: LLVMConstNeg(lhsVal))
55+
}
56+
}
57+
4258
public static prefix func -(lhs: Constant<Signed>) -> Constant<Signed> {
4359
precondition(lhs.repr == .signed, "Invalid representation")
4460
return Constant<Signed>(llvm: LLVMConstNeg(lhs.llvm))
@@ -49,6 +65,27 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
4965
return Constant<Floating>(llvm: LLVMConstFNeg(lhs.llvm))
5066
}
5167

68+
public static func add(_ lhs: Constant, _ rhs: Constant, overflowBehavior: OverflowBehavior = .default) -> Constant {
69+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
70+
71+
let lhsVal = lhs.asLLVM()
72+
let rhsVal = rhs.asLLVM()
73+
switch lhs.repr {
74+
case .signed: fallthrough
75+
case .unsigned:
76+
switch overflowBehavior {
77+
case .noSignedWrap:
78+
return Constant(llvm: LLVMConstNSWAdd(lhsVal, rhsVal))
79+
case .noUnsignedWrap:
80+
return Constant(llvm: LLVMConstNUWAdd(lhsVal, rhsVal))
81+
case .default:
82+
return lhs + rhs
83+
}
84+
case .floating:
85+
return Constant(llvm: LLVMConstFAdd(lhsVal, rhsVal))
86+
}
87+
}
88+
5289
public static func +(lhs: Constant, rhs: Constant) -> Constant {
5390
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
5491

@@ -61,6 +98,27 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
6198
}
6299
}
63100

101+
public static func sub(_ lhs: Constant, _ rhs: Constant, overflowBehavior: OverflowBehavior = .default) -> Constant {
102+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
103+
104+
let lhsVal = lhs.asLLVM()
105+
let rhsVal = rhs.asLLVM()
106+
switch lhs.repr {
107+
case .signed: fallthrough
108+
case .unsigned:
109+
switch overflowBehavior {
110+
case .noSignedWrap:
111+
return Constant(llvm: LLVMConstNSWSub(lhsVal, rhsVal))
112+
case .noUnsignedWrap:
113+
return Constant(llvm: LLVMConstNUWSub(lhsVal, rhsVal))
114+
case .default:
115+
return lhs - rhs
116+
}
117+
case .floating:
118+
return lhs - rhs
119+
}
120+
}
121+
64122
public static func -(lhs: Constant, rhs: Constant) -> Constant {
65123
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
66124

@@ -73,6 +131,27 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
73131
}
74132
}
75133

134+
public static func mul(_ lhs: Constant, _ rhs: Constant, overflowBehavior: OverflowBehavior = .default) -> Constant {
135+
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
136+
137+
let lhsVal = lhs.asLLVM()
138+
let rhsVal = rhs.asLLVM()
139+
switch lhs.repr {
140+
case .signed: fallthrough
141+
case .unsigned:
142+
switch overflowBehavior {
143+
case .noSignedWrap:
144+
return Constant(llvm: LLVMConstNSWMul(lhsVal, rhsVal))
145+
case .noUnsignedWrap:
146+
return Constant(llvm: LLVMConstNUWMul(lhsVal, rhsVal))
147+
case .default:
148+
return lhs * rhs
149+
}
150+
case .floating:
151+
return lhs * rhs
152+
}
153+
}
154+
76155
public static func *(lhs: Constant, rhs: Constant) -> Constant {
77156
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
78157

@@ -111,6 +190,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
111190
}
112191
}
113192

193+
// MARK: Comparison Operations
194+
114195
public static func ==(lhs: Constant, rhs: Constant) -> Constant {
115196
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
116197

@@ -169,6 +250,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
169250
}
170251
}
171252

253+
// MARK: Logical Operations
254+
172255
public static prefix func ! <T: IntegralConstantRepresentation>(lhs: Constant<T>) -> Constant<T> {
173256
precondition(lhs.repr == .signed || lhs.repr == .unsigned, "Invalid representation")
174257
return Constant<T>(llvm: LLVMConstNeg(lhs.llvm))
@@ -192,6 +275,8 @@ public struct Constant<Repr: ConstantRepresentation>: IRValue {
192275
return Constant(llvm: LLVMConstXor(lhs.llvm, rhs.llvm))
193276
}
194277

278+
// MARK: Shifts
279+
195280
public static func >> <T: IntegralConstantRepresentation, U: IntegralConstantRepresentation>(lhs: Constant<T>, rhs: Constant<U>) -> Constant<T> {
196281
precondition(lhs.repr == rhs.repr, "Mixed-representation constant operations are disallowed")
197282

0 commit comments

Comments
 (0)