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 {
104104 Stdcall,
105105 Fastcall,
106106 Vectorcall,
107 Thiscall,
107108 APCS,
108109 AAPCS,
109110 AAPCSVFP,
src-self-hosted/translate_c.zig+1
......@@ -3975,6 +3975,7 @@ fn transCC(
39753975 .X86StdCall => return CallingConvention.Stdcall,
39763976 .X86FastCall => return CallingConvention.Fastcall,
39773977 .X86VectorCall, .AArch64VectorCall => return CallingConvention.Vectorcall,
3978 .X86ThisCall => return CallingConvention.Thiscall,
39783979 .AAPCS => return CallingConvention.AAPCS,
39793980 .AAPCS_VFP => return CallingConvention.AAPCSVFP,
39803981 else => return revertAndWarn(
src/all_types.hpp+1
......@@ -68,6 +68,7 @@ enum CallingConvention {
6868 CallingConventionStdcall,
6969 CallingConventionFastcall,
7070 CallingConventionVectorcall,
71 CallingConventionThiscall,
7172 CallingConventionAPCS,
7273 CallingConventionAAPCS,
7374 CallingConventionAAPCSVFP,
src/analyze.cpp+15-11
......@@ -929,6 +929,7 @@ const char *calling_convention_name(CallingConvention cc) {
929929 case CallingConventionStdcall: return "Stdcall";
930930 case CallingConventionFastcall: return "Fastcall";
931931 case CallingConventionVectorcall: return "Vectorcall";
932 case CallingConventionThiscall: return "Thiscall";
932933 case CallingConventionAPCS: return "Apcs";
933934 case CallingConventionAAPCS: return "Aapcs";
934935 case CallingConventionAAPCSVFP: return "Aapcsvfp";
......@@ -949,6 +950,7 @@ bool calling_convention_allows_zig_types(CallingConvention cc) {
949950 case CallingConventionStdcall:
950951 case CallingConventionFastcall:
951952 case CallingConventionVectorcall:
953 case CallingConventionThiscall:
952954 case CallingConventionAPCS:
953955 case CallingConventionAAPCS:
954956 case CallingConventionAAPCSVFP:
......@@ -1706,9 +1708,7 @@ Error type_allowed_in_extern(CodeGen *g, ZigType *type_entry, bool *result) {
17061708 case ZigTypeIdArray:
17071709 return type_allowed_in_extern(g, type_entry->data.array.child_type, result);
17081710 case ZigTypeIdFn:
1709 *result = type_entry->data.fn.fn_type_id.cc == CallingConventionC ||
1710 type_entry->data.fn.fn_type_id.cc == CallingConventionStdcall ||
1711 type_entry->data.fn.fn_type_id.cc == CallingConventionAAPCS;
1711 *result = !calling_convention_allows_zig_types(type_entry->data.fn.fn_type_id.cc);
17121712 return ErrorNone;
17131713 case ZigTypeIdPointer:
17141714 if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
......@@ -3445,24 +3445,21 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
34453445 fn_table_entry->cc = (CallingConvention)bigint_as_u32(&result_val->data.x_enum_tag);
34463446 }
34473447
3448 fn_table_entry->type_entry = analyze_fn_type(g, source_node, child_scope, fn_table_entry);
3449
34503448 if (fn_proto->section_expr != nullptr) {
34513449 if (!analyze_const_string(g, child_scope, fn_proto->section_expr, &fn_table_entry->section_name)) {
34523450 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
3451 tld_fn->base.resolution = TldResolutionInvalid;
3452 return;
34533453 }
34543454 }
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)) {
34573459 tld_fn->base.resolution = TldResolutionInvalid;
34583460 return;
34593461 }
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
34663463 const CallingConvention fn_cc = fn_table_entry->type_entry->data.fn.fn_type_id.cc;
34673464
34683465 if (fn_proto->is_export) {
......@@ -3470,6 +3467,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
34703467 case CallingConventionAsync:
34713468 add_node_error(g, fn_def_node,
34723469 buf_sprintf("exported function cannot be async"));
3470 fn_table_entry->type_entry = g->builtin_types.entry_invalid;
34733471 tld_fn->base.resolution = TldResolutionInvalid;
34743472 return;
34753473 case CallingConventionC:
......@@ -3480,6 +3478,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
34803478 case CallingConventionStdcall:
34813479 case CallingConventionFastcall:
34823480 case CallingConventionVectorcall:
3481 case CallingConventionThiscall:
34833482 case CallingConventionAPCS:
34843483 case CallingConventionAAPCS:
34853484 case CallingConventionAAPCSVFP:
......@@ -3495,6 +3494,11 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
34953494 }
34963495 }
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
34983502 // if the calling convention implies that it cannot be async, we save that for later
34993503 // and leave the value to be nullptr to indicate that we have not emitted possible
35003504 // 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) {
301301 return LLVMAARCH64VectorCallCallConv;
302302#endif
303303 return LLVMCCallConv;
304 case CallingConventionThiscall:
305 if (g->zig_target->arch == ZigLLVM_x86)
306 return LLVMX86ThisCallCallConv;
307 return LLVMCCallConv;
304308 case CallingConventionAsync:
305309 return LLVMFastCallConv;
306310 case CallingConventionAPCS:
......@@ -424,6 +428,7 @@ static bool cc_want_sret_attr(CallingConvention cc) {
424428 case CallingConventionStdcall:
425429 case CallingConventionFastcall:
426430 case CallingConventionVectorcall:
431 case CallingConventionThiscall:
427432 case CallingConventionAPCS:
428433 case CallingConventionAAPCS:
429434 case CallingConventionAAPCSVFP:
......@@ -8512,9 +8517,10 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
85128517 static_assert(CallingConventionStdcall == 7, "");
85138518 static_assert(CallingConventionFastcall == 8, "");
85148519 static_assert(CallingConventionVectorcall == 9, "");
8515 static_assert(CallingConventionAPCS == 10, "");
8516 static_assert(CallingConventionAAPCS == 11, "");
8517 static_assert(CallingConventionAAPCSVFP == 12, "");
8520 static_assert(CallingConventionThiscall == 10, "");
8521 static_assert(CallingConventionAPCS == 11, "");
8522 static_assert(CallingConventionAAPCS == 12, "");
8523 static_assert(CallingConventionAAPCSVFP == 13, "");
85188524
85198525 static_assert(FnInlineAuto == 0, "");
85208526 static_assert(FnInlineAlways == 1, "");
src/ir.cpp+1
......@@ -16752,6 +16752,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio
1675216752 case CallingConventionStdcall:
1675316753 case CallingConventionFastcall:
1675416754 case CallingConventionVectorcall:
16755 case CallingConventionThiscall:
1675516756 case CallingConventionAPCS:
1675616757 case CallingConventionAAPCS:
1675716758 case CallingConventionAAPCSVFP:
test/translate_c.zig+2
......@@ -850,11 +850,13 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
850850 \\void __attribute__((stdcall)) foo2(float *a);
851851 \\void __attribute__((vectorcall)) foo3(float *a);
852852 \\void __attribute__((cdecl)) foo4(float *a);
853 \\void __attribute__((thiscall)) foo5(float *a);
853854 , &[_][]const u8{
854855 \\pub fn foo1(a: [*c]f32) callconv(.Fastcall) void;
855856 \\pub fn foo2(a: [*c]f32) callconv(.Stdcall) void;
856857 \\pub fn foo3(a: [*c]f32) callconv(.Vectorcall) void;
857858 \\pub extern fn foo4(a: [*c]f32) void;
859 \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void;
858860 });
859861
860862 cases.addWithTarget("Calling convention", tests.Target{