diff --git a/src/codegen.cpp b/src/codegen.cpp index 23a9103877..d569bfc8d2 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -262,76 +262,66 @@ static const char *get_mangled_name(CodeGen *g, const char *original_name, bool } } -static LLVMCallConv get_llvm_cc(CodeGen *g, CallingConvention cc) { +static ZigLLVM_CallingConv get_llvm_cc(CodeGen *g, CallingConvention cc) { switch (cc) { - case CallingConventionUnspecified: return LLVMFastCallConv; - case CallingConventionC: return LLVMCCallConv; + case CallingConventionUnspecified: + return ZigLLVM_Fast; + case CallingConventionC: + return ZigLLVM_C; case CallingConventionCold: - // cold calling convention only works on x86. - if (g->zig_target->arch == ZigLLVM_x86 || - g->zig_target->arch == ZigLLVM_x86_64) - { - // cold calling convention is not supported on windows - if (g->zig_target->os == OsWindows) { - return LLVMCCallConv; - } else { - return LLVMColdCallConv; - } - } else { - return LLVMCCallConv; - } - break; + if ((g->zig_target->arch == ZigLLVM_x86 || + g->zig_target->arch == ZigLLVM_x86_64) && + g->zig_target->os != OsWindows) + return ZigLLVM_Cold; + return ZigLLVM_C; case CallingConventionNaked: zig_unreachable(); case CallingConventionStdcall: if (g->zig_target->arch == ZigLLVM_x86) - return LLVMX86StdcallCallConv; - return LLVMCCallConv; + return ZigLLVM_X86_StdCall; + return ZigLLVM_C; case CallingConventionFastcall: if (g->zig_target->arch == ZigLLVM_x86) - return LLVMX86FastcallCallConv; - return LLVMCCallConv; + return ZigLLVM_X86_FastCall; + return ZigLLVM_C; case CallingConventionVectorcall: if (g->zig_target->arch == ZigLLVM_x86) - return LLVMX86VectorCallCallConv; - // XXX Enable this when the C API exports this enum member too -#if 0 + return ZigLLVM_X86_VectorCall; if (target_is_arm(g->zig_target) && target_arch_pointer_bit_width(g->zig_target->arch) == 64) - return LLVMAARCH64VectorCallCallConv; -#endif - return LLVMCCallConv; + return ZigLLVM_AArch64_VectorCall; + return ZigLLVM_C; case CallingConventionThiscall: if (g->zig_target->arch == ZigLLVM_x86) - return LLVMX86ThisCallCallConv; - return LLVMCCallConv; + return ZigLLVM_X86_ThisCall; + return ZigLLVM_C; case CallingConventionAsync: - return LLVMFastCallConv; + return ZigLLVM_Fast; case CallingConventionAPCS: if (target_is_arm(g->zig_target)) - return LLVMARMAPCSCallConv; - return LLVMCCallConv; + return ZigLLVM_ARM_APCS; + return ZigLLVM_C; case CallingConventionAAPCS: if (target_is_arm(g->zig_target)) - return LLVMARMAAPCSCallConv; - return LLVMCCallConv; + return ZigLLVM_ARM_AAPCS; + return ZigLLVM_C; case CallingConventionAAPCSVFP: if (target_is_arm(g->zig_target)) - return LLVMARMAAPCSVFPCallConv; - return LLVMCCallConv; + return ZigLLVM_ARM_AAPCS_VFP; + return ZigLLVM_C; case CallingConventionInterrupt: if (g->zig_target->arch == ZigLLVM_x86 || g->zig_target->arch == ZigLLVM_x86_64) - return LLVMX86INTRCallConv; + return ZigLLVM_X86_INTR; if (g->zig_target->arch == ZigLLVM_avr) - return LLVMAVRINTRCallConv; + return ZigLLVM_AVR_INTR; if (g->zig_target->arch == ZigLLVM_msp430) - return LLVMMSP430INTRCallConv; - return LLVMCCallConv; + return ZigLLVM_MSP430_INTR; + return ZigLLVM_C; case CallingConventionSignal: if (g->zig_target->arch == ZigLLVM_avr) - return LLVMAVRSIGNALCallConv; - return LLVMCCallConv; + return ZigLLVM_AVR_SIGNAL; + return ZigLLVM_C; } zig_unreachable(); } @@ -528,7 +518,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { if (cc == CallingConventionNaked) { addLLVMFnAttr(llvm_fn, "naked"); } else { - LLVMSetFunctionCallConv(llvm_fn, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc)); + ZigLLVMFunctionSetCallingConv(llvm_fn, get_llvm_cc(g, fn_type->data.fn.fn_type_id.cc)); } bool want_cold = fn->is_cold || cc == CallingConventionCold; @@ -1023,7 +1013,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace { assert(g->panic_fn != nullptr); LLVMValueRef fn_val = fn_llvm_value(g, g->panic_fn); - LLVMCallConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc); + ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, g->panic_fn->type_entry->data.fn.fn_type_id.cc); if (stack_trace_arg == nullptr) { stack_trace_arg = LLVMConstNull(get_llvm_type(g, ptr_to_stack_trace_type(g))); } @@ -1134,7 +1124,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); addLLVMFnAttr(fn_val, "alwaysinline"); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); // Error return trace memory is in the stack, which is impossible to be at address 0 @@ -1215,7 +1205,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { addLLVMFnAttr(fn_val, "noinline"); // so that we can look at return address addLLVMFnAttr(fn_val, "cold"); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { @@ -1299,7 +1289,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { addLLVMFnAttr(fn_val, "noreturn"); addLLVMFnAttr(fn_val, "cold"); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { @@ -2195,7 +2185,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { const char *fn_name = get_mangled_name(g, "__zig_merge_error_return_traces", false); LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); addLLVMArgAttr(fn_val, (unsigned)0, "noalias"); @@ -2372,7 +2362,7 @@ static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef tar LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), LLVMConstInt(usize_type_ref, resume_id, false)); LLVMValueRef args[] = {target_frame_ptr, arg_val}; - return ZigLLVMBuildCall(g->builder, fn_val, args, 2, LLVMFastCallConv, ZigLLVM_CallAttrAuto, ""); + return ZigLLVMBuildCall(g->builder, fn_val, args, 2, ZigLLVM_Fast, ZigLLVM_CallAttrAuto, ""); } static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) { @@ -4262,7 +4252,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr break; } - LLVMCallConv llvm_cc = get_llvm_cc(g, cc); + ZigLLVM_CallingConv llvm_cc = get_llvm_cc(g, cc); LLVMValueRef result; if (callee_is_async) { @@ -4972,7 +4962,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { buf_ptr(buf_sprintf("__zig_tag_name_%s", buf_ptr(&enum_type->name))), false); LLVMValueRef fn_val = LLVMAddFunction(g->module, fn_name, fn_type_ref); LLVMSetLinkage(fn_val, LLVMInternalLinkage); - LLVMSetFunctionCallConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); + ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 7ecb717047..b5c43b632b 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -273,10 +273,10 @@ ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) { } LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, - unsigned NumArgs, unsigned CC, ZigLLVM_CallAttr attr, const char *Name) + unsigned NumArgs, ZigLLVM_CallingConv CC, ZigLLVM_CallAttr attr, const char *Name) { CallInst *call_inst = CallInst::Create(unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name); - call_inst->setCallingConv(CC); + call_inst->setCallingConv(static_cast(CC)); switch (attr) { case ZigLLVM_CallAttrAuto: break; @@ -932,6 +932,9 @@ void ZigLLVMFunctionSetPrefixData(LLVMValueRef function, LLVMValueRef data) { unwrap(function)->setPrefixData(unwrap(data)); } +void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, ZigLLVM_CallingConv cc) { + unwrap(function)->setCallingConv(static_cast(cc)); +} class MyOStream: public raw_ostream { public: @@ -1315,3 +1318,49 @@ static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_XCOFF == Triple::XCOFF, ""); + +static_assert((CallingConv::ID)ZigLLVM_C == llvm::CallingConv::C, ""); +static_assert((CallingConv::ID)ZigLLVM_Fast == llvm::CallingConv::Fast, ""); +static_assert((CallingConv::ID)ZigLLVM_Cold == llvm::CallingConv::Cold, ""); +static_assert((CallingConv::ID)ZigLLVM_GHC == llvm::CallingConv::GHC, ""); +static_assert((CallingConv::ID)ZigLLVM_HiPE == llvm::CallingConv::HiPE, ""); +static_assert((CallingConv::ID)ZigLLVM_WebKit_JS == llvm::CallingConv::WebKit_JS, ""); +static_assert((CallingConv::ID)ZigLLVM_AnyReg == llvm::CallingConv::AnyReg, ""); +static_assert((CallingConv::ID)ZigLLVM_PreserveMost == llvm::CallingConv::PreserveMost, ""); +static_assert((CallingConv::ID)ZigLLVM_PreserveAll == llvm::CallingConv::PreserveAll, ""); +static_assert((CallingConv::ID)ZigLLVM_Swift == llvm::CallingConv::Swift, ""); +static_assert((CallingConv::ID)ZigLLVM_CXX_FAST_TLS == llvm::CallingConv::CXX_FAST_TLS, ""); +static_assert((CallingConv::ID)ZigLLVM_FirstTargetCC == llvm::CallingConv::FirstTargetCC, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_StdCall == llvm::CallingConv::X86_StdCall, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_FastCall == llvm::CallingConv::X86_FastCall, ""); +static_assert((CallingConv::ID)ZigLLVM_ARM_APCS == llvm::CallingConv::ARM_APCS, ""); +static_assert((CallingConv::ID)ZigLLVM_ARM_AAPCS == llvm::CallingConv::ARM_AAPCS, ""); +static_assert((CallingConv::ID)ZigLLVM_ARM_AAPCS_VFP == llvm::CallingConv::ARM_AAPCS_VFP, ""); +static_assert((CallingConv::ID)ZigLLVM_MSP430_INTR == llvm::CallingConv::MSP430_INTR, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_ThisCall == llvm::CallingConv::X86_ThisCall, ""); +static_assert((CallingConv::ID)ZigLLVM_PTX_Kernel == llvm::CallingConv::PTX_Kernel, ""); +static_assert((CallingConv::ID)ZigLLVM_PTX_Device == llvm::CallingConv::PTX_Device, ""); +static_assert((CallingConv::ID)ZigLLVM_SPIR_FUNC == llvm::CallingConv::SPIR_FUNC, ""); +static_assert((CallingConv::ID)ZigLLVM_SPIR_KERNEL == llvm::CallingConv::SPIR_KERNEL, ""); +static_assert((CallingConv::ID)ZigLLVM_Intel_OCL_BI == llvm::CallingConv::Intel_OCL_BI, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_64_SysV == llvm::CallingConv::X86_64_SysV, ""); +static_assert((CallingConv::ID)ZigLLVM_Win64 == llvm::CallingConv::Win64, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_VectorCall == llvm::CallingConv::X86_VectorCall, ""); +static_assert((CallingConv::ID)ZigLLVM_HHVM == llvm::CallingConv::HHVM, ""); +static_assert((CallingConv::ID)ZigLLVM_HHVM_C == llvm::CallingConv::HHVM_C, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_INTR == llvm::CallingConv::X86_INTR, ""); +static_assert((CallingConv::ID)ZigLLVM_AVR_INTR == llvm::CallingConv::AVR_INTR, ""); +static_assert((CallingConv::ID)ZigLLVM_AVR_SIGNAL == llvm::CallingConv::AVR_SIGNAL, ""); +static_assert((CallingConv::ID)ZigLLVM_AVR_BUILTIN == llvm::CallingConv::AVR_BUILTIN, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_VS == llvm::CallingConv::AMDGPU_VS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_GS == llvm::CallingConv::AMDGPU_GS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_PS == llvm::CallingConv::AMDGPU_PS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_CS == llvm::CallingConv::AMDGPU_CS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_KERNEL == llvm::CallingConv::AMDGPU_KERNEL, ""); +static_assert((CallingConv::ID)ZigLLVM_X86_RegCall == llvm::CallingConv::X86_RegCall, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_HS == llvm::CallingConv::AMDGPU_HS, ""); +static_assert((CallingConv::ID)ZigLLVM_MSP430_BUILTIN == llvm::CallingConv::MSP430_BUILTIN, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_LS == llvm::CallingConv::AMDGPU_LS, ""); +static_assert((CallingConv::ID)ZigLLVM_AMDGPU_ES == llvm::CallingConv::AMDGPU_ES, ""); +static_assert((CallingConv::ID)ZigLLVM_AArch64_VectorCall == llvm::CallingConv::AArch64_VectorCall, ""); +static_assert((CallingConv::ID)ZigLLVM_MaxID == llvm::CallingConv::MaxID, ""); diff --git a/src/zig_llvm.h b/src/zig_llvm.h index 4d8a3fa927..ba9816b4f8 100644 --- a/src/zig_llvm.h +++ b/src/zig_llvm.h @@ -64,6 +64,54 @@ ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, co ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref); +enum ZigLLVM_CallingConv { + ZigLLVM_C = 0, + ZigLLVM_Fast = 8, + ZigLLVM_Cold = 9, + ZigLLVM_GHC = 10, + ZigLLVM_HiPE = 11, + ZigLLVM_WebKit_JS = 12, + ZigLLVM_AnyReg = 13, + ZigLLVM_PreserveMost = 14, + ZigLLVM_PreserveAll = 15, + ZigLLVM_Swift = 16, + ZigLLVM_CXX_FAST_TLS = 17, + ZigLLVM_FirstTargetCC = 64, + ZigLLVM_X86_StdCall = 64, + ZigLLVM_X86_FastCall = 65, + ZigLLVM_ARM_APCS = 66, + ZigLLVM_ARM_AAPCS = 67, + ZigLLVM_ARM_AAPCS_VFP = 68, + ZigLLVM_MSP430_INTR = 69, + ZigLLVM_X86_ThisCall = 70, + ZigLLVM_PTX_Kernel = 71, + ZigLLVM_PTX_Device = 72, + ZigLLVM_SPIR_FUNC = 75, + ZigLLVM_SPIR_KERNEL = 76, + ZigLLVM_Intel_OCL_BI = 77, + ZigLLVM_X86_64_SysV = 78, + ZigLLVM_Win64 = 79, + ZigLLVM_X86_VectorCall = 80, + ZigLLVM_HHVM = 81, + ZigLLVM_HHVM_C = 82, + ZigLLVM_X86_INTR = 83, + ZigLLVM_AVR_INTR = 84, + ZigLLVM_AVR_SIGNAL = 85, + ZigLLVM_AVR_BUILTIN = 86, + ZigLLVM_AMDGPU_VS = 87, + ZigLLVM_AMDGPU_GS = 88, + ZigLLVM_AMDGPU_PS = 89, + ZigLLVM_AMDGPU_CS = 90, + ZigLLVM_AMDGPU_KERNEL = 91, + ZigLLVM_X86_RegCall = 92, + ZigLLVM_AMDGPU_HS = 93, + ZigLLVM_MSP430_BUILTIN = 94, + ZigLLVM_AMDGPU_LS = 95, + ZigLLVM_AMDGPU_ES = 96, + ZigLLVM_AArch64_VectorCall = 97, + ZigLLVM_MaxID = 1023, +}; + enum ZigLLVM_CallAttr { ZigLLVM_CallAttrAuto, ZigLLVM_CallAttrNeverTail, @@ -72,7 +120,7 @@ enum ZigLLVM_CallAttr { ZigLLVM_CallAttrAlwaysInline, }; ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, - unsigned NumArgs, unsigned CC, enum ZigLLVM_CallAttr attr, const char *Name); + unsigned NumArgs, enum ZigLLVM_CallingConv CC, enum ZigLLVM_CallAttr attr, const char *Name); ZIG_EXTERN_C LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile); @@ -215,6 +263,7 @@ ZIG_EXTERN_C struct ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigne ZIG_EXTERN_C void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state); ZIG_EXTERN_C void ZigLLVMSetTailCall(LLVMValueRef Call); ZIG_EXTERN_C void ZigLLVMFunctionSetPrefixData(LLVMValueRef fn, LLVMValueRef data); +ZIG_EXTERN_C void ZigLLVMFunctionSetCallingConv(LLVMValueRef function, enum ZigLLVM_CallingConv cc); ZIG_EXTERN_C void ZigLLVMAddFunctionAttr(LLVMValueRef fn, const char *attr_name, const char *attr_value); ZIG_EXTERN_C void ZigLLVMAddByValAttr(LLVMValueRef fn_ref, unsigned ArgNo, LLVMTypeRef type_val);