@@ -921,6 +921,40 @@ pub const Object = struct {
921
921
};
922
922
try args .append (loaded );
923
923
},
924
+ .multiple_llvm_float = > {
925
+ const llvm_floats = it .llvm_types_buffer [0.. it .llvm_types_len ];
926
+ const param_ty = fn_info .param_types [it .zig_index - 1 ];
927
+ const param_llvm_ty = try dg .lowerType (param_ty );
928
+ const param_alignment = param_ty .abiAlignment (target );
929
+ const arg_ptr = buildAllocaInner (builder , llvm_func , false , param_llvm_ty );
930
+ arg_ptr .setAlignment (param_alignment );
931
+ var field_types_buf : [8 ]* const llvm.Type = undefined ;
932
+ const field_types = field_types_buf [0.. llvm_floats .len ];
933
+ for (llvm_floats ) | float_bits , i | {
934
+ switch (float_bits ) {
935
+ 64 = > field_types [i ] = dg .context .doubleType (),
936
+ 80 = > field_types [i ] = dg .context .x86FP80Type (),
937
+ else = > {},
938
+ }
939
+ }
940
+ const ints_llvm_ty = dg .context .structType (field_types .ptr , @intCast (c_uint , field_types .len ), .False );
941
+ const casted_ptr = builder .buildBitCast (arg_ptr , ints_llvm_ty .pointerType (0 ), "" );
942
+ for (llvm_floats ) | _ , i_usize | {
943
+ const i = @intCast (c_uint , i_usize );
944
+ const param = llvm_func .getParam (i );
945
+ const field_ptr = builder .buildStructGEP (casted_ptr , i , "" );
946
+ const store_inst = builder .buildStore (param , field_ptr );
947
+ store_inst .setAlignment (target .cpu .arch .ptrBitWidth () / 8 );
948
+ }
949
+
950
+ const is_by_ref = isByRef (param_ty );
951
+ const loaded = if (is_by_ref ) arg_ptr else l : {
952
+ const load_inst = builder .buildLoad (arg_ptr , "" );
953
+ load_inst .setAlignment (param_alignment );
954
+ break :l load_inst ;
955
+ };
956
+ try args .append (loaded );
957
+ },
924
958
.as_u16 = > {
925
959
const param = llvm_func .getParam (llvm_arg_i );
926
960
llvm_arg_i += 1 ;
@@ -2341,6 +2375,14 @@ pub const DeclGen = struct {
2341
2375
dg .addFnAttr (llvm_fn , "noreturn" );
2342
2376
}
2343
2377
2378
+ var llvm_arg_i = @as (c_uint , @boolToInt (sret )) + @boolToInt (err_return_tracing );
2379
+ var it = iterateParamTypes (dg , fn_info );
2380
+ while (it .next ()) | _ | : (llvm_arg_i += 1 ) {
2381
+ if (! it .byval_attr ) continue ;
2382
+ const param = llvm_fn .getParam (llvm_arg_i );
2383
+ llvm_fn .addByValAttr (llvm_arg_i , param .typeOf ().getElementType ());
2384
+ }
2385
+
2344
2386
return llvm_fn ;
2345
2387
}
2346
2388
@@ -2894,6 +2936,18 @@ pub const DeclGen = struct {
2894
2936
llvm_params .appendAssumeCapacity (big_int_ty );
2895
2937
}
2896
2938
},
2939
+ .multiple_llvm_float = > {
2940
+ const llvm_ints = it .llvm_types_buffer [0.. it .llvm_types_len ];
2941
+ try llvm_params .ensureUnusedCapacity (it .llvm_types_len );
2942
+ for (llvm_ints ) | float_bits | {
2943
+ const float_ty = switch (float_bits ) {
2944
+ 64 = > dg .context .doubleType (),
2945
+ 80 = > dg .context .x86FP80Type (),
2946
+ else = > unreachable ,
2947
+ };
2948
+ llvm_params .appendAssumeCapacity (float_ty );
2949
+ }
2950
+ },
2897
2951
.as_u16 = > {
2898
2952
try llvm_params .append (dg .context .intType (16 ));
2899
2953
},
@@ -4402,6 +4456,39 @@ pub const FuncGen = struct {
4402
4456
llvm_args .appendAssumeCapacity (load_inst );
4403
4457
}
4404
4458
},
4459
+ .multiple_llvm_float = > {
4460
+ const arg = args [it .zig_index - 1 ];
4461
+ const param_ty = self .air .typeOf (arg );
4462
+ const llvm_floats = it .llvm_types_buffer [0.. it .llvm_types_len ];
4463
+ const llvm_arg = try self .resolveInst (arg );
4464
+ const is_by_ref = isByRef (param_ty );
4465
+ const arg_ptr = if (is_by_ref ) llvm_arg else p : {
4466
+ const p = self .buildAlloca (llvm_arg .typeOf ());
4467
+ const store_inst = self .builder .buildStore (llvm_arg , p );
4468
+ store_inst .setAlignment (param_ty .abiAlignment (target ));
4469
+ break :p p ;
4470
+ };
4471
+
4472
+ var field_types_buf : [8 ]* const llvm.Type = undefined ;
4473
+ const field_types = field_types_buf [0.. llvm_floats .len ];
4474
+ for (llvm_floats ) | float_bits , i | {
4475
+ switch (float_bits ) {
4476
+ 64 = > field_types [i ] = self .dg .context .doubleType (),
4477
+ 80 = > field_types [i ] = self .dg .context .x86FP80Type (),
4478
+ else = > {},
4479
+ }
4480
+ }
4481
+ const ints_llvm_ty = self .dg .context .structType (field_types .ptr , @intCast (c_uint , field_types .len ), .False );
4482
+ const casted_ptr = self .builder .buildBitCast (arg_ptr , ints_llvm_ty .pointerType (0 ), "" );
4483
+ try llvm_args .ensureUnusedCapacity (it .llvm_types_len );
4484
+ for (llvm_floats ) | _ , i_usize | {
4485
+ const i = @intCast (c_uint , i_usize );
4486
+ const field_ptr = self .builder .buildStructGEP (casted_ptr , i , "" );
4487
+ const load_inst = self .builder .buildLoad (field_ptr , "" );
4488
+ load_inst .setAlignment (target .cpu .arch .ptrBitWidth () / 8 );
4489
+ llvm_args .appendAssumeCapacity (load_inst );
4490
+ }
4491
+ },
4405
4492
.as_u16 = > {
4406
4493
const arg = args [it .zig_index - 1 ];
4407
4494
const llvm_arg = try self .resolveInst (arg );
@@ -9367,16 +9454,20 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm.
9367
9454
llvm_types_index += 1 ;
9368
9455
},
9369
9456
.sse = > {
9370
- @panic ("TODO" );
9457
+ llvm_types_buffer [llvm_types_index ] = dg .context .doubleType ();
9458
+ llvm_types_index += 1 ;
9371
9459
},
9372
9460
.sseup = > {
9373
- @panic ("TODO" );
9461
+ llvm_types_buffer [llvm_types_index ] = dg .context .doubleType ();
9462
+ llvm_types_index += 1 ;
9374
9463
},
9375
9464
.x87 = > {
9376
- @panic ("TODO" );
9465
+ llvm_types_buffer [llvm_types_index ] = dg .context .x86FP80Type ();
9466
+ llvm_types_index += 1 ;
9377
9467
},
9378
9468
.x87up = > {
9379
- @panic ("TODO" );
9469
+ llvm_types_buffer [llvm_types_index ] = dg .context .x86FP80Type ();
9470
+ llvm_types_index += 1 ;
9380
9471
},
9381
9472
.complex_x87 = > {
9382
9473
@panic ("TODO" );
@@ -9422,20 +9513,23 @@ const ParamTypeIterator = struct {
9422
9513
target : std.Target ,
9423
9514
llvm_types_len : u32 ,
9424
9515
llvm_types_buffer : [8 ]u16 ,
9516
+ byval_attr : bool ,
9425
9517
9426
9518
const Lowering = enum {
9427
9519
no_bits ,
9428
9520
byval ,
9429
9521
byref ,
9430
9522
abi_sized_int ,
9431
9523
multiple_llvm_ints ,
9524
+ multiple_llvm_float ,
9432
9525
slice ,
9433
9526
as_u16 ,
9434
9527
};
9435
9528
9436
9529
pub fn next (it : * ParamTypeIterator ) ? Lowering {
9437
9530
if (it .zig_index >= it .fn_info .param_types .len ) return null ;
9438
9531
const ty = it .fn_info .param_types [it .zig_index ];
9532
+ it .byval_attr = false ;
9439
9533
return nextInner (it , ty );
9440
9534
}
9441
9535
@@ -9521,6 +9615,7 @@ const ParamTypeIterator = struct {
9521
9615
.memory = > {
9522
9616
it .zig_index += 1 ;
9523
9617
it .llvm_index += 1 ;
9618
+ it .byval_attr = true ;
9524
9619
return .byref ;
9525
9620
},
9526
9621
.sse = > {
@@ -9540,6 +9635,7 @@ const ParamTypeIterator = struct {
9540
9635
if (classes [0 ] == .memory ) {
9541
9636
it .zig_index += 1 ;
9542
9637
it .llvm_index += 1 ;
9638
+ it .byval_attr = true ;
9543
9639
return .byref ;
9544
9640
}
9545
9641
var llvm_types_buffer : [8 ]u16 = undefined ;
@@ -9551,16 +9647,20 @@ const ParamTypeIterator = struct {
9551
9647
llvm_types_index += 1 ;
9552
9648
},
9553
9649
.sse = > {
9554
- @panic ("TODO" );
9650
+ llvm_types_buffer [llvm_types_index ] = 64 ;
9651
+ llvm_types_index += 1 ;
9555
9652
},
9556
9653
.sseup = > {
9557
- @panic ("TODO" );
9654
+ llvm_types_buffer [llvm_types_index ] = 64 ;
9655
+ llvm_types_index += 1 ;
9558
9656
},
9559
9657
.x87 = > {
9560
- @panic ("TODO" );
9658
+ llvm_types_buffer [llvm_types_index ] = 80 ;
9659
+ llvm_types_index += 1 ;
9561
9660
},
9562
9661
.x87up = > {
9563
- @panic ("TODO" );
9662
+ llvm_types_buffer [llvm_types_index ] = 80 ;
9663
+ llvm_types_index += 1 ;
9564
9664
},
9565
9665
.complex_x87 = > {
9566
9666
@panic ("TODO" );
@@ -9574,11 +9674,16 @@ const ParamTypeIterator = struct {
9574
9674
it .llvm_index += 1 ;
9575
9675
return .abi_sized_int ;
9576
9676
}
9677
+ if (classes [0 ] == .sse and classes [1 ] == .none ) {
9678
+ it .zig_index += 1 ;
9679
+ it .llvm_index += 1 ;
9680
+ return .byval ;
9681
+ }
9577
9682
it .llvm_types_buffer = llvm_types_buffer ;
9578
9683
it .llvm_types_len = llvm_types_index ;
9579
9684
it .llvm_index += llvm_types_index ;
9580
9685
it .zig_index += 1 ;
9581
- return . multiple_llvm_ints ;
9686
+ return if ( classes [ 0 ] == .integer ) . multiple_llvm_ints else .multiple_llvm_float ;
9582
9687
},
9583
9688
},
9584
9689
.wasm32 = > {
@@ -9619,6 +9724,7 @@ fn iterateParamTypes(dg: *DeclGen, fn_info: Type.Payload.Function.Data) ParamTyp
9619
9724
.target = dg .module .getTarget (),
9620
9725
.llvm_types_buffer = undefined ,
9621
9726
.llvm_types_len = 0 ,
9727
+ .byval_attr = false ,
9622
9728
};
9623
9729
}
9624
9730
0 commit comments