| author | |
| committer | |
| log | 61ed4fe07ad660f3cb4372937ccd5188ce404a44 |
| tree | b8baa621a18dfb06d86b9cd48774cc4c525a4d74 |
| parent | 7c1061784b8b126633cfe84f46280f7bf72beffc |
closes #104453 files changed, 76 insertions(+), 2 deletions(-)
src/stage1/analyze.cpp+11-2| ... | @@ -8684,14 +8684,23 @@ static Error resolve_llvm_c_abi_type(CodeGen *g, ZigType *ty) { | ... | @@ -8684,14 +8684,23 @@ static Error resolve_llvm_c_abi_type(CodeGen *g, ZigType *ty) { |
| 8684 | if (ty->data.structure.fields[i]->offset >= 8) { | 8684 | if (ty->data.structure.fields[i]->offset >= 8) { |
| 8685 | eightbyte_index = 1; | 8685 | eightbyte_index = 1; |
| 8686 | } | 8686 | } |
| 8687 | X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields[i]->type_entry); | 8687 | ZigType *field_ty = ty->data.structure.fields[i]->type_entry; |
| 8688 | X64CABIClass field_class = type_c_abi_x86_64_class(g, field_ty); | ||
| 8688 | 8689 | ||
| 8689 | if (field_class == X64CABIClass_INTEGER) { | 8690 | if (field_class == X64CABIClass_INTEGER) { |
| 8690 | type_classes[eightbyte_index] = X64CABIClass_INTEGER; | 8691 | type_classes[eightbyte_index] = X64CABIClass_INTEGER; |
| 8691 | } else if (type_classes[eightbyte_index] == X64CABIClass_Unknown) { | 8692 | } else if (type_classes[eightbyte_index] == X64CABIClass_Unknown) { |
| 8692 | type_classes[eightbyte_index] = field_class; | 8693 | type_classes[eightbyte_index] = field_class; |
| 8693 | } | 8694 | } |
| 8694 | type_sizes[eightbyte_index] += ty->data.structure.fields[i]->type_entry->abi_size; | 8695 | if (field_ty->abi_size > 8) { |
| 8696 | assert(eightbyte_index == 0); | ||
| 8697 | type_sizes[0] = 8; | ||
| 8698 | type_sizes[1] = field_ty->abi_size - 8; | ||
| 8699 | type_classes[1] = type_classes[0]; | ||
| 8700 | eightbyte_index = 1; | ||
| 8701 | } else { | ||
| 8702 | type_sizes[eightbyte_index] += field_ty->abi_size; | ||
| 8703 | } | ||
| 8695 | } | 8704 | } |
| 8696 | 8705 | ||
| 8697 | LLVMTypeRef return_elem_types[] = { | 8706 | LLVMTypeRef return_elem_types[] = { |
test/stage1/c_abi/cfuncs.c+38| ... | @@ -11,14 +11,26 @@ static void assert_or_panic(bool ok) { | ... | @@ -11,14 +11,26 @@ static void assert_or_panic(bool ok) { |
| 11 | } | 11 | } |
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | struct i128 { | ||
| 15 | __int128 value; | ||
| 16 | }; | ||
| 17 | |||
| 18 | struct u128 { | ||
| 19 | unsigned __int128 value; | ||
| 20 | }; | ||
| 21 | |||
| 14 | void zig_u8(uint8_t); | 22 | void zig_u8(uint8_t); |
| 15 | void zig_u16(uint16_t); | 23 | void zig_u16(uint16_t); |
| 16 | void zig_u32(uint32_t); | 24 | void zig_u32(uint32_t); |
| 17 | void zig_u64(uint64_t); | 25 | void zig_u64(uint64_t); |
| 26 | void zig_u128(unsigned __int128); | ||
| 27 | void zig_struct_u128(struct u128); | ||
| 18 | void zig_i8(int8_t); | 28 | void zig_i8(int8_t); |
| 19 | void zig_i16(int16_t); | 29 | void zig_i16(int16_t); |
| 20 | void zig_i32(int32_t); | 30 | void zig_i32(int32_t); |
| 21 | void zig_i64(int64_t); | 31 | void zig_i64(int64_t); |
| 32 | void zig_i128(__int128); | ||
| 33 | void zig_struct_i128(struct i128); | ||
| 22 | void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); | 34 | void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); |
| 23 | 35 | ||
| 24 | void zig_f32(float); | 36 | void zig_f32(float); |
| ... | @@ -130,11 +142,21 @@ void run_c_tests(void) { | ... | @@ -130,11 +142,21 @@ void run_c_tests(void) { |
| 130 | zig_u16(0xfffe); | 142 | zig_u16(0xfffe); |
| 131 | zig_u32(0xfffffffd); | 143 | zig_u32(0xfffffffd); |
| 132 | zig_u64(0xfffffffffffffffc); | 144 | zig_u64(0xfffffffffffffffc); |
| 145 | zig_u128(0xfffffffffffffffc); | ||
| 146 | { | ||
| 147 | struct u128 s = {0xfffffffffffffffc}; | ||
| 148 | zig_struct_u128(s); | ||
| 149 | } | ||
| 133 | 150 | ||
| 134 | zig_i8(-1); | 151 | zig_i8(-1); |
| 135 | zig_i16(-2); | 152 | zig_i16(-2); |
| 136 | zig_i32(-3); | 153 | zig_i32(-3); |
| 137 | zig_i64(-4); | 154 | zig_i64(-4); |
| 155 | zig_i128(-5); | ||
| 156 | { | ||
| 157 | struct i128 s = {-6}; | ||
| 158 | zig_struct_i128(s); | ||
| 159 | } | ||
| 138 | zig_five_integers(12, 34, 56, 78, 90); | 160 | zig_five_integers(12, 34, 56, 78, 90); |
| 139 | 161 | ||
| 140 | zig_f32(12.34f); | 162 | zig_f32(12.34f); |
| ... | @@ -221,6 +243,14 @@ void c_u64(uint64_t x) { | ... | @@ -221,6 +243,14 @@ void c_u64(uint64_t x) { |
| 221 | assert_or_panic(x == 0xfffffffffffffffcULL); | 243 | assert_or_panic(x == 0xfffffffffffffffcULL); |
| 222 | } | 244 | } |
| 223 | 245 | ||
| 246 | void c_u128(unsigned __int128 x) { | ||
| 247 | assert_or_panic(x == 0xfffffffffffffffcULL); | ||
| 248 | } | ||
| 249 | |||
| 250 | void c_struct_u128(struct u128 x) { | ||
| 251 | assert_or_panic(x.value == 0xfffffffffffffffcULL); | ||
| 252 | } | ||
| 253 | |||
| 224 | void c_i8(int8_t x) { | 254 | void c_i8(int8_t x) { |
| 225 | assert_or_panic(x == -1); | 255 | assert_or_panic(x == -1); |
| 226 | } | 256 | } |
| ... | @@ -237,6 +267,14 @@ void c_i64(int64_t x) { | ... | @@ -237,6 +267,14 @@ void c_i64(int64_t x) { |
| 237 | assert_or_panic(x == -4); | 267 | assert_or_panic(x == -4); |
| 238 | } | 268 | } |
| 239 | 269 | ||
| 270 | void c_i128(__int128 x) { | ||
| 271 | assert_or_panic(x == -5); | ||
| 272 | } | ||
| 273 | |||
| 274 | void c_struct_i128(struct i128 x) { | ||
| 275 | assert_or_panic(x.value == -6); | ||
| 276 | } | ||
| 277 | |||
| 240 | void c_f32(float x) { | 278 | void c_f32(float x) { |
| 241 | assert_or_panic(x == 12.34f); | 279 | assert_or_panic(x == 12.34f); |
| 242 | } | 280 | } |
test/stage1/c_abi/main.zig+27| ... | @@ -16,10 +16,14 @@ extern fn c_u8(u8) void; | ... | @@ -16,10 +16,14 @@ extern fn c_u8(u8) void; |
| 16 | extern fn c_u16(u16) void; | 16 | extern fn c_u16(u16) void; |
| 17 | extern fn c_u32(u32) void; | 17 | extern fn c_u32(u32) void; |
| 18 | extern fn c_u64(u64) void; | 18 | extern fn c_u64(u64) void; |
| 19 | extern fn c_u128(u128) void; | ||
| 20 | extern fn c_struct_u128(U128) void; | ||
| 19 | extern fn c_i8(i8) void; | 21 | extern fn c_i8(i8) void; |
| 20 | extern fn c_i16(i16) void; | 22 | extern fn c_i16(i16) void; |
| 21 | extern fn c_i32(i32) void; | 23 | extern fn c_i32(i32) void; |
| 22 | extern fn c_i64(i64) void; | 24 | extern fn c_i64(i64) void; |
| 25 | extern fn c_i128(i128) void; | ||
| 26 | extern fn c_struct_i128(I128) void; | ||
| 23 | 27 | ||
| 24 | // On windows x64, the first 4 are passed via registers, others on the stack. | 28 | // On windows x64, the first 4 are passed via registers, others on the stack. |
| 25 | extern fn c_five_integers(i32, i32, i32, i32, i32) void; | 29 | extern fn c_five_integers(i32, i32, i32, i32, i32) void; |
| ... | @@ -37,11 +41,15 @@ test "C ABI integers" { | ... | @@ -37,11 +41,15 @@ test "C ABI integers" { |
| 37 | c_u16(0xfffe); | 41 | c_u16(0xfffe); |
| 38 | c_u32(0xfffffffd); | 42 | c_u32(0xfffffffd); |
| 39 | c_u64(0xfffffffffffffffc); | 43 | c_u64(0xfffffffffffffffc); |
| 44 | c_u128(0xfffffffffffffffc); | ||
| 45 | c_struct_u128(.{ .value = 0xfffffffffffffffc }); | ||
| 40 | 46 | ||
| 41 | c_i8(-1); | 47 | c_i8(-1); |
| 42 | c_i16(-2); | 48 | c_i16(-2); |
| 43 | c_i32(-3); | 49 | c_i32(-3); |
| 44 | c_i64(-4); | 50 | c_i64(-4); |
| 51 | c_i128(-5); | ||
| 52 | c_struct_i128(.{ .value = -6 }); | ||
| 45 | c_five_integers(12, 34, 56, 78, 90); | 53 | c_five_integers(12, 34, 56, 78, 90); |
| 46 | } | 54 | } |
| 47 | 55 | ||
| ... | @@ -57,6 +65,9 @@ export fn zig_u32(x: u32) void { | ... | @@ -57,6 +65,9 @@ export fn zig_u32(x: u32) void { |
| 57 | export fn zig_u64(x: u64) void { | 65 | export fn zig_u64(x: u64) void { |
| 58 | expect(x == 0xfffffffffffffffc) catch @panic("test failure"); | 66 | expect(x == 0xfffffffffffffffc) catch @panic("test failure"); |
| 59 | } | 67 | } |
| 68 | export fn zig_u128(x: u128) void { | ||
| 69 | expect(x == 0xfffffffffffffffc) catch @panic("test failure"); | ||
| 70 | } | ||
| 60 | export fn zig_i8(x: i8) void { | 71 | export fn zig_i8(x: i8) void { |
| 61 | expect(x == -1) catch @panic("test failure"); | 72 | expect(x == -1) catch @panic("test failure"); |
| 62 | } | 73 | } |
| ... | @@ -69,6 +80,22 @@ export fn zig_i32(x: i32) void { | ... | @@ -69,6 +80,22 @@ export fn zig_i32(x: i32) void { |
| 69 | export fn zig_i64(x: i64) void { | 80 | export fn zig_i64(x: i64) void { |
| 70 | expect(x == -4) catch @panic("test failure"); | 81 | expect(x == -4) catch @panic("test failure"); |
| 71 | } | 82 | } |
| 83 | export fn zig_i128(x: i128) void { | ||
| 84 | expect(x == -5) catch @panic("test failure"); | ||
| 85 | } | ||
| 86 | |||
| 87 | const I128 = extern struct { | ||
| 88 | value: i128, | ||
| 89 | }; | ||
| 90 | const U128 = extern struct { | ||
| 91 | value: u128, | ||
| 92 | }; | ||
| 93 | export fn zig_struct_i128(a: I128) void { | ||
| 94 | expect(a.value == -6) catch @panic("test failure"); | ||
| 95 | } | ||
| 96 | export fn zig_struct_u128(a: U128) void { | ||
| 97 | expect(a.value == 0xfffffffffffffffc) catch @panic("test failure"); | ||
| 98 | } | ||
| 72 | 99 | ||
| 73 | extern fn c_f32(f32) void; | 100 | extern fn c_f32(f32) void; |
| 74 | extern fn c_f64(f64) void; | 101 | extern fn c_f64(f64) void; |