@@ -1408,11 +1408,22 @@ fn resolveCallingConventionValues(
1408
1408
},
1409
1409
.wasm_mvp = > {
1410
1410
for (fn_info .param_types .get (ip )) | ty | {
1411
- const ty_classes = abi .classifyType (Type .fromInterned (ty ), zcu );
1412
- for (ty_classes ) | class | {
1413
- if (class == .none ) continue ;
1414
- try args .append (.{ .local = .{ .value = result .local_index , .references = 1 } });
1415
- result .local_index += 1 ;
1411
+ if (! Type .fromInterned (ty ).hasRuntimeBitsIgnoreComptime (zcu )) {
1412
+ continue ;
1413
+ }
1414
+ switch (abi .classifyType (.fromInterned (ty ), zcu )) {
1415
+ .direct = > | scalar_ty | if (! abi .lowerAsDoubleI64 (scalar_ty , zcu )) {
1416
+ try args .append (.{ .local = .{ .value = result .local_index , .references = 1 } });
1417
+ result .local_index += 1 ;
1418
+ } else {
1419
+ try args .append (.{ .local = .{ .value = result .local_index , .references = 1 } });
1420
+ try args .append (.{ .local = .{ .value = result .local_index + 1 , .references = 1 } });
1421
+ result .local_index += 2 ;
1422
+ },
1423
+ .indirect = > {
1424
+ try args .append (.{ .local = .{ .value = result .local_index , .references = 1 } });
1425
+ result .local_index += 1 ;
1426
+ },
1416
1427
}
1417
1428
}
1418
1429
},
@@ -1428,14 +1439,13 @@ pub fn firstParamSRet(
1428
1439
zcu : * const Zcu ,
1429
1440
target : * const std.Target ,
1430
1441
) bool {
1442
+ if (! return_type .hasRuntimeBitsIgnoreComptime (zcu )) return false ;
1431
1443
switch (cc ) {
1432
1444
.@"inline" = > unreachable ,
1433
1445
.auto = > return isByRef (return_type , zcu , target ),
1434
- .wasm_mvp = > {
1435
- const ty_classes = abi .classifyType (return_type , zcu );
1436
- if (ty_classes [0 ] == .indirect ) return true ;
1437
- if (ty_classes [0 ] == .direct and ty_classes [1 ] == .direct ) return true ;
1438
- return false ;
1446
+ .wasm_mvp = > switch (abi .classifyType (return_type , zcu )) {
1447
+ .direct = > | scalar_ty | return abi .lowerAsDoubleI64 (scalar_ty , zcu ),
1448
+ .indirect = > return true ,
1439
1449
},
1440
1450
else = > return false ,
1441
1451
}
@@ -1449,34 +1459,27 @@ fn lowerArg(cg: *CodeGen, cc: std.builtin.CallingConvention, ty: Type, value: WV
1449
1459
}
1450
1460
1451
1461
const zcu = cg .pt .zcu ;
1452
- const ty_classes = abi .classifyType (ty , zcu );
1453
- assert (ty_classes [0 ] != .none );
1454
- switch (ty .zigTypeTag (zcu )) {
1455
- .@"struct" , .@"union" = > {
1456
- if (ty_classes [0 ] == .indirect ) {
1457
- return cg .lowerToStack (value );
1458
- }
1459
- assert (ty_classes [0 ] == .direct );
1460
- const scalar_type = abi .scalarType (ty , zcu );
1461
- switch (value ) {
1462
- .nav_ref , .stack_offset = > _ = try cg .load (value , scalar_type , 0 ),
1463
- .dead = > unreachable ,
1464
- else = > try cg .emitWValue (value ),
1465
- }
1466
- },
1467
- .int , .float = > {
1468
- if (ty_classes [1 ] == .none ) {
1462
+
1463
+ switch (abi .classifyType (ty , zcu )) {
1464
+ .direct = > | scalar_type | if (! abi .lowerAsDoubleI64 (scalar_type , zcu )) {
1465
+ if (! isByRef (ty , zcu , cg .target )) {
1469
1466
return cg .lowerToStack (value );
1467
+ } else {
1468
+ switch (value ) {
1469
+ .nav_ref , .stack_offset = > _ = try cg .load (value , scalar_type , 0 ),
1470
+ .dead = > unreachable ,
1471
+ else = > try cg .emitWValue (value ),
1472
+ }
1470
1473
}
1471
- assert ( ty_classes [ 0 ] == .direct and ty_classes [ 1 ] == .direct );
1474
+ } else {
1472
1475
assert (ty .abiSize (zcu ) == 16 );
1473
1476
// in this case we have an integer or float that must be lowered as 2 i64's.
1474
1477
try cg .emitWValue (value );
1475
1478
try cg .addMemArg (.i64_load , .{ .offset = value .offset (), .alignment = 8 });
1476
1479
try cg .emitWValue (value );
1477
1480
try cg .addMemArg (.i64_load , .{ .offset = value .offset () + 8 , .alignment = 8 });
1478
1481
},
1479
- else = > return cg .lowerToStack (value ),
1482
+ .indirect = > return cg .lowerToStack (value ),
1480
1483
}
1481
1484
}
1482
1485
@@ -2142,23 +2145,16 @@ fn airRet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2142
2145
if (cg .return_value != .none ) {
2143
2146
try cg .store (cg .return_value , operand , ret_ty , 0 );
2144
2147
} else if (fn_info .cc == .wasm_mvp and ret_ty .hasRuntimeBitsIgnoreComptime (zcu )) {
2145
- switch (ret_ty .zigTypeTag (zcu )) {
2146
- // Aggregate types can be lowered as a singular value
2147
- .@"struct" , .@"union" = > {
2148
- const scalar_type = abi .scalarType (ret_ty , zcu );
2149
- try cg .emitWValue (operand );
2150
- const opcode = buildOpcode (.{
2151
- .op = .load ,
2152
- .width = @as (u8 , @intCast (scalar_type .abiSize (zcu ) * 8 )),
2153
- .signedness = if (scalar_type .isSignedInt (zcu )) .signed else .unsigned ,
2154
- .valtype1 = typeToValtype (scalar_type , zcu , cg .target ),
2155
- });
2156
- try cg .addMemArg (Mir .Inst .Tag .fromOpcode (opcode ), .{
2157
- .offset = operand .offset (),
2158
- .alignment = @intCast (scalar_type .abiAlignment (zcu ).toByteUnits ().? ),
2159
- });
2148
+ switch (abi .classifyType (ret_ty , zcu )) {
2149
+ .direct = > | scalar_type | {
2150
+ assert (! abi .lowerAsDoubleI64 (scalar_type , zcu ));
2151
+ if (! isByRef (ret_ty , zcu , cg .target )) {
2152
+ try cg .emitWValue (operand );
2153
+ } else {
2154
+ _ = try cg .load (operand , scalar_type , 0 );
2155
+ }
2160
2156
},
2161
- else = > try cg . emitWValue ( operand ) ,
2157
+ .indirect = > unreachable ,
2162
2158
}
2163
2159
} else {
2164
2160
if (! ret_ty .hasRuntimeBitsIgnoreComptime (zcu ) and ret_ty .isError (zcu )) {
@@ -2284,14 +2280,24 @@ fn airCall(cg: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModifie
2284
2280
break :result_value .none ;
2285
2281
} else if (first_param_sret ) {
2286
2282
break :result_value sret ;
2287
- // TODO: Make this less fragile and optimize
2288
- } else if (zcu .typeToFunc (fn_ty ).? .cc == .wasm_mvp and ret_ty .zigTypeTag (zcu ) == .@"struct" or ret_ty .zigTypeTag (zcu ) == .@"union" ) {
2289
- const result_local = try cg .allocLocal (ret_ty );
2290
- try cg .addLocal (.local_set , result_local .local .value );
2291
- const scalar_type = abi .scalarType (ret_ty , zcu );
2292
- const result = try cg .allocStack (scalar_type );
2293
- try cg .store (result , result_local , scalar_type , 0 );
2294
- break :result_value result ;
2283
+ } else if (zcu .typeToFunc (fn_ty ).? .cc == .wasm_mvp ) {
2284
+ switch (abi .classifyType (ret_ty , zcu )) {
2285
+ .direct = > | scalar_type | {
2286
+ assert (! abi .lowerAsDoubleI64 (scalar_type , zcu ));
2287
+ if (! isByRef (ret_ty , zcu , cg .target )) {
2288
+ const result_local = try cg .allocLocal (ret_ty );
2289
+ try cg .addLocal (.local_set , result_local .local .value );
2290
+ break :result_value result_local ;
2291
+ } else {
2292
+ const result_local = try cg .allocLocal (ret_ty );
2293
+ try cg .addLocal (.local_set , result_local .local .value );
2294
+ const result = try cg .allocStack (ret_ty );
2295
+ try cg .store (result , result_local , scalar_type , 0 );
2296
+ break :result_value result ;
2297
+ }
2298
+ },
2299
+ .indirect = > unreachable ,
2300
+ }
2295
2301
} else {
2296
2302
const result_local = try cg .allocLocal (ret_ty );
2297
2303
try cg .addLocal (.local_set , result_local .local .value );
@@ -2597,26 +2603,17 @@ fn airArg(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void {
2597
2603
const cc = zcu .typeToFunc (zcu .navValue (cg .owner_nav ).typeOf (zcu )).? .cc ;
2598
2604
const arg_ty = cg .typeOfIndex (inst );
2599
2605
if (cc == .wasm_mvp ) {
2600
- const arg_classes = abi .classifyType (arg_ty , zcu );
2601
- for (arg_classes ) | class | {
2602
- if (class != .none ) {
2606
+ switch (abi .classifyType (arg_ty , zcu )) {
2607
+ .direct = > | scalar_ty | if (! abi .lowerAsDoubleI64 (scalar_ty , zcu )) {
2603
2608
cg .arg_index += 1 ;
2604
- }
2605
- }
2606
-
2607
- // When we have an argument that's passed using more than a single parameter,
2608
- // we combine them into a single stack value
2609
- if (arg_classes [0 ] == .direct and arg_classes [1 ] == .direct ) {
2610
- if (arg_ty .zigTypeTag (zcu ) != .int and arg_ty .zigTypeTag (zcu ) != .float ) {
2611
- return cg .fail (
2612
- "TODO: Implement C-ABI argument for type '{}'" ,
2613
- .{arg_ty .fmt (pt )},
2614
- );
2615
- }
2616
- const result = try cg .allocStack (arg_ty );
2617
- try cg .store (result , arg , Type .u64 , 0 );
2618
- try cg .store (result , cg .args [arg_index + 1 ], Type .u64 , 8 );
2619
- return cg .finishAir (inst , result , &.{});
2609
+ } else {
2610
+ cg .arg_index += 2 ;
2611
+ const result = try cg .allocStack (arg_ty );
2612
+ try cg .store (result , arg , Type .u64 , 0 );
2613
+ try cg .store (result , cg .args [arg_index + 1 ], Type .u64 , 8 );
2614
+ return cg .finishAir (inst , result , &.{});
2615
+ },
2616
+ .indirect = > cg .arg_index += 1 ,
2620
2617
}
2621
2618
} else {
2622
2619
cg .arg_index += 1 ;
0 commit comments