authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2019-12-29 19:34:54+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-02 18:57:08+01:00
log0ccac79c8ebc1ed56dbdab068076a86924a015bc
treea7dfe2ba2535f7d4c50f2f8bae07e97df1a2ef19
parent08a26fea0918fba1dd315781fa96d457da5bcb50

Implement Thiscall CC


7 files changed, 30 insertions(+), 14 deletions(-)

lib/std/builtin.zig+1
...@@ -104,6 +104,7 @@ pub const CallingConvention = enum {...@@ -104,6 +104,7 @@ pub const CallingConvention = enum {
104 Stdcall,104 Stdcall,
105 Fastcall,105 Fastcall,
106 Vectorcall,106 Vectorcall,
107 Thiscall,
107 APCS,108 APCS,
108 AAPCS,109 AAPCS,
109 AAPCSVFP,110 AAPCSVFP,
src-self-hosted/translate_c.zig+1
...@@ -3975,6 +3975,7 @@ fn transCC(...@@ -3975,6 +3975,7 @@ fn transCC(
3975 .X86StdCall => return CallingConvention.Stdcall,3975 .X86StdCall => return CallingConvention.Stdcall,
3976 .X86FastCall => return CallingConvention.Fastcall,3976 .X86FastCall => return CallingConvention.Fastcall,
3977 .X86VectorCall, .AArch64VectorCall => return CallingConvention.Vectorcall,3977 .X86VectorCall, .AArch64VectorCall => return CallingConvention.Vectorcall,
3978 .X86ThisCall => return CallingConvention.Thiscall,
3978 .AAPCS => return CallingConvention.AAPCS,3979 .AAPCS => return CallingConvention.AAPCS,
3979 .AAPCS_VFP => return CallingConvention.AAPCSVFP,3980 .AAPCS_VFP => return CallingConvention.AAPCSVFP,
3980 else => return revertAndWarn(3981 else => return revertAndWarn(
src/all_types.hpp+1
...@@ -68,6 +68,7 @@ enum CallingConvention {...@@ -68,6 +68,7 @@ enum CallingConvention {
68 CallingConventionStdcall,68 CallingConventionStdcall,
69 CallingConventionFastcall,69 CallingConventionFastcall,
70 CallingConventionVectorcall,70 CallingConventionVectorcall,
71 CallingConventionThiscall,
71 CallingConventionAPCS,72 CallingConventionAPCS,
72 CallingConventionAAPCS,73 CallingConventionAAPCS,
73 CallingConventionAAPCSVFP,74 CallingConventionAAPCSVFP,
src/analyze.cpp+15-11
...@@ -929,6 +929,7 @@ const char *calling_convention_name(CallingConvention cc) {...@@ -929,6 +929,7 @@ const char *calling_convention_name(CallingConvention cc) {
929 case CallingConventionStdcall: return "Stdcall";929 case CallingConventionStdcall: return "Stdcall";
930 case CallingConventionFastcall: return "Fastcall";930 case CallingConventionFastcall: return "Fastcall";
931 case CallingConventionVectorcall: return "Vectorcall";931 case CallingConventionVectorcall: return "Vectorcall";
932 case CallingConventionThiscall: return "Thiscall";
932 case CallingConventionAPCS: return "Apcs";933 case CallingConventionAPCS: return "Apcs";
933 case CallingConventionAAPCS: return "Aapcs";934 case CallingConventionAAPCS: return "Aapcs";
934 case CallingConventionAAPCSVFP: return "Aapcsvfp";935 case CallingConventionAAPCSVFP: return "Aapcsvfp";
...@@ -949,6 +950,7 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {...@@ -949,6 +950,7 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {
949 case CallingConventionStdcall:950 case CallingConventionStdcall:
950 case CallingConventionFastcall:951 case CallingConventionFastcall:
951 case CallingConventionVectorcall:952 case CallingConventionVectorcall:
953 case CallingConventionThiscall:
952 case CallingConventionAPCS:954 case CallingConventionAPCS:
953 case CallingConventionAAPCS:955 case CallingConventionAAPCS:
954 case CallingConventionAAPCSVFP:956 case CallingConventionAAPCSVFP:
...@@ -1706,9 +1708,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {...@@ -1706,9 +1708,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {
1706 case ZigTypeIdArray:1708 case ZigTypeIdArray:
1707 return type_allowed_in_extern(g, type_entry->data.array.child_type, result);1709 return type_allowed_in_extern(g, type_entry->data.array.child_type, result);
1708 case ZigTypeIdFn:1710 case ZigTypeIdFn:
1709 *result = type_entry->data.fn.fn_type_id.cc == CallingConventionC ||1711 *result = !calling_convention_allows_zig_types(type_entry->data.fn.fn_type_id.cc);
1710 type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall ||
1711 type_entry->data.fn.fn_type_id.cc == CallingConventionAAPCS;
1712 return ErrorNone;1712 return ErrorNone;
1713 case ZigTypeIdPointer:1713 case ZigTypeIdPointer:
1714 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))1714 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
...@@ -3445,24 +3445,21 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3445,24 +3445,21 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3445 fn_table_entry->cc = (CallingConvention)bigint_as_u32(&result_val->data.x_enum_tag);3445 fn_table_entry->cc = (CallingConvention)bigint_as_u32(&result_val->data.x_enum_tag);
3446 }3446 }
34473447
3448 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
3449
3450 if (fn_proto->section_expr != nullptr) {3448 if (fn_proto->section_expr != nullptr) {
3451 if (!analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name)) {3449 if (!analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name)) {
3452 fn_table_entry->type_entry = g->builtin_types.entry_invalid;3450 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
3451 tld_fn->base.resolution = TldResolutionInvalid;
3452 return;
3453 }3453 }
3454 }3454 }
34553455
3456 if (fn_table_entry->type_entry->id == ZigTypeIdInvalid) {3456 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
3457
3458 if (type_is_invalid(fn_table_entry->type_entry)) {
3457 tld_fn->base.resolution = TldResolutionInvalid;3459 tld_fn->base.resolution = TldResolutionInvalid;
3458 return;3460 return;
3459 }3461 }
34603462
3461 if (!fn_table_entry->type_entry->data.fn.is_generic) {
3462 if (fn_def_node)
3463 g->fn_defs.append(fn_table_entry);
3464 }
3465
3466 const CallingConvention fn_cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc;3463 const CallingConvention fn_cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc;
34673464
3468 if (fn_proto->is_export) {3465 if (fn_proto->is_export) {
...@@ -3470,6 +3467,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3470,6 +3467,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3470 case CallingConventionAsync:3467 case CallingConventionAsync:
3471 add_node_error(g, fn_def_node,3468 add_node_error(g, fn_def_node,
3472 buf_sprintf("exported function cannot be async"));3469 buf_sprintf("exported function cannot be async"));
3470 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
3473 tld_fn->base.resolution = TldResolutionInvalid;3471 tld_fn->base.resolution = TldResolutionInvalid;
3474 return;3472 return;
3475 case CallingConventionC:3473 case CallingConventionC:
...@@ -3480,6 +3478,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3480,6 +3478,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3480 case CallingConventionStdcall:3478 case CallingConventionStdcall:
3481 case CallingConventionFastcall:3479 case CallingConventionFastcall:
3482 case CallingConventionVectorcall:3480 case CallingConventionVectorcall:
3481 case CallingConventionThiscall:
3483 case CallingConventionAPCS:3482 case CallingConventionAPCS:
3484 case CallingConventionAAPCS:3483 case CallingConventionAAPCS:
3485 case CallingConventionAAPCSVFP:3484 case CallingConventionAAPCSVFP:
...@@ -3495,6 +3494,11 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {...@@ -3495,6 +3494,11 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
3495 }3494 }
3496 }3495 }
34973496
3497 if (!fn_table_entry->type_entry->data.fn.is_generic) {
3498 if (fn_def_node)
3499 g->fn_defs.append(fn_table_entry);
3500 }
3501
3498 // if the calling convention implies that it cannot be async, we save that for later3502 // if the calling convention implies that it cannot be async, we save that for later
3499 // and leave the value to be nullptr to indicate that we have not emitted possible3503 // and leave the value to be nullptr to indicate that we have not emitted possible
3500 // compile errors for improperly calling async functions.3504 // compile errors for improperly calling async functions.
src/codegen.cpp+9-3
...@@ -301,6 +301,10 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {...@@ -301,6 +301,10 @@ static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) {
301 return LLVMAARCH64VectorCallCallConv;301 return LLVMAARCH64VectorCallCallConv;
302#endif302#endif
303 return LLVMCCallConv;303 return LLVMCCallConv;
304 case CallingConventionThiscall:
305 if (g->zig_target->arch == ZigLLVM_x86)
306 return LLVMX86ThisCallCallConv;
307 return LLVMCCallConv;
304 case CallingConventionAsync:308 case CallingConventionAsync:
305 return LLVMFastCallConv;309 return LLVMFastCallConv;
306 case CallingConventionAPCS:310 case CallingConventionAPCS:
...@@ -424,6 +428,7 @@ static bool cc_want_sret_attr(CallingConvention cc) {...@@ -424,6 +428,7 @@ static bool cc_want_sret_attr(CallingConvention cc) {
424 case CallingConventionStdcall:428 case CallingConventionStdcall:
425 case CallingConventionFastcall:429 case CallingConventionFastcall:
426 case CallingConventionVectorcall:430 case CallingConventionVectorcall:
431 case CallingConventionThiscall:
427 case CallingConventionAPCS:432 case CallingConventionAPCS:
428 case CallingConventionAAPCS:433 case CallingConventionAAPCS:
429 case CallingConventionAAPCSVFP:434 case CallingConventionAAPCSVFP:
...@@ -8512,9 +8517,10 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8512,9 +8517,10 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8512 static_assert(CallingConventionStdcall == 7, "");8517 static_assert(CallingConventionStdcall == 7, "");
8513 static_assert(CallingConventionFastcall == 8, "");8518 static_assert(CallingConventionFastcall == 8, "");
8514 static_assert(CallingConventionVectorcall == 9, "");8519 static_assert(CallingConventionVectorcall == 9, "");
8515 static_assert(CallingConventionAPCS == 10, "");8520 static_assert(CallingConventionThiscall == 10, "");
8516 static_assert(CallingConventionAAPCS == 11, "");8521 static_assert(CallingConventionAPCS == 11, "");
8517 static_assert(CallingConventionAAPCSVFP == 12, "");8522 static_assert(CallingConventionAAPCS == 12, "");
8523 static_assert(CallingConventionAAPCSVFP == 13, "");
85188524
8519 static_assert(FnInlineAuto == 0, "");8525 static_assert(FnInlineAuto == 0, "");
8520 static_assert(FnInlineAlways == 1, "");8526 static_assert(FnInlineAlways == 1, "");
src/ir.cpp+1
...@@ -16752,6 +16752,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio...@@ -16752,6 +16752,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
16752 case CallingConventionStdcall:16752 case CallingConventionStdcall:
16753 case CallingConventionFastcall:16753 case CallingConventionFastcall:
16754 case CallingConventionVectorcall:16754 case CallingConventionVectorcall:
16755 case CallingConventionThiscall:
16755 case CallingConventionAPCS:16756 case CallingConventionAPCS:
16756 case CallingConventionAAPCS:16757 case CallingConventionAAPCS:
16757 case CallingConventionAAPCSVFP:16758 case CallingConventionAAPCSVFP:
test/translate_c.zig+2
...@@ -850,11 +850,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -850,11 +850,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
850 \\void __attribute__((stdcall)) foo2(float *a);850 \\void __attribute__((stdcall)) foo2(float *a);
851 \\void __attribute__((vectorcall)) foo3(float *a);851 \\void __attribute__((vectorcall)) foo3(float *a);
852 \\void __attribute__((cdecl)) foo4(float *a);852 \\void __attribute__((cdecl)) foo4(float *a);
853 \\void __attribute__((thiscall)) foo5(float *a);
853 , &[_][]const u8{854 , &[_][]const u8{
854 \\pub fn foo1(a: [*c]f32) callconv(.Fastcall) void;855 \\pub fn foo1(a: [*c]f32) callconv(.Fastcall) void;
855 \\pub fn foo2(a: [*c]f32) callconv(.Stdcall) void;856 \\pub fn foo2(a: [*c]f32) callconv(.Stdcall) void;
856 \\pub fn foo3(a: [*c]f32) callconv(.Vectorcall) void;857 \\pub fn foo3(a: [*c]f32) callconv(.Vectorcall) void;
857 \\pub extern fn foo4(a: [*c]f32) void;858 \\pub extern fn foo4(a: [*c]f32) void;
859 \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void;
858 });860 });
859861
860 cases.addWithTarget("Calling convention", tests.Target{862 cases.addWithTarget("Calling convention", tests.Target{