@@ -16,6 +16,9 @@ public enum LLVMIntrinsic: String {
16
16
case prefetch = " llvm.prefetch "
17
17
case pcmarker = " llvm.pcmarker "
18
18
case readcyclecounter = " llvm.readcyclecounter "
19
+ case assume = " llvm.assume "
20
+ case stackprotector = " llvm.stackprotector "
21
+ case stackprotectorcheck = " llvm.stackprotectorcheck "
19
22
case memcpy_i8 = " llvm.memcpy.i8 "
20
23
case memcpy_i16 = " llvm.memcpy.i16 "
21
24
case memcpy_i32 = " llvm.memcpy.i32 "
@@ -146,7 +149,6 @@ public enum LLVMIntrinsic: String {
146
149
case annotation_i64 = " llvm.annotation.i64 "
147
150
case annotation_i256 = " llvm.annotation.i256 "
148
151
case trap = " llvm.trap "
149
- case stackprotector = " llvm.stackprotector "
150
152
151
153
var signature : FunctionType {
152
154
switch self {
@@ -215,6 +217,21 @@ public enum LLVMIntrinsic: String {
215
217
argTypes: [ ] ,
216
218
returnType: IntType . int64
217
219
)
220
+ case . assume:
221
+ return FunctionType (
222
+ argTypes: [ IntType . int1] ,
223
+ returnType: VoidType ( )
224
+ )
225
+ case . stackprotector:
226
+ return FunctionType (
227
+ argTypes: [ PointerType ( pointee: IntType . int8) , PointerType ( pointee: PointerType ( pointee: IntType . int8) ) ] ,
228
+ returnType: VoidType ( )
229
+ )
230
+ case . stackprotectorcheck:
231
+ return FunctionType (
232
+ argTypes: [ PointerType ( pointee: PointerType ( pointee: IntType . int8) ) ] ,
233
+ returnType: VoidType ( )
234
+ )
218
235
case . memcpy_i8:
219
236
return FunctionType (
220
237
argTypes: [ PointerType ( pointee: IntType . int8) , PointerType ( pointee: IntType . int8) ] ,
@@ -865,38 +882,131 @@ public enum LLVMIntrinsic: String {
865
882
argTypes: [ ] ,
866
883
returnType: VoidType ( )
867
884
)
868
- case . stackprotector:
869
- return FunctionType (
870
- argTypes: [ PointerType ( pointee: IntType . int8) , PointerType ( pointee: PointerType ( pointee: IntType . int8) ) ] ,
871
- returnType: VoidType ( )
872
- )
873
885
}
874
886
}
875
887
}
876
888
877
889
extension IRBuilder {
878
- public func buildIntrinsic( _ i : LLVMIntrinsic ) -> Function {
890
+ public func buildIntrinsic( _ i: LLVMIntrinsic ) -> Function {
879
891
if let f = self . module. function ( named: i. rawValue) {
880
892
return f
881
893
}
882
894
var f = self . addFunction ( i. rawValue, type: i. signature)
883
895
f. linkage = . external
884
896
return f
885
897
}
886
- //
887
- // func buildva_start(PointerType(pointee: IntType.int8))
888
- // func buildva_copy(PointerType(pointee: IntType.int8), PointerType(pointee: IntType.int8))
889
- // func buildva_end(PointerType(pointee: IntType.int8))
890
- // func buildgcroot(PointerType(pointee: PointerType(pointee: IntType.int8)), PointerType(pointee: IntType.int8))
891
- // func buildgcread(PointerType(pointee: IntType.int8), PointerType(pointee: PointerType(pointee: IntType.int8)))
892
- // func buildgcwrite(PointerType(pointee: IntType.int8), PointerType(pointee: IntType.int8), PointerType(pointee: PointerType(pointee: IntType.int8)))
893
- // func buildreturnaddress(IntType.int32)
894
- // func buildframeaddress(IntType.int32)
895
- // func buildstacksave()
896
- // func buildstackrestore(PointerType(pointee: IntType.int8))
897
- // func buildprefetch(PointerType(pointee: IntType.int8), IntType.int32, IntType.int32)
898
- // func buildpcmarker(IntType.int32)
899
- // func buildreadcyclecounter()
898
+
899
+ private func typeCheckArguments( to fn: LLVMIntrinsic , args: IRValue ... ) -> Bool {
900
+ let fnArgTypes = fn. signature. argTypes
901
+ guard fnArgTypes. count == args. count else { return false }
902
+ for t in zip ( fnArgTypes, args) {
903
+ guard t. 0 . asLLVM ( ) == t. 1 . type. asLLVM ( ) else { return false }
904
+ }
905
+ return true
906
+ }
907
+
908
+ private func resolveOverloadedArguments( to fns: [ LLVMIntrinsic ] , args: IRValue ... ) -> LLVMIntrinsic ? {
909
+ return fns. filter ( { ( fn) -> Bool in
910
+ let fnArgTypes = fn. signature. argTypes
911
+ guard fnArgTypes. count == args. count else { return false }
912
+ for t in zip ( fnArgTypes, args) {
913
+ guard t. 0 . asLLVM ( ) == t. 1 . type. asLLVM ( ) else { return false }
914
+ }
915
+ return true
916
+ } ) . first
917
+ }
918
+
919
+ @discardableResult
920
+ public func buildVaStart( _ x: IRValue , name: String = " " ) -> IRValue {
921
+ precondition ( typeCheckArguments ( to: . va_start, args: x) )
922
+ return buildCall ( buildIntrinsic ( . va_start) , args: [ x] , name: name)
923
+ }
924
+
925
+ @discardableResult
926
+ public func buildVaCopy( from src: IRValue , to dest: IRValue , name: String = " " ) -> IRValue {
927
+ precondition ( typeCheckArguments ( to: . va_copy, args: dest, src) )
928
+ return buildCall ( buildIntrinsic ( . va_copy) , args: [ dest, src] , name: name)
929
+ }
930
+
931
+ @discardableResult
932
+ public func buildVaEnd( _ x: IRValue , name: String = " " ) -> IRValue {
933
+ precondition ( typeCheckArguments ( to: . va_end, args: x) )
934
+ return buildCall ( buildIntrinsic ( . va_end) , args: [ x] , name: name)
935
+ }
936
+
937
+ func buildGCRoot( _ x: IRValue , _ y: IRValue , name: String = " " ) -> IRValue {
938
+ precondition ( typeCheckArguments ( to: . gcroot, args: x, y) )
939
+ return buildCall ( buildIntrinsic ( . gcroot) , args: [ x, y] , name: name)
940
+ }
941
+
942
+ func buildGCRead( _ x: IRValue , _ y: IRValue , _ z: IRValue , name: String = " " ) -> IRValue {
943
+ precondition ( typeCheckArguments ( to: . gcread, args: x, y, z) )
944
+ return buildCall ( buildIntrinsic ( . gcread) , args: [ x, y, z] , name: name)
945
+ }
946
+
947
+ func buildGCWrite( _ x: IRValue , _ y: IRValue , _ z: IRValue , name: String = " " ) -> IRValue {
948
+ precondition ( typeCheckArguments ( to: . gcwrite, args: x, y, z) )
949
+ return buildCall ( buildIntrinsic ( . gcwrite) , args: [ x, y, z] , name: name)
950
+ }
951
+
952
+ func buildReturnAddress( _ x: IRValue , name: String = " " ) -> IRValue {
953
+ precondition ( typeCheckArguments ( to: . returnaddress, args: x) )
954
+ return buildCall ( buildIntrinsic ( . returnaddress) , args: [ x] , name: name)
955
+ }
956
+
957
+ func buildFrameAddress( _ x: IRValue , name: String = " " ) -> IRValue {
958
+ precondition ( typeCheckArguments ( to: . frameaddress, args: x) )
959
+ return buildCall ( buildIntrinsic ( . frameaddress) , args: [ x] , name: name)
960
+ }
961
+
962
+ func buildStackSave( name: String = " " ) -> IRValue {
963
+ precondition ( typeCheckArguments ( to: . stacksave) )
964
+ return buildCall ( buildIntrinsic ( . stacksave) , args: [ ] , name: name)
965
+ }
966
+
967
+ func buildStackRestore( _ x: IRValue , name: String = " " ) -> IRValue {
968
+ precondition ( typeCheckArguments ( to: . stackrestore, args: x) )
969
+ return buildCall ( buildIntrinsic ( . stackrestore) , args: [ x] , name: name)
970
+ }
971
+
972
+ func buildPrefetch( _ x: IRValue , _ y: IRValue , _ z: IRValue , name: String = " " ) -> IRValue {
973
+ precondition ( typeCheckArguments ( to: . prefetch, args: x, y, z) )
974
+ return buildCall ( buildIntrinsic ( . prefetch) , args: [ x, y, z] , name: name)
975
+ }
976
+
977
+ func buildPCMarker( _ x: IRValue , name: String = " " ) -> IRValue {
978
+ precondition ( typeCheckArguments ( to: . pcmarker, args: x) )
979
+ return buildCall ( buildIntrinsic ( . pcmarker) , args: [ x] , name: name)
980
+ }
981
+
982
+ func buildReadyCycleCounter( name: String = " " ) -> IRValue {
983
+ precondition ( typeCheckArguments ( to: . readcyclecounter) )
984
+ return buildCall ( buildIntrinsic ( . readcyclecounter) , args: [ ] , name: name)
985
+ }
986
+
987
+ func buildAssume( _ x: IRValue , name: String = " " ) -> IRValue {
988
+ precondition ( typeCheckArguments ( to: . assume, args: x) )
989
+ return buildCall ( buildIntrinsic ( . assume) , args: [ x] , name: name)
990
+ }
991
+
992
+ func buildStackProtector( _ x: IRValue , _ y: IRValue , name: String = " " ) -> IRValue {
993
+ precondition ( typeCheckArguments ( to: . stackprotector, args: x, y) )
994
+ return buildCall ( buildIntrinsic ( . stackprotector) , args: [ x, y] , name: name)
995
+ }
996
+
997
+ func buildStackProtectorCheck( _ x: IRValue , name: String = " " ) -> IRValue {
998
+ precondition ( typeCheckArguments ( to: . stackprotectorcheck, args: x) )
999
+ return buildCall ( buildIntrinsic ( . stackprotectorcheck) , args: [ x] , name: name)
1000
+ }
1001
+
1002
+ func buildMemcpy( dest: IRValue , src: IRValue , len: IRValue , align: IRValue = IntType . int32. constant ( 0 ) , name: String = " " ) -> IRValue {
1003
+ guard let overload = resolveOverloadedArguments ( to: [ . memcpy_i8, . memcpy_i16, . memcpy_i32, . memcpy_i64] , args: dest, src, len, align) else {
1004
+ fatalError ( " Could not resolve overload of 'memcpy' " )
1005
+ }
1006
+ precondition ( typeCheckArguments ( to: overload, args: dest, src, len, align) )
1007
+ return buildCall ( buildIntrinsic ( overload) , args: [ dest, src, len, align] , name: name)
1008
+ }
1009
+
900
1010
// func buildmemcpy(PointerType(pointee: IntType.int8), PointerType(pointee: IntType.int8))
901
1011
// func buildmemmove(PointerType(pointee: IntType.int8), PointerType(pointee: IntType.int8))
902
1012
// func buildmemset(PointerType(pointee: IntType.int8), IntType.int8)
0 commit comments