| author | |
| committer | |
| log | d01609af2aaf5a3c9ddd2ddf75a5d211e0e94b07 |
| tree | 7a2dd5f38533be031bd1aa6df6866e2f5e240ff1 |
| parent | 63cb57eb31acc7d250b624b5d4501ebb6e969213 |
Closes #359103 files changed, 30 insertions(+), 7 deletions(-)
src/codegen/x86_64/CodeGen.zig+14-4| ... | @@ -176621,10 +176621,20 @@ fn genCall(cg: *CodeGen, info: union(enum) { | ... | @@ -176621,10 +176621,20 @@ fn genCall(cg: *CodeGen, info: union(enum) { |
| 176621 | 176621 | ||
| 176622 | for (call_info.args, arg_types, args, frame_indices) |dst_arg, arg_ty, src_arg, frame_index| switch (dst_arg) { | 176622 | for (call_info.args, arg_types, args, frame_indices) |dst_arg, arg_ty, src_arg, frame_index| switch (dst_arg) { |
| 176623 | .none, .load_frame, .indirect_load_frame => {}, | 176623 | .none, .load_frame, .indirect_load_frame => {}, |
| 176624 | .register => |dst_reg| try cg.genSetReg(registerAlias( | 176624 | .register => |dst_reg| switch (fn_info.cc) { |
| 176625 | dst_reg, | 176625 | else => try cg.genSetReg(registerAlias( |
| 176626 | @intCast(cg.unalignedSize(arg_ty)), | 176626 | dst_reg, |
| 176627 | ), arg_ty, src_arg, opts), | 176627 | @intCast(cg.unalignedSize(arg_ty)), |
| 176628 | ), arg_ty, src_arg, opts), | ||
| 176629 | .x86_64_sysv, .x86_64_win => { | ||
| 176630 | const promoted_ty = cg.promoteInt(arg_ty); | ||
| 176631 | const promoted_unaligned_size: u32 = @intCast(cg.unalignedSize(promoted_ty)); | ||
| 176632 | const dst_alias = registerAlias(dst_reg, promoted_unaligned_size); | ||
| 176633 | try cg.genSetReg(dst_alias, promoted_ty, src_arg, opts); | ||
| 176634 | if (promoted_ty.toIntern() != arg_ty.toIntern()) | ||
| 176635 | try cg.truncateRegister(arg_ty, dst_alias); | ||
| 176636 | }, | ||
| 176637 | }, | ||
| 176628 | .register_pair, | 176638 | .register_pair, |
| 176629 | .register_triple, | 176639 | .register_triple, |
| 176630 | .register_quadruple, | 176640 | .register_quadruple, |
test/c_abi/cfuncs.c+7-2| ... | @@ -16386,7 +16386,13 @@ void __attribute__((vectorcall)) c_vectorcall_check(int a, float b, double c, vo | ... | @@ -16386,7 +16386,13 @@ void __attribute__((vectorcall)) c_vectorcall_check(int a, float b, double c, vo |
| 16386 | } | 16386 | } |
| 16387 | #endif | 16387 | #endif |
| 16388 | 16388 | ||
| 16389 | #if defined(__x86_64__) && defined(_WIN64) | 16389 | void c_x86_64_sysv_uint_int_uint_int(unsigned a, int b, unsigned c, int d) { |
| 16390 | assert_or_panic(a == 1); | ||
| 16391 | assert_or_panic(b == -2); | ||
| 16392 | assert_or_panic(c == 3); | ||
| 16393 | assert_or_panic(d == -4); | ||
| 16394 | } | ||
| 16395 | |||
| 16390 | void c_win64_varargs_u64_f64_u64_f64(uint64_t a, double b, uint64_t c, double d) { | 16396 | void c_win64_varargs_u64_f64_u64_f64(uint64_t a, double b, uint64_t c, double d) { |
| 16391 | assert_or_panic(a == UINT64_C(0x3ff0000000000000)); | 16397 | assert_or_panic(a == UINT64_C(0x3ff0000000000000)); |
| 16392 | assert_or_panic(b == 2.0); | 16398 | assert_or_panic(b == 2.0); |
| ... | @@ -16399,4 +16405,3 @@ void c_win64_varargs_f64_u64_f64_u64(double a, uint64_t b, double c, uint64_t d) | ... | @@ -16399,4 +16405,3 @@ void c_win64_varargs_f64_u64_f64_u64(double a, uint64_t b, double c, uint64_t d) |
| 16399 | assert_or_panic(c == 7.0); | 16405 | assert_or_panic(c == 7.0); |
| 16400 | assert_or_panic(d == UINT64_C(0x4020000000000000)); | 16406 | assert_or_panic(d == UINT64_C(0x4020000000000000)); |
| 16401 | } | 16407 | } |
| 16402 | #endif |
test/c_abi/main.zig+9-1| ... | @@ -17448,11 +17448,19 @@ test "x86 vectorcall calling convention" { | ... | @@ -17448,11 +17448,19 @@ test "x86 vectorcall calling convention" { |
| 17448 | static.c_vectorcall_check(1, 2.0, 3.0, @ptrFromInt(4), 5.0, 6.0, 7.0, 8.0, 9.0, 10); | 17448 | static.c_vectorcall_check(1, 2.0, 3.0, @ptrFromInt(4), 5.0, 6.0, 7.0, 8.0, 9.0, 10); |
| 17449 | } | 17449 | } |
| 17450 | 17450 | ||
| 17451 | extern fn c_x86_64_sysv_uint_int_uint_int(a: u8, b: i8, c: u16, d: i16) void; | ||
| 17452 | |||
| 17453 | test "x86_64 sysv args" { | ||
| 17454 | if (std.lang.CallingConvention.c != .x86_64_sysv) return error.SkipZigTest; | ||
| 17455 | |||
| 17456 | c_x86_64_sysv_uint_int_uint_int(1, -2, 3, -4); | ||
| 17457 | } | ||
| 17458 | |||
| 17451 | extern fn c_win64_varargs_u64_f64_u64_f64(...) void; | 17459 | extern fn c_win64_varargs_u64_f64_u64_f64(...) void; |
| 17452 | extern fn c_win64_varargs_f64_u64_f64_u64(...) void; | 17460 | extern fn c_win64_varargs_f64_u64_f64_u64(...) void; |
| 17453 | 17461 | ||
| 17454 | test "win64 varargs" { | 17462 | test "win64 varargs" { |
| 17455 | if (builtin.cpu.arch != .x86_64 or builtin.os.tag != .windows) return error.SkipZigTest; | 17463 | if (std.lang.CallingConvention.c != .x86_64_win) return error.SkipZigTest; |
| 17456 | 17464 | ||
| 17457 | const Opv = extern struct {}; | 17465 | const Opv = extern struct {}; |
| 17458 | c_win64_varargs_u64_f64_u64_f64( | 17466 | c_win64_varargs_u64_f64_u64_f64( |