| author | |
| committer | |
| log | db56d74a3bc9c6240d24838753a7042ba91501a1 |
| tree | d5205539c16c3c22e31b18c5cb01efb929b6f308 |
| parent | 92cb17a331b0f2f3a89b8e5e6995e8e36b9f3679 |
| parent | 77a6031edbd17dfdf654f24d139f27ac7adeb82f |
| signature |
stage1: fix x86 i128 C ABI for extern structs5 files changed, 166 insertions(+), 51 deletions(-)
src/arch/x86_64/abi.zig+27-3| ... | @@ -18,10 +18,34 @@ pub fn classifyWindows(ty: Type, target: Target) Class { | ... | @@ -18,10 +18,34 @@ pub fn classifyWindows(ty: Type, target: Target) Class { |
| 18 | else => return .memory, | 18 | else => return .memory, |
| 19 | } | 19 | } |
| 20 | return switch (ty.zigTypeTag()) { | 20 | return switch (ty.zigTypeTag()) { |
| 21 | .Int, .Bool, .Enum, .Void, .NoReturn, .ErrorSet, .Struct, .Union => .integer, | 21 | .Pointer, |
| 22 | .Optional => if (ty.isPtrLikeOptional()) return .integer else return .memory, | 22 | .Int, |
| 23 | .Bool, | ||
| 24 | .Enum, | ||
| 25 | .Void, | ||
| 26 | .NoReturn, | ||
| 27 | .ErrorSet, | ||
| 28 | .Struct, | ||
| 29 | .Union, | ||
| 30 | .Optional, | ||
| 31 | .Array, | ||
| 32 | .ErrorUnion, | ||
| 33 | .AnyFrame, | ||
| 34 | .Frame, | ||
| 35 | => .integer, | ||
| 36 | |||
| 23 | .Float, .Vector => .sse, | 37 | .Float, .Vector => .sse, |
| 24 | else => unreachable, | 38 | |
| 39 | .Type, | ||
| 40 | .ComptimeFloat, | ||
| 41 | .ComptimeInt, | ||
| 42 | .Undefined, | ||
| 43 | .Null, | ||
| 44 | .BoundFn, | ||
| 45 | .Fn, | ||
| 46 | .Opaque, | ||
| 47 | .EnumLiteral, | ||
| 48 | => unreachable, | ||
| 25 | }; | 49 | }; |
| 26 | } | 50 | } |
| 27 | 51 |
src/stage1/analyze.cpp+61-16| ... | @@ -8279,23 +8279,53 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents_buf) { | ... | @@ -8279,23 +8279,53 @@ Error file_fetch(CodeGen *g, Buf *resolved_path, Buf *contents_buf) { |
| 8279 | 8279 | ||
| 8280 | static X64CABIClass type_windows_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) { | 8280 | static X64CABIClass type_windows_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) { |
| 8281 | // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017 | 8281 | // https://docs.microsoft.com/en-gb/cpp/build/x64-calling-convention?view=vs-2017 |
| 8282 | switch (ty_size) { | ||
| 8283 | case 1: | ||
| 8284 | case 2: | ||
| 8285 | case 4: | ||
| 8286 | case 8: | ||
| 8287 | break; | ||
| 8288 | case 16: | ||
| 8289 | return (ty->id == ZigTypeIdVector) ? X64CABIClass_SSE : X64CABIClass_MEMORY; | ||
| 8290 | default: | ||
| 8291 | return X64CABIClass_MEMORY; | ||
| 8292 | } | ||
| 8282 | switch (ty->id) { | 8293 | switch (ty->id) { |
| 8283 | case ZigTypeIdEnum: | 8294 | case ZigTypeIdInvalid: |
| 8295 | case ZigTypeIdMetaType: | ||
| 8296 | case ZigTypeIdComptimeFloat: | ||
| 8297 | case ZigTypeIdComptimeInt: | ||
| 8298 | case ZigTypeIdNull: | ||
| 8299 | case ZigTypeIdUndefined: | ||
| 8300 | case ZigTypeIdBoundFn: | ||
| 8301 | case ZigTypeIdOpaque: | ||
| 8302 | case ZigTypeIdEnumLiteral: | ||
| 8303 | zig_unreachable(); | ||
| 8304 | |||
| 8305 | case ZigTypeIdFn: | ||
| 8306 | case ZigTypeIdPointer: | ||
| 8284 | case ZigTypeIdInt: | 8307 | case ZigTypeIdInt: |
| 8285 | case ZigTypeIdBool: | 8308 | case ZigTypeIdBool: |
| 8309 | case ZigTypeIdEnum: | ||
| 8310 | case ZigTypeIdVoid: | ||
| 8311 | case ZigTypeIdUnreachable: | ||
| 8312 | case ZigTypeIdErrorSet: | ||
| 8313 | case ZigTypeIdErrorUnion: | ||
| 8314 | case ZigTypeIdStruct: | ||
| 8315 | case ZigTypeIdUnion: | ||
| 8316 | case ZigTypeIdOptional: | ||
| 8317 | case ZigTypeIdFnFrame: | ||
| 8318 | case ZigTypeIdAnyFrame: | ||
| 8286 | return X64CABIClass_INTEGER; | 8319 | return X64CABIClass_INTEGER; |
| 8320 | |||
| 8287 | case ZigTypeIdFloat: | 8321 | case ZigTypeIdFloat: |
| 8288 | case ZigTypeIdVector: | 8322 | case ZigTypeIdVector: |
| 8289 | return X64CABIClass_SSE; | 8323 | return X64CABIClass_SSE; |
| 8290 | case ZigTypeIdStruct: | 8324 | |
| 8291 | case ZigTypeIdUnion: { | 8325 | case ZigTypeIdArray: |
| 8292 | if (ty_size <= 8) | ||
| 8293 | return X64CABIClass_INTEGER; | ||
| 8294 | return X64CABIClass_MEMORY; | ||
| 8295 | } | ||
| 8296 | default: | ||
| 8297 | return X64CABIClass_Unknown; | 8326 | return X64CABIClass_Unknown; |
| 8298 | } | 8327 | } |
| 8328 | zig_unreachable(); | ||
| 8299 | } | 8329 | } |
| 8300 | 8330 | ||
| 8301 | static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) { | 8331 | static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size_t ty_size) { |
| ... | @@ -8374,17 +8404,19 @@ static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size | ... | @@ -8374,17 +8404,19 @@ static X64CABIClass type_system_V_abi_x86_64_class(CodeGen *g, ZigType *ty, size |
| 8374 | 8404 | ||
| 8375 | X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) { | 8405 | X64CABIClass type_c_abi_x86_64_class(CodeGen *g, ZigType *ty) { |
| 8376 | Error err; | 8406 | Error err; |
| 8377 | |||
| 8378 | const size_t ty_size = type_size(g, ty); | 8407 | const size_t ty_size = type_size(g, ty); |
| 8408 | |||
| 8409 | if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) { | ||
| 8410 | return type_windows_abi_x86_64_class(g, ty, ty_size); | ||
| 8411 | } | ||
| 8412 | |||
| 8379 | ZigType *ptr_type; | 8413 | ZigType *ptr_type; |
| 8380 | if ((err = get_codegen_ptr_type(g, ty, &ptr_type))) return X64CABIClass_Unknown; | 8414 | if ((err = get_codegen_ptr_type(g, ty, &ptr_type))) return X64CABIClass_Unknown; |
| 8381 | if (ptr_type != nullptr) | 8415 | if (ptr_type != nullptr) |
| 8382 | return X64CABIClass_INTEGER; | 8416 | return X64CABIClass_INTEGER; |
| 8383 | 8417 | ||
| 8384 | if (g->zig_target->os == OsWindows || g->zig_target->os == OsUefi) { | 8418 | if (g->zig_target->arch == ZigLLVM_aarch64 || |
| 8385 | return type_windows_abi_x86_64_class(g, ty, ty_size); | 8419 | g->zig_target->arch == ZigLLVM_aarch64_be) |
| 8386 | } else if (g->zig_target->arch == ZigLLVM_aarch64 || | ||
| 8387 | g->zig_target->arch == ZigLLVM_aarch64_be) | ||
| 8388 | { | 8420 | { |
| 8389 | X64CABIClass result = type_system_V_abi_x86_64_class(g, ty, ty_size); | 8421 | X64CABIClass result = type_system_V_abi_x86_64_class(g, ty, ty_size); |
| 8390 | return (result == X64CABIClass_MEMORY) ? X64CABIClass_MEMORY_nobyval : result; | 8422 | return (result == X64CABIClass_MEMORY) ? X64CABIClass_MEMORY_nobyval : result; |
| ... | @@ -8684,14 +8716,23 @@ static Error resolve_llvm_c_abi_type(CodeGen *g, ZigType *ty) { | ... | @@ -8684,14 +8716,23 @@ static Error resolve_llvm_c_abi_type(CodeGen *g, ZigType *ty) { |
| 8684 | if (ty->data.structure.fields[i]->offset >= 8) { | 8716 | if (ty->data.structure.fields[i]->offset >= 8) { |
| 8685 | eightbyte_index = 1; | 8717 | eightbyte_index = 1; |
| 8686 | } | 8718 | } |
| 8687 | X64CABIClass field_class = type_c_abi_x86_64_class(g, ty->data.structure.fields[i]->type_entry); | 8719 | ZigType *field_ty = ty->data.structure.fields[i]->type_entry; |
| 8720 | X64CABIClass field_class = type_c_abi_x86_64_class(g, field_ty); | ||
| 8688 | 8721 | ||
| 8689 | if (field_class == X64CABIClass_INTEGER) { | 8722 | if (field_class == X64CABIClass_INTEGER) { |
| 8690 | type_classes[eightbyte_index] = X64CABIClass_INTEGER; | 8723 | type_classes[eightbyte_index] = X64CABIClass_INTEGER; |
| 8691 | } else if (type_classes[eightbyte_index] == X64CABIClass_Unknown) { | 8724 | } else if (type_classes[eightbyte_index] == X64CABIClass_Unknown) { |
| 8692 | type_classes[eightbyte_index] = field_class; | 8725 | type_classes[eightbyte_index] = field_class; |
| 8693 | } | 8726 | } |
| 8694 | type_sizes[eightbyte_index] += ty->data.structure.fields[i]->type_entry->abi_size; | 8727 | if (field_ty->abi_size > 8) { |
| 8728 | assert(eightbyte_index == 0); | ||
| 8729 | type_sizes[0] = 8; | ||
| 8730 | type_sizes[1] = field_ty->abi_size - 8; | ||
| 8731 | type_classes[1] = type_classes[0]; | ||
| 8732 | eightbyte_index = 1; | ||
| 8733 | } else { | ||
| 8734 | type_sizes[eightbyte_index] += field_ty->abi_size; | ||
| 8735 | } | ||
| 8695 | } | 8736 | } |
| 8696 | 8737 | ||
| 8697 | LLVMTypeRef return_elem_types[] = { | 8738 | LLVMTypeRef return_elem_types[] = { |
| ... | @@ -8980,8 +9021,12 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS | ... | @@ -8980,8 +9021,12 @@ static void resolve_llvm_types_struct(CodeGen *g, ZigType *struct_type, ResolveS |
| 8980 | struct_type->data.structure.llvm_full_type_queue_index = SIZE_MAX; | 9021 | struct_type->data.structure.llvm_full_type_queue_index = SIZE_MAX; |
| 8981 | } | 9022 | } |
| 8982 | 9023 | ||
| 8983 | if (struct_type->abi_size <= 16 && (struct_type->data.structure.layout == ContainerLayoutExtern || struct_type->data.structure.layout == ContainerLayoutPacked)) | 9024 | if (struct_type->abi_size <= 16 && |
| 9025 | (struct_type->data.structure.layout == ContainerLayoutExtern || | ||
| 9026 | struct_type->data.structure.layout == ContainerLayoutPacked)) | ||
| 9027 | { | ||
| 8984 | resolve_llvm_c_abi_type(g, struct_type); | 9028 | resolve_llvm_c_abi_type(g, struct_type); |
| 9029 | } | ||
| 8985 | } | 9030 | } |
| 8986 | 9031 | ||
| 8987 | // This is to be used instead of void for debug info types, to avoid tripping | 9032 | // This is to be used instead of void for debug info types, to avoid tripping |
test/stage1/c_abi/build.zig+3| ... | @@ -2,15 +2,18 @@ const Builder = @import("std").build.Builder; | ... | @@ -2,15 +2,18 @@ const Builder = @import("std").build.Builder; |
| 2 | 2 | ||
| 3 | pub fn build(b: *Builder) void { | 3 | pub fn build(b: *Builder) void { |
| 4 | const rel_opts = b.standardReleaseOptions(); | 4 | const rel_opts = b.standardReleaseOptions(); |
| 5 | const target = b.standardTargetOptions(.{}); | ||
| 5 | 6 | ||
| 6 | const c_obj = b.addObject("cfuncs", null); | 7 | const c_obj = b.addObject("cfuncs", null); |
| 7 | c_obj.addCSourceFile("cfuncs.c", &[_][]const u8{"-std=c99"}); | 8 | c_obj.addCSourceFile("cfuncs.c", &[_][]const u8{"-std=c99"}); |
| 8 | c_obj.setBuildMode(rel_opts); | 9 | c_obj.setBuildMode(rel_opts); |
| 9 | c_obj.linkSystemLibrary("c"); | 10 | c_obj.linkSystemLibrary("c"); |
| 11 | c_obj.target = target; | ||
| 10 | 12 | ||
| 11 | const main = b.addTest("main.zig"); | 13 | const main = b.addTest("main.zig"); |
| 12 | main.setBuildMode(rel_opts); | 14 | main.setBuildMode(rel_opts); |
| 13 | main.addObject(c_obj); | 15 | main.addObject(c_obj); |
| 16 | main.target = target; | ||
| 14 | 17 | ||
| 15 | const test_step = b.step("test", "Test the program"); | 18 | const test_step = b.step("test", "Test the program"); |
| 16 | test_step.dependOn(&main.step); | 19 | test_step.dependOn(&main.step); |
test/stage1/c_abi/cfuncs.c+26| ... | @@ -11,14 +11,24 @@ static void assert_or_panic(bool ok) { | ... | @@ -11,14 +11,24 @@ 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_struct_u128(struct u128); | ||
| 18 | void zig_i8(int8_t); | 27 | void zig_i8(int8_t); |
| 19 | void zig_i16(int16_t); | 28 | void zig_i16(int16_t); |
| 20 | void zig_i32(int32_t); | 29 | void zig_i32(int32_t); |
| 21 | void zig_i64(int64_t); | 30 | void zig_i64(int64_t); |
| 31 | void zig_struct_i128(struct i128); | ||
| 22 | void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); | 32 | void zig_five_integers(int32_t, int32_t, int32_t, int32_t, int32_t); |
| 23 | 33 | ||
| 24 | void zig_f32(float); | 34 | void zig_f32(float); |
| ... | @@ -130,11 +140,19 @@ void run_c_tests(void) { | ... | @@ -130,11 +140,19 @@ void run_c_tests(void) { |
| 130 | zig_u16(0xfffe); | 140 | zig_u16(0xfffe); |
| 131 | zig_u32(0xfffffffd); | 141 | zig_u32(0xfffffffd); |
| 132 | zig_u64(0xfffffffffffffffc); | 142 | zig_u64(0xfffffffffffffffc); |
| 143 | { | ||
| 144 | struct u128 s = {0xfffffffffffffffc}; | ||
| 145 | zig_struct_u128(s); | ||
| 146 | } | ||
| 133 | 147 | ||
| 134 | zig_i8(-1); | 148 | zig_i8(-1); |
| 135 | zig_i16(-2); | 149 | zig_i16(-2); |
| 136 | zig_i32(-3); | 150 | zig_i32(-3); |
| 137 | zig_i64(-4); | 151 | zig_i64(-4); |
| 152 | { | ||
| 153 | struct i128 s = {-6}; | ||
| 154 | zig_struct_i128(s); | ||
| 155 | } | ||
| 138 | zig_five_integers(12, 34, 56, 78, 90); | 156 | zig_five_integers(12, 34, 56, 78, 90); |
| 139 | 157 | ||
| 140 | zig_f32(12.34f); | 158 | zig_f32(12.34f); |
| ... | @@ -221,6 +239,10 @@ void c_u64(uint64_t x) { | ... | @@ -221,6 +239,10 @@ void c_u64(uint64_t x) { |
| 221 | assert_or_panic(x == 0xfffffffffffffffcULL); | 239 | assert_or_panic(x == 0xfffffffffffffffcULL); |
| 222 | } | 240 | } |
| 223 | 241 | ||
| 242 | void c_struct_u128(struct u128 x) { | ||
| 243 | assert_or_panic(x.value == 0xfffffffffffffffcULL); | ||
| 244 | } | ||
| 245 | |||
| 224 | void c_i8(int8_t x) { | 246 | void c_i8(int8_t x) { |
| 225 | assert_or_panic(x == -1); | 247 | assert_or_panic(x == -1); |
| 226 | } | 248 | } |
| ... | @@ -237,6 +259,10 @@ void c_i64(int64_t x) { | ... | @@ -237,6 +259,10 @@ void c_i64(int64_t x) { |
| 237 | assert_or_panic(x == -4); | 259 | assert_or_panic(x == -4); |
| 238 | } | 260 | } |
| 239 | 261 | ||
| 262 | void c_struct_i128(struct i128 x) { | ||
| 263 | assert_or_panic(x.value == -6); | ||
| 264 | } | ||
| 265 | |||
| 240 | void c_f32(float x) { | 266 | void c_f32(float x) { |
| 241 | assert_or_panic(x == 12.34f); | 267 | assert_or_panic(x == 12.34f); |
| 242 | } | 268 | } |
test/stage1/c_abi/main.zig+49-32| ... | @@ -16,20 +16,22 @@ extern fn c_u8(u8) void; | ... | @@ -16,20 +16,22 @@ 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_struct_u128(U128) void; | ||
| 19 | extern fn c_i8(i8) void; | 20 | extern fn c_i8(i8) void; |
| 20 | extern fn c_i16(i16) void; | 21 | extern fn c_i16(i16) void; |
| 21 | extern fn c_i32(i32) void; | 22 | extern fn c_i32(i32) void; |
| 22 | extern fn c_i64(i64) void; | 23 | extern fn c_i64(i64) void; |
| 24 | extern fn c_struct_i128(I128) void; | ||
| 23 | 25 | ||
| 24 | // On windows x64, the first 4 are passed via registers, others on the stack. | 26 | // 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; | 27 | extern fn c_five_integers(i32, i32, i32, i32, i32) void; |
| 26 | 28 | ||
| 27 | export fn zig_five_integers(a: i32, b: i32, c: i32, d: i32, e: i32) void { | 29 | export fn zig_five_integers(a: i32, b: i32, c: i32, d: i32, e: i32) void { |
| 28 | expect(a == 12) catch @panic("test failure"); | 30 | expect(a == 12) catch @panic("test failure: zig_five_integers 12"); |
| 29 | expect(b == 34) catch @panic("test failure"); | 31 | expect(b == 34) catch @panic("test failure: zig_five_integers 34"); |
| 30 | expect(c == 56) catch @panic("test failure"); | 32 | expect(c == 56) catch @panic("test failure: zig_five_integers 56"); |
| 31 | expect(d == 78) catch @panic("test failure"); | 33 | expect(d == 78) catch @panic("test failure: zig_five_integers 78"); |
| 32 | expect(e == 90) catch @panic("test failure"); | 34 | expect(e == 90) catch @panic("test failure: zig_five_integers 90"); |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | test "C ABI integers" { | 37 | test "C ABI integers" { |
| ... | @@ -37,37 +39,52 @@ test "C ABI integers" { | ... | @@ -37,37 +39,52 @@ test "C ABI integers" { |
| 37 | c_u16(0xfffe); | 39 | c_u16(0xfffe); |
| 38 | c_u32(0xfffffffd); | 40 | c_u32(0xfffffffd); |
| 39 | c_u64(0xfffffffffffffffc); | 41 | c_u64(0xfffffffffffffffc); |
| 42 | c_struct_u128(.{ .value = 0xfffffffffffffffc }); | ||
| 40 | 43 | ||
| 41 | c_i8(-1); | 44 | c_i8(-1); |
| 42 | c_i16(-2); | 45 | c_i16(-2); |
| 43 | c_i32(-3); | 46 | c_i32(-3); |
| 44 | c_i64(-4); | 47 | c_i64(-4); |
| 48 | c_struct_i128(.{ .value = -6 }); | ||
| 45 | c_five_integers(12, 34, 56, 78, 90); | 49 | c_five_integers(12, 34, 56, 78, 90); |
| 46 | } | 50 | } |
| 47 | 51 | ||
| 48 | export fn zig_u8(x: u8) void { | 52 | export fn zig_u8(x: u8) void { |
| 49 | expect(x == 0xff) catch @panic("test failure"); | 53 | expect(x == 0xff) catch @panic("test failure: zig_u8"); |
| 50 | } | 54 | } |
| 51 | export fn zig_u16(x: u16) void { | 55 | export fn zig_u16(x: u16) void { |
| 52 | expect(x == 0xfffe) catch @panic("test failure"); | 56 | expect(x == 0xfffe) catch @panic("test failure: zig_u16"); |
| 53 | } | 57 | } |
| 54 | export fn zig_u32(x: u32) void { | 58 | export fn zig_u32(x: u32) void { |
| 55 | expect(x == 0xfffffffd) catch @panic("test failure"); | 59 | expect(x == 0xfffffffd) catch @panic("test failure: zig_u32"); |
| 56 | } | 60 | } |
| 57 | export fn zig_u64(x: u64) void { | 61 | export fn zig_u64(x: u64) void { |
| 58 | expect(x == 0xfffffffffffffffc) catch @panic("test failure"); | 62 | expect(x == 0xfffffffffffffffc) catch @panic("test failure: zig_u64"); |
| 59 | } | 63 | } |
| 60 | export fn zig_i8(x: i8) void { | 64 | export fn zig_i8(x: i8) void { |
| 61 | expect(x == -1) catch @panic("test failure"); | 65 | expect(x == -1) catch @panic("test failure: zig_i8"); |
| 62 | } | 66 | } |
| 63 | export fn zig_i16(x: i16) void { | 67 | export fn zig_i16(x: i16) void { |
| 64 | expect(x == -2) catch @panic("test failure"); | 68 | expect(x == -2) catch @panic("test failure: zig_i16"); |
| 65 | } | 69 | } |
| 66 | export fn zig_i32(x: i32) void { | 70 | export fn zig_i32(x: i32) void { |
| 67 | expect(x == -3) catch @panic("test failure"); | 71 | expect(x == -3) catch @panic("test failure: zig_i32"); |
| 68 | } | 72 | } |
| 69 | export fn zig_i64(x: i64) void { | 73 | export fn zig_i64(x: i64) void { |
| 70 | expect(x == -4) catch @panic("test failure"); | 74 | expect(x == -4) catch @panic("test failure: zig_i64"); |
| 75 | } | ||
| 76 | |||
| 77 | const I128 = extern struct { | ||
| 78 | value: i128, | ||
| 79 | }; | ||
| 80 | const U128 = extern struct { | ||
| 81 | value: u128, | ||
| 82 | }; | ||
| 83 | export fn zig_struct_i128(a: I128) void { | ||
| 84 | expect(a.value == -6) catch @panic("test failure: zig_struct_i128"); | ||
| 85 | } | ||
| 86 | export fn zig_struct_u128(a: U128) void { | ||
| 87 | expect(a.value == 0xfffffffffffffffc) catch @panic("test failure: zig_struct_u128"); | ||
| 71 | } | 88 | } |
| 72 | 89 | ||
| 73 | extern fn c_f32(f32) void; | 90 | extern fn c_f32(f32) void; |
| ... | @@ -77,11 +94,11 @@ extern fn c_f64(f64) void; | ... | @@ -77,11 +94,11 @@ extern fn c_f64(f64) void; |
| 77 | extern fn c_five_floats(f32, f32, f32, f32, f32) void; | 94 | extern fn c_five_floats(f32, f32, f32, f32, f32) void; |
| 78 | 95 | ||
| 79 | export fn zig_five_floats(a: f32, b: f32, c: f32, d: f32, e: f32) void { | 96 | export fn zig_five_floats(a: f32, b: f32, c: f32, d: f32, e: f32) void { |
| 80 | expect(a == 1.0) catch @panic("test failure"); | 97 | expect(a == 1.0) catch @panic("test failure: zig_five_floats 1.0"); |
| 81 | expect(b == 2.0) catch @panic("test failure"); | 98 | expect(b == 2.0) catch @panic("test failure: zig_five_floats 2.0"); |
| 82 | expect(c == 3.0) catch @panic("test failure"); | 99 | expect(c == 3.0) catch @panic("test failure: zig_five_floats 3.0"); |
| 83 | expect(d == 4.0) catch @panic("test failure"); | 100 | expect(d == 4.0) catch @panic("test failure: zig_five_floats 4.0"); |
| 84 | expect(e == 5.0) catch @panic("test failure"); | 101 | expect(e == 5.0) catch @panic("test failure: zig_five_floats 5.0"); |
| 85 | } | 102 | } |
| 86 | 103 | ||
| 87 | test "C ABI floats" { | 104 | test "C ABI floats" { |
| ... | @@ -91,10 +108,10 @@ test "C ABI floats" { | ... | @@ -91,10 +108,10 @@ test "C ABI floats" { |
| 91 | } | 108 | } |
| 92 | 109 | ||
| 93 | export fn zig_f32(x: f32) void { | 110 | export fn zig_f32(x: f32) void { |
| 94 | expect(x == 12.34) catch @panic("test failure"); | 111 | expect(x == 12.34) catch @panic("test failure: zig_f32"); |
| 95 | } | 112 | } |
| 96 | export fn zig_f64(x: f64) void { | 113 | export fn zig_f64(x: f64) void { |
| 97 | expect(x == 56.78) catch @panic("test failure"); | 114 | expect(x == 56.78) catch @panic("test failure: zig_f64"); |
| 98 | } | 115 | } |
| 99 | 116 | ||
| 100 | extern fn c_ptr(*anyopaque) void; | 117 | extern fn c_ptr(*anyopaque) void; |
| ... | @@ -104,7 +121,7 @@ test "C ABI pointer" { | ... | @@ -104,7 +121,7 @@ test "C ABI pointer" { |
| 104 | } | 121 | } |
| 105 | 122 | ||
| 106 | export fn zig_ptr(x: *anyopaque) void { | 123 | export fn zig_ptr(x: *anyopaque) void { |
| 107 | expect(@ptrToInt(x) == 0xdeadbeef) catch @panic("test failure"); | 124 | expect(@ptrToInt(x) == 0xdeadbeef) catch @panic("test failure: zig_ptr"); |
| 108 | } | 125 | } |
| 109 | 126 | ||
| 110 | extern fn c_bool(bool) void; | 127 | extern fn c_bool(bool) void; |
| ... | @@ -114,7 +131,7 @@ test "C ABI bool" { | ... | @@ -114,7 +131,7 @@ test "C ABI bool" { |
| 114 | } | 131 | } |
| 115 | 132 | ||
| 116 | export fn zig_bool(x: bool) void { | 133 | export fn zig_bool(x: bool) void { |
| 117 | expect(x) catch @panic("test failure"); | 134 | expect(x) catch @panic("test failure: zig_bool"); |
| 118 | } | 135 | } |
| 119 | 136 | ||
| 120 | const BigStruct = extern struct { | 137 | const BigStruct = extern struct { |
| ... | @@ -138,11 +155,11 @@ test "C ABI big struct" { | ... | @@ -138,11 +155,11 @@ test "C ABI big struct" { |
| 138 | } | 155 | } |
| 139 | 156 | ||
| 140 | export fn zig_big_struct(x: BigStruct) void { | 157 | export fn zig_big_struct(x: BigStruct) void { |
| 141 | expect(x.a == 1) catch @panic("test failure"); | 158 | expect(x.a == 1) catch @panic("test failure: zig_big_struct 1"); |
| 142 | expect(x.b == 2) catch @panic("test failure"); | 159 | expect(x.b == 2) catch @panic("test failure: zig_big_struct 2"); |
| 143 | expect(x.c == 3) catch @panic("test failure"); | 160 | expect(x.c == 3) catch @panic("test failure: zig_big_struct 3"); |
| 144 | expect(x.d == 4) catch @panic("test failure"); | 161 | expect(x.d == 4) catch @panic("test failure: zig_big_struct 4"); |
| 145 | expect(x.e == 5) catch @panic("test failure"); | 162 | expect(x.e == 5) catch @panic("test failure: zig_big_struct 5"); |
| 146 | } | 163 | } |
| 147 | 164 | ||
| 148 | const BigUnion = extern union { | 165 | const BigUnion = extern union { |
| ... | @@ -164,11 +181,11 @@ test "C ABI big union" { | ... | @@ -164,11 +181,11 @@ test "C ABI big union" { |
| 164 | } | 181 | } |
| 165 | 182 | ||
| 166 | export fn zig_big_union(x: BigUnion) void { | 183 | export fn zig_big_union(x: BigUnion) void { |
| 167 | expect(x.a.a == 1) catch @panic("test failure"); | 184 | expect(x.a.a == 1) catch @panic("test failure: zig_big_union a"); |
| 168 | expect(x.a.b == 2) catch @panic("test failure"); | 185 | expect(x.a.b == 2) catch @panic("test failure: zig_big_union b"); |
| 169 | expect(x.a.c == 3) catch @panic("test failure"); | 186 | expect(x.a.c == 3) catch @panic("test failure: zig_big_union c"); |
| 170 | expect(x.a.d == 4) catch @panic("test failure"); | 187 | expect(x.a.d == 4) catch @panic("test failure: zig_big_union d"); |
| 171 | expect(x.a.e == 5) catch @panic("test failure"); | 188 | expect(x.a.e == 5) catch @panic("test failure: zig_big_union e"); |
| 172 | } | 189 | } |
| 173 | 190 | ||
| 174 | const MedStructMixed = extern struct { | 191 | const MedStructMixed = extern struct { |