@@ -1237,12 +1237,123 @@ fn autocast<'ll>(
12371237 }
12381238}
12391239
1240+ fn parse_integer ( string : & mut & [ u8 ] ) -> Option < u64 > {
1241+ let mut number = 0 ;
1242+ let mut position = 0 ;
1243+ while let Some ( & digit @ b'0' ..=b'9' ) = string. get ( position) {
1244+ number = ( 10 * number) + ( digit - b'0' ) as u64 ;
1245+ position += 1 ;
1246+ }
1247+
1248+ if position != number. checked_ilog10 ( ) . unwrap_or ( 0 ) as usize + 1 {
1249+ return None ;
1250+ }
1251+
1252+ * string = & string[ position..] ;
1253+ Some ( number)
1254+ }
1255+
1256+ fn strip_off_prefix ( slice : & mut & [ u8 ] , prefix : & [ u8 ] ) -> bool {
1257+ slice. strip_prefix ( prefix) . map ( |remainder| * slice = remainder) . is_some ( )
1258+ }
1259+
1260+ fn demangle_type_str < ' ll > ( cx : & CodegenCx < ' ll , ' _ > , slice : & mut & [ u8 ] ) -> Option < & ' ll Type > {
1261+ Some ( if strip_off_prefix ( slice, b"isVoid" ) {
1262+ cx. type_void ( )
1263+ } else if strip_off_prefix ( slice, b"f16" ) {
1264+ cx. type_f16 ( )
1265+ } else if strip_off_prefix ( slice, b"bf16" ) {
1266+ cx. type_bf16 ( )
1267+ } else if strip_off_prefix ( slice, b"f32" ) {
1268+ cx. type_f32 ( )
1269+ } else if strip_off_prefix ( slice, b"f64" ) {
1270+ cx. type_f64 ( )
1271+ } else if strip_off_prefix ( slice, b"f128" ) {
1272+ cx. type_f128 ( )
1273+ } else if strip_off_prefix ( slice, b"i" ) {
1274+ let width = parse_integer ( slice) ?;
1275+ cx. type_ix ( width)
1276+ } else if strip_off_prefix ( slice, b"p" ) {
1277+ let address_space = parse_integer ( slice) ?;
1278+ cx. type_ptr_ext ( AddressSpace ( address_space as u32 ) )
1279+ } else if strip_off_prefix ( slice, b"v" ) {
1280+ let length = parse_integer ( slice) ?;
1281+ let element_type = demangle_type_str ( cx, slice) ?;
1282+ cx. type_vector ( element_type, length)
1283+ } else if strip_off_prefix ( slice, b"nvx" ) {
1284+ let length = parse_integer ( slice) ?;
1285+ let element_type = demangle_type_str ( cx, slice) ?;
1286+ cx. type_scalable_vector ( element_type, length)
1287+ } else if strip_off_prefix ( slice, b"a" ) {
1288+ let length = parse_integer ( slice) ?;
1289+ let element_type = demangle_type_str ( cx, slice) ?;
1290+ cx. type_array ( element_type, length)
1291+ } else if strip_off_prefix ( slice, b"sl_" ) {
1292+ let mut elements = Vec :: new ( ) ;
1293+
1294+ loop {
1295+ if let Some ( remainder) = slice. strip_prefix ( b"s" )
1296+ && !remainder. starts_with ( b"_" )
1297+ && !remainder. starts_with ( b"l_" )
1298+ {
1299+ * slice = remainder;
1300+ break cx. type_struct ( & elements, true ) ;
1301+ }
1302+ elements. push ( demangle_type_str ( cx, slice) ?) ;
1303+ }
1304+ } else if strip_off_prefix ( slice, b"f_" ) {
1305+ let return_type = demangle_type_str ( cx, slice) ?;
1306+ let mut arguments = Vec :: new ( ) ;
1307+
1308+ loop {
1309+ if let Some ( remainder) = slice. strip_prefix ( b"f" )
1310+ && !remainder. starts_with ( b"_" )
1311+ {
1312+ * slice = remainder;
1313+ break cx. type_func ( & arguments, return_type) ;
1314+ }
1315+ if strip_off_prefix ( slice, b"varargf" ) {
1316+ break cx. type_variadic_func ( & arguments, return_type) ;
1317+ }
1318+ arguments. push ( demangle_type_str ( cx, slice) ?) ;
1319+ }
1320+ } else {
1321+ return None ;
1322+ } )
1323+ }
1324+
1325+ fn parse_type_parameters < ' ll , ' tcx > (
1326+ cx : & CodegenCx < ' ll , ' tcx > ,
1327+ intrinsic : llvm:: Intrinsic ,
1328+ name : & str ,
1329+ ) -> Option < Vec < & ' ll Type > > {
1330+ let base_name: & ' ll [ u8 ] = intrinsic. base_name ( ) ;
1331+
1332+ let slice = & mut name. as_bytes ( ) . strip_prefix ( base_name) . unwrap ( ) ;
1333+
1334+ if !intrinsic. is_overloaded ( ) {
1335+ return slice. is_empty ( ) . then ( || Vec :: new ( ) ) ;
1336+ }
1337+
1338+ let mut type_params = Vec :: new ( ) ;
1339+
1340+ while !slice. is_empty ( ) {
1341+ if !strip_off_prefix ( slice, b"." ) {
1342+ return None ;
1343+ }
1344+
1345+ type_params. push ( demangle_type_str ( cx, slice) ?) ;
1346+ }
1347+
1348+ Some ( type_params)
1349+ }
1350+
12401351fn intrinsic_fn < ' ll , ' tcx > (
12411352 bx : & Builder < ' _ , ' ll , ' tcx > ,
12421353 name : & str ,
12431354 rust_return_ty : & ' ll Type ,
12441355 rust_argument_tys : Vec < & ' ll Type > ,
1245- instance : ty :: Instance < ' tcx > ,
1356+ instance : Instance < ' tcx > ,
12461357) -> & ' ll Value {
12471358 let tcx = bx. tcx ;
12481359
@@ -1268,10 +1379,9 @@ fn intrinsic_fn<'ll, 'tcx>(
12681379 }
12691380
12701381 if let Some ( intrinsic) = intrinsic
1271- && !intrinsic . is_overloaded ( )
1382+ && let Some ( type_params ) = parse_type_parameters ( bx . cx , intrinsic , name )
12721383 {
1273- // FIXME: also do this for overloaded intrinsics
1274- let llfn = intrinsic. get_declaration ( bx. llmod , & [ ] ) ;
1384+ let llfn = intrinsic. get_declaration ( bx. llmod , & type_params) ;
12751385 let llvm_fn_ty = bx. get_type_of_global ( llfn) ;
12761386
12771387 let llvm_return_ty = bx. get_return_type ( llvm_fn_ty) ;
0 commit comments