| 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 | 176621 | |
| 176622 | 176622 | for (call_info.args, arg_types, args, frame_indices) |dst_arg, arg_ty, src_arg, frame_index| switch (dst_arg) { |
| 176623 | 176623 | .none, .load_frame, .indirect_load_frame => {}, |
| 176624 | .register => |dst_reg| try cg.genSetReg(registerAlias( | |
| 176625 | dst_reg, | |
| 176626 | @intCast(cg.unalignedSize(arg_ty)), | |
| 176627 | ), arg_ty, src_arg, opts), | |
| 176624 | .register => |dst_reg| switch (fn_info.cc) { | |
| 176625 | else => try cg.genSetReg(registerAlias( | |
| 176626 | dst_reg, | |
| 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 | 176638 | .register_pair, |
| 176629 | 176639 | .register_triple, |
| 176630 | 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 | 16386 | } |
| 16387 | 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 | 16396 | void c_win64_varargs_u64_f64_u64_f64(uint64_t a, double b, uint64_t c, double d) { |
| 16391 | 16397 | assert_or_panic(a == UINT64_C(0x3ff0000000000000)); |
| 16392 | 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 | 16405 | assert_or_panic(c == 7.0); |
| 16400 | 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 | 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 | 17459 | extern fn c_win64_varargs_u64_f64_u64_f64(...) void; |
| 17452 | 17460 | extern fn c_win64_varargs_f64_u64_f64_u64(...) void; |
| 17453 | 17461 | |
| 17454 | 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 | 17465 | const Opv = extern struct {}; |
| 17458 | 17466 | c_win64_varargs_u64_f64_u64_f64( |