mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-27 01:40:03 +00:00
Merge remote-tracking branch 'offical/master'
This commit is contained in:
@@ -621,3 +621,7 @@ gb_internal String big_int_to_string(gbAllocator allocator, BigInt const *x, u64
|
||||
}
|
||||
return make_string(cast(u8 *)buf.data, buf.count);
|
||||
}
|
||||
|
||||
gb_internal int big_int_log2(BigInt const *x) {
|
||||
return mp_count_bits(x) - 1;
|
||||
}
|
||||
|
||||
+9
-1
@@ -155,7 +155,7 @@ gb_internal void report_windows_product_type(DWORD ProductType) {
|
||||
#endif
|
||||
|
||||
gb_internal void odin_cpuid(int leaf, int result[]) {
|
||||
#if defined(GB_CPU_ARM)
|
||||
#if defined(GB_CPU_ARM) || defined(GB_CPU_RISCV)
|
||||
return;
|
||||
|
||||
#elif defined(GB_CPU_X86)
|
||||
@@ -225,6 +225,12 @@ gb_internal void report_cpu_info() {
|
||||
gb_printf("ARM\n");
|
||||
#endif
|
||||
}
|
||||
#elif defined(GB_CPU_RISCV)
|
||||
#if defined(GB_ARCH_64_BIT)
|
||||
gb_printf("RISCV64\n");
|
||||
#else
|
||||
gb_printf("RISCV32\n");
|
||||
#endif
|
||||
#else
|
||||
gb_printf("Unknown\n");
|
||||
#endif
|
||||
@@ -911,6 +917,8 @@ gb_internal void report_os_info() {
|
||||
{"23E214", {23, 4, 0}, "macOS", {"Sonoma", {14, 4, 0}}},
|
||||
{"23E224", {23, 4, 0}, "macOS", {"Sonoma", {14, 4, 1}}},
|
||||
{"23F79", {23, 5, 0}, "macOS", {"Sonoma", {14, 5, 0}}},
|
||||
{"23G80", {23, 6, 0}, "macOS", {"Sonoma", {14, 6, 0}}},
|
||||
{"23G93", {23, 6, 0}, "macOS", {"Sonoma", {14, 6, 1}}},
|
||||
};
|
||||
|
||||
|
||||
|
||||
+55
-26
@@ -39,6 +39,7 @@ enum TargetArchKind : u16 {
|
||||
TargetArch_arm64,
|
||||
TargetArch_wasm32,
|
||||
TargetArch_wasm64p32,
|
||||
TargetArch_riscv64,
|
||||
|
||||
TargetArch_COUNT,
|
||||
};
|
||||
@@ -104,6 +105,7 @@ gb_global String target_arch_names[TargetArch_COUNT] = {
|
||||
str_lit("arm64"),
|
||||
str_lit("wasm32"),
|
||||
str_lit("wasm64p32"),
|
||||
str_lit("riscv64"),
|
||||
};
|
||||
|
||||
#include "build_settings_microarch.cpp"
|
||||
@@ -428,6 +430,7 @@ struct BuildContext {
|
||||
bool json_errors;
|
||||
bool has_ansi_terminal_colours;
|
||||
|
||||
bool fast_isel;
|
||||
bool ignore_lazy;
|
||||
bool ignore_llvm_build;
|
||||
bool ignore_panic;
|
||||
@@ -518,113 +521,123 @@ gb_internal isize MAX_ERROR_COLLECTOR_COUNT(void) {
|
||||
#define AMD64_MAX_ALIGNMENT 8
|
||||
#endif
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 18
|
||||
#define I386_MAX_ALIGNMENT 16
|
||||
#else
|
||||
#define I386_MAX_ALIGNMENT 4
|
||||
#endif
|
||||
|
||||
gb_global TargetMetrics target_windows_i386 = {
|
||||
TargetOs_windows,
|
||||
TargetArch_i386,
|
||||
4, 4, 4, 8,
|
||||
4, 4, I386_MAX_ALIGNMENT, 16,
|
||||
str_lit("i386-pc-windows-msvc"),
|
||||
};
|
||||
gb_global TargetMetrics target_windows_amd64 = {
|
||||
TargetOs_windows,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-pc-windows-msvc"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_linux_i386 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_i386,
|
||||
4, 4, 4, 8,
|
||||
4, 4, I386_MAX_ALIGNMENT, 16,
|
||||
str_lit("i386-pc-linux-gnu"),
|
||||
|
||||
};
|
||||
gb_global TargetMetrics target_linux_amd64 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-pc-linux-gnu"),
|
||||
};
|
||||
gb_global TargetMetrics target_linux_arm64 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16, 16,
|
||||
8, 8, 16, 32,
|
||||
str_lit("aarch64-linux-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_linux_arm32 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_arm32,
|
||||
4, 4, 4, 8,
|
||||
4, 4, 8, 16,
|
||||
str_lit("arm-unknown-linux-gnueabihf"),
|
||||
};
|
||||
gb_global TargetMetrics target_linux_riscv64 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_riscv64,
|
||||
8, 8, 16, 32,
|
||||
str_lit("riscv64-linux-gnu"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_darwin_amd64 = {
|
||||
TargetOs_darwin,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-apple-macosx"), // NOTE: Changes during initialization based on build flags.
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_darwin_arm64 = {
|
||||
TargetOs_darwin,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16, 16,
|
||||
8, 8, 16, 32,
|
||||
str_lit("arm64-apple-macosx"), // NOTE: Changes during initialization based on build flags.
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_freebsd_i386 = {
|
||||
TargetOs_freebsd,
|
||||
TargetArch_i386,
|
||||
4, 4, 4, 8,
|
||||
4, 4, I386_MAX_ALIGNMENT, 16,
|
||||
str_lit("i386-unknown-freebsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_freebsd_amd64 = {
|
||||
TargetOs_freebsd,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-unknown-freebsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_freebsd_arm64 = {
|
||||
TargetOs_freebsd,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16, 16,
|
||||
8, 8, 16, 32,
|
||||
str_lit("aarch64-unknown-freebsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_openbsd_amd64 = {
|
||||
TargetOs_openbsd,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-unknown-openbsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_netbsd_amd64 = {
|
||||
TargetOs_netbsd,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-unknown-netbsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_netbsd_arm64 = {
|
||||
TargetOs_netbsd,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16, 16,
|
||||
8, 8, 16, 32,
|
||||
str_lit("aarch64-unknown-netbsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_haiku_amd64 = {
|
||||
TargetOs_haiku,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-unknown-haiku"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_essence_amd64 = {
|
||||
TargetOs_essence,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-pc-none-elf"),
|
||||
};
|
||||
|
||||
@@ -685,7 +698,7 @@ gb_global TargetMetrics target_wasi_wasm64p32 = {
|
||||
gb_global TargetMetrics target_freestanding_amd64_sysv = {
|
||||
TargetOs_freestanding,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-pc-none-gnu"),
|
||||
TargetABI_SysV,
|
||||
};
|
||||
@@ -693,7 +706,7 @@ gb_global TargetMetrics target_freestanding_amd64_sysv = {
|
||||
gb_global TargetMetrics target_freestanding_amd64_win64 = {
|
||||
TargetOs_freestanding,
|
||||
TargetArch_amd64,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 16,
|
||||
8, 8, AMD64_MAX_ALIGNMENT, 32,
|
||||
str_lit("x86_64-pc-none-msvc"),
|
||||
TargetABI_Win64,
|
||||
};
|
||||
@@ -701,16 +714,22 @@ gb_global TargetMetrics target_freestanding_amd64_win64 = {
|
||||
gb_global TargetMetrics target_freestanding_arm64 = {
|
||||
TargetOs_freestanding,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16, 16,
|
||||
8, 8, 16, 32,
|
||||
str_lit("aarch64-none-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_freestanding_arm32 = {
|
||||
TargetOs_freestanding,
|
||||
TargetArch_arm32,
|
||||
4, 4, 4, 8,
|
||||
4, 4, 8, 16,
|
||||
str_lit("arm-unknown-unknown-gnueabihf"),
|
||||
};
|
||||
gb_global TargetMetrics target_freestanding_riscv64 = {
|
||||
TargetOs_freestanding,
|
||||
TargetArch_riscv64,
|
||||
8, 8, 16, 32,
|
||||
str_lit("riscv64-unknown-gnu"),
|
||||
};
|
||||
|
||||
|
||||
struct NamedTargetMetrics {
|
||||
@@ -728,6 +747,7 @@ gb_global NamedTargetMetrics named_targets[] = {
|
||||
{ str_lit("linux_amd64"), &target_linux_amd64 },
|
||||
{ str_lit("linux_arm64"), &target_linux_arm64 },
|
||||
{ str_lit("linux_arm32"), &target_linux_arm32 },
|
||||
{ str_lit("linux_riscv64"), &target_linux_riscv64 },
|
||||
|
||||
{ str_lit("windows_i386"), &target_windows_i386 },
|
||||
{ str_lit("windows_amd64"), &target_windows_amd64 },
|
||||
@@ -756,6 +776,8 @@ gb_global NamedTargetMetrics named_targets[] = {
|
||||
|
||||
{ str_lit("freestanding_arm64"), &target_freestanding_arm64 },
|
||||
{ str_lit("freestanding_arm32"), &target_freestanding_arm32 },
|
||||
|
||||
{ str_lit("freestanding_riscv64"), &target_freestanding_riscv64 },
|
||||
};
|
||||
|
||||
gb_global NamedTargetMetrics *selected_target_metrics;
|
||||
@@ -1504,6 +1526,8 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
metrics = &target_haiku_amd64;
|
||||
#elif defined(GB_CPU_ARM)
|
||||
metrics = &target_linux_arm64;
|
||||
#elif defined(GB_CPU_RISCV)
|
||||
metrics = &target_linux_riscv64;
|
||||
#else
|
||||
metrics = &target_linux_amd64;
|
||||
#endif
|
||||
@@ -1626,6 +1650,8 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta
|
||||
|
||||
// Disallow on wasm
|
||||
bc->use_separate_modules = false;
|
||||
} if(bc->metrics.arch == TargetArch_riscv64 && bc->cross_compiling) {
|
||||
bc->link_flags = str_lit("-target riscv64 ");
|
||||
} else {
|
||||
// NOTE: for targets other than darwin, we don't specify a `-target` link flag.
|
||||
// This is because we don't support cross-linking and clang is better at figuring
|
||||
@@ -2020,11 +2046,14 @@ gb_internal bool init_build_paths(String init_filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
gbFile output_file_test;
|
||||
gbFileError output_test_err = gb_file_open_mode(&output_file_test, gbFileMode_Append | gbFileMode_Rw, (const char*)output_file.text);
|
||||
defer (gb_file_close(&output_file_test));
|
||||
gbFile output_file_test;
|
||||
const char* output_file_name = (const char*)output_file.text;
|
||||
gbFileError output_test_err = gb_file_open_mode(&output_file_test, gbFileMode_Append | gbFileMode_Rw, output_file_name);
|
||||
|
||||
if (output_test_err != 0) {
|
||||
if (output_test_err == 0) {
|
||||
gb_file_close(&output_file_test);
|
||||
gb_file_remove(output_file_name);
|
||||
} else {
|
||||
String output_file = path_to_string(ha, bc->build_paths[BuildPath_Output]);
|
||||
defer (gb_free(ha, output_file.text));
|
||||
gb_printf_err("No write permissions for output path: %.*s\n", LIT(output_file));
|
||||
|
||||
@@ -3,17 +3,19 @@ gb_global String target_microarch_list[TargetArch_COUNT] = {
|
||||
// TargetArch_Invalid:
|
||||
str_lit(""),
|
||||
// TargetArch_amd64:
|
||||
str_lit("alderlake,amdfam10,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4"),
|
||||
str_lit("alderlake,amdfam10,arrowlake,arrowlake-s,arrowlake_s,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,clearwaterforest,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,gracemont,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,lunarlake,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,pantherlake,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4"),
|
||||
// TargetArch_i386:
|
||||
str_lit("alderlake,amdfam10,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4"),
|
||||
str_lit("alderlake,amdfam10,arrowlake,arrowlake-s,arrowlake_s,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,clearwaterforest,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,gracemont,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,lunarlake,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,pantherlake,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4"),
|
||||
// TargetArch_arm32:
|
||||
str_lit("arm1020e,arm1020t,arm1022e,arm10e,arm10tdmi,arm1136j-s,arm1136jf-s,arm1156t2-s,arm1156t2f-s,arm1176jz-s,arm1176jzf-s,arm710t,arm720t,arm7tdmi,arm7tdmi-s,arm8,arm810,arm9,arm920,arm920t,arm922t,arm926ej-s,arm940t,arm946e-s,arm966e-s,arm968e-s,arm9e,arm9tdmi,cortex-a12,cortex-a15,cortex-a17,cortex-a32,cortex-a35,cortex-a5,cortex-a53,cortex-a55,cortex-a57,cortex-a7,cortex-a710,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-a8,cortex-a9,cortex-m0,cortex-m0plus,cortex-m1,cortex-m23,cortex-m3,cortex-m33,cortex-m35p,cortex-m4,cortex-m55,cortex-m7,cortex-m85,cortex-r4,cortex-r4f,cortex-r5,cortex-r52,cortex-r7,cortex-r8,cortex-x1,cortex-x1c,cyclone,ep9312,exynos-m3,exynos-m4,exynos-m5,generic,iwmmxt,krait,kryo,mpcore,mpcorenovfp,neoverse-n1,neoverse-n2,neoverse-v1,sc000,sc300,strongarm,strongarm110,strongarm1100,strongarm1110,swift,xscale"),
|
||||
str_lit("arm1020e,arm1020t,arm1022e,arm10e,arm10tdmi,arm1136j-s,arm1136jf-s,arm1156t2-s,arm1156t2f-s,arm1176jz-s,arm1176jzf-s,arm710t,arm720t,arm7tdmi,arm7tdmi-s,arm8,arm810,arm9,arm920,arm920t,arm922t,arm926ej-s,arm940t,arm946e-s,arm966e-s,arm968e-s,arm9e,arm9tdmi,cortex-a12,cortex-a15,cortex-a17,cortex-a32,cortex-a35,cortex-a5,cortex-a53,cortex-a55,cortex-a57,cortex-a7,cortex-a710,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-a8,cortex-a9,cortex-m0,cortex-m0plus,cortex-m1,cortex-m23,cortex-m3,cortex-m33,cortex-m35p,cortex-m4,cortex-m52,cortex-m55,cortex-m7,cortex-m85,cortex-r4,cortex-r4f,cortex-r5,cortex-r52,cortex-r7,cortex-r8,cortex-x1,cortex-x1c,cyclone,ep9312,exynos-m3,exynos-m4,exynos-m5,generic,iwmmxt,krait,kryo,mpcore,mpcorenovfp,neoverse-n1,neoverse-n2,neoverse-v1,sc000,sc300,strongarm,strongarm110,strongarm1100,strongarm1110,swift,xscale"),
|
||||
// TargetArch_arm64:
|
||||
str_lit("a64fx,ampere1,ampere1a,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a8,apple-a9,apple-latest,apple-m1,apple-m2,apple-s4,apple-s5,carmel,cortex-a34,cortex-a35,cortex-a510,cortex-a53,cortex-a55,cortex-a57,cortex-a65,cortex-a65ae,cortex-a710,cortex-a715,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-r82,cortex-x1,cortex-x1c,cortex-x2,cortex-x3,cyclone,exynos-m3,exynos-m4,exynos-m5,falkor,generic,kryo,neoverse-512tvb,neoverse-e1,neoverse-n1,neoverse-n2,neoverse-v1,neoverse-v2,saphira,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tsv110"),
|
||||
str_lit("a64fx,ampere1,ampere1a,ampere1b,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a17,apple-a7,apple-a8,apple-a9,apple-latest,apple-m1,apple-m2,apple-m3,apple-s4,apple-s5,carmel,cortex-a34,cortex-a35,cortex-a510,cortex-a520,cortex-a53,cortex-a55,cortex-a57,cortex-a65,cortex-a65ae,cortex-a710,cortex-a715,cortex-a72,cortex-a720,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-r82,cortex-x1,cortex-x1c,cortex-x2,cortex-x3,cortex-x4,cyclone,exynos-m3,exynos-m4,exynos-m5,falkor,generic,kryo,neoverse-512tvb,neoverse-e1,neoverse-n1,neoverse-n2,neoverse-v1,neoverse-v2,saphira,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tsv110"),
|
||||
// TargetArch_wasm32:
|
||||
str_lit("bleeding-edge,generic,mvp"),
|
||||
// TargetArch_wasm64p32:
|
||||
str_lit("bleeding-edge,generic,mvp"),
|
||||
// TargetArch_riscv64:
|
||||
str_lit("generic,generic-rv32,generic-rv64,rocket,rocket-rv32,rocket-rv64,sifive-7-series,sifive-e20,sifive-e21,sifive-e24,sifive-e31,sifive-e34,sifive-e76,sifive-p450,sifive-p670,sifive-s21,sifive-s51,sifive-s54,sifive-s76,sifive-u54,sifive-u74,sifive-x280,syntacore-scr1-base,syntacore-scr1-max,veyron-v1,xiangshan-nanhu"),
|
||||
};
|
||||
|
||||
// Generated with the featuregen script in `misc/featuregen`
|
||||
@@ -21,17 +23,19 @@ gb_global String target_features_list[TargetArch_COUNT] = {
|
||||
// TargetArch_Invalid:
|
||||
str_lit(""),
|
||||
// TargetArch_amd64:
|
||||
str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-gather,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"),
|
||||
str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx10.1-256,avx10.1-512,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,ccmp,cf,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,egpr,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-gather,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,ndd,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,ppx,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,push2pop2,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"),
|
||||
// TargetArch_i386:
|
||||
str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-gather,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"),
|
||||
str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx10.1-256,avx10.1-512,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,ccmp,cf,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,egpr,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-gather,fast-hops,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,ndd,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,ppx,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,push2pop2,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"),
|
||||
// TargetArch_arm32:
|
||||
str_lit("32bit,8msecext,a12,a15,a17,a32,a35,a5,a53,a55,a57,a7,a72,a73,a75,a76,a77,a78c,a8,a9,aapcs-frame-chain,aapcs-frame-chain-leaf,aclass,acquire-release,aes,armv4,armv4t,armv5t,armv5te,armv5tej,armv6,armv6-m,armv6j,armv6k,armv6kz,armv6s-m,armv6t2,armv7-a,armv7-m,armv7-r,armv7e-m,armv7k,armv7s,armv7ve,armv8-a,armv8-m.base,armv8-m.main,armv8-r,armv8.1-a,armv8.1-m.main,armv8.2-a,armv8.3-a,armv8.4-a,armv8.5-a,armv8.6-a,armv8.7-a,armv8.8-a,armv8.9-a,armv9-a,armv9.1-a,armv9.2-a,armv9.3-a,armv9.4-a,atomics-32,avoid-movs-shop,avoid-partial-cpsr,bf16,big-endian-instructions,cde,cdecp0,cdecp1,cdecp2,cdecp3,cdecp4,cdecp5,cdecp6,cdecp7,cheap-predicable-cpsr,clrbhb,cortex-a710,cortex-a78,cortex-x1,cortex-x1c,crc,crypto,d32,db,dfb,disable-postra-scheduler,dont-widen-vmovs,dotprod,dsp,execute-only,expand-fp-mlx,exynos,fix-cmse-cve-2021-35465,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpao,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hwdiv,hwdiv-arm,i8mm,iwmmxt,iwmmxt2,krait,kryo,lob,long-calls,loop-align,m3,m7,mclass,mp,muxed-units,mve,mve.fp,mve1beat,mve2beat,mve4beat,nacl-trap,neon,neon-fpmovs,neonfp,neoverse-v1,no-branch-predictor,no-bti-at-return-twice,no-movt,no-neg-immediates,noarm,nonpipelined-vfp,pacbti,perfmon,prefer-ishst,prefer-vmovsr,prof-unpr,r4,r5,r52,r7,ras,rclass,read-tp-tpidrprw,read-tp-tpidruro,read-tp-tpidrurw,reserve-r9,ret-addr-stack,sb,sha2,slow-fp-brcc,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,soft-float,splat-vfp-neon,strict-align,swift,thumb-mode,thumb2,trustzone,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.1m.main,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8m,v8m.main,v9.1a,v9.2a,v9.3a,v9.4a,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align,vmlx-forwarding,vmlx-hazards,wide-stride-vfp,xscale,zcz"),
|
||||
str_lit("32bit,8msecext,a12,a15,a17,a32,a35,a5,a53,a55,a57,a7,a72,a73,a75,a76,a77,a78c,a8,a9,aapcs-frame-chain,aapcs-frame-chain-leaf,aclass,acquire-release,aes,armv4,armv4t,armv5t,armv5te,armv5tej,armv6,armv6-m,armv6j,armv6k,armv6kz,armv6s-m,armv6t2,armv7-a,armv7-m,armv7-r,armv7e-m,armv7k,armv7s,armv7ve,armv8-a,armv8-m.base,armv8-m.main,armv8-r,armv8.1-a,armv8.1-m.main,armv8.2-a,armv8.3-a,armv8.4-a,armv8.5-a,armv8.6-a,armv8.7-a,armv8.8-a,armv8.9-a,armv9-a,armv9.1-a,armv9.2-a,armv9.3-a,armv9.4-a,armv9.5-a,atomics-32,avoid-movs-shop,avoid-partial-cpsr,bf16,big-endian-instructions,cde,cdecp0,cdecp1,cdecp2,cdecp3,cdecp4,cdecp5,cdecp6,cdecp7,cheap-predicable-cpsr,clrbhb,cortex-a710,cortex-a78,cortex-x1,cortex-x1c,crc,crypto,d32,db,dfb,disable-postra-scheduler,dont-widen-vmovs,dotprod,dsp,execute-only,expand-fp-mlx,exynos,fix-cmse-cve-2021-35465,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpao,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hwdiv,hwdiv-arm,i8mm,iwmmxt,iwmmxt2,krait,kryo,lob,long-calls,loop-align,m3,m7,mclass,mp,muxed-units,mve,mve.fp,mve1beat,mve2beat,mve4beat,nacl-trap,neon,neon-fpmovs,neonfp,neoverse-v1,no-branch-predictor,no-bti-at-return-twice,no-movt,no-neg-immediates,noarm,nonpipelined-vfp,pacbti,perfmon,prefer-ishst,prefer-vmovsr,prof-unpr,r4,r5,r52,r7,ras,rclass,read-tp-tpidrprw,read-tp-tpidruro,read-tp-tpidrurw,reserve-r9,ret-addr-stack,sb,sha2,slow-fp-brcc,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,soft-float,splat-vfp-neon,strict-align,swift,thumb-mode,thumb2,trustzone,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.1m.main,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8m,v8m.main,v9.1a,v9.2a,v9.3a,v9.4a,v9.5a,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align,vmlx-forwarding,vmlx-hazards,wide-stride-vfp,xscale,zcz"),
|
||||
// TargetArch_arm64:
|
||||
str_lit("CONTEXTIDREL2,a35,a510,a53,a55,a57,a64fx,a65,a710,a715,a72,a73,a75,a76,a77,a78,a78c,aes,aggressive-fma,all,alternate-sextload-cvt-f32-pattern,altnzcv,am,ampere1,ampere1a,amvs,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,ascend-store-address,b16b16,balance-fp-ops,bf16,brbe,bti,call-saved-x10,call-saved-x11,call-saved-x12,call-saved-x13,call-saved-x14,call-saved-x15,call-saved-x18,call-saved-x8,call-saved-x9,carmel,ccdp,ccidx,ccpp,chk,clrbhb,cmp-bcc-fusion,complxnum,cortex-r82,cortex-x1,cortex-x2,cortex-x3,crc,crypto,cssc,custom-cheap-as-move,d128,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,exynos-cheap-as-move,exynosm3,exynosm4,f32mm,f64mm,falkor,fgt,fix-cortex-a53-835769,flagm,fmv,force-32bit-jump-tables,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-addsub-2reg-const1,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,gcs,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hbc,hcx,i8mm,ite,jsconv,kryo,lor,ls64,lse,lse128,lse2,lsl-fast,mec,mops,mpam,mte,neon,neoverse512tvb,neoversee1,neoversen1,neoversen2,neoversev1,neoversev2,nmi,no-bti-at-return-twice,no-neg-immediates,no-sve-fp-ld1r,no-zcz-fp,nv,outline-atomics,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,prfm-slc-target,rand,ras,rasv2,rcpc,rcpc-immo,rcpc3,rdm,reserve-x1,reserve-x10,reserve-x11,reserve-x12,reserve-x13,reserve-x14,reserve-x15,reserve-x18,reserve-x2,reserve-x20,reserve-x21,reserve-x22,reserve-x23,reserve-x24,reserve-x25,reserve-x26,reserve-x27,reserve-x28,reserve-x3,reserve-x30,reserve-x4,reserve-x5,reserve-x6,reserve-x7,reserve-x9,rme,saphira,sb,sel2,sha2,sha3,slow-misaligned-128store,slow-paired-128,slow-strqro-store,sm4,sme,sme-f16f16,sme-f64f64,sme-i16i64,sme2,sme2p1,spe,spe-eef,specres2,specrestrict,ssbs,strict-align,sve,sve2,sve2-aes,sve2-bitperm,sve2-sha3,sve2-sm4,sve2p1,tagged-globals,the,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tlb-rmi,tme,tpidr-el1,tpidr-el2,tpidr-el3,tpidrro-el0,tracev8.4,trbe,tsv110,uaops,use-experimental-zeroing-pseudos,use-postra-scheduler,use-reciprocal-square-root,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8a,v8r,v9.1a,v9.2a,v9.3a,v9.4a,v9a,vh,wfxt,xs,zcm,zcz,zcz-fp-workaround,zcz-gp"),
|
||||
str_lit("CONTEXTIDREL2,a35,a510,a520,a53,a55,a57,a64fx,a65,a710,a715,a72,a720,a73,a75,a76,a77,a78,a78c,addr-lsl-fast,aes,aggressive-fma,all,alternate-sextload-cvt-f32-pattern,altnzcv,alu-lsl-fast,am,ampere1,ampere1a,ampere1b,amvs,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a17,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,ascend-store-address,b16b16,balance-fp-ops,bf16,brbe,bti,call-saved-x10,call-saved-x11,call-saved-x12,call-saved-x13,call-saved-x14,call-saved-x15,call-saved-x18,call-saved-x8,call-saved-x9,carmel,ccdp,ccidx,ccpp,chk,clrbhb,cmp-bcc-fusion,complxnum,cortex-r82,cortex-x1,cortex-x2,cortex-x3,cortex-x4,cpa,crc,crypto,cssc,d128,disable-latency-sched-heuristic,disable-ldp,disable-stp,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,exynos-cheap-as-move,exynosm3,exynosm4,f32mm,f64mm,falkor,faminmax,fgt,fix-cortex-a53-835769,flagm,fmv,force-32bit-jump-tables,fp-armv8,fp16fml,fp8,fp8dot2,fp8dot4,fp8fma,fpmr,fptoint,fullfp16,fuse-address,fuse-addsub-2reg-const1,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,gcs,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hbc,hcx,i8mm,ite,jsconv,kryo,ldp-aligned-only,lor,ls64,lse,lse128,lse2,lut,mec,mops,mpam,mte,neon,neoverse512tvb,neoversee1,neoversen1,neoversen2,neoversev1,neoversev2,nmi,no-bti-at-return-twice,no-neg-immediates,no-sve-fp-ld1r,no-zcz-fp,nv,outline-atomics,pan,pan-rwv,pauth,pauth-lr,perfmon,predictable-select-expensive,predres,prfm-slc-target,rand,ras,rasv2,rcpc,rcpc-immo,rcpc3,rdm,reserve-x1,reserve-x10,reserve-x11,reserve-x12,reserve-x13,reserve-x14,reserve-x15,reserve-x18,reserve-x2,reserve-x20,reserve-x21,reserve-x22,reserve-x23,reserve-x24,reserve-x25,reserve-x26,reserve-x27,reserve-x28,reserve-x3,reserve-x30,reserve-x4,reserve-x5,reserve-x6,reserve-x7,reserve-x9,rme,saphira,sb,sel2,sha2,sha3,slow-misaligned-128store,slow-paired-128,slow-strqro-store,sm4,sme,sme-f16f16,sme-f64f64,sme-f8f16,sme-f8f32,sme-fa64,sme-i16i64,sme-lutv2,sme2,sme2p1,spe,spe-eef,specres2,specrestrict,ssbs,ssve-fp8dot2,ssve-fp8dot4,ssve-fp8fma,store-pair-suppress,stp-aligned-only,strict-align,sve,sve2,sve2-aes,sve2-bitperm,sve2-sha3,sve2-sm4,sve2p1,tagged-globals,the,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tlb-rmi,tlbiw,tme,tpidr-el1,tpidr-el2,tpidr-el3,tpidrro-el0,tracev8.4,trbe,tsv110,uaops,use-experimental-zeroing-pseudos,use-postra-scheduler,use-reciprocal-square-root,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8a,v8r,v9.1a,v9.2a,v9.3a,v9.4a,v9.5a,v9a,vh,wfxt,xs,zcm,zcz,zcz-fp-workaround,zcz-gp"),
|
||||
// TargetArch_wasm32:
|
||||
str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"),
|
||||
str_lit("atomics,bulk-memory,exception-handling,extended-const,multimemory,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"),
|
||||
// TargetArch_wasm64p32:
|
||||
str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"),
|
||||
str_lit("atomics,bulk-memory,exception-handling,extended-const,multimemory,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"),
|
||||
// TargetArch_riscv64:
|
||||
str_lit("32bit,64bit,a,auipc-addi-fusion,c,conditional-cmv-fusion,d,dlen-factor-2,e,experimental,experimental-zacas,experimental-zcmop,experimental-zfbfmin,experimental-zicfilp,experimental-zicfiss,experimental-zimop,experimental-ztso,experimental-zvfbfmin,experimental-zvfbfwma,f,fast-unaligned-access,forced-atomics,h,i,ld-add-fusion,lui-addi-fusion,m,no-default-unroll,no-optimized-zero-stride-load,no-rvc-hints,relax,reserve-x1,reserve-x10,reserve-x11,reserve-x12,reserve-x13,reserve-x14,reserve-x15,reserve-x16,reserve-x17,reserve-x18,reserve-x19,reserve-x2,reserve-x20,reserve-x21,reserve-x22,reserve-x23,reserve-x24,reserve-x25,reserve-x26,reserve-x27,reserve-x28,reserve-x29,reserve-x3,reserve-x30,reserve-x31,reserve-x4,reserve-x5,reserve-x6,reserve-x7,reserve-x8,reserve-x9,save-restore,seq-cst-trailing-fence,shifted-zextw-fusion,short-forward-branch-opt,sifive7,smaia,smepmp,ssaia,svinval,svnapot,svpbmt,tagged-globals,unaligned-scalar-mem,use-postra-scheduler,v,ventana-veyron,xcvalu,xcvbi,xcvbitmanip,xcvelw,xcvmac,xcvmem,xcvsimd,xsfvcp,xsfvfnrclipxfqf,xsfvfwmaccqqq,xsfvqmaccdod,xsfvqmaccqoq,xtheadba,xtheadbb,xtheadbs,xtheadcmo,xtheadcondmov,xtheadfmemidx,xtheadmac,xtheadmemidx,xtheadmempair,xtheadsync,xtheadvdot,xventanacondops,za128rs,za64rs,zawrs,zba,zbb,zbc,zbkb,zbkc,zbkx,zbs,zca,zcb,zcd,zce,zcf,zcmp,zcmt,zdinx,zexth-fusion,zextw-fusion,zfa,zfh,zfhmin,zfinx,zhinx,zhinxmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicntr,zicond,zicsr,zifencei,zihintntl,zihintpause,zihpm,zk,zkn,zknd,zkne,zknh,zkr,zks,zksed,zksh,zkt,zmmul,zvbb,zvbc,zve32f,zve32x,zve64d,zve64f,zve64x,zvfh,zvfhmin,zvkb,zvkg,zvkn,zvknc,zvkned,zvkng,zvknha,zvknhb,zvks,zvksc,zvksed,zvksg,zvksh,zvkt,zvl1024b,zvl128b,zvl16384b,zvl2048b,zvl256b,zvl32768b,zvl32b,zvl4096b,zvl512b,zvl64b,zvl65536b,zvl8192b"),
|
||||
};
|
||||
|
||||
// Generated with the featuregen script in `misc/featuregen`
|
||||
@@ -39,17 +43,19 @@ gb_global int target_microarch_counts[TargetArch_COUNT] = {
|
||||
// TargetArch_Invalid:
|
||||
0,
|
||||
// TargetArch_amd64:
|
||||
120,
|
||||
127,
|
||||
// TargetArch_i386:
|
||||
120,
|
||||
127,
|
||||
// TargetArch_arm32:
|
||||
90,
|
||||
91,
|
||||
// TargetArch_arm64:
|
||||
63,
|
||||
69,
|
||||
// TargetArch_wasm32:
|
||||
3,
|
||||
// TargetArch_wasm64p32:
|
||||
3,
|
||||
// TargetArch_riscv64:
|
||||
26,
|
||||
};
|
||||
|
||||
// Generated with the featuregen script in `misc/featuregen`
|
||||
@@ -57,6 +63,9 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
// TargetArch_amd64:
|
||||
{ str_lit("alderlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("amdfam10"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") },
|
||||
{ str_lit("arrowlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("arrowlake-s"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("arrowlake_s"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("athlon"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
{ str_lit("athlon-4"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
{ str_lit("athlon-fx"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
@@ -81,6 +90,7 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("c3-2"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
{ str_lit("cannonlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vl,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,sha,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("cascadelake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("clearwaterforest"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("cooperlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("core-avx-i"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") },
|
||||
{ str_lit("core-avx2"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") },
|
||||
@@ -103,6 +113,7 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("goldmont"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("goldmont-plus"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("goldmont_plus"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("gracemont"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("grandridge"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("graniterapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("graniterapids-d"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
@@ -125,12 +136,14 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("knl"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") },
|
||||
{ str_lit("knm"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") },
|
||||
{ str_lit("lakemont"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper") },
|
||||
{ str_lit("lunarlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("meteorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("mic_avx512"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") },
|
||||
{ str_lit("nehalem"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") },
|
||||
{ str_lit("nocona"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") },
|
||||
{ str_lit("opteron"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
{ str_lit("opteron-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") },
|
||||
{ str_lit("pantherlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("penryn"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") },
|
||||
{ str_lit("pentium"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
{ str_lit("pentium-m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
@@ -178,6 +191,9 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
// TargetArch_i386:
|
||||
{ str_lit("alderlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("amdfam10"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") },
|
||||
{ str_lit("arrowlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("arrowlake-s"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("arrowlake_s"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("athlon"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") },
|
||||
{ str_lit("athlon-4"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") },
|
||||
{ str_lit("athlon-fx"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
@@ -202,6 +218,7 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("c3-2"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,slow-unaligned-mem-16,sse,vzeroupper,x87") },
|
||||
{ str_lit("cannonlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vl,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,sha,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("cascadelake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("clearwaterforest"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("cooperlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("core-avx-i"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") },
|
||||
{ str_lit("core-avx2"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") },
|
||||
@@ -224,6 +241,7 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("goldmont"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("goldmont-plus"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("goldmont_plus"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("gracemont"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivl-to-divb,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("grandridge"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("graniterapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("graniterapids-d"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
@@ -246,12 +264,14 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("knl"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") },
|
||||
{ str_lit("knm"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") },
|
||||
{ str_lit("lakemont"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper") },
|
||||
{ str_lit("lunarlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("meteorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("mic_avx512"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") },
|
||||
{ str_lit("nehalem"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") },
|
||||
{ str_lit("nocona"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") },
|
||||
{ str_lit("opteron"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
{ str_lit("opteron-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") },
|
||||
{ str_lit("pantherlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") },
|
||||
{ str_lit("penryn"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") },
|
||||
{ str_lit("pentium"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper,x87") },
|
||||
{ str_lit("pentium-m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") },
|
||||
@@ -325,16 +345,16 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("arm968e-s"), str_lit("armv5te,v4t,v5t,v5te") },
|
||||
{ str_lit("arm9e"), str_lit("armv5te,v4t,v5t,v5te") },
|
||||
{ str_lit("arm9tdmi"), str_lit("armv4t,v4t") },
|
||||
{ str_lit("cortex-a12"), str_lit("a12,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") },
|
||||
{ str_lit("cortex-a15"), str_lit("a15,aclass,armv7-a,avoid-partial-cpsr,d32,db,dont-widen-vmovs,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,muxed-units,neon,perfmon,ret-addr-stack,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align") },
|
||||
{ str_lit("cortex-a17"), str_lit("a17,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") },
|
||||
{ str_lit("cortex-a12"), str_lit("a12,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") },
|
||||
{ str_lit("cortex-a15"), str_lit("a15,aclass,armv7-a,avoid-partial-cpsr,d32,db,dont-widen-vmovs,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,muxed-units,perfmon,ret-addr-stack,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align") },
|
||||
{ str_lit("cortex-a17"), str_lit("a17,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") },
|
||||
{ str_lit("cortex-a32"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a35"), str_lit("a35,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a5"), str_lit("a5,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,mp,neon,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-forwarding") },
|
||||
{ str_lit("cortex-a5"), str_lit("a5,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,mp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-forwarding") },
|
||||
{ str_lit("cortex-a53"), str_lit("a53,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a55"), str_lit("a55,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a57"), str_lit("a57,aclass,acquire-release,aes,armv8-a,avoid-partial-cpsr,cheap-predicable-cpsr,crc,crypto,d32,db,dsp,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a7"), str_lit("a7,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding,vmlx-hazards") },
|
||||
{ str_lit("cortex-a7"), str_lit("a7,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding,vmlx-hazards") },
|
||||
{ str_lit("cortex-a710"), str_lit("aclass,acquire-release,armv9-a,bf16,cortex-a710,crc,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sb,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8m,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a72"), str_lit("a72,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a73"), str_lit("a73,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
@@ -344,8 +364,8 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("cortex-a77"), str_lit("a77,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a78"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-a78,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a78c"), str_lit("a78c,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("cortex-a8"), str_lit("a8,aclass,armv7-a,d32,db,dsp,fp64,fpregs,fpregs64,neon,nonpipelined-vfp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vmlx-forwarding,vmlx-hazards") },
|
||||
{ str_lit("cortex-a9"), str_lit("a9,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,expand-fp-mlx,fp16,fp64,fpregs,fpregs64,mp,muxed-units,neon,neon-fpmovs,perfmon,prefer-vmovsr,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vldn-align,vmlx-forwarding,vmlx-hazards") },
|
||||
{ str_lit("cortex-a8"), str_lit("a8,aclass,armv7-a,d32,db,dsp,fp64,fpregs,fpregs64,nonpipelined-vfp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vmlx-forwarding,vmlx-hazards") },
|
||||
{ str_lit("cortex-a9"), str_lit("a9,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,expand-fp-mlx,fp16,fp64,fpregs,fpregs64,mp,muxed-units,neon-fpmovs,perfmon,prefer-vmovsr,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vldn-align,vmlx-forwarding,vmlx-hazards") },
|
||||
{ str_lit("cortex-m0"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") },
|
||||
{ str_lit("cortex-m0plus"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") },
|
||||
{ str_lit("cortex-m1"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") },
|
||||
@@ -354,6 +374,7 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("cortex-m33"), str_lit("8msecext,acquire-release,armv8-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") },
|
||||
{ str_lit("cortex-m35p"), str_lit("8msecext,acquire-release,armv8-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") },
|
||||
{ str_lit("cortex-m4"), str_lit("armv7e-m,db,dsp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2sp,vfp3d16sp,vfp4d16sp") },
|
||||
{ str_lit("cortex-m52"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,loop-align,mclass,mve,mve.fp,mve1beat,no-branch-predictor,noarm,pacbti,ras,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") },
|
||||
{ str_lit("cortex-m55"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,loop-align,mclass,mve,mve.fp,no-branch-predictor,noarm,ras,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") },
|
||||
{ str_lit("cortex-m7"), str_lit("armv7e-m,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs64,hwdiv,m7,mclass,noarm,thumb-mode,thumb2,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") },
|
||||
{ str_lit("cortex-m85"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,mclass,mve,mve.fp,noarm,pacbti,ras,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") },
|
||||
@@ -372,7 +393,7 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("exynos-m5"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dont-widen-vmovs,dotprod,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ras,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") },
|
||||
{ str_lit("generic"), str_lit("") },
|
||||
{ str_lit("iwmmxt"), str_lit("armv5te,v4t,v5t,v5te") },
|
||||
{ str_lit("krait"), str_lit("aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,krait,muxed-units,neon,perfmon,ret-addr-stack,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vldn-align,vmlx-forwarding") },
|
||||
{ str_lit("krait"), str_lit("aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,krait,muxed-units,perfmon,ret-addr-stack,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vldn-align,vmlx-forwarding") },
|
||||
{ str_lit("kryo"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,kryo,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") },
|
||||
{ str_lit("mpcore"), str_lit("armv6k,fp64,fpregs,fpregs64,slowfpvmlx,v4t,v5t,v5te,v6,v6k,vfp2,vfp2sp") },
|
||||
{ str_lit("mpcorenovfp"), str_lit("armv6k,v4t,v5t,v5te,v6,v6k") },
|
||||
@@ -385,12 +406,13 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("strongarm110"), str_lit("armv4") },
|
||||
{ str_lit("strongarm1100"), str_lit("armv4") },
|
||||
{ str_lit("strongarm1110"), str_lit("armv4") },
|
||||
{ str_lit("swift"), str_lit("aclass,armv7-a,avoid-movs-shop,avoid-partial-cpsr,d32,db,disable-postra-scheduler,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,neonfp,perfmon,prefer-ishst,prof-unpr,ret-addr-stack,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,swift,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-hazards,wide-stride-vfp") },
|
||||
{ str_lit("swift"), str_lit("aclass,armv7-a,avoid-movs-shop,avoid-partial-cpsr,d32,db,disable-postra-scheduler,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neonfp,perfmon,prefer-ishst,prof-unpr,ret-addr-stack,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,swift,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-hazards,wide-stride-vfp") },
|
||||
{ str_lit("xscale"), str_lit("armv5te,v4t,v5t,v5te") },
|
||||
// TargetArch_arm64:
|
||||
{ str_lit("a64fx"), str_lit("CONTEXTIDREL2,a64fx,aggressive-fma,arith-bcc-fusion,ccpp,complxnum,crc,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rdm,sha2,store-pair-suppress,sve,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") },
|
||||
{ str_lit("ampere1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fptoint,fuse-address,fuse-aes,fuse-literals,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") },
|
||||
{ str_lit("ampere1a"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1a,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fptoint,fuse-address,fuse-aes,fuse-literals,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") },
|
||||
{ str_lit("ampere1b"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1b,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,cssc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,fgt,flagm,fp-armv8,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,hcx,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,vh,wfxt,xs") },
|
||||
{ str_lit("apple-a10"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a10,arith-bcc-fusion,arith-cbz-fusion,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,lor,neon,pan,perfmon,rdm,sha2,store-pair-suppress,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-a11"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a11,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-a12"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
@@ -398,18 +420,21 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("apple-a14"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,alternate-sextload-cvt-f32-pattern,altnzcv,am,apple-a14,arith-bcc-fusion,arith-cbz-fusion,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-a15"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a15,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-a16"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-a17"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a17,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-a7"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") },
|
||||
{ str_lit("apple-a8"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") },
|
||||
{ str_lit("apple-a9"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") },
|
||||
{ str_lit("apple-latest"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-m1"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,alternate-sextload-cvt-f32-pattern,altnzcv,am,apple-a14,arith-bcc-fusion,arith-cbz-fusion,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-m2"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a15,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-m3"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-s4"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("apple-s5"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm,zcz,zcz-gp") },
|
||||
{ str_lit("carmel"), str_lit("CONTEXTIDREL2,aes,carmel,ccpp,crc,crypto,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,ras,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") },
|
||||
{ str_lit("cortex-a34"), str_lit("a35,aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") },
|
||||
{ str_lit("cortex-a35"), str_lit("a35,aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") },
|
||||
{ str_lit("cortex-a510"), str_lit("CONTEXTIDREL2,a510,altnzcv,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") },
|
||||
{ str_lit("cortex-a520"), str_lit("CONTEXTIDREL2,a520,altnzcv,am,amvs,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,ete,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") },
|
||||
{ str_lit("cortex-a53"), str_lit("a53,aes,balance-fp-ops,crc,crypto,el2vmsa,el3,fp-armv8,fuse-adrp-add,fuse-aes,neon,perfmon,sha2,use-postra-scheduler,v8a") },
|
||||
{ str_lit("cortex-a55"), str_lit("CONTEXTIDREL2,a55,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,ras,rcpc,rdm,sha2,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") },
|
||||
{ str_lit("cortex-a57"), str_lit("a57,aes,balance-fp-ops,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,use-postra-scheduler,v8a") },
|
||||
@@ -418,6 +443,7 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("cortex-a710"), str_lit("CONTEXTIDREL2,a710,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") },
|
||||
{ str_lit("cortex-a715"), str_lit("CONTEXTIDREL2,a715,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") },
|
||||
{ str_lit("cortex-a72"), str_lit("a72,aes,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,v8a") },
|
||||
{ str_lit("cortex-a720"), str_lit("CONTEXTIDREL2,a720,addr-lsl-fast,altnzcv,alu-lsl-fast,am,amvs,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") },
|
||||
{ str_lit("cortex-a73"), str_lit("a73,aes,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,neon,perfmon,predictable-select-expensive,sha2,v8a") },
|
||||
{ str_lit("cortex-a75"), str_lit("CONTEXTIDREL2,a75,aes,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") },
|
||||
{ str_lit("cortex-a76"), str_lit("CONTEXTIDREL2,a76,addr-lsl-fast,aes,alu-lsl-fast,ccpp,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") },
|
||||
@@ -430,6 +456,7 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("cortex-x1c"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,lse2,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rcpc-immo,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") },
|
||||
{ str_lit("cortex-x2"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,cortex-x2,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") },
|
||||
{ str_lit("cortex-x3"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x3,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") },
|
||||
{ str_lit("cortex-x4"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,amvs,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x4,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") },
|
||||
{ str_lit("cyclone"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") },
|
||||
{ str_lit("exynos-m3"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,el2vmsa,el3,exynos-cheap-as-move,exynosm3,force-32bit-jump-tables,fp-armv8,fuse-address,fuse-adrp-add,fuse-aes,fuse-csel,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,use-postra-scheduler,v8a") },
|
||||
{ str_lit("exynos-m4"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,dotprod,el2vmsa,el3,exynos-cheap-as-move,exynosm4,force-32bit-jump-tables,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-csel,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh,zcz,zcz-gp") },
|
||||
@@ -459,4 +486,31 @@ gb_global MicroarchFeatureList microarch_features_list[] = {
|
||||
{ str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") },
|
||||
{ str_lit("generic"), str_lit("mutable-globals,sign-ext") },
|
||||
{ str_lit("mvp"), str_lit("") },
|
||||
};
|
||||
// TargetArch_riscv64:
|
||||
{ str_lit("generic"), str_lit("64bit") },
|
||||
{ str_lit("generic-rv32"), str_lit("32bit") },
|
||||
{ str_lit("generic-rv64"), str_lit("64bit") },
|
||||
{ str_lit("rocket"), str_lit("") },
|
||||
{ str_lit("rocket-rv32"), str_lit("32bit,zicsr,zifencei") },
|
||||
{ str_lit("rocket-rv64"), str_lit("64bit,zicsr,zifencei") },
|
||||
{ str_lit("sifive-7-series"), str_lit("no-default-unroll,short-forward-branch-opt,sifive7") },
|
||||
{ str_lit("sifive-e20"), str_lit("32bit,c,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-e21"), str_lit("32bit,a,c,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-e24"), str_lit("32bit,a,c,f,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-e31"), str_lit("32bit,a,c,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-e34"), str_lit("32bit,a,c,f,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-e76"), str_lit("32bit,a,c,f,m,no-default-unroll,short-forward-branch-opt,sifive7,zicsr,zifencei") },
|
||||
{ str_lit("sifive-p450"), str_lit("64bit,a,auipc-addi-fusion,c,conditional-cmv-fusion,d,f,fast-unaligned-access,lui-addi-fusion,m,no-default-unroll,za64rs,zba,zbb,zbs,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicsr,zifencei,zihintntl,zihintpause,zihpm") },
|
||||
{ str_lit("sifive-p670"), str_lit("64bit,a,auipc-addi-fusion,c,conditional-cmv-fusion,d,f,fast-unaligned-access,lui-addi-fusion,m,no-default-unroll,v,za64rs,zba,zbb,zbs,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicsr,zifencei,zihintntl,zihintpause,zihpm,zvbb,zvbc,zve32f,zve32x,zve64d,zve64f,zve64x,zvkb,zvkg,zvkn,zvknc,zvkned,zvkng,zvknhb,zvks,zvksc,zvksed,zvksg,zvksh,zvkt,zvl128b,zvl32b,zvl64b") },
|
||||
{ str_lit("sifive-s21"), str_lit("64bit,a,c,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-s51"), str_lit("64bit,a,c,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-s54"), str_lit("64bit,a,c,d,f,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-s76"), str_lit("64bit,a,c,d,f,m,no-default-unroll,short-forward-branch-opt,sifive7,zicsr,zifencei,zihintpause") },
|
||||
{ str_lit("sifive-u54"), str_lit("64bit,a,c,d,f,m,zicsr,zifencei") },
|
||||
{ str_lit("sifive-u74"), str_lit("64bit,a,c,d,f,m,no-default-unroll,short-forward-branch-opt,sifive7,zicsr,zifencei") },
|
||||
{ str_lit("sifive-x280"), str_lit("64bit,a,c,d,dlen-factor-2,f,m,no-default-unroll,short-forward-branch-opt,sifive7,v,zba,zbb,zfh,zfhmin,zicsr,zifencei,zve32f,zve32x,zve64d,zve64f,zve64x,zvfh,zvfhmin,zvl128b,zvl256b,zvl32b,zvl512b,zvl64b") },
|
||||
{ str_lit("syntacore-scr1-base"), str_lit("32bit,c,no-default-unroll,zicsr,zifencei") },
|
||||
{ str_lit("syntacore-scr1-max"), str_lit("32bit,c,m,no-default-unroll,zicsr,zifencei") },
|
||||
{ str_lit("veyron-v1"), str_lit("64bit,a,auipc-addi-fusion,c,d,f,ld-add-fusion,lui-addi-fusion,m,shifted-zextw-fusion,ventana-veyron,xventanacondops,zba,zbb,zbc,zbs,zexth-fusion,zextw-fusion,zicbom,zicbop,zicboz,zicntr,zicsr,zifencei,zihintpause,zihpm") },
|
||||
{ str_lit("xiangshan-nanhu"), str_lit("64bit,a,c,d,f,m,svinval,zba,zbb,zbc,zbkb,zbkc,zbkx,zbs,zicbom,zicboz,zicsr,zifencei,zkn,zknd,zkne,zknh,zksed,zksh") },
|
||||
};
|
||||
|
||||
+212
-8
@@ -155,6 +155,11 @@ gb_internal bool does_require_msgSend_stret(Type *return_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No objc here so this doesn't matter, right?
|
||||
if (build_context.metrics.arch == TargetArch_riscv64) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if (build_context.metrics.arch == TargetArch_arm32) {
|
||||
// i64 struct_limit = type_size_of(t_uintptr);
|
||||
// // NOTE(bill): This is technically wrong
|
||||
@@ -470,8 +475,8 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
||||
}
|
||||
|
||||
// Integer only
|
||||
case BuiltinProc_simd_add_sat:
|
||||
case BuiltinProc_simd_sub_sat:
|
||||
case BuiltinProc_simd_saturating_add:
|
||||
case BuiltinProc_simd_saturating_sub:
|
||||
case BuiltinProc_simd_bit_and:
|
||||
case BuiltinProc_simd_bit_or:
|
||||
case BuiltinProc_simd_bit_xor:
|
||||
@@ -501,8 +506,8 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
||||
Type *elem = base_array_type(x.type);
|
||||
|
||||
switch (id) {
|
||||
case BuiltinProc_simd_add_sat:
|
||||
case BuiltinProc_simd_sub_sat:
|
||||
case BuiltinProc_simd_saturating_add:
|
||||
case BuiltinProc_simd_saturating_sub:
|
||||
if (!is_type_integer(elem)) {
|
||||
gbString xs = type_to_string(x.type);
|
||||
error(x.expr, "'%.*s' expected a #simd type with an integer element, got '%s'", LIT(builtin_name), xs);
|
||||
@@ -663,6 +668,91 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
||||
return true;
|
||||
}
|
||||
|
||||
case BuiltinProc_simd_gather:
|
||||
case BuiltinProc_simd_scatter:
|
||||
case BuiltinProc_simd_masked_load:
|
||||
case BuiltinProc_simd_masked_store:
|
||||
case BuiltinProc_simd_masked_expand_load:
|
||||
case BuiltinProc_simd_masked_compress_store:
|
||||
{
|
||||
// gather (ptr: #simd[N]rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool) -> #simd[N]T
|
||||
// scatter(ptr: #simd[N]rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool)
|
||||
|
||||
// masked_load (ptr: rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool) -> #simd[N]T
|
||||
// masked_store(ptr: rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool)
|
||||
// masked_expand_load (ptr: rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool) -> #simd[N]T
|
||||
// masked_compress_store(ptr: rawptr, values: #simd[N]T, mask: #simd[N]int_or_bool)
|
||||
|
||||
Operand ptr = {};
|
||||
Operand values = {};
|
||||
Operand mask = {};
|
||||
check_expr(c, &ptr, ce->args[0]); if (ptr.mode == Addressing_Invalid) return false;
|
||||
check_expr(c, &values, ce->args[1]); if (values.mode == Addressing_Invalid) return false;
|
||||
check_expr(c, &mask, ce->args[2]); if (mask.mode == Addressing_Invalid) return false;
|
||||
if (!is_type_simd_vector(values.type)) { error(values.expr, "'%.*s' expected a simd vector type", LIT(builtin_name)); return false; }
|
||||
if (!is_type_simd_vector(mask.type)) { error(mask.expr, "'%.*s' expected a simd vector type", LIT(builtin_name)); return false; }
|
||||
|
||||
if (id == BuiltinProc_simd_gather || id == BuiltinProc_simd_scatter) {
|
||||
if (!is_type_simd_vector(ptr.type)) { error(ptr.expr, "'%.*s' expected a simd vector type", LIT(builtin_name)); return false; }
|
||||
Type *ptr_elem = base_array_type(ptr.type);
|
||||
if (!is_type_rawptr(ptr_elem)) {
|
||||
gbString s = type_to_string(ptr.type);
|
||||
error(ptr.expr, "Expected a simd vector of 'rawptr' for the addresses, got %s", s);
|
||||
gb_string_free(s);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!is_type_pointer(ptr.type)) {
|
||||
gbString s = type_to_string(ptr.type);
|
||||
error(ptr.expr, "Expected a pointer type for the address, got %s", s);
|
||||
gb_string_free(s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Type *mask_elem = base_array_type(mask.type);
|
||||
|
||||
if (!is_type_integer(mask_elem) && !is_type_boolean(mask_elem)) {
|
||||
gbString s = type_to_string(mask.type);
|
||||
error(mask.expr, "Expected a simd vector of integers or booleans for the mask, got %s", s);
|
||||
gb_string_free(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (id == BuiltinProc_simd_gather || id == BuiltinProc_simd_scatter) {
|
||||
i64 ptr_count = get_array_type_count(ptr.type);
|
||||
i64 values_count = get_array_type_count(values.type);
|
||||
i64 mask_count = get_array_type_count(mask.type);
|
||||
if (ptr_count != values_count ||
|
||||
values_count != mask_count ||
|
||||
mask_count != ptr_count) {
|
||||
gbString s = type_to_string(mask.type);
|
||||
error(mask.expr, "All simd vectors must be of the same length, got %lld vs %lld vs %lld", cast(long long)ptr_count, cast(long long)values_count, cast(long long)mask_count);
|
||||
gb_string_free(s);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
i64 values_count = get_array_type_count(values.type);
|
||||
i64 mask_count = get_array_type_count(mask.type);
|
||||
if (values_count != mask_count) {
|
||||
gbString s = type_to_string(mask.type);
|
||||
error(mask.expr, "All simd vectors must be of the same length, got %lld vs %lld", cast(long long)values_count, cast(long long)mask_count);
|
||||
gb_string_free(s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (id == BuiltinProc_simd_gather ||
|
||||
id == BuiltinProc_simd_masked_load ||
|
||||
id == BuiltinProc_simd_masked_expand_load) {
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = values.type;
|
||||
} else {
|
||||
operand->mode = Addressing_NoValue;
|
||||
operand->type = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case BuiltinProc_simd_extract:
|
||||
{
|
||||
Operand x = {};
|
||||
@@ -775,6 +865,29 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
|
||||
return true;
|
||||
}
|
||||
|
||||
case BuiltinProc_simd_reduce_any:
|
||||
case BuiltinProc_simd_reduce_all:
|
||||
{
|
||||
Operand x = {};
|
||||
check_expr(c, &x, ce->args[0]); if (x.mode == Addressing_Invalid) return false;
|
||||
|
||||
if (!is_type_simd_vector(x.type)) {
|
||||
error(x.expr, "'%.*s' expected a simd vector type", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
Type *elem = base_array_type(x.type);
|
||||
if (!is_type_boolean(elem)) {
|
||||
gbString xs = type_to_string(x.type);
|
||||
error(x.expr, "'%.*s' expected a #simd type with a boolean element, got '%s'", LIT(builtin_name), xs);
|
||||
gb_string_free(xs);
|
||||
return false;
|
||||
}
|
||||
|
||||
operand->mode = Addressing_Value;
|
||||
operand->type = t_untyped_bool;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
case BuiltinProc_simd_shuffle:
|
||||
{
|
||||
@@ -1679,7 +1792,10 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o
|
||||
error(call, "'#assert' expects either 1 or 2 arguments, got %td", ce->args.count);
|
||||
return false;
|
||||
}
|
||||
if (!is_type_boolean(operand->type) || operand->mode != Addressing_Constant) {
|
||||
|
||||
// operand->type can be nil if the condition is a procedure, for example: #assert(assert())
|
||||
// So let's check it before we use it, so we get the same error as if we wrote `#exists(assert())
|
||||
if (operand->type == nullptr || !is_type_boolean(operand->type) || operand->mode != Addressing_Constant) {
|
||||
gbString str = expr_to_string(ce->args[0]);
|
||||
error(call, "'%s' is not a constant boolean", str);
|
||||
gb_string_free(str);
|
||||
@@ -1949,6 +2065,14 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
return ok;
|
||||
}
|
||||
|
||||
if (BuiltinProc__atomic_begin < id && id < BuiltinProc__atomic_end) {
|
||||
if (build_context.metrics.arch == TargetArch_riscv64) {
|
||||
if (!check_target_feature_is_enabled(str_lit("a"), nullptr)) {
|
||||
error(call, "missing required target feature \"a\" for atomics, enable it by setting a different -microarch or explicitly adding it through -target-features");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
default:
|
||||
GB_PANIC("Implement built-in procedure: %.*s", LIT(builtin_name));
|
||||
@@ -2474,7 +2598,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
arg_count++;
|
||||
}
|
||||
|
||||
if (arg_count > max_count) {
|
||||
if (false && arg_count > max_count) {
|
||||
error(call, "Too many 'swizzle' indices, %td > %td", arg_count, max_count);
|
||||
return false;
|
||||
} else if (arg_count < 2) {
|
||||
@@ -3885,6 +4009,23 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_constant_log2: {
|
||||
Operand o = {};
|
||||
check_expr(c, &o, ce->args[0]);
|
||||
|
||||
if (!is_type_integer(o.type) && (o.mode != Addressing_Constant)) {
|
||||
error(ce->args[0], "Expected a constant integer for '%.*s'", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
|
||||
int log2 = big_int_log2(&o.value.value_integer);
|
||||
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->value = exact_value_i64(cast(i64)log2);
|
||||
operand->type = t_untyped_integer;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_soa_struct: {
|
||||
Operand x = {};
|
||||
Operand y = {};
|
||||
@@ -4316,8 +4457,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
}
|
||||
break;
|
||||
|
||||
case BuiltinProc_add_sat:
|
||||
case BuiltinProc_sub_sat:
|
||||
case BuiltinProc_saturating_add:
|
||||
case BuiltinProc_saturating_sub:
|
||||
{
|
||||
Operand x = {};
|
||||
Operand y = {};
|
||||
@@ -5076,6 +5217,16 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sz >= 64) {
|
||||
if (is_type_unsigned(x.type)) {
|
||||
add_package_dependency(c, "runtime", "umodti3", true);
|
||||
add_package_dependency(c, "runtime", "udivti3", true);
|
||||
} else {
|
||||
add_package_dependency(c, "runtime", "modti3", true);
|
||||
add_package_dependency(c, "runtime", "divti3", true);
|
||||
}
|
||||
}
|
||||
|
||||
operand->type = x.type;
|
||||
operand->mode = Addressing_Value;
|
||||
}
|
||||
@@ -5549,6 +5700,59 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case BuiltinProc_type_has_shared_fields:
|
||||
{
|
||||
Type *u = check_type(c, ce->args[0]);
|
||||
Type *ut = base_type(u);
|
||||
if (ut == nullptr || ut == t_invalid) {
|
||||
error(ce->args[0], "Expected a type for '%.*s'", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
if (ut->kind != Type_Struct || ut->Struct.soa_kind != StructSoa_None) {
|
||||
gbString t = type_to_string(ut);
|
||||
error(ce->args[0], "Expected a struct type for '%.*s', got %s", LIT(builtin_name), t);
|
||||
gb_string_free(t);
|
||||
return false;
|
||||
}
|
||||
|
||||
Type *v = check_type(c, ce->args[1]);
|
||||
Type *vt = base_type(v);
|
||||
if (vt == nullptr || vt == t_invalid) {
|
||||
error(ce->args[1], "Expected a type for '%.*s'", LIT(builtin_name));
|
||||
return false;
|
||||
}
|
||||
if (vt->kind != Type_Struct || vt->Struct.soa_kind != StructSoa_None) {
|
||||
gbString t = type_to_string(vt);
|
||||
error(ce->args[1], "Expected a struct type for '%.*s', got %s", LIT(builtin_name), t);
|
||||
gb_string_free(t);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_shared = true;
|
||||
|
||||
for (Entity *v_field : vt->Struct.fields) {
|
||||
bool found = false;
|
||||
for (Entity *u_field : ut->Struct.fields) {
|
||||
if (v_field->token.string == u_field->token.string &&
|
||||
are_types_identical(v_field->type, u_field->type)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
is_shared = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
operand->mode = Addressing_Constant;
|
||||
operand->value = exact_value_bool(is_shared);
|
||||
operand->type = t_untyped_bool;
|
||||
break;
|
||||
}
|
||||
|
||||
case BuiltinProc_type_field_type:
|
||||
{
|
||||
Operand op = {};
|
||||
|
||||
+63
-4
@@ -180,6 +180,8 @@ gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_e
|
||||
|
||||
original_entity->flags |= EntityFlag_Overridden;
|
||||
original_entity->type = new_entity->type;
|
||||
original_entity->kind = new_entity->kind;
|
||||
original_entity->decl_info = new_entity->decl_info;
|
||||
original_entity->aliased_of = new_entity;
|
||||
|
||||
original_entity->identifier.store(new_entity->identifier);
|
||||
@@ -193,7 +195,7 @@ gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_e
|
||||
// This is most likely NEVER required, but it does not at all hurt to keep
|
||||
isize offset = cast(u8 *)&original_entity->Dummy.start - cast(u8 *)original_entity;
|
||||
isize size = gb_size_of(*original_entity) - offset;
|
||||
gb_memmove(cast(u8 *)original_entity, cast(u8 *)new_entity, size);
|
||||
gb_memmove(cast(u8 *)original_entity + offset, cast(u8 *)new_entity + offset, size);
|
||||
}
|
||||
|
||||
gb_internal bool check_override_as_type_due_to_aliasing(CheckerContext *ctx, Entity *e, Entity *entity, Ast *init, Type *named_type) {
|
||||
@@ -689,6 +691,13 @@ gb_internal bool sig_compare(TypeCheckSig *a, TypeCheckSig *b, Type *x, Type *y)
|
||||
}
|
||||
|
||||
gb_internal bool signature_parameter_similar_enough(Type *x, Type *y) {
|
||||
if (is_type_bit_set(x)) {
|
||||
x = bit_set_to_int(x);
|
||||
}
|
||||
if (is_type_bit_set(y)) {
|
||||
y = bit_set_to_int(y);
|
||||
}
|
||||
|
||||
if (sig_compare(is_type_pointer, x, y)) {
|
||||
return true;
|
||||
}
|
||||
@@ -735,6 +744,14 @@ gb_internal bool signature_parameter_similar_enough(Type *x, Type *y) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (sig_compare(is_type_slice, x, y)) {
|
||||
Type *s1 = core_type(x);
|
||||
Type *s2 = core_type(y);
|
||||
if (signature_parameter_similar_enough(s1->Slice.elem, s2->Slice.elem)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return are_types_identical(x, y);
|
||||
}
|
||||
|
||||
@@ -751,16 +768,56 @@ gb_internal bool are_signatures_similar_enough(Type *a_, Type *b_) {
|
||||
if (a->result_count != b->result_count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a->c_vararg != b->c_vararg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a->variadic != b->variadic) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (a->variadic && a->variadic_index != b->variadic_index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (isize i = 0; i < a->param_count; i++) {
|
||||
Type *x = core_type(a->params->Tuple.variables[i]->type);
|
||||
Type *y = core_type(b->params->Tuple.variables[i]->type);
|
||||
|
||||
if (x->kind == Type_BitSet && x->BitSet.underlying) {
|
||||
x = core_type(x->BitSet.underlying);
|
||||
}
|
||||
if (y->kind == Type_BitSet && y->BitSet.underlying) {
|
||||
y = core_type(y->BitSet.underlying);
|
||||
}
|
||||
|
||||
// Allow a `#c_vararg args: ..any` with `#c_vararg args: ..foo`.
|
||||
if (a->variadic && i == a->variadic_index) {
|
||||
GB_ASSERT(x->kind == Type_Slice);
|
||||
GB_ASSERT(y->kind == Type_Slice);
|
||||
Type *x_elem = core_type(x->Slice.elem);
|
||||
Type *y_elem = core_type(y->Slice.elem);
|
||||
if (is_type_any(x_elem) || is_type_any(y_elem)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!signature_parameter_similar_enough(x, y)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (isize i = 0; i < a->result_count; i++) {
|
||||
Type *x = base_type(a->results->Tuple.variables[i]->type);
|
||||
Type *y = base_type(b->results->Tuple.variables[i]->type);
|
||||
Type *x = core_type(a->results->Tuple.variables[i]->type);
|
||||
Type *y = core_type(b->results->Tuple.variables[i]->type);
|
||||
|
||||
if (x->kind == Type_BitSet && x->BitSet.underlying) {
|
||||
x = core_type(x->BitSet.underlying);
|
||||
}
|
||||
if (y->kind == Type_BitSet && y->BitSet.underlying) {
|
||||
y = core_type(y->BitSet.underlying);
|
||||
}
|
||||
|
||||
if (!signature_parameter_similar_enough(x, y)) {
|
||||
return false;
|
||||
}
|
||||
@@ -1122,7 +1179,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
||||
|
||||
e->deprecated_message = ac.deprecated_message;
|
||||
e->warning_message = ac.warning_message;
|
||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix,ac.link_suffix);
|
||||
ac.link_name = handle_link_name(ctx, e->token, ac.link_name, ac.link_prefix, ac.link_suffix);
|
||||
if (ac.has_disabled_proc) {
|
||||
if (ac.disabled_proc) {
|
||||
e->flags |= EntityFlag_Disabled;
|
||||
@@ -1219,6 +1276,8 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
|
||||
} else {
|
||||
pt->require_results = true;
|
||||
}
|
||||
} else if (d->foreign_require_results && pt->result_count != 0) {
|
||||
pt->require_results = true;
|
||||
}
|
||||
|
||||
if (ac.link_name.len > 0) {
|
||||
|
||||
+241
-73
@@ -1071,16 +1071,19 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab definite or indefinite article matching `context_name`, or "" if not found.
|
||||
String article = error_article(context_name);
|
||||
|
||||
if (is_type_untyped(operand->type)) {
|
||||
Type *target_type = type;
|
||||
if (type == nullptr || is_type_any(type)) {
|
||||
if (type == nullptr && is_type_untyped_uninit(operand->type)) {
|
||||
error(operand->expr, "Use of --- in %.*s", LIT(context_name));
|
||||
error(operand->expr, "Use of --- in %.*s%.*s", LIT(article), LIT(context_name));
|
||||
operand->mode = Addressing_Invalid;
|
||||
return;
|
||||
}
|
||||
if (type == nullptr && is_type_untyped_nil(operand->type)) {
|
||||
error(operand->expr, "Use of untyped nil in %.*s", LIT(context_name));
|
||||
error(operand->expr, "Use of untyped nil in %.*s%.*s", LIT(article), LIT(context_name));
|
||||
operand->mode = Addressing_Invalid;
|
||||
return;
|
||||
}
|
||||
@@ -1135,9 +1138,10 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
|
||||
|
||||
// TODO(bill): is this a good enough error message?
|
||||
error(operand->expr,
|
||||
"Cannot assign overloaded procedure group '%s' to '%s' in %.*s",
|
||||
"Cannot assign overloaded procedure group '%s' to '%s' in %.*s%.*s",
|
||||
expr_str,
|
||||
op_type_str,
|
||||
LIT(article),
|
||||
LIT(context_name));
|
||||
operand->mode = Addressing_Invalid;
|
||||
}
|
||||
@@ -1163,21 +1167,28 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
|
||||
switch (operand->mode) {
|
||||
case Addressing_Builtin:
|
||||
error(operand->expr,
|
||||
"Cannot assign built-in procedure '%s' in %.*s",
|
||||
"Cannot assign built-in procedure '%s' to %.*s%.*s",
|
||||
expr_str,
|
||||
LIT(article),
|
||||
LIT(context_name));
|
||||
break;
|
||||
case Addressing_Type:
|
||||
if (is_type_polymorphic(operand->type)) {
|
||||
error(operand->expr,
|
||||
"Cannot assign '%s' which is a polymorphic type in %.*s",
|
||||
"Cannot assign '%s', a polymorphic type, to %.*s%.*s",
|
||||
op_type_str,
|
||||
LIT(article),
|
||||
LIT(context_name));
|
||||
} else {
|
||||
ERROR_BLOCK();
|
||||
error(operand->expr,
|
||||
"Cannot assign '%s' which is a type in %.*s",
|
||||
"Cannot assign '%s', a type, to %.*s%.*s",
|
||||
op_type_str,
|
||||
LIT(article),
|
||||
LIT(context_name));
|
||||
if (type && are_types_identical(type, t_any)) {
|
||||
error_line("\tSuggestion: 'typeid_of(%s)'", expr_str);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1203,10 +1214,11 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
|
||||
|
||||
ERROR_BLOCK();
|
||||
error(operand->expr,
|
||||
"Cannot assign value '%s' of type '%s%s' to '%s%s' in %.*s",
|
||||
"Cannot assign value '%s' of type '%s%s' to '%s%s' in %.*s%.*s",
|
||||
expr_str,
|
||||
op_type_str, op_type_extra,
|
||||
type_str, type_extra,
|
||||
LIT(article),
|
||||
LIT(context_name));
|
||||
check_assignment_error_suggestion(c, operand, type);
|
||||
|
||||
@@ -1237,6 +1249,24 @@ gb_internal void check_assignment(CheckerContext *c, Operand *operand, Type *typ
|
||||
error_line("\t Got: %s\n", s_got);
|
||||
gb_string_free(s_got);
|
||||
gb_string_free(s_expected);
|
||||
} else if (same_inputs && same_outputs &&
|
||||
x->Proc.diverging != y->Proc.diverging) {
|
||||
|
||||
gbString s_expected = type_to_string(y);
|
||||
if (y->Proc.diverging) {
|
||||
s_expected = gb_string_appendc(s_expected, " -> !");
|
||||
}
|
||||
|
||||
gbString s_got = type_to_string(x);
|
||||
if (x->Proc.diverging) {
|
||||
s_got = gb_string_appendc(s_got, " -> !");
|
||||
}
|
||||
|
||||
error_line("\tNote: One of the procedures is diverging while the other isn't\n");
|
||||
error_line("\t Expected: %s\n", s_expected);
|
||||
error_line("\t Got: %s\n", s_got);
|
||||
gb_string_free(s_got);
|
||||
gb_string_free(s_expected);
|
||||
} else if (same_inputs && !same_outputs) {
|
||||
gbString s_expected = type_to_string(y->Proc.results);
|
||||
gbString s_got = type_to_string(x->Proc.results);
|
||||
@@ -2314,14 +2344,24 @@ gb_internal bool check_integer_exceed_suggestion(CheckerContext *c, Operand *o,
|
||||
}
|
||||
BigInt *bi = &o->value.value_integer;
|
||||
if (is_type_unsigned(type)) {
|
||||
BigInt one = big_int_make_u64(1);
|
||||
BigInt max_size = big_int_make_u64(1);
|
||||
BigInt bits = big_int_make_i64(bit_size);
|
||||
big_int_shl_eq(&max_size, &bits);
|
||||
big_int_sub_eq(&max_size, &one);
|
||||
|
||||
if (big_int_is_neg(bi)) {
|
||||
error_line("\tA negative value cannot be represented by the unsigned integer type '%s'\n", b);
|
||||
BigInt dst = {};
|
||||
big_int_neg(&dst, bi);
|
||||
if (big_int_cmp(&dst, &max_size) < 0) {
|
||||
big_int_sub_eq(&dst, &one);
|
||||
String dst_str = big_int_to_string(temporary_allocator(), &dst);
|
||||
gbString t = type_to_string(type);
|
||||
error_line("\tSuggestion: ~%s(%.*s)\n", t, LIT(dst_str));
|
||||
gb_string_free(t);
|
||||
}
|
||||
} else {
|
||||
BigInt one = big_int_make_u64(1);
|
||||
BigInt max_size = big_int_make_u64(1);
|
||||
BigInt bits = big_int_make_i64(bit_size);
|
||||
big_int_shl_eq(&max_size, &bits);
|
||||
big_int_sub_eq(&max_size, &one);
|
||||
String max_size_str = big_int_to_string(temporary_allocator(), &max_size);
|
||||
|
||||
if (size_changed) {
|
||||
@@ -2535,6 +2575,84 @@ gb_internal bool check_is_not_addressable(CheckerContext *c, Operand *o) {
|
||||
return o->mode != Addressing_Variable && o->mode != Addressing_SoaVariable;
|
||||
}
|
||||
|
||||
gb_internal ExactValue exact_bit_set_all_set_mask(Type *type) {
|
||||
type = base_type(type);
|
||||
GB_ASSERT(type->kind == Type_BitSet);
|
||||
|
||||
i64 lower = type->BitSet.lower;
|
||||
i64 upper = type->BitSet.upper;
|
||||
Type *elem = type->BitSet.elem;
|
||||
Type *underlying = type->BitSet.underlying;
|
||||
bool is_backed = underlying != nullptr;
|
||||
gb_unused(is_backed);
|
||||
|
||||
BigInt b_lower = {};
|
||||
BigInt b_upper = {};
|
||||
big_int_from_i64(&b_lower, lower);
|
||||
big_int_from_i64(&b_upper, upper);
|
||||
|
||||
|
||||
BigInt one = {};
|
||||
big_int_from_u64(&one, 1);
|
||||
|
||||
BigInt mask = {};
|
||||
|
||||
if (elem == nullptr) {
|
||||
big_int_from_i64(&mask, -1);
|
||||
} else if (is_type_enum(elem)) {
|
||||
Type *e = base_type(elem);
|
||||
GB_ASSERT(e->kind == Type_Enum);
|
||||
gb_unused(e);
|
||||
|
||||
if ((big_int_cmp(&e->Enum.min_value->value_integer, &b_lower) == 0 || is_backed) &&
|
||||
big_int_cmp(&e->Enum.max_value->value_integer, &b_upper) == 0) {
|
||||
|
||||
i64 lower_base = is_backed ? gb_min(0, lower) : lower;
|
||||
BigInt b_lower_base = {};
|
||||
big_int_from_i64(&b_lower_base, lower_base);
|
||||
|
||||
for (Entity *f : e->Enum.fields) {
|
||||
if (f->kind != Entity_Constant) {
|
||||
continue;
|
||||
}
|
||||
if (f->Constant.value.kind != ExactValue_Integer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BigInt shift_amount = f->Constant.value.value_integer;
|
||||
big_int_sub_eq(&shift_amount, &b_lower_base);
|
||||
|
||||
|
||||
BigInt value = {};
|
||||
big_int_shl(&value, &one, &shift_amount);
|
||||
|
||||
big_int_or(&mask, &mask, &value);
|
||||
}
|
||||
|
||||
} else {
|
||||
// TODO(bill): enum range based");
|
||||
big_int_from_i64(&mask, -1);
|
||||
}
|
||||
} else {
|
||||
i64 lower_base = lower;
|
||||
for (i64 x = lower; x <= upper; x++) {
|
||||
BigInt shift_amount = {};
|
||||
big_int_from_i64(&shift_amount, x - lower_base);
|
||||
|
||||
BigInt value = {};
|
||||
big_int_shl(&value, &one, &shift_amount);
|
||||
|
||||
big_int_or(&mask, &mask, &value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ExactValue res = {};
|
||||
res.kind = ExactValue_Integer;
|
||||
res.value_integer = mask;
|
||||
return res;
|
||||
}
|
||||
|
||||
gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) {
|
||||
switch (op.kind) {
|
||||
case Token_And: { // Pointer address
|
||||
@@ -2674,6 +2792,10 @@ gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *
|
||||
}
|
||||
|
||||
o->value = exact_unary_operator_value(op.kind, o->value, precision, is_unsigned);
|
||||
if (op.kind == Token_Xor && is_type_bit_set(type)) {
|
||||
ExactValue mask = exact_bit_set_all_set_mask(type);
|
||||
o->value = exact_binary_operator_value(Token_And, o->value, mask);
|
||||
}
|
||||
|
||||
if (is_type_typed(type)) {
|
||||
if (node != nullptr) {
|
||||
@@ -3020,7 +3142,7 @@ gb_internal void check_shift(CheckerContext *c, Operand *x, Operand *y, Ast *nod
|
||||
x->mode = Addressing_Value;
|
||||
if (type_hint) {
|
||||
if (is_type_integer(type_hint)) {
|
||||
x->type = type_hint;
|
||||
convert_to_typed(c, x, type_hint);
|
||||
} else {
|
||||
gbString x_str = expr_to_string(x->expr);
|
||||
gbString to_type = type_to_string(type_hint);
|
||||
@@ -3746,10 +3868,10 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ
|
||||
// NOTE(bill): Allow comparisons between types
|
||||
if (is_ise_expr(be->left)) {
|
||||
// Evalute the right before the left for an '.X' expression
|
||||
check_expr_or_type(c, y, be->right, type_hint);
|
||||
check_expr_or_type(c, y, be->right, nullptr /* ignore type hint */);
|
||||
check_expr_or_type(c, x, be->left, y->type);
|
||||
} else {
|
||||
check_expr_or_type(c, x, be->left, type_hint);
|
||||
check_expr_or_type(c, x, be->left, nullptr /* ignore type hint */);
|
||||
check_expr_or_type(c, y, be->right, x->type);
|
||||
}
|
||||
bool xt = x->mode == Addressing_Type;
|
||||
@@ -3917,6 +4039,60 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ
|
||||
return;
|
||||
}
|
||||
|
||||
bool REQUIRE = true;
|
||||
Type *bt = base_type(x->type);
|
||||
if (op.kind == Token_Mod || op.kind == Token_ModEq ||
|
||||
op.kind == Token_ModMod || op.kind == Token_ModModEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_u128: add_package_dependency(c, "runtime", "umodti3", REQUIRE); break;
|
||||
case Basic_i128: add_package_dependency(c, "runtime", "modti3", REQUIRE); break;
|
||||
}
|
||||
} else if (op.kind == Token_Quo || op.kind == Token_QuoEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_complex32: add_package_dependency(c, "runtime", "quo_complex32"); break;
|
||||
case Basic_complex64: add_package_dependency(c, "runtime", "quo_complex64"); break;
|
||||
case Basic_complex128: add_package_dependency(c, "runtime", "quo_complex128"); break;
|
||||
case Basic_quaternion64: add_package_dependency(c, "runtime", "quo_quaternion64"); break;
|
||||
case Basic_quaternion128: add_package_dependency(c, "runtime", "quo_quaternion128"); break;
|
||||
case Basic_quaternion256: add_package_dependency(c, "runtime", "quo_quaternion256"); break;
|
||||
|
||||
case Basic_u128: add_package_dependency(c, "runtime", "udivti3", REQUIRE); break;
|
||||
case Basic_i128: add_package_dependency(c, "runtime", "divti3", REQUIRE); break;
|
||||
}
|
||||
} else if (op.kind == Token_Mul || op.kind == Token_MulEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_quaternion64: add_package_dependency(c, "runtime", "mul_quaternion64"); break;
|
||||
case Basic_quaternion128: add_package_dependency(c, "runtime", "mul_quaternion128"); break;
|
||||
case Basic_quaternion256: add_package_dependency(c, "runtime", "mul_quaternion256"); break;
|
||||
|
||||
|
||||
case Basic_u128:
|
||||
case Basic_i128:
|
||||
if (is_arch_wasm()) {
|
||||
add_package_dependency(c, "runtime", "__multi3", REQUIRE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (op.kind == Token_Shl || op.kind == Token_ShlEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_u128:
|
||||
case Basic_i128:
|
||||
if (is_arch_wasm()) {
|
||||
add_package_dependency(c, "runtime", "__ashlti3", REQUIRE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (op.kind == Token_Shr || op.kind == Token_ShrEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_u128:
|
||||
case Basic_i128:
|
||||
if (is_arch_wasm()) {
|
||||
add_package_dependency(c, "runtime", "__lshrti3", REQUIRE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (token_is_shift(op.kind)) {
|
||||
check_shift(c, x, y, node, type_hint);
|
||||
return;
|
||||
@@ -4085,52 +4261,6 @@ gb_internal void check_binary_expr(CheckerContext *c, Operand *x, Ast *node, Typ
|
||||
return;
|
||||
}
|
||||
|
||||
bool REQUIRE = true;
|
||||
|
||||
Type *bt = base_type(x->type);
|
||||
if (op.kind == Token_Mod || op.kind == Token_ModEq ||
|
||||
op.kind == Token_ModMod || op.kind == Token_ModModEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_u128: add_package_dependency(c, "runtime", "umodti3", REQUIRE); break;
|
||||
case Basic_i128: add_package_dependency(c, "runtime", "modti3", REQUIRE); break;
|
||||
}
|
||||
} else if (op.kind == Token_Quo || op.kind == Token_QuoEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_complex32: add_package_dependency(c, "runtime", "quo_complex32"); break;
|
||||
case Basic_complex64: add_package_dependency(c, "runtime", "quo_complex64"); break;
|
||||
case Basic_complex128: add_package_dependency(c, "runtime", "quo_complex128"); break;
|
||||
case Basic_quaternion64: add_package_dependency(c, "runtime", "quo_quaternion64"); break;
|
||||
case Basic_quaternion128: add_package_dependency(c, "runtime", "quo_quaternion128"); break;
|
||||
case Basic_quaternion256: add_package_dependency(c, "runtime", "quo_quaternion256"); break;
|
||||
|
||||
case Basic_u128: add_package_dependency(c, "runtime", "udivti3", REQUIRE); break;
|
||||
case Basic_i128: add_package_dependency(c, "runtime", "divti3", REQUIRE); break;
|
||||
}
|
||||
} else if (op.kind == Token_Mul || op.kind == Token_MulEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_quaternion64: add_package_dependency(c, "runtime", "mul_quaternion64"); break;
|
||||
case Basic_quaternion128: add_package_dependency(c, "runtime", "mul_quaternion128"); break;
|
||||
case Basic_quaternion256: add_package_dependency(c, "runtime", "mul_quaternion256"); break;
|
||||
|
||||
|
||||
case Basic_u128:
|
||||
case Basic_i128:
|
||||
if (is_arch_wasm()) {
|
||||
add_package_dependency(c, "runtime", "__multi3", REQUIRE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (op.kind == Token_Shl || op.kind == Token_ShlEq) {
|
||||
if (bt->kind == Type_Basic) switch (bt->Basic.kind) {
|
||||
case Basic_u128:
|
||||
case Basic_i128:
|
||||
if (is_arch_wasm()) {
|
||||
add_package_dependency(c, "runtime", "__ashlti3", REQUIRE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
x->mode = Addressing_Value;
|
||||
}
|
||||
|
||||
@@ -4614,7 +4744,8 @@ gb_internal bool check_index_value(CheckerContext *c, Type *main_type, bool open
|
||||
check_expr_with_type_hint(c, &operand, index_value, type_hint);
|
||||
if (operand.mode == Addressing_Invalid) {
|
||||
if (value) *value = 0;
|
||||
return false;
|
||||
// NOTE(bill): return true here to propagate the errors better
|
||||
return true;
|
||||
}
|
||||
|
||||
Type *index_type = t_int;
|
||||
@@ -4835,7 +4966,7 @@ gb_internal ExactValue get_constant_field_single(CheckerContext *c, ExactValue v
|
||||
TypeAndValue tav = fv->value->tav;
|
||||
if (success_) *success_ = true;
|
||||
if (finish_) *finish_ = false;
|
||||
return tav.value;;
|
||||
return tav.value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4910,7 +5041,6 @@ gb_internal ExactValue get_constant_field(CheckerContext *c, Operand const *oper
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
if (success_) *success_ = true;
|
||||
return value;
|
||||
} else if (value.kind == ExactValue_Quaternion) {
|
||||
@@ -5150,7 +5280,14 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod
|
||||
add_entity_use(c, op_expr, e);
|
||||
expr_entity = e;
|
||||
|
||||
if (e != nullptr && e->kind == Entity_ImportName && selector->kind == Ast_Ident) {
|
||||
if (e != nullptr && (e->kind == Entity_Procedure || e->kind == Entity_ProcGroup) && selector->kind == Ast_Ident) {
|
||||
gbString sel_str = expr_to_string(selector);
|
||||
error(node, "'%s' is not declared by by '%.*s'", sel_str, LIT(e->token.string));
|
||||
gb_string_free(sel_str);
|
||||
operand->mode = Addressing_Invalid;
|
||||
operand->expr = node;
|
||||
return nullptr;
|
||||
} else if (e != nullptr && e->kind == Entity_ImportName && selector->kind == Ast_Ident) {
|
||||
// IMPORTANT NOTE(bill): This is very sloppy code but it's also very fragile
|
||||
// It pretty much needs to be in this order and this way
|
||||
// If you can clean this up, please do but be really careful
|
||||
@@ -5158,6 +5295,14 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod
|
||||
Scope *import_scope = e->ImportName.scope;
|
||||
String entity_name = selector->Ident.token.string;
|
||||
|
||||
if (import_scope == nullptr) {
|
||||
ERROR_BLOCK();
|
||||
error(node, "'%.*s' is not imported in this file, '%.*s' is unavailable", LIT(import_name), LIT(entity_name));
|
||||
operand->mode = Addressing_Invalid;
|
||||
operand->expr = node;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
check_op_expr = false;
|
||||
entity = scope_lookup_current(import_scope, entity_name);
|
||||
bool allow_builtin = false;
|
||||
@@ -5593,7 +5738,7 @@ gb_internal bool check_identifier_exists(Scope *s, Ast *node, bool nested = fals
|
||||
gb_internal bool check_no_copy_assignment(Operand const &o, String const &context) {
|
||||
if (o.type && is_type_no_copy(o.type)) {
|
||||
Ast *expr = unparen_expr(o.expr);
|
||||
if (expr && o.mode != Addressing_Constant) {
|
||||
if (expr && o.mode != Addressing_Constant && o.mode != Addressing_Type) {
|
||||
if (expr->kind == Ast_CallExpr) {
|
||||
// Okay
|
||||
} else {
|
||||
@@ -6227,7 +6372,9 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A
|
||||
}
|
||||
|
||||
if (param_is_variadic) {
|
||||
continue;
|
||||
if (!named_variadic_param) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
score += eval_param_and_score(c, o, e->type, err, false, e, show_error);
|
||||
}
|
||||
@@ -7564,7 +7711,7 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O
|
||||
gbString s = gb_string_make_reserve(heap_allocator(), e->token.string.len+3);
|
||||
s = gb_string_append_fmt(s, "%.*s(", LIT(e->token.string));
|
||||
|
||||
TypeTuple *tuple = get_record_polymorphic_params(e->type);
|
||||
TypeTuple *tuple = get_record_polymorphic_params(bt);
|
||||
if (tuple != nullptr) for_array(i, tuple->variables) {
|
||||
Entity *v = tuple->variables[i];
|
||||
String name = v->token.string;
|
||||
@@ -7579,8 +7726,10 @@ gb_internal CallArgumentError check_polymorphic_record_type(CheckerContext *c, O
|
||||
s = write_type_to_string(s, v->type, false);
|
||||
}
|
||||
} else if (v->kind == Entity_Constant) {
|
||||
s = gb_string_append_fmt(s, "=");
|
||||
s = write_exact_value_to_string(s, v->Constant.value);
|
||||
if (v->Constant.value.kind != ExactValue_Invalid) {
|
||||
s = gb_string_append_fmt(s, "=");
|
||||
s = write_exact_value_to_string(s, v->Constant.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
s = gb_string_append_fmt(s, ")");
|
||||
@@ -9996,6 +10145,22 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *
|
||||
is_constant = o->mode == Addressing_Constant;
|
||||
}
|
||||
|
||||
if (elem->kind == Ast_BinaryExpr) {
|
||||
switch (elem->BinaryExpr.op.kind) {
|
||||
case Token_Or:
|
||||
{
|
||||
gbString x = expr_to_string(elem->BinaryExpr.left);
|
||||
gbString y = expr_to_string(elem->BinaryExpr.right);
|
||||
gbString e = expr_to_string(elem);
|
||||
error(elem, "Was the following intended? '%s, %s'; if not, surround the expression with parentheses '(%s)'", x, y, e);
|
||||
gb_string_free(e);
|
||||
gb_string_free(y);
|
||||
gb_string_free(x);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
check_assignment(c, o, t->BitSet.elem, str_lit("bit_set literal"));
|
||||
if (o->mode == Addressing_Constant) {
|
||||
i64 lower = t->BitSet.lower;
|
||||
@@ -10004,7 +10169,9 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast *
|
||||
if (lower <= v && v <= upper) {
|
||||
// okay
|
||||
} else {
|
||||
error(elem, "Bit field value out of bounds, %lld not in the range %lld .. %lld", v, lower, upper);
|
||||
gbString s = expr_to_string(o->expr);
|
||||
error(elem, "Bit field value out of bounds, %s (%lld) not in the range %lld .. %lld", s, v, lower, upper);
|
||||
gb_string_free(s);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -10485,7 +10652,8 @@ gb_internal ExprKind check_index_expr(CheckerContext *c, Operand *o, Ast *node,
|
||||
o->expr = node;
|
||||
return kind;
|
||||
} else if (ok && !is_type_matrix(t)) {
|
||||
ExactValue value = type_and_value_of_expr(ie->expr).value;
|
||||
TypeAndValue tav = type_and_value_of_expr(ie->expr);
|
||||
ExactValue value = tav.value;
|
||||
o->mode = Addressing_Constant;
|
||||
bool success = false;
|
||||
bool finish = false;
|
||||
@@ -10762,7 +10930,7 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast
|
||||
case Token_context:
|
||||
{
|
||||
if (c->proc_name.len == 0 && c->curr_proc_sig == nullptr) {
|
||||
error(node, "'context' is only allowed within procedures %p", c->curr_proc_decl);
|
||||
error(node, "'context' is only allowed within procedures");
|
||||
return kind;
|
||||
}
|
||||
if (unparen_expr(c->assignment_lhs_hint) == node) {
|
||||
|
||||
+36
-5
@@ -199,6 +199,9 @@ gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit)
|
||||
}
|
||||
break;
|
||||
|
||||
case Ast_DeferStmt:
|
||||
return check_has_break(stmt->DeferStmt.stmt, label, implicit);
|
||||
|
||||
case Ast_BlockStmt:
|
||||
return check_has_break_list(stmt->BlockStmt.stmts, label, implicit);
|
||||
|
||||
@@ -474,8 +477,15 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O
|
||||
rhs->proc_group = nullptr;
|
||||
}
|
||||
} else {
|
||||
Ast *ident_node = nullptr;
|
||||
|
||||
if (node->kind == Ast_Ident) {
|
||||
ast_node(i, Ident, node);
|
||||
ident_node = node;
|
||||
} else if (node->kind == Ast_IndexExpr && node->IndexExpr.expr->kind == Ast_Ident) {
|
||||
ident_node = node->IndexExpr.expr;
|
||||
}
|
||||
if (ident_node != nullptr) {
|
||||
ast_node(i, Ident, ident_node);
|
||||
e = scope_lookup(ctx->scope, i->token.string);
|
||||
if (e != nullptr && e->kind == Entity_Variable) {
|
||||
used = (e->flags & EntityFlag_Used) != 0; // NOTE(bill): Make backup just in case
|
||||
@@ -817,7 +827,8 @@ gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us,
|
||||
if (f->kind == Entity_Variable) {
|
||||
Entity *uvar = alloc_entity_using_variable(e, f->token, f->type, expr);
|
||||
if (!is_ptr && e->flags & EntityFlag_Value) uvar->flags |= EntityFlag_Value;
|
||||
if (e->flags & EntityFlag_Param) uvar->flags |= EntityFlag_Param;
|
||||
if (e->flags & EntityFlag_Param) uvar->flags |= EntityFlag_Param;
|
||||
if (e->flags & EntityFlag_SoaPtrField) uvar->flags |= EntityFlag_SoaPtrField;
|
||||
Entity *prev = scope_insert(ctx->scope, uvar);
|
||||
if (prev != nullptr) {
|
||||
gbString expr_str = expr_to_string(expr);
|
||||
@@ -1471,7 +1482,7 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_
|
||||
case_type = nullptr;
|
||||
}
|
||||
if (case_type == nullptr) {
|
||||
case_type = x.type;
|
||||
case_type = type_deref(x.type);
|
||||
}
|
||||
if (switch_kind == TypeSwitch_Any) {
|
||||
if (!is_type_untyped(case_type)) {
|
||||
@@ -1630,6 +1641,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
|
||||
Ast *expr = unparen_expr(rs->expr);
|
||||
|
||||
bool is_range = false;
|
||||
bool is_possibly_addressable = true;
|
||||
isize max_val_count = 2;
|
||||
if (is_ast_range(expr)) {
|
||||
@@ -1638,6 +1650,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
Operand y = {};
|
||||
|
||||
is_possibly_addressable = false;
|
||||
is_range = true;
|
||||
|
||||
bool ok = check_range(ctx, expr, true, &x, &y, nullptr);
|
||||
if (!ok) {
|
||||
@@ -1685,7 +1698,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
bool is_ptr = type_deref(operand.type);
|
||||
bool is_ptr = is_type_pointer(type_deref(operand.type));
|
||||
Type *t = base_type(type_deref(operand.type));
|
||||
|
||||
switch (t->kind) {
|
||||
@@ -1725,6 +1738,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
break;
|
||||
|
||||
case Type_EnumeratedArray:
|
||||
is_possibly_addressable = operand.mode == Addressing_Variable || is_ptr;
|
||||
array_add(&vals, t->EnumeratedArray.elem);
|
||||
array_add(&vals, t->EnumeratedArray.index);
|
||||
break;
|
||||
@@ -1882,7 +1896,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
}
|
||||
if (found == nullptr) {
|
||||
entity = alloc_entity_variable(ctx->scope, token, type, EntityState_Resolved);
|
||||
entity->flags |= EntityFlag_ForValue;
|
||||
if (!is_range) {
|
||||
entity->flags |= EntityFlag_ForValue;
|
||||
}
|
||||
entity->flags |= EntityFlag_Value;
|
||||
entity->identifier = name;
|
||||
entity->Variable.for_loop_parent_type = type_of_expr(expr);
|
||||
@@ -2489,6 +2505,16 @@ gb_internal void check_return_stmt(CheckerContext *ctx, Ast *node) {
|
||||
continue;
|
||||
}
|
||||
Ast *expr = unparen_expr(o.expr);
|
||||
while (expr->kind == Ast_CallExpr && expr->CallExpr.proc->tav.mode == Addressing_Type) {
|
||||
if (expr->CallExpr.args.count != 1) {
|
||||
break;
|
||||
}
|
||||
Ast *arg = expr->CallExpr.args[0];
|
||||
if (arg->kind == Ast_FieldValue || !are_types_identical(arg->tav.type, expr->tav.type)) {
|
||||
break;
|
||||
}
|
||||
expr = unparen_expr(arg);
|
||||
}
|
||||
|
||||
auto unsafe_return_error = [](Operand const &o, char const *msg, Type *extra_type=nullptr) {
|
||||
gbString s = expr_to_string(o.expr);
|
||||
@@ -2684,6 +2710,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
||||
error(bs->label, "A branch statement's label name must be an identifier");
|
||||
return;
|
||||
}
|
||||
|
||||
Ast *ident = bs->label;
|
||||
String name = ident->Ident.token.string;
|
||||
Operand o = {};
|
||||
@@ -2715,6 +2742,10 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (ctx->in_defer) {
|
||||
error(bs->label, "A labelled '%.*s' cannot be used within a 'defer'", LIT(token.string));
|
||||
}
|
||||
}
|
||||
|
||||
case_end;
|
||||
|
||||
+39
-1
@@ -1781,6 +1781,11 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (default_value != nullptr) {
|
||||
error(type_expr, "A variadic parameter may not have a default value");
|
||||
success = false;
|
||||
}
|
||||
|
||||
GB_ASSERT(original_type_expr->kind == Ast_Ellipsis);
|
||||
type_expr = ast_array_type(type_expr->file(), original_type_expr->Ellipsis.token, nullptr, type_expr);
|
||||
}
|
||||
@@ -2309,8 +2314,28 @@ gb_internal Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_res
|
||||
return tuple;
|
||||
}
|
||||
|
||||
gb_internal void check_procedure_param_polymorphic_type(CheckerContext *ctx, Type *type, Ast *type_expr) {
|
||||
GB_ASSERT_NOT_NULL(type_expr);
|
||||
if (type == nullptr || ctx->in_polymorphic_specialization) { return; }
|
||||
if (!is_type_polymorphic_record_unspecialized(type)) { return; }
|
||||
|
||||
bool invalid_polymorpic_type_use = false;
|
||||
switch (type_expr->kind) {
|
||||
case_ast_node(pt, Ident, type_expr);
|
||||
invalid_polymorpic_type_use = true;
|
||||
case_end;
|
||||
|
||||
case_ast_node(pt, SelectorExpr, type_expr);
|
||||
invalid_polymorpic_type_use = true;
|
||||
case_end;
|
||||
}
|
||||
|
||||
if (invalid_polymorpic_type_use) {
|
||||
gbString expr_str = expr_to_string(type_expr);
|
||||
defer (gb_string_free(expr_str));
|
||||
error(type_expr, "Invalid use of a non-specialized polymorphic type '%s'", expr_str);
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(bill): 'operands' is for generating non generic procedure type
|
||||
gb_internal bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node, Array<Operand> const *operands) {
|
||||
@@ -2433,6 +2458,7 @@ gb_internal bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc
|
||||
if (e->kind != Entity_Variable) {
|
||||
is_polymorphic = true;
|
||||
} else if (is_type_polymorphic(e->type)) {
|
||||
check_procedure_param_polymorphic_type(c, e->type, e->Variable.type_expr);
|
||||
is_polymorphic = true;
|
||||
}
|
||||
|
||||
@@ -2718,6 +2744,18 @@ gb_internal void check_map_type(CheckerContext *ctx, Type *type, Ast *node) {
|
||||
GB_ASSERT(type->kind == Type_Map);
|
||||
ast_node(mt, MapType, node);
|
||||
|
||||
if (mt->key == NULL) {
|
||||
if (mt->value != NULL) {
|
||||
Type *value = check_type(ctx, mt->value);
|
||||
gbString str = type_to_string(value);
|
||||
error(node, "Missing map key type, got 'map[]%s'", str);
|
||||
gb_string_free(str);
|
||||
return;
|
||||
}
|
||||
error(node, "Missing map key type, got 'map[]T'");
|
||||
return;
|
||||
}
|
||||
|
||||
Type *key = check_type(ctx, mt->key);
|
||||
Type *value = check_type(ctx, mt->value);
|
||||
|
||||
@@ -3171,7 +3209,7 @@ gb_internal void check_array_type_internal(CheckerContext *ctx, Ast *e, Type **t
|
||||
} else if (name == "simd") {
|
||||
if (!is_type_valid_vector_elem(elem) && !is_type_polymorphic(elem)) {
|
||||
gbString str = type_to_string(elem);
|
||||
error(at->elem, "Invalid element type for #simd, expected an integer, float, or boolean with no specific endianness, got '%s'", str);
|
||||
error(at->elem, "Invalid element type for #simd, expected an integer, float, boolean, or 'rawptr' with no specific endianness, got '%s'", str);
|
||||
gb_string_free(str);
|
||||
*type = alloc_type_array(elem, count, generic_type);
|
||||
return;
|
||||
|
||||
+76
-20
@@ -1039,6 +1039,7 @@ gb_internal void init_universal(void) {
|
||||
{"arm64", TargetArch_arm64},
|
||||
{"wasm32", TargetArch_wasm32},
|
||||
{"wasm64p32", TargetArch_wasm64p32},
|
||||
{"riscv64", TargetArch_riscv64},
|
||||
};
|
||||
|
||||
auto fields = add_global_enum_type(str_lit("Odin_Arch_Type"), values, gb_count_of(values));
|
||||
@@ -1651,9 +1652,9 @@ gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMo
|
||||
|
||||
if (mode == Addressing_Constant || mode == Addressing_Invalid) {
|
||||
expr->tav.value = value;
|
||||
} else if (mode == Addressing_Value && is_type_typeid(type)) {
|
||||
} else if (mode == Addressing_Value && type != nullptr && is_type_typeid(type)) {
|
||||
expr->tav.value = value;
|
||||
} else if (mode == Addressing_Value && is_type_proc(type)) {
|
||||
} else if (mode == Addressing_Value && type != nullptr && is_type_proc(type)) {
|
||||
expr->tav.value = value;
|
||||
}
|
||||
|
||||
@@ -1785,7 +1786,9 @@ gb_internal void add_entity_use(CheckerContext *c, Ast *identifier, Entity *enti
|
||||
entity->flags |= EntityFlag_Used;
|
||||
if (entity_has_deferred_procedure(entity)) {
|
||||
Entity *deferred = entity->Procedure.deferred_procedure.entity;
|
||||
add_entity_use(c, nullptr, deferred);
|
||||
if (deferred != entity) {
|
||||
add_entity_use(c, nullptr, deferred);
|
||||
}
|
||||
}
|
||||
if (identifier == nullptr || identifier->kind != Ast_Ident) {
|
||||
return;
|
||||
@@ -2723,6 +2726,7 @@ gb_internal void generate_minimum_dependency_set(Checker *c, Entity *start) {
|
||||
// WASM Specific
|
||||
str_lit("__ashlti3"),
|
||||
str_lit("__multi3"),
|
||||
str_lit("__lshrti3"),
|
||||
);
|
||||
|
||||
FORCE_ADD_RUNTIME_ENTITIES(!build_context.no_rtti,
|
||||
@@ -2991,6 +2995,9 @@ gb_internal void init_core_type_info(Checker *c) {
|
||||
}
|
||||
Entity *type_info_entity = find_core_entity(c, str_lit("Type_Info"));
|
||||
GB_ASSERT(type_info_entity != nullptr);
|
||||
if (type_info_entity->type == nullptr) {
|
||||
check_single_global_entity(c, type_info_entity, type_info_entity->decl_info);
|
||||
}
|
||||
GB_ASSERT(type_info_entity->type != nullptr);
|
||||
|
||||
t_type_info = type_info_entity->type;
|
||||
@@ -3169,8 +3176,8 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
||||
return true;
|
||||
} else if (name == "link_prefix") {
|
||||
if (ev.kind == ExactValue_String) {
|
||||
String link_prefix = ev.value_string;
|
||||
if (!is_foreign_name_valid(link_prefix)) {
|
||||
String link_prefix = string_trim_whitespace(ev.value_string);
|
||||
if (link_prefix.len != 0 && !is_foreign_name_valid(link_prefix)) {
|
||||
error(elem, "Invalid link prefix: '%.*s'", LIT(link_prefix));
|
||||
} else {
|
||||
c->foreign_context.link_prefix = link_prefix;
|
||||
@@ -3181,8 +3188,8 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
||||
return true;
|
||||
} else if (name == "link_suffix") {
|
||||
if (ev.kind == ExactValue_String) {
|
||||
String link_suffix = ev.value_string;
|
||||
if (!is_foreign_name_valid(link_suffix)) {
|
||||
String link_suffix = string_trim_whitespace(ev.value_string);
|
||||
if (link_suffix.len != 0 && !is_foreign_name_valid(link_suffix)) {
|
||||
error(elem, "Invalid link suffix: '%.*s'", LIT(link_suffix));
|
||||
} else {
|
||||
c->foreign_context.link_suffix = link_suffix;
|
||||
@@ -3209,6 +3216,12 @@ gb_internal DECL_ATTRIBUTE_PROC(foreign_block_decl_attribute) {
|
||||
}
|
||||
c->foreign_context.visibility_kind = kind;
|
||||
return true;
|
||||
} else if (name == "require_results") {
|
||||
if (value != nullptr) {
|
||||
error(elem, "Expected no value for '%.*s'", LIT(name));
|
||||
}
|
||||
c->foreign_context.require_results = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -3478,7 +3491,7 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
||||
|
||||
if (ev.kind == ExactValue_String) {
|
||||
ac->link_prefix = ev.value_string;
|
||||
if (!is_foreign_name_valid(ac->link_prefix)) {
|
||||
if (ac->link_prefix.len != 0 && !is_foreign_name_valid(ac->link_prefix)) {
|
||||
error(elem, "Invalid link prefix: %.*s", LIT(ac->link_prefix));
|
||||
}
|
||||
} else {
|
||||
@@ -3490,7 +3503,7 @@ gb_internal DECL_ATTRIBUTE_PROC(proc_decl_attribute) {
|
||||
|
||||
if (ev.kind == ExactValue_String) {
|
||||
ac->link_suffix = ev.value_string;
|
||||
if (!is_foreign_name_valid(ac->link_suffix)) {
|
||||
if (ac->link_suffix.len != 0 && !is_foreign_name_valid(ac->link_suffix)) {
|
||||
error(elem, "Invalid link suffix: %.*s", LIT(ac->link_suffix));
|
||||
}
|
||||
} else {
|
||||
@@ -3763,7 +3776,7 @@ gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
||||
ExactValue ev = check_decl_attribute_value(c, value);
|
||||
if (ev.kind == ExactValue_String) {
|
||||
ac->link_prefix = ev.value_string;
|
||||
if (!is_foreign_name_valid(ac->link_prefix)) {
|
||||
if (ac->link_prefix.len != 0 && !is_foreign_name_valid(ac->link_prefix)) {
|
||||
error(elem, "Invalid link prefix: %.*s", LIT(ac->link_prefix));
|
||||
}
|
||||
} else {
|
||||
@@ -3774,7 +3787,7 @@ gb_internal DECL_ATTRIBUTE_PROC(var_decl_attribute) {
|
||||
ExactValue ev = check_decl_attribute_value(c, value);
|
||||
if (ev.kind == ExactValue_String) {
|
||||
ac->link_suffix = ev.value_string;
|
||||
if (!is_foreign_name_valid(ac->link_suffix)) {
|
||||
if (ac->link_suffix.len != 0 && !is_foreign_name_valid(ac->link_suffix)) {
|
||||
error(elem, "Invalid link suffix: %.*s", LIT(ac->link_suffix));
|
||||
}
|
||||
} else {
|
||||
@@ -4297,6 +4310,7 @@ gb_internal void check_collect_value_decl(CheckerContext *c, Ast *decl) {
|
||||
}
|
||||
ast_node(pl, ProcLit, init);
|
||||
e = alloc_entity_procedure(d->scope, token, nullptr, pl->tags);
|
||||
d->foreign_require_results = c->foreign_context.require_results;
|
||||
if (fl != nullptr) {
|
||||
GB_ASSERT(fl->kind == Ast_Ident);
|
||||
e->Procedure.foreign_library_ident = fl;
|
||||
@@ -4520,7 +4534,9 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice<Ast *> const &n
|
||||
case_end;
|
||||
|
||||
case_ast_node(fb, ForeignBlockDecl, decl);
|
||||
check_add_foreign_block_decl(c, decl);
|
||||
if (curr_file != nullptr) {
|
||||
array_add(&curr_file->delayed_decls_queues[AstDelayQueue_ForeignBlock], decl);
|
||||
}
|
||||
case_end;
|
||||
|
||||
default:
|
||||
@@ -4536,6 +4552,14 @@ gb_internal void check_collect_entities(CheckerContext *c, Slice<Ast *> const &n
|
||||
// NOTE(bill): 'when' stmts need to be handled after the other as the condition may refer to something
|
||||
// declared after this stmt in source
|
||||
if (curr_file == nullptr) {
|
||||
// For 'foreign' block statements that are not in file scope.
|
||||
for_array(decl_index, nodes) {
|
||||
Ast *decl = nodes[decl_index];
|
||||
if (decl->kind == Ast_ForeignBlockDecl) {
|
||||
check_add_foreign_block_decl(c, decl);
|
||||
}
|
||||
}
|
||||
|
||||
for_array(decl_index, nodes) {
|
||||
Ast *decl = nodes[decl_index];
|
||||
if (decl->kind == Ast_WhenStmt) {
|
||||
@@ -4922,12 +4946,18 @@ gb_internal void check_add_import_decl(CheckerContext *ctx, Ast *decl) {
|
||||
}
|
||||
|
||||
|
||||
if (import_name.len == 0) {
|
||||
if (is_blank_ident(import_name) && !is_blank_ident(id->import_name.string)) {
|
||||
String invalid_name = id->fullpath;
|
||||
invalid_name = get_invalid_import_name(invalid_name);
|
||||
|
||||
error(id->token, "Import name %.*s, is not a valid identifier. Perhaps you want to reference the package by a different name like this: import <new_name> \"%.*s\" ", LIT(invalid_name), LIT(invalid_name));
|
||||
error(token, "Import name, %.*s, cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string));
|
||||
ERROR_BLOCK();
|
||||
|
||||
if (id->import_name.string.len > 0) {
|
||||
error(token, "Import name '%.*s' cannot be use as an import name as it is not a valid identifier", LIT(id->import_name.string));
|
||||
} else {
|
||||
error(id->token, "Import name '%.*s' is not a valid identifier", LIT(invalid_name));
|
||||
error_line("\tSuggestion: Rename the directory or explicitly set an import name like this 'import <new_name> %.*s'", LIT(id->relpath.string));
|
||||
}
|
||||
} else {
|
||||
GB_ASSERT(id->import_name.pos.line != 0);
|
||||
id->import_name.string = import_name;
|
||||
@@ -5206,9 +5236,9 @@ gb_internal bool collect_file_decl(CheckerContext *ctx, Ast *decl) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(fb, ForeignBlockDecl, decl);
|
||||
if (check_add_foreign_block_decl(ctx, decl)) {
|
||||
return true;
|
||||
}
|
||||
GB_ASSERT(ctx->collect_delayed_decls);
|
||||
decl->state_flags |= StateFlag_BeenHandled;
|
||||
array_add(&curr_file->delayed_decls_queues[AstDelayQueue_ForeignBlock], decl);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ws, WhenStmt, decl);
|
||||
@@ -5491,11 +5521,20 @@ gb_internal void check_import_entities(Checker *c) {
|
||||
for_array(i, pkg->files) {
|
||||
AstFile *f = pkg->files[i];
|
||||
reset_checker_context(&ctx, f, &untyped);
|
||||
ctx.collect_delayed_decls = false;
|
||||
|
||||
correct_type_aliases_in_scope(&ctx, pkg->scope);
|
||||
}
|
||||
|
||||
for_array(i, pkg->files) {
|
||||
AstFile *f = pkg->files[i];
|
||||
reset_checker_context(&ctx, f, &untyped);
|
||||
|
||||
ctx.collect_delayed_decls = true;
|
||||
for (Ast *decl : f->delayed_decls_queues[AstDelayQueue_ForeignBlock]) {
|
||||
check_add_foreign_block_decl(&ctx, decl);
|
||||
}
|
||||
array_clear(&f->delayed_decls_queues[AstDelayQueue_ForeignBlock]);
|
||||
}
|
||||
|
||||
for_array(i, pkg->files) {
|
||||
AstFile *f = pkg->files[i];
|
||||
reset_checker_context(&ctx, f, &untyped);
|
||||
@@ -5676,6 +5715,18 @@ gb_internal void check_procedure_later_from_entity(Checker *c, Entity *e, char c
|
||||
if ((e->flags & EntityFlag_ProcBodyChecked) != 0) {
|
||||
return;
|
||||
}
|
||||
if ((e->flags & EntityFlag_Overridden) != 0) {
|
||||
// NOTE (zen3ger) Delay checking of a proc alias until the underlying proc is checked.
|
||||
GB_ASSERT(e->aliased_of != nullptr);
|
||||
GB_ASSERT(e->aliased_of->kind == Entity_Procedure);
|
||||
if ((e->aliased_of->flags & EntityFlag_ProcBodyChecked) != 0) {
|
||||
e->flags |= EntityFlag_ProcBodyChecked;
|
||||
return;
|
||||
}
|
||||
// NOTE (zen3ger) A proc alias *does not* have a body and tags!
|
||||
check_procedure_later(c, e->file, e->token, e->decl_info, e->type, nullptr, 0);
|
||||
return;
|
||||
}
|
||||
Type *type = base_type(e->type);
|
||||
if (type == t_invalid) {
|
||||
return;
|
||||
@@ -6071,6 +6122,11 @@ gb_internal void check_deferred_procedures(Checker *c) {
|
||||
case DeferredProcedure_in_out_by_ptr: attribute = "deferred_in_out_by_ptr"; break;
|
||||
}
|
||||
|
||||
if (src == dst) {
|
||||
error(src->token, "'%.*s' cannot be used as its own %s", LIT(dst->token.string), attribute);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_type_polymorphic(src->type) || is_type_polymorphic(dst->type)) {
|
||||
error(src->token, "'%s' cannot be used with a polymorphic procedure", attribute);
|
||||
continue;
|
||||
|
||||
@@ -204,9 +204,12 @@ struct DeclInfo {
|
||||
Array<Ast *> attributes;
|
||||
Ast * proc_lit; // Ast_ProcLit
|
||||
Type * gen_proc_type; // Precalculated
|
||||
|
||||
bool is_using;
|
||||
bool where_clauses_evaluated;
|
||||
bool foreign_require_results;
|
||||
std::atomic<ProcCheckedState> proc_checked_state;
|
||||
|
||||
BlockingMutex proc_checked_mutex;
|
||||
isize defer_used;
|
||||
bool defer_use_checked;
|
||||
@@ -322,6 +325,7 @@ struct ForeignContext {
|
||||
String link_prefix;
|
||||
String link_suffix;
|
||||
EntityVisiblityKind visibility_kind;
|
||||
bool require_results;
|
||||
};
|
||||
|
||||
typedef Array<Entity *> CheckerTypePath;
|
||||
|
||||
@@ -46,6 +46,8 @@ enum BuiltinProcId {
|
||||
|
||||
BuiltinProc_has_target_feature,
|
||||
|
||||
BuiltinProc_constant_log2,
|
||||
|
||||
BuiltinProc_transpose,
|
||||
BuiltinProc_outer_product,
|
||||
BuiltinProc_hadamard_product,
|
||||
@@ -70,8 +72,8 @@ enum BuiltinProcId {
|
||||
BuiltinProc_overflow_sub,
|
||||
BuiltinProc_overflow_mul,
|
||||
|
||||
BuiltinProc_add_sat,
|
||||
BuiltinProc_sub_sat,
|
||||
BuiltinProc_saturating_add,
|
||||
BuiltinProc_saturating_sub,
|
||||
|
||||
BuiltinProc_sqrt,
|
||||
BuiltinProc_fused_mul_add,
|
||||
@@ -97,6 +99,7 @@ enum BuiltinProcId {
|
||||
BuiltinProc_prefetch_write_instruction,
|
||||
BuiltinProc_prefetch_write_data,
|
||||
|
||||
BuiltinProc__atomic_begin,
|
||||
BuiltinProc_atomic_type_is_lock_free,
|
||||
BuiltinProc_atomic_thread_fence,
|
||||
BuiltinProc_atomic_signal_fence,
|
||||
@@ -122,6 +125,7 @@ enum BuiltinProcId {
|
||||
BuiltinProc_atomic_compare_exchange_strong_explicit,
|
||||
BuiltinProc_atomic_compare_exchange_weak,
|
||||
BuiltinProc_atomic_compare_exchange_weak_explicit,
|
||||
BuiltinProc__atomic_end,
|
||||
|
||||
BuiltinProc_fixed_point_mul,
|
||||
BuiltinProc_fixed_point_div,
|
||||
@@ -141,8 +145,8 @@ BuiltinProc__simd_begin,
|
||||
BuiltinProc_simd_shl_masked, // C logic
|
||||
BuiltinProc_simd_shr_masked, // C logic
|
||||
|
||||
BuiltinProc_simd_add_sat, // saturation arithmetic
|
||||
BuiltinProc_simd_sub_sat, // saturation arithmetic
|
||||
BuiltinProc_simd_saturating_add, // saturation arithmetic
|
||||
BuiltinProc_simd_saturating_sub, // saturation arithmetic
|
||||
|
||||
BuiltinProc_simd_bit_and,
|
||||
BuiltinProc_simd_bit_or,
|
||||
@@ -174,6 +178,9 @@ BuiltinProc__simd_begin,
|
||||
BuiltinProc_simd_reduce_or,
|
||||
BuiltinProc_simd_reduce_xor,
|
||||
|
||||
BuiltinProc_simd_reduce_any,
|
||||
BuiltinProc_simd_reduce_all,
|
||||
|
||||
BuiltinProc_simd_shuffle,
|
||||
BuiltinProc_simd_select,
|
||||
|
||||
@@ -188,6 +195,12 @@ BuiltinProc__simd_begin,
|
||||
BuiltinProc_simd_lanes_rotate_left,
|
||||
BuiltinProc_simd_lanes_rotate_right,
|
||||
|
||||
BuiltinProc_simd_gather,
|
||||
BuiltinProc_simd_scatter,
|
||||
BuiltinProc_simd_masked_load,
|
||||
BuiltinProc_simd_masked_store,
|
||||
BuiltinProc_simd_masked_expand_load,
|
||||
BuiltinProc_simd_masked_compress_store,
|
||||
|
||||
// Platform specific SIMD intrinsics
|
||||
BuiltinProc_simd_x86__MM_SHUFFLE,
|
||||
@@ -302,6 +315,8 @@ BuiltinProc__type_simple_boolean_end,
|
||||
BuiltinProc_type_map_info,
|
||||
BuiltinProc_type_map_cell_info,
|
||||
|
||||
BuiltinProc_type_has_shared_fields,
|
||||
|
||||
BuiltinProc__type_end,
|
||||
|
||||
BuiltinProc_procedure_of,
|
||||
@@ -371,6 +386,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
|
||||
{STR_LIT("has_target_feature"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("constant_log2"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("transpose"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("outer_product"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("hadamard_product"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
@@ -396,8 +413,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("overflow_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("overflow_mul"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("add_sat"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("sub_sat"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("saturating_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("saturating_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("sqrt"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("fused_mul_add"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
@@ -423,6 +440,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("prefetch_write_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("atomic_type_is_lock_free"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("atomic_thread_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("atomic_signal_fence"), 1, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
@@ -448,6 +466,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("atomic_compare_exchange_strong_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||
{STR_LIT("atomic_compare_exchange_weak"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||
{STR_LIT("atomic_compare_exchange_weak_explicit"), 5, false, Expr_Expr, BuiltinProcPkg_intrinsics, false, true},
|
||||
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("fixed_point_mul"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("fixed_point_div"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
@@ -467,8 +486,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("simd_shl_masked"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_shr_masked"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("simd_add_sat"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_sub_sat"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_saturating_add"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_saturating_sub"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("simd_bit_and"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_bit_or"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
@@ -501,6 +520,10 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("simd_reduce_or"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_reduce_xor"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("simd_reduce_any"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_reduce_all"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
|
||||
{STR_LIT("simd_shuffle"), 2, true, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_select"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
@@ -515,6 +538,13 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("simd_lanes_rotate_left"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_lanes_rotate_right"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("simd_gather"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_scatter"), 3, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_masked_load"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_masked_store"), 3, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_masked_expand_load"), 3, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("simd_masked_compress_store"), 3, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("simd_x86__MM_SHUFFLE"), 4, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
@@ -623,6 +653,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
||||
{STR_LIT("type_map_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
{STR_LIT("type_map_cell_info"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT("type_has_shared_fields"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics},
|
||||
|
||||
{STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
|
||||
|
||||
|
||||
+14
-2
@@ -829,7 +829,6 @@ gb_internal OdinDocEntityIndex odin_doc_add_entity(OdinDocWriter *w, Entity *e)
|
||||
OdinDocEntityIndex doc_entity_index = odin_doc_write_item(w, &w->entities, &doc_entity, &dst);
|
||||
map_set(&w->entity_cache, e, doc_entity_index);
|
||||
|
||||
|
||||
Ast *type_expr = nullptr;
|
||||
Ast *init_expr = nullptr;
|
||||
Ast *decl_node = nullptr;
|
||||
@@ -997,7 +996,8 @@ gb_internal void odin_doc_update_entities(OdinDocWriter *w) {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const &entry : w->entity_cache) {
|
||||
for (u32 i = 0; i < w->entity_cache.count; i++) {
|
||||
auto entry = w->entity_cache.entries[i];
|
||||
Entity *e = entry.key;
|
||||
OdinDocEntityIndex entity_index = entry.value;
|
||||
OdinDocTypeIndex type_index = odin_doc_type(w, e->type);
|
||||
@@ -1007,6 +1007,9 @@ gb_internal void odin_doc_update_entities(OdinDocWriter *w) {
|
||||
|
||||
switch (e->kind) {
|
||||
case Entity_Variable:
|
||||
if (w->state == OdinDocWriterState_Writing) {
|
||||
GB_ASSERT(type_index != 0);
|
||||
}
|
||||
foreign_library = odin_doc_add_entity(w, e->Variable.foreign_library);
|
||||
break;
|
||||
case Entity_Procedure:
|
||||
@@ -1026,8 +1029,17 @@ gb_internal void odin_doc_update_entities(OdinDocWriter *w) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (w->state == OdinDocWriterState_Preparing) {
|
||||
GB_ASSERT(entity_index == 0);
|
||||
} else {
|
||||
GB_ASSERT(entity_index != 0);
|
||||
}
|
||||
|
||||
OdinDocEntity *dst = odin_doc_get_item(w, &w->entities, entity_index);
|
||||
if (dst) {
|
||||
if (dst->kind == OdinDocEntity_Variable) {
|
||||
GB_ASSERT(type_index != 0);
|
||||
}
|
||||
dst->type = type_index;
|
||||
dst->foreign_library = foreign_library;
|
||||
dst->grouped_entities = grouped_entities;
|
||||
|
||||
@@ -820,6 +820,35 @@ gb_internal int error_value_cmp(void const *a, void const *b) {
|
||||
return token_pos_cmp(x->pos, y->pos);
|
||||
}
|
||||
|
||||
gb_global String error_article_table[][2] = {
|
||||
{str_lit("a "), str_lit("bit_set literal")},
|
||||
{str_lit("a "), str_lit("constant declaration")},
|
||||
{str_lit("a "), str_lit("dynamiic array literal")},
|
||||
{str_lit("a "), str_lit("map index")},
|
||||
{str_lit("a "), str_lit("map literal")},
|
||||
{str_lit("a "), str_lit("matrix literal")},
|
||||
{str_lit("a "), str_lit("polymorphic type argument")},
|
||||
{str_lit("a "), str_lit("procedure argument")},
|
||||
{str_lit("a "), str_lit("simd vector literal")},
|
||||
{str_lit("a "), str_lit("slice literal")},
|
||||
{str_lit("a "), str_lit("structure literal")},
|
||||
{str_lit("a "), str_lit("variable declaration")},
|
||||
{str_lit("an "), str_lit("'any' literal")},
|
||||
{str_lit("an "), str_lit("array literal")},
|
||||
{str_lit("an "), str_lit("enumerated array literal")},
|
||||
|
||||
};
|
||||
|
||||
// Returns definite or indefinite article matching `context_name`, or "" if not found.
|
||||
gb_internal String error_article(String context_name) {
|
||||
for (int i = 0; i < gb_count_of(error_article_table); i += 1) {
|
||||
if (context_name == error_article_table[i][1]) {
|
||||
return error_article_table[i][0];
|
||||
}
|
||||
}
|
||||
return str_lit("");
|
||||
}
|
||||
|
||||
gb_internal bool errors_already_printed = false;
|
||||
|
||||
gb_internal void print_all_errors(void) {
|
||||
|
||||
+15
-2
@@ -39,7 +39,7 @@ extern "C" {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) || defined(__aarch64__)
|
||||
#if defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) || defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64)
|
||||
#ifndef GB_ARCH_64_BIT
|
||||
#define GB_ARCH_64_BIT 1
|
||||
#endif
|
||||
@@ -144,6 +144,13 @@ extern "C" {
|
||||
#define GB_CACHE_LINE_SIZE 64
|
||||
#endif
|
||||
|
||||
#elif defined(__riscv)
|
||||
#ifndef GB_CPU_RISCV
|
||||
#define GB_CPU_RISCV 1
|
||||
#endif
|
||||
#ifndef GB_CACHE_LINE_SIZE
|
||||
#define GB_CACHE_LINE_SIZE 64
|
||||
#endif
|
||||
#else
|
||||
#error Unknown CPU Type
|
||||
#endif
|
||||
@@ -2562,7 +2569,7 @@ gb_inline void *gb_memcopy(void *dest, void const *source, isize n) {
|
||||
|
||||
void *dest_copy = dest;
|
||||
__asm__ __volatile__("rep movsb" : "+D"(dest_copy), "+S"(source), "+c"(n) : : "memory");
|
||||
#elif defined(GB_CPU_ARM)
|
||||
#elif defined(GB_CPU_ARM) || defined(GB_CPU_RISCV)
|
||||
u8 *s = cast(u8 *)source;
|
||||
u8 *d = cast(u8 *)dest;
|
||||
for (isize i = 0; i < n; i++) {
|
||||
@@ -6267,6 +6274,12 @@ gb_no_inline isize gb_snprintf_va(char *text, isize max_len, char const *fmt, va
|
||||
asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value));
|
||||
return virtual_timer_value;
|
||||
}
|
||||
#elif defined(__riscv)
|
||||
gb_inline u64 gb_rdtsc(void) {
|
||||
u64 result = 0;
|
||||
__asm__ volatile("rdcycle %0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
#warning "gb_rdtsc not supported"
|
||||
gb_inline u64 gb_rdtsc(void) { return 0; }
|
||||
|
||||
+21
-8
@@ -388,6 +388,12 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
} else {
|
||||
timings_start_section(timings, str_lit("ld-link"));
|
||||
|
||||
// Link using `clang`, unless overridden by `ODIN_CLANG_PATH` environment variable.
|
||||
const char* clang_path = gb_get_env("ODIN_CLANG_PATH", permanent_allocator());
|
||||
if (clang_path == NULL) {
|
||||
clang_path = "clang";
|
||||
}
|
||||
|
||||
// NOTE(vassvik): get cwd, for used for local shared libs linking, since those have to be relative to the exe
|
||||
char cwd[256];
|
||||
#if !defined(GB_SYSTEM_WINDOWS)
|
||||
@@ -458,7 +464,20 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
}
|
||||
#endif // GB_ARCH_*_BIT
|
||||
|
||||
if (is_osx) {
|
||||
if (build_context.metrics.arch == TargetArch_riscv64) {
|
||||
result = system_exec_command_line_app("clang",
|
||||
"%s \"%.*s\" "
|
||||
"-c -o \"%.*s\" "
|
||||
"-target %.*s -march=rv64gc "
|
||||
"%.*s "
|
||||
"",
|
||||
clang_path,
|
||||
LIT(asm_file),
|
||||
LIT(obj_file),
|
||||
LIT(build_context.metrics.target_triplet),
|
||||
LIT(build_context.extra_assembler_flags)
|
||||
);
|
||||
} else if (is_osx) {
|
||||
// `as` comes with MacOS.
|
||||
result = system_exec_command_line_app("as",
|
||||
"as \"%.*s\" "
|
||||
@@ -592,7 +611,7 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
link_settings = gb_string_appendc(link_settings, "-Wl,-fini,'_odin_exit_point' ");
|
||||
}
|
||||
|
||||
} else if (build_context.metrics.os != TargetOs_openbsd && build_context.metrics.os != TargetOs_haiku) {
|
||||
} else if (build_context.metrics.os != TargetOs_openbsd && build_context.metrics.os != TargetOs_haiku && build_context.metrics.arch != TargetArch_riscv64) {
|
||||
// OpenBSD and Haiku default to PIE executable. do not pass -no-pie for it.
|
||||
link_settings = gb_string_appendc(link_settings, "-no-pie ");
|
||||
}
|
||||
@@ -635,12 +654,6 @@ gb_internal i32 linker_stage(LinkerData *gen) {
|
||||
}
|
||||
}
|
||||
|
||||
// Link using `clang`, unless overridden by `ODIN_CLANG_PATH` environment variable.
|
||||
const char* clang_path = gb_get_env("ODIN_CLANG_PATH", permanent_allocator());
|
||||
if (clang_path == NULL) {
|
||||
clang_path = "clang";
|
||||
}
|
||||
|
||||
gbString link_command_line = gb_string_make(heap_allocator(), clang_path);
|
||||
defer (gb_string_free(link_command_line));
|
||||
|
||||
|
||||
+270
-14
@@ -332,7 +332,7 @@ gb_internal i64 lb_alignof(LLVMTypeRef type) {
|
||||
}
|
||||
|
||||
|
||||
#define LB_ABI_INFO(name) lbFunctionType *name(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, LLVMTypeRef return_type, bool return_is_defined, bool return_is_tuple, ProcCallingConvention calling_convention, Type *original_type)
|
||||
#define LB_ABI_INFO(name) lbFunctionType *name(lbModule *m, LLVMTypeRef *arg_types, unsigned arg_count, LLVMTypeRef return_type, bool return_is_defined, bool return_is_tuple, ProcCallingConvention calling_convention, Type *original_type)
|
||||
typedef LB_ABI_INFO(lbAbiInfoType);
|
||||
|
||||
#define LB_ABI_COMPUTE_RETURN_TYPE(name) lbArgType name(lbFunctionType *ft, LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined, bool return_is_tuple)
|
||||
@@ -380,6 +380,7 @@ namespace lbAbi386 {
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count);
|
||||
@@ -461,6 +462,7 @@ namespace lbAbiAmd64Win64 {
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count);
|
||||
@@ -571,6 +573,7 @@ namespace lbAbiAmd64SysV {
|
||||
gb_internal LLVMTypeRef llreg(LLVMContextRef c, Array<RegClass> const ®_classes, LLVMTypeRef type);
|
||||
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->calling_convention = calling_convention;
|
||||
@@ -1009,6 +1012,7 @@ namespace lbAbiArm64 {
|
||||
gb_internal bool is_homogenous_aggregate(LLVMContextRef c, LLVMTypeRef type, LLVMTypeRef *base_type_, unsigned *member_count_);
|
||||
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count);
|
||||
@@ -1243,6 +1247,7 @@ namespace lbAbiWasm {
|
||||
enum {MAX_DIRECT_STRUCT_SIZE = 32};
|
||||
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->calling_convention = calling_convention;
|
||||
@@ -1408,6 +1413,7 @@ namespace lbAbiArm32 {
|
||||
gb_internal lbArgType compute_return_type(LLVMContextRef c, LLVMTypeRef return_type, bool return_is_defined);
|
||||
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention);
|
||||
@@ -1485,8 +1491,256 @@ namespace lbAbiArm32 {
|
||||
}
|
||||
};
|
||||
|
||||
namespace lbAbiRiscv64 {
|
||||
|
||||
gb_internal bool is_register(LLVMTypeRef type) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
switch (kind) {
|
||||
case LLVMIntegerTypeKind:
|
||||
case LLVMHalfTypeKind:
|
||||
case LLVMFloatTypeKind:
|
||||
case LLVMDoubleTypeKind:
|
||||
case LLVMPointerTypeKind:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gb_internal bool is_float(LLVMTypeRef type) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
switch (kind) {
|
||||
case LLVMHalfTypeKind:
|
||||
case LLVMFloatTypeKind:
|
||||
case LLVMDoubleTypeKind:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal lbArgType non_struct(LLVMContextRef c, LLVMTypeRef type) {
|
||||
LLVMAttributeRef attr = nullptr;
|
||||
LLVMTypeRef i1 = LLVMInt1TypeInContext(c);
|
||||
if (type == i1) {
|
||||
attr = lb_create_enum_attribute(c, "zeroext");
|
||||
}
|
||||
return lb_arg_type_direct(type, nullptr, nullptr, attr);
|
||||
}
|
||||
|
||||
gb_internal void flatten(lbModule *m, Array<LLVMTypeRef> *fields, LLVMTypeRef type, bool with_padding) {
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
switch (kind) {
|
||||
case LLVMStructTypeKind: {
|
||||
if (LLVMIsPackedStruct(type)) {
|
||||
array_add(fields, type);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!with_padding) {
|
||||
auto field_remapping = map_get(&m->struct_field_remapping, cast(void *)type);
|
||||
if (field_remapping) {
|
||||
auto remap = *field_remapping;
|
||||
for_array(i, remap) {
|
||||
flatten(m, fields, LLVMStructGetTypeAtIndex(type, remap[i]), with_padding);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
debugf("no field mapping for type: %s\n", LLVMPrintTypeToString(type));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned elem_count = LLVMCountStructElementTypes(type);
|
||||
for (unsigned i = 0; i < elem_count; i += 1) {
|
||||
flatten(m, fields, LLVMStructGetTypeAtIndex(type, i), with_padding);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case LLVMArrayTypeKind: {
|
||||
unsigned len = LLVMGetArrayLength(type);
|
||||
LLVMTypeRef elem = OdinLLVMGetArrayElementType(type);
|
||||
for (unsigned i = 0; i < len; i += 1) {
|
||||
flatten(m, fields, elem, with_padding);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
array_add(fields, type);
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal lbArgType compute_arg_type(lbModule *m, LLVMTypeRef type, int *gprs_left, int *fprs_left, Type *odin_type) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
|
||||
int xlen = 8; // 8 byte int register size for riscv64.
|
||||
|
||||
// NOTE: we are requiring both of these to be enabled so we can just hard-code 8.
|
||||
// int flen = 0;
|
||||
// if (check_target_feature_is_enabled(str_lit("d"), nullptr)) {
|
||||
// flen = 8; // Double precision floats are enabled.
|
||||
// } else if (check_target_feature_is_enabled(str_lit("f"), nullptr)) {
|
||||
// flen = 4; // Single precision floats are enabled.
|
||||
// }
|
||||
int flen = 8;
|
||||
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(type);
|
||||
i64 size = lb_sizeof(type);
|
||||
|
||||
if (size == 0) {
|
||||
return lb_arg_type_direct(type, LLVMStructTypeInContext(c, nullptr, 0, false), nullptr, nullptr);
|
||||
}
|
||||
|
||||
LLVMTypeRef orig_type = type;
|
||||
|
||||
// Flatten down the type so it is easier to check all the ABI conditions.
|
||||
// Note that we also need to remove all implicit padding fields Odin adds so we keep ABI
|
||||
// compatibility for struct declarations.
|
||||
if (kind == LLVMStructTypeKind && size <= gb_max(2*xlen, 2*flen)) {
|
||||
Array<LLVMTypeRef> fields = array_make<LLVMTypeRef>(temporary_allocator(), 0, LLVMCountStructElementTypes(type));
|
||||
flatten(m, &fields, type, false);
|
||||
|
||||
if (fields.count == 1) {
|
||||
type = fields[0];
|
||||
} else {
|
||||
type = LLVMStructTypeInContext(c, fields.data, cast(unsigned)fields.count, false);
|
||||
}
|
||||
|
||||
kind = LLVMGetTypeKind(type);
|
||||
size = lb_sizeof(type);
|
||||
GB_ASSERT_MSG(size == lb_sizeof(orig_type), "flattened: %s of size %d, original: %s of size %d", LLVMPrintTypeToString(type), size, LLVMPrintTypeToString(orig_type), lb_sizeof(orig_type));
|
||||
}
|
||||
|
||||
if (is_float(type) && size <= flen && *fprs_left >= 1) {
|
||||
*fprs_left -= 1;
|
||||
return non_struct(c, orig_type);
|
||||
}
|
||||
|
||||
if (kind == LLVMStructTypeKind && size <= 2*flen) {
|
||||
unsigned elem_count = LLVMCountStructElementTypes(type);
|
||||
if (elem_count == 2) {
|
||||
LLVMTypeRef ty1 = LLVMStructGetTypeAtIndex(type, 0);
|
||||
i64 ty1s = lb_sizeof(ty1);
|
||||
LLVMTypeRef ty2 = LLVMStructGetTypeAtIndex(type, 1);
|
||||
i64 ty2s = lb_sizeof(ty2);
|
||||
|
||||
if (is_float(ty1) && is_float(ty2) && ty1s <= flen && ty2s <= flen && *fprs_left >= 2) {
|
||||
*fprs_left -= 2;
|
||||
return lb_arg_type_direct(orig_type, type, nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (is_float(ty1) && is_register(ty2) && ty1s <= flen && ty2s <= xlen && *fprs_left >= 1 && *gprs_left >= 1) {
|
||||
*fprs_left -= 1;
|
||||
*gprs_left -= 1;
|
||||
return lb_arg_type_direct(orig_type, type, nullptr, nullptr);
|
||||
}
|
||||
|
||||
if (is_register(ty1) && is_float(ty2) && ty1s <= xlen && ty2s <= flen && *gprs_left >= 1 && *fprs_left >= 1) {
|
||||
*fprs_left -= 1;
|
||||
*gprs_left -= 1;
|
||||
return lb_arg_type_direct(orig_type, type, nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// At this point all the cases for floating point registers are exhausted, fit it into
|
||||
// integer registers or the stack.
|
||||
// LLVM automatically handles putting args on the stack so we don't check the amount of registers that are left here.
|
||||
|
||||
if (size <= xlen) {
|
||||
*gprs_left -= 1;
|
||||
if (is_register(type)) {
|
||||
return non_struct(c, orig_type);
|
||||
} else {
|
||||
return lb_arg_type_direct(orig_type, LLVMIntTypeInContext(c, cast(unsigned)(size*8)), nullptr, nullptr);
|
||||
}
|
||||
} else if (size <= 2*xlen) {
|
||||
LLVMTypeRef *fields = gb_alloc_array(temporary_allocator(), LLVMTypeRef, 2);
|
||||
fields[0] = LLVMIntTypeInContext(c, cast(unsigned)(xlen*8));
|
||||
fields[1] = LLVMIntTypeInContext(c, cast(unsigned)((size-xlen)*8));
|
||||
|
||||
*gprs_left -= 2;
|
||||
return lb_arg_type_direct(orig_type, LLVMStructTypeInContext(c, fields, 2, false), nullptr, nullptr);
|
||||
} else {
|
||||
return lb_arg_type_indirect(orig_type, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal Array<lbArgType> compute_arg_types(lbModule *m, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention, Type *odin_type, int *gprs, int *fprs) {
|
||||
auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
|
||||
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
LLVMTypeRef type = arg_types[i];
|
||||
args[i] = compute_arg_type(m, type, gprs, fprs, odin_type);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
gb_internal lbArgType compute_return_type(lbFunctionType *ft, lbModule *m, LLVMTypeRef return_type, bool return_is_defined, bool return_is_tuple, Type *odin_type, int *agprs) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
|
||||
if (!return_is_defined) {
|
||||
return lb_arg_type_direct(LLVMVoidTypeInContext(c));
|
||||
}
|
||||
|
||||
// There are two registers for return types.
|
||||
int gprs = 2;
|
||||
int fprs = 2;
|
||||
lbArgType ret = compute_arg_type(m, return_type, &gprs, &fprs, odin_type);
|
||||
|
||||
// Return didn't fit into the return registers, so caller allocates and it is returned via
|
||||
// an out-pointer.
|
||||
if (ret.kind == lbArg_Indirect) {
|
||||
|
||||
// Transform multiple return into out pointers if possible.
|
||||
if (return_is_tuple) {
|
||||
if (lb_is_type_kind(return_type, LLVMStructTypeKind)) {
|
||||
int field_count = cast(int)LLVMCountStructElementTypes(return_type);
|
||||
if (field_count > 1 && field_count <= *agprs) {
|
||||
ft->original_arg_count = ft->args.count;
|
||||
ft->multiple_return_original_type = return_type;
|
||||
|
||||
for (int i = 0; i < field_count-1; i++) {
|
||||
LLVMTypeRef field_type = LLVMStructGetTypeAtIndex(return_type, i);
|
||||
LLVMTypeRef field_pointer_type = LLVMPointerType(field_type, 0);
|
||||
lbArgType ret_partial = lb_arg_type_direct(field_pointer_type);
|
||||
array_add(&ft->args, ret_partial);
|
||||
*agprs -= 1;
|
||||
}
|
||||
GB_ASSERT(*agprs >= 0);
|
||||
|
||||
// override the return type for the last field
|
||||
LLVMTypeRef new_return_type = LLVMStructGetTypeAtIndex(return_type, field_count-1);
|
||||
return compute_return_type(ft, m, new_return_type, true, false, odin_type, agprs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLVMAttributeRef attr = lb_create_enum_attribute_with_type(c, "sret", ret.type);
|
||||
return lb_arg_type_indirect(ret.type, attr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = m->ctx;
|
||||
ft->calling_convention = calling_convention;
|
||||
|
||||
int gprs = 8;
|
||||
int fprs = 8;
|
||||
|
||||
ft->args = compute_arg_types(m, arg_types, arg_count, calling_convention, original_type, &gprs, &fprs);
|
||||
ft->ret = compute_return_type(ft, m, return_type, return_is_defined, return_is_tuple, original_type, &gprs);
|
||||
|
||||
return ft;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gb_internal LB_ABI_INFO(lb_get_abi_info_internal) {
|
||||
LLVMContextRef c = m->ctx;
|
||||
|
||||
switch (calling_convention) {
|
||||
case ProcCC_None:
|
||||
case ProcCC_InlineAsm:
|
||||
@@ -1507,33 +1761,35 @@ gb_internal LB_ABI_INFO(lb_get_abi_info_internal) {
|
||||
}
|
||||
case ProcCC_Win64:
|
||||
GB_ASSERT(build_context.metrics.arch == TargetArch_amd64);
|
||||
return lbAbiAmd64Win64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiAmd64Win64::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
case ProcCC_SysV:
|
||||
GB_ASSERT(build_context.metrics.arch == TargetArch_amd64);
|
||||
return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiAmd64SysV::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
}
|
||||
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_amd64:
|
||||
if (build_context.metrics.os == TargetOs_windows) {
|
||||
return lbAbiAmd64Win64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiAmd64Win64::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
} else if (build_context.metrics.abi == TargetABI_Win64) {
|
||||
return lbAbiAmd64Win64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiAmd64Win64::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
} else if (build_context.metrics.abi == TargetABI_SysV) {
|
||||
return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiAmd64SysV::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
} else {
|
||||
return lbAbiAmd64SysV::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiAmd64SysV::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
}
|
||||
case TargetArch_i386:
|
||||
return lbAbi386::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbi386::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
case TargetArch_arm32:
|
||||
return lbAbiArm32::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiArm32::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
case TargetArch_arm64:
|
||||
return lbAbiArm64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiArm64::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
case TargetArch_wasm32:
|
||||
return lbAbiWasm::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiWasm::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
case TargetArch_wasm64p32:
|
||||
return lbAbiWasm::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
return lbAbiWasm::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
case TargetArch_riscv64:
|
||||
return lbAbiRiscv64::abi_info(m, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
}
|
||||
|
||||
GB_PANIC("Unsupported ABI");
|
||||
@@ -1543,7 +1799,7 @@ gb_internal LB_ABI_INFO(lb_get_abi_info_internal) {
|
||||
|
||||
gb_internal LB_ABI_INFO(lb_get_abi_info) {
|
||||
lbFunctionType *ft = lb_get_abi_info_internal(
|
||||
c,
|
||||
m,
|
||||
arg_types, arg_count,
|
||||
return_type, return_is_defined,
|
||||
ALLOW_SPLIT_MULTI_RETURNS && return_is_tuple && is_calling_convention_odin(calling_convention),
|
||||
@@ -1555,7 +1811,7 @@ gb_internal LB_ABI_INFO(lb_get_abi_info) {
|
||||
// This is to make it consistent when and how it is handled
|
||||
if (calling_convention == ProcCC_Odin) {
|
||||
// append the `context` pointer
|
||||
lbArgType context_param = lb_arg_type_direct(LLVMPointerType(LLVMInt8TypeInContext(c), 0));
|
||||
lbArgType context_param = lb_arg_type_direct(LLVMPointerType(LLVMInt8TypeInContext(m->ctx), 0));
|
||||
array_add(&ft->args, context_param);
|
||||
}
|
||||
|
||||
|
||||
+37
-1
@@ -40,7 +40,10 @@ String get_default_microarchitecture() {
|
||||
default_march = str_lit("x86-64-v2");
|
||||
}
|
||||
}
|
||||
} else if (build_context.metrics.arch == TargetArch_riscv64) {
|
||||
default_march = str_lit("generic-rv64");
|
||||
}
|
||||
|
||||
return default_march;
|
||||
}
|
||||
|
||||
@@ -65,13 +68,33 @@ gb_internal String get_default_features() {
|
||||
}
|
||||
|
||||
String microarch = get_final_microarchitecture();
|
||||
|
||||
// NOTE(laytan): for riscv64 to work properly with Odin, we need to enforce some features.
|
||||
// and we also overwrite the generic target to include more features so we don't default to
|
||||
// a potato feature set.
|
||||
if (bc->metrics.arch == TargetArch_riscv64) {
|
||||
if (microarch == str_lit("generic-rv64")) {
|
||||
// This is what clang does by default (on -march=rv64gc for General Computing), seems good to also default to.
|
||||
String features = str_lit("64bit,a,c,d,f,m,relax,zicsr,zifencei");
|
||||
|
||||
// Update the features string so LLVM uses it later.
|
||||
if (bc->target_features_string.len > 0) {
|
||||
bc->target_features_string = concatenate3_strings(permanent_allocator(), features, str_lit(","), bc->target_features_string);
|
||||
} else {
|
||||
bc->target_features_string = features;
|
||||
}
|
||||
|
||||
return features;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = off; i < off+target_microarch_counts[bc->metrics.arch]; i += 1) {
|
||||
if (microarch_features_list[i].microarch == microarch) {
|
||||
return microarch_features_list[i].features;
|
||||
}
|
||||
}
|
||||
|
||||
GB_PANIC("unknown microarch");
|
||||
GB_PANIC("unknown microarch: %.*s", LIT(microarch));
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -3030,6 +3053,12 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
|
||||
// Always use PIC for OpenBSD and Haiku: they default to PIE
|
||||
reloc_mode = LLVMRelocPIC;
|
||||
}
|
||||
|
||||
if (build_context.metrics.arch == TargetArch_riscv64) {
|
||||
// NOTE(laytan): didn't seem to work without this.
|
||||
reloc_mode = LLVMRelocPIC;
|
||||
}
|
||||
|
||||
break;
|
||||
case RelocMode_Static:
|
||||
reloc_mode = LLVMRelocStatic;
|
||||
@@ -3052,6 +3081,13 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
|
||||
lbModule *m = entry.value;
|
||||
m->target_machine = target_machine;
|
||||
LLVMSetModuleDataLayout(m->mod, LLVMCreateTargetDataLayout(target_machine));
|
||||
|
||||
#if LLVM_VERSION_MAJOR >= 18
|
||||
if (build_context.fast_isel) {
|
||||
LLVMSetTargetMachineFastISel(m->target_machine, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
array_add(&target_machines, target_machine);
|
||||
}
|
||||
|
||||
|
||||
@@ -137,6 +137,12 @@ enum lbFunctionPassManagerKind {
|
||||
lbFunctionPassManager_COUNT
|
||||
};
|
||||
|
||||
struct lbPadType {
|
||||
i64 padding;
|
||||
i64 padding_align;
|
||||
LLVMTypeRef type;
|
||||
};
|
||||
|
||||
struct lbModule {
|
||||
LLVMModuleRef mod;
|
||||
LLVMContextRef ctx;
|
||||
@@ -199,6 +205,9 @@ struct lbModule {
|
||||
PtrMap<Ast *, lbAddr> exact_value_compound_literal_addr_map; // Key: Ast_CompoundLit
|
||||
|
||||
LLVMPassManagerRef function_pass_managers[lbFunctionPassManager_COUNT];
|
||||
|
||||
BlockingMutex pad_types_mutex;
|
||||
Array<lbPadType> pad_types;
|
||||
};
|
||||
|
||||
struct lbEntityCorrection {
|
||||
|
||||
+57
-10
@@ -55,6 +55,16 @@ gb_internal void lb_debug_file_line(lbModule *m, Ast *node, LLVMMetadataRef *fil
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal LLVMMetadataRef lb_debug_procedure_parameters(lbModule *m, Type *type) {
|
||||
if (is_type_proc(type)) {
|
||||
return lb_debug_type(m, t_rawptr);
|
||||
}
|
||||
if (type->kind == Type_Tuple && type->Tuple.variables.count == 1) {
|
||||
return lb_debug_procedure_parameters(m, type->Tuple.variables[0]->type);
|
||||
}
|
||||
return lb_debug_type(m, type);
|
||||
}
|
||||
|
||||
gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type) {
|
||||
i64 size = type_size_of(type); // Check size
|
||||
gb_unused(size);
|
||||
@@ -72,13 +82,36 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type)
|
||||
parameter_count += 1;
|
||||
}
|
||||
}
|
||||
LLVMMetadataRef *parameters = gb_alloc_array(permanent_allocator(), LLVMMetadataRef, parameter_count);
|
||||
|
||||
unsigned param_index = 0;
|
||||
if (type->Proc.result_count == 0) {
|
||||
parameters[param_index++] = nullptr;
|
||||
} else {
|
||||
parameters[param_index++] = lb_debug_type(m, type->Proc.results);
|
||||
auto parameters = array_make<LLVMMetadataRef>(permanent_allocator(), 0, type->Proc.param_count+type->Proc.result_count+2);
|
||||
|
||||
array_add(¶meters, cast(LLVMMetadataRef)nullptr);
|
||||
|
||||
bool return_is_tuple = false;
|
||||
if (type->Proc.result_count != 0) {
|
||||
Type *single_ret = reduce_tuple_to_single_type(type->Proc.results);
|
||||
if (is_type_proc(single_ret)) {
|
||||
single_ret = t_rawptr;
|
||||
}
|
||||
if (is_type_tuple(single_ret) && is_calling_convention_odin(type->Proc.calling_convention)) {
|
||||
LLVMTypeRef actual = lb_type_internal_for_procedures_raw(m, type);
|
||||
actual = LLVMGetReturnType(actual);
|
||||
if (actual == nullptr) {
|
||||
// results were passed as a single pointer
|
||||
parameters[0] = lb_debug_procedure_parameters(m, single_ret);
|
||||
} else {
|
||||
LLVMTypeRef possible = lb_type(m, type->Proc.results);
|
||||
if (possible == actual) {
|
||||
// results were returned directly
|
||||
parameters[0] = lb_debug_procedure_parameters(m, single_ret);
|
||||
} else {
|
||||
// resulsts were returned separately
|
||||
return_is_tuple = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parameters[0] = lb_debug_procedure_parameters(m, single_ret);
|
||||
}
|
||||
}
|
||||
|
||||
LLVMMetadataRef file = nullptr;
|
||||
@@ -88,8 +121,22 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type)
|
||||
if (e->kind != Entity_Variable) {
|
||||
continue;
|
||||
}
|
||||
parameters[param_index] = lb_debug_type(m, e->type);
|
||||
param_index += 1;
|
||||
array_add(¶meters, lb_debug_procedure_parameters(m, e->type));
|
||||
}
|
||||
|
||||
|
||||
if (return_is_tuple) {
|
||||
Type *results = type->Proc.results;
|
||||
GB_ASSERT(results != nullptr && results->kind == Type_Tuple);
|
||||
isize count = results->Tuple.variables.count;
|
||||
parameters[0] = lb_debug_procedure_parameters(m, results->Tuple.variables[count-1]->type);
|
||||
for (isize i = 0; i < count-1; i++) {
|
||||
array_add(¶meters, lb_debug_procedure_parameters(m, results->Tuple.variables[i]->type));
|
||||
}
|
||||
}
|
||||
|
||||
if (type->Proc.calling_convention == ProcCC_Odin) {
|
||||
array_add(¶meters, lb_debug_type(m, t_context_ptr));
|
||||
}
|
||||
|
||||
LLVMDIFlags flags = LLVMDIFlagZero;
|
||||
@@ -97,7 +144,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type)
|
||||
flags = LLVMDIFlagNoReturn;
|
||||
}
|
||||
|
||||
return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters, parameter_count, flags);
|
||||
return LLVMDIBuilderCreateSubroutineType(m->debug_builder, file, parameters.data, cast(unsigned)parameters.count, flags);
|
||||
}
|
||||
|
||||
gb_internal LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &name, Type *type, u64 offset_in_bits) {
|
||||
@@ -969,7 +1016,7 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
|
||||
return lb_debug_struct(m, type, bt, name, scope, file, line);
|
||||
}
|
||||
|
||||
case Type_Struct: return lb_debug_struct(m, type, base_type(type), name, scope, file, line);
|
||||
case Type_Struct: return lb_debug_struct(m, type, bt, name, scope, file, line);
|
||||
case Type_Slice: return lb_debug_slice(m, type, name, scope, file, line);
|
||||
case Type_DynamicArray: return lb_debug_dynamic_array(m, type, name, scope, file, line);
|
||||
case Type_Union: return lb_debug_union(m, type, name, scope, file, line);
|
||||
|
||||
+62
-36
@@ -136,6 +136,11 @@ gb_internal lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x,
|
||||
switch (op) {
|
||||
case Token_Xor:
|
||||
opv = LLVMBuildNot(p->builder, v, "");
|
||||
if (is_type_bit_set(elem_type)) {
|
||||
ExactValue ev_mask = exact_bit_set_all_set_mask(elem_type);
|
||||
lbValue mask = lb_const_value(p->module, elem_type, ev_mask);
|
||||
opv = LLVMBuildAnd(p->builder, opv, mask.value, "");
|
||||
}
|
||||
break;
|
||||
case Token_Sub:
|
||||
if (is_type_float(elem_type)) {
|
||||
@@ -176,8 +181,14 @@ gb_internal lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x,
|
||||
|
||||
if (op == Token_Xor) {
|
||||
lbValue cmp = {};
|
||||
cmp.value = LLVMBuildNot(p->builder, x.value, "");
|
||||
cmp.type = x.type;
|
||||
if (is_type_bit_set(x.type)) {
|
||||
ExactValue ev_mask = exact_bit_set_all_set_mask(x.type);
|
||||
lbValue mask = lb_const_value(p->module, x.type, ev_mask);
|
||||
cmp.value = LLVMBuildXor(p->builder, x.value, mask.value, "");
|
||||
} else {
|
||||
cmp.value = LLVMBuildNot(p->builder, x.value, "");
|
||||
}
|
||||
return lb_emit_conv(p, cmp, type);
|
||||
}
|
||||
|
||||
@@ -694,31 +705,37 @@ gb_internal lbValue lb_emit_matrix_flatten(lbProcedure *p, lbValue m, Type *type
|
||||
|
||||
lbAddr res = lb_add_local_generated(p, type, true);
|
||||
|
||||
i64 row_count = mt->Matrix.row_count;
|
||||
i64 column_count = mt->Matrix.column_count;
|
||||
TEMPORARY_ALLOCATOR_GUARD();
|
||||
GB_ASSERT(type_size_of(type) == type_size_of(m.type));
|
||||
|
||||
auto srcs = array_make<lbValue>(temporary_allocator(), 0, row_count*column_count);
|
||||
auto dsts = array_make<lbValue>(temporary_allocator(), 0, row_count*column_count);
|
||||
lbValue m_ptr = lb_address_from_load_or_generate_local(p, m);
|
||||
lbValue n = lb_const_int(p->module, t_int, type_size_of(type));
|
||||
lb_mem_copy_non_overlapping(p, res.addr, m_ptr, n);
|
||||
|
||||
for (i64 j = 0; j < column_count; j++) {
|
||||
for (i64 i = 0; i < row_count; i++) {
|
||||
lbValue src = lb_emit_matrix_ev(p, m, i, j);
|
||||
array_add(&srcs, src);
|
||||
}
|
||||
}
|
||||
// i64 row_count = mt->Matrix.row_count;
|
||||
// i64 column_count = mt->Matrix.column_count;
|
||||
// TEMPORARY_ALLOCATOR_GUARD();
|
||||
|
||||
for (i64 j = 0; j < column_count; j++) {
|
||||
for (i64 i = 0; i < row_count; i++) {
|
||||
lbValue dst = lb_emit_array_epi(p, res.addr, i + j*row_count);
|
||||
array_add(&dsts, dst);
|
||||
}
|
||||
}
|
||||
// auto srcs = array_make<lbValue>(temporary_allocator(), 0, row_count*column_count);
|
||||
// auto dsts = array_make<lbValue>(temporary_allocator(), 0, row_count*column_count);
|
||||
|
||||
GB_ASSERT(srcs.count == dsts.count);
|
||||
for_array(i, srcs) {
|
||||
lb_emit_store(p, dsts[i], srcs[i]);
|
||||
}
|
||||
// for (i64 j = 0; j < column_count; j++) {
|
||||
// for (i64 i = 0; i < row_count; i++) {
|
||||
// lbValue src = lb_emit_matrix_ev(p, m, i, j);
|
||||
// array_add(&srcs, src);
|
||||
// }
|
||||
// }
|
||||
|
||||
// for (i64 j = 0; j < column_count; j++) {
|
||||
// for (i64 i = 0; i < row_count; i++) {
|
||||
// lbValue dst = lb_emit_array_epi(p, res.addr, i + j*row_count);
|
||||
// array_add(&dsts, dst);
|
||||
// }
|
||||
// }
|
||||
|
||||
// GB_ASSERT(srcs.count == dsts.count);
|
||||
// for_array(i, srcs) {
|
||||
// lb_emit_store(p, dsts[i], srcs[i]);
|
||||
// }
|
||||
return lb_addr_load(p, res);
|
||||
}
|
||||
|
||||
@@ -2028,7 +2045,11 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
} else if (is_type_integer(src_elem) && is_type_boolean(dst_elem)) {
|
||||
LLVMValueRef i1vector = LLVMBuildICmp(p->builder, LLVMIntNE, value.value, LLVMConstNull(LLVMTypeOf(value.value)), "");
|
||||
res.value = LLVMBuildIntCast2(p->builder, i1vector, lb_type(m, t), !is_type_unsigned(src_elem), "");
|
||||
} else {
|
||||
} else if (is_type_pointer(src_elem) && is_type_integer(dst_elem)) {
|
||||
res.value = LLVMBuildPtrToInt(p->builder, value.value, lb_type(m, t), "");
|
||||
} else if (is_type_integer(src_elem) && is_type_pointer(dst_elem)) {
|
||||
res.value = LLVMBuildIntToPtr(p->builder, value.value, lb_type(m, t), "");
|
||||
}else {
|
||||
GB_PANIC("Unhandled simd vector conversion: %s -> %s", type_to_string(src), type_to_string(dst));
|
||||
}
|
||||
return res;
|
||||
@@ -2465,6 +2486,17 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) {
|
||||
return {};
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_emit_c_vararg(lbProcedure *p, lbValue arg, Type *type) {
|
||||
Type *core = core_type(type);
|
||||
if (core->kind == Type_BitSet) {
|
||||
core = core_type(bit_set_to_int(core));
|
||||
arg = lb_emit_transmute(p, arg, core);
|
||||
}
|
||||
|
||||
Type *promoted = c_vararg_promote_type(core);
|
||||
return lb_emit_conv(p, arg, promoted);
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_compare_records(lbProcedure *p, TokenKind op_kind, lbValue left, lbValue right, Type *type) {
|
||||
GB_ASSERT((is_type_struct(type) || is_type_union(type)) && is_type_comparable(type));
|
||||
lbValue left_ptr = lb_address_from_load_or_generate_local(p, left);
|
||||
@@ -3125,15 +3157,6 @@ gb_internal lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind,
|
||||
return {};
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue const &addr, lbValue const &index) {
|
||||
lbAddr v = lb_add_local_generated(p, type, false);
|
||||
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
|
||||
lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
|
||||
lb_emit_store(p, ptr, addr);
|
||||
lb_emit_store(p, idx, lb_emit_conv(p, index, t_int));
|
||||
|
||||
return lb_addr_load(p, v);
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_build_unary_and(lbProcedure *p, Ast *expr) {
|
||||
ast_node(ue, UnaryExpr, expr);
|
||||
@@ -3739,7 +3762,9 @@ gb_internal lbValue lb_get_using_variable(lbProcedure *p, Entity *e) {
|
||||
|
||||
lbValue v = {};
|
||||
|
||||
bool is_soa = false;
|
||||
if (pv == nullptr && parent->flags & EntityFlag_SoaPtrField) {
|
||||
is_soa = true;
|
||||
// NOTE(bill): using SOA value (probably from for-in statement)
|
||||
lbAddr parent_addr = lb_get_soa_variable_addr(p, parent);
|
||||
v = lb_addr_get_ptr(p, parent_addr);
|
||||
@@ -3750,7 +3775,7 @@ gb_internal lbValue lb_get_using_variable(lbProcedure *p, Entity *e) {
|
||||
v = lb_build_addr_ptr(p, e->using_expr);
|
||||
}
|
||||
GB_ASSERT(v.value != nullptr);
|
||||
GB_ASSERT_MSG(parent->type == type_deref(v.type), "%s %s", type_to_string(parent->type), type_to_string(v.type));
|
||||
GB_ASSERT_MSG(is_soa || parent->type == type_deref(v.type), "%s %s", type_to_string(parent->type), type_to_string(v.type));
|
||||
lbValue ptr = lb_emit_deep_field_gep(p, v, sel);
|
||||
if (parent->scope) {
|
||||
if ((parent->scope->flags & (ScopeFlag_File|ScopeFlag_Pkg)) == 0) {
|
||||
@@ -3814,7 +3839,7 @@ gb_internal lbAddr lb_build_array_swizzle_addr(lbProcedure *p, AstCallExpr *ce,
|
||||
Type *type = base_type(lb_addr_type(addr));
|
||||
GB_ASSERT(type->kind == Type_Array);
|
||||
i64 count = type->Array.count;
|
||||
if (count <= 4) {
|
||||
if (count <= 4 && index_count <= 4) {
|
||||
u8 indices[4] = {};
|
||||
u8 index_count = 0;
|
||||
for (i32 i = 1; i < ce->args.count; i++) {
|
||||
@@ -5101,8 +5126,9 @@ gb_internal lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
||||
a = lb_addr_get_ptr(p, addr);
|
||||
}
|
||||
|
||||
GB_ASSERT(is_type_array(expr->tav.type) || is_type_simd_vector(expr->tav.type));
|
||||
return lb_addr_swizzle(a, expr->tav.type, swizzle_count, swizzle_indices);
|
||||
Type *type = type_deref(expr->tav.type);
|
||||
GB_ASSERT(is_type_array(type) || is_type_simd_vector(type));
|
||||
return lb_addr_swizzle(a, type, swizzle_count, swizzle_indices);
|
||||
}
|
||||
|
||||
Selection sel = lookup_field(type, selector, false);
|
||||
|
||||
@@ -91,6 +91,9 @@ gb_internal void lb_init_module(lbModule *m, Checker *c) {
|
||||
map_init(&m->map_cell_info_map, 0);
|
||||
map_init(&m->exact_value_compound_literal_addr_map, 1024);
|
||||
|
||||
array_init(&m->pad_types, heap_allocator());
|
||||
|
||||
|
||||
m->const_dummy_builder = LLVMCreateBuilderInContext(m->ctx);
|
||||
|
||||
}
|
||||
@@ -534,6 +537,15 @@ gb_internal lbValue lb_relative_pointer_to_pointer(lbProcedure *p, lbAddr const
|
||||
return final_ptr;
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_make_soa_pointer(lbProcedure *p, Type *type, lbValue const &addr, lbValue const &index) {
|
||||
lbAddr v = lb_add_local_generated(p, type, false);
|
||||
lbValue ptr = lb_emit_struct_ep(p, v.addr, 0);
|
||||
lbValue idx = lb_emit_struct_ep(p, v.addr, 1);
|
||||
lb_emit_store(p, ptr, addr);
|
||||
lb_emit_store(p, idx, lb_emit_conv(p, index, t_int));
|
||||
|
||||
return lb_addr_load(p, v);
|
||||
}
|
||||
|
||||
gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
||||
if (addr.addr.value == nullptr) {
|
||||
@@ -549,8 +561,12 @@ gb_internal lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
||||
return lb_relative_pointer_to_pointer(p, addr);
|
||||
|
||||
case lbAddr_SoaVariable:
|
||||
// TODO(bill): FIX THIS HACK
|
||||
return lb_address_from_load(p, lb_addr_load(p, addr));
|
||||
{
|
||||
Type *soa_ptr_type = alloc_type_soa_pointer(lb_addr_type(addr));
|
||||
return lb_address_from_load_or_generate_local(p, lb_make_soa_pointer(p, soa_ptr_type, addr.addr, addr.soa.index));
|
||||
// TODO(bill): FIX THIS HACK
|
||||
// return lb_address_from_load(p, lb_addr_load(p, addr));
|
||||
}
|
||||
|
||||
case lbAddr_Context:
|
||||
GB_PANIC("lbAddr_Context should be handled elsewhere");
|
||||
@@ -1771,7 +1787,7 @@ gb_internal LLVMTypeRef lb_type_internal_for_procedures_raw(lbModule *m, Type *t
|
||||
}
|
||||
}
|
||||
GB_ASSERT(param_index == param_count);
|
||||
lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, return_is_tuple, type->Proc.calling_convention, type);
|
||||
lbFunctionType *ft = lb_get_abi_info(m, params, param_count, ret, ret != nullptr, return_is_tuple, type->Proc.calling_convention, type);
|
||||
{
|
||||
for_array(j, ft->args) {
|
||||
auto arg = ft->args[j];
|
||||
@@ -2098,6 +2114,12 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
llvm_type = LLVMStructCreateNamed(ctx, name);
|
||||
map_set(&m->types, type, llvm_type);
|
||||
lb_clone_struct_type(llvm_type, lb_type(m, base));
|
||||
|
||||
if (base->kind == Type_Struct) {
|
||||
map_set(&m->struct_field_remapping, cast(void *)llvm_type, lb_get_struct_remapping(m, base));
|
||||
map_set(&m->struct_field_remapping, cast(void *)type, lb_get_struct_remapping(m, base));
|
||||
}
|
||||
|
||||
return llvm_type;
|
||||
}
|
||||
}
|
||||
|
||||
+136
-15
@@ -1527,6 +1527,23 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
|
||||
return res;
|
||||
}
|
||||
|
||||
case BuiltinProc_simd_reduce_any:
|
||||
case BuiltinProc_simd_reduce_all:
|
||||
{
|
||||
char const *name = nullptr;
|
||||
switch (builtin_id) {
|
||||
case BuiltinProc_simd_reduce_any: name = "llvm.vector.reduce.or"; break;
|
||||
case BuiltinProc_simd_reduce_all: name = "llvm.vector.reduce.and"; break;
|
||||
}
|
||||
|
||||
LLVMTypeRef types[1] = { lb_type(p->module, arg0.type) };
|
||||
LLVMValueRef args[1] = { arg0.value };
|
||||
|
||||
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
case BuiltinProc_simd_shuffle:
|
||||
{
|
||||
Type *vt = arg0.type;
|
||||
@@ -1629,13 +1646,13 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
|
||||
}
|
||||
|
||||
|
||||
case BuiltinProc_simd_add_sat:
|
||||
case BuiltinProc_simd_sub_sat:
|
||||
case BuiltinProc_simd_saturating_add:
|
||||
case BuiltinProc_simd_saturating_sub:
|
||||
{
|
||||
char const *name = nullptr;
|
||||
switch (builtin_id) {
|
||||
case BuiltinProc_simd_add_sat: name = is_signed ? "llvm.sadd.sat" : "llvm.uadd.sat"; break;
|
||||
case BuiltinProc_simd_sub_sat: name = is_signed ? "llvm.ssub.sat" : "llvm.usub.sat"; break;
|
||||
case BuiltinProc_simd_saturating_add: name = is_signed ? "llvm.sadd.sat" : "llvm.uadd.sat"; break;
|
||||
case BuiltinProc_simd_saturating_sub: name = is_signed ? "llvm.ssub.sat" : "llvm.usub.sat"; break;
|
||||
}
|
||||
|
||||
LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
|
||||
@@ -1671,6 +1688,85 @@ gb_internal lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAn
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
case BuiltinProc_simd_gather:
|
||||
case BuiltinProc_simd_scatter:
|
||||
case BuiltinProc_simd_masked_load:
|
||||
case BuiltinProc_simd_masked_store:
|
||||
case BuiltinProc_simd_masked_expand_load:
|
||||
case BuiltinProc_simd_masked_compress_store:
|
||||
{
|
||||
LLVMValueRef ptr = arg0.value;
|
||||
LLVMValueRef val = arg1.value;
|
||||
LLVMValueRef mask = arg2.value;
|
||||
|
||||
unsigned count = cast(unsigned)get_array_type_count(arg1.type);
|
||||
|
||||
LLVMTypeRef mask_type = LLVMVectorType(LLVMInt1TypeInContext(p->module->ctx), count);
|
||||
mask = LLVMBuildTrunc(p->builder, mask, mask_type, "");
|
||||
|
||||
char const *name = nullptr;
|
||||
switch (builtin_id) {
|
||||
case BuiltinProc_simd_gather: name = "llvm.masked.gather"; break;
|
||||
case BuiltinProc_simd_scatter: name = "llvm.masked.scatter"; break;
|
||||
case BuiltinProc_simd_masked_load: name = "llvm.masked.load"; break;
|
||||
case BuiltinProc_simd_masked_store: name = "llvm.masked.store"; break;
|
||||
case BuiltinProc_simd_masked_expand_load: name = "llvm.masked.expandload"; break;
|
||||
case BuiltinProc_simd_masked_compress_store: name = "llvm.masked.compressstore"; break;
|
||||
}
|
||||
unsigned type_count = 2;
|
||||
LLVMTypeRef types[2] = {
|
||||
lb_type(p->module, arg1.type),
|
||||
lb_type(p->module, arg0.type)
|
||||
};
|
||||
|
||||
auto alignment = cast(unsigned long long)type_align_of(base_array_type(arg1.type));
|
||||
LLVMValueRef align = LLVMConstInt(LLVMInt32TypeInContext(p->module->ctx), alignment, false);
|
||||
|
||||
unsigned arg_count = 4;
|
||||
LLVMValueRef args[4] = {};
|
||||
switch (builtin_id) {
|
||||
case BuiltinProc_simd_masked_load:
|
||||
types[1] = lb_type(p->module, t_rawptr);
|
||||
/*fallthrough*/
|
||||
case BuiltinProc_simd_gather:
|
||||
args[0] = ptr;
|
||||
args[1] = align;
|
||||
args[2] = mask;
|
||||
args[3] = val;
|
||||
break;
|
||||
|
||||
case BuiltinProc_simd_masked_store:
|
||||
types[1] = lb_type(p->module, t_rawptr);
|
||||
/*fallthrough*/
|
||||
case BuiltinProc_simd_scatter:
|
||||
args[0] = val;
|
||||
args[1] = ptr;
|
||||
args[2] = align;
|
||||
args[3] = mask;
|
||||
break;
|
||||
|
||||
case BuiltinProc_simd_masked_expand_load:
|
||||
arg_count = 3;
|
||||
type_count = 1;
|
||||
args[0] = ptr;
|
||||
args[1] = mask;
|
||||
args[2] = val;
|
||||
break;
|
||||
|
||||
case BuiltinProc_simd_masked_compress_store:
|
||||
arg_count = 3;
|
||||
type_count = 1;
|
||||
args[0] = val;
|
||||
args[1] = ptr;
|
||||
args[2] = mask;
|
||||
break;
|
||||
}
|
||||
|
||||
res.value = lb_call_intrinsic(p, name, args, arg_count, types, type_count);
|
||||
return res;
|
||||
|
||||
}
|
||||
}
|
||||
GB_PANIC("Unhandled simd intrinsic: '%.*s'", LIT(builtin_procs[builtin_id].name));
|
||||
|
||||
@@ -2285,8 +2381,8 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
return res;
|
||||
}
|
||||
|
||||
case BuiltinProc_add_sat:
|
||||
case BuiltinProc_sub_sat:
|
||||
case BuiltinProc_saturating_add:
|
||||
case BuiltinProc_saturating_sub:
|
||||
{
|
||||
Type *main_type = tv.type;
|
||||
Type *type = main_type;
|
||||
@@ -2299,13 +2395,13 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
char const *name = nullptr;
|
||||
if (is_type_unsigned(type)) {
|
||||
switch (id) {
|
||||
case BuiltinProc_add_sat: name = "llvm.uadd.sat"; break;
|
||||
case BuiltinProc_sub_sat: name = "llvm.usub.sat"; break;
|
||||
case BuiltinProc_saturating_add: name = "llvm.uadd.sat"; break;
|
||||
case BuiltinProc_saturating_sub: name = "llvm.usub.sat"; break;
|
||||
}
|
||||
} else {
|
||||
switch (id) {
|
||||
case BuiltinProc_add_sat: name = "llvm.sadd.sat"; break;
|
||||
case BuiltinProc_sub_sat: name = "llvm.ssub.sat"; break;
|
||||
case BuiltinProc_saturating_add: name = "llvm.sadd.sat"; break;
|
||||
case BuiltinProc_saturating_sub: name = "llvm.ssub.sat"; break;
|
||||
}
|
||||
}
|
||||
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
||||
@@ -2781,6 +2877,31 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
LLVMValueRef inline_asm = nullptr;
|
||||
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_riscv64:
|
||||
{
|
||||
GB_ASSERT(arg_count <= 7);
|
||||
|
||||
char asm_string[] = "ecall";
|
||||
gbString constraints = gb_string_make(heap_allocator(), "={a0}");
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
constraints = gb_string_appendc(constraints, ",{");
|
||||
static char const *regs[] = {
|
||||
"a7",
|
||||
"a0",
|
||||
"a1",
|
||||
"a2",
|
||||
"a3",
|
||||
"a4",
|
||||
"a5",
|
||||
"a6"
|
||||
};
|
||||
constraints = gb_string_appendc(constraints, regs[i]);
|
||||
constraints = gb_string_appendc(constraints, "}");
|
||||
}
|
||||
|
||||
inline_asm = llvm_get_inline_asm(func_type, make_string_c(asm_string), make_string_c(constraints));
|
||||
}
|
||||
break;
|
||||
case TargetArch_amd64:
|
||||
{
|
||||
GB_ASSERT(arg_count <= 7);
|
||||
@@ -3473,9 +3594,9 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
|
||||
if (is_type_untyped_nil(arg.type)) {
|
||||
arg = lb_const_nil(p->module, t_rawptr);
|
||||
}
|
||||
array_add(&args, lb_emit_conv(p, arg, c_vararg_promote_type(default_type(arg.type))));
|
||||
array_add(&args, lb_emit_c_vararg(p, arg, arg.type));
|
||||
} else {
|
||||
array_add(&args, lb_emit_conv(p, arg, c_vararg_promote_type(elem_type)));
|
||||
array_add(&args, lb_emit_c_vararg(p, arg, elem_type));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3601,15 +3722,15 @@ gb_internal lbValue lb_build_call_expr_internal(lbProcedure *p, Ast *expr) {
|
||||
if (is_type_untyped_nil(arg.type)) {
|
||||
arg = lb_const_nil(p->module, t_rawptr);
|
||||
}
|
||||
array_add(&args, lb_emit_conv(p, arg, c_vararg_promote_type(default_type(arg.type))));
|
||||
array_add(&args, lb_emit_c_vararg(p, arg, arg.type));
|
||||
} else {
|
||||
array_add(&args, lb_emit_conv(p, arg, c_vararg_promote_type(elem_type)));
|
||||
array_add(&args, lb_emit_c_vararg(p, arg, elem_type));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lbValue value = lb_build_expr(p, fv->value);
|
||||
GB_ASSERT(!is_type_tuple(value.type));
|
||||
array_add(&args, lb_emit_conv(p, value, c_vararg_promote_type(value.type)));
|
||||
array_add(&args, lb_emit_c_vararg(p, value, value.type));
|
||||
}
|
||||
} else {
|
||||
lbValue value = lb_build_expr(p, fv->value);
|
||||
|
||||
@@ -1404,6 +1404,10 @@ gb_internal bool lb_switch_stmt_can_be_trivial_jump_table(AstSwitchStmt *ss, boo
|
||||
|
||||
}
|
||||
|
||||
if (is_typeid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1574,9 +1578,14 @@ gb_internal void lb_store_type_case_implicit(lbProcedure *p, Ast *clause, lbValu
|
||||
GB_ASSERT(e != nullptr);
|
||||
if (e->flags & EntityFlag_Value) {
|
||||
// by value
|
||||
GB_ASSERT(are_types_identical(e->type, value.type));
|
||||
lbAddr x = lb_add_local(p, e->type, e, false);
|
||||
lb_addr_store(p, x, value);
|
||||
if (are_types_identical(e->type, value.type)) {
|
||||
lbAddr x = lb_add_local(p, e->type, e, false);
|
||||
lb_addr_store(p, x, value);
|
||||
} else {
|
||||
GB_ASSERT_MSG(are_types_identical(e->type, type_deref(value.type)), "%s", type_to_string(value.type));
|
||||
lbAddr x = lb_add_local(p, e->type, e, false);
|
||||
lb_addr_store(p, x, lb_emit_load(p, value));
|
||||
}
|
||||
} else {
|
||||
if (!is_default_case) {
|
||||
Type *clause_type = e->type;
|
||||
@@ -1646,7 +1655,7 @@ gb_internal void lb_build_type_switch_stmt(lbProcedure *p, AstTypeSwitchStmt *ss
|
||||
union_data = lb_emit_conv(p, parent_ptr, t_rawptr);
|
||||
Type *union_type = type_deref(parent_ptr.type);
|
||||
if (is_type_union_maybe_pointer(union_type)) {
|
||||
tag = lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_NotEq, union_data), t_int);
|
||||
tag = lb_emit_conv(p, lb_emit_comp_against_nil(p, Token_NotEq, parent_value), t_int);
|
||||
} else if (union_tag_size(union_type) == 0) {
|
||||
tag = {}; // there is no tag for a zero sized union
|
||||
} else {
|
||||
@@ -2190,8 +2199,7 @@ gb_internal void lb_build_if_stmt(lbProcedure *p, Ast *node) {
|
||||
// and `LLVMConstIntGetZExtValue()` calls below will be valid and `LLVMInstructionEraseFromParent()`
|
||||
// will target the correct (& only) branch statement
|
||||
|
||||
|
||||
if (cond.value && LLVMIsConstant(cond.value)) {
|
||||
if (cond.value && LLVMIsAConstantInt(cond.value)) {
|
||||
// NOTE(bill): Do a compile time short circuit for when the condition is constantly known.
|
||||
// This done manually rather than relying on the SSA passes because sometimes the SSA passes
|
||||
// miss some even if they are constantly known, especially with few optimization passes.
|
||||
|
||||
@@ -263,7 +263,7 @@ gb_internal lbValue lb_emit_transmute(lbProcedure *p, lbValue value, Type *t) {
|
||||
if (is_type_simd_vector(src) && is_type_simd_vector(dst)) {
|
||||
res.value = LLVMBuildBitCast(p->builder, value.value, lb_type(p->module, t), "");
|
||||
return res;
|
||||
} else if (is_type_array_like(src) && is_type_simd_vector(dst)) {
|
||||
} else if (is_type_array_like(src) && (is_type_simd_vector(dst) || is_type_integer_128bit(dst))) {
|
||||
unsigned align = cast(unsigned)gb_max(type_align_of(src), type_align_of(dst));
|
||||
lbValue ptr = lb_address_from_load_or_generate_local(p, value);
|
||||
if (lb_try_update_alignment(ptr, align)) {
|
||||
@@ -1003,6 +1003,21 @@ gb_internal i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) {
|
||||
}
|
||||
|
||||
gb_internal LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align) {
|
||||
MUTEX_GUARD(&m->pad_types_mutex);
|
||||
if (padding % padding_align == 0) {
|
||||
for (auto pd : m->pad_types) {
|
||||
if (pd.padding == padding && pd.padding_align == padding_align) {
|
||||
return pd.type;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto pd : m->pad_types) {
|
||||
if (pd.padding == padding && pd.padding_align == 1) {
|
||||
return pd.type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(bill): limit to `[N x u64]` to prevent ABI issues
|
||||
padding_align = gb_clamp(padding_align, 1, 8);
|
||||
if (padding % padding_align == 0) {
|
||||
@@ -1016,13 +1031,19 @@ gb_internal LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 pad
|
||||
}
|
||||
|
||||
GB_ASSERT_MSG(elem != nullptr, "Invalid lb_type_padding_filler padding and padding_align: %lld", padding_align);
|
||||
|
||||
LLVMTypeRef type = nullptr;
|
||||
if (len != 1) {
|
||||
return llvm_array_type(elem, len);
|
||||
type = llvm_array_type(elem, len);
|
||||
} else {
|
||||
return elem;
|
||||
type = elem;
|
||||
}
|
||||
array_add(&m->pad_types, lbPadType{padding, padding_align, type});
|
||||
return type;
|
||||
} else {
|
||||
return llvm_array_type(lb_type(m, t_u8), padding);
|
||||
LLVMTypeRef type = llvm_array_type(lb_type(m, t_u8), padding);
|
||||
array_add(&m->pad_types, lbPadType{padding, 1, type});
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+29
-2
@@ -389,6 +389,7 @@ enum BuildFlagKind {
|
||||
BuildFlag_PrintLinkerFlags,
|
||||
|
||||
// internal use only
|
||||
BuildFlag_InternalFastISel,
|
||||
BuildFlag_InternalIgnoreLazy,
|
||||
BuildFlag_InternalIgnoreLLVMBuild,
|
||||
BuildFlag_InternalIgnorePanic,
|
||||
@@ -594,6 +595,7 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
|
||||
add_flag(&build_flags, BuildFlag_PrintLinkerFlags, str_lit("print-linker-flags"), BuildFlagParam_None, Command_build);
|
||||
|
||||
add_flag(&build_flags, BuildFlag_InternalFastISel, str_lit("internal-fast-isel"), BuildFlagParam_None, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_InternalIgnoreLLVMBuild, str_lit("internal-ignore-llvm-build"),BuildFlagParam_None, Command_all);
|
||||
add_flag(&build_flags, BuildFlag_InternalIgnorePanic, str_lit("internal-ignore-panic"), BuildFlagParam_None, Command_all);
|
||||
@@ -1408,6 +1410,9 @@ gb_internal bool parse_build_flags(Array<String> args) {
|
||||
build_context.print_linker_flags = true;
|
||||
break;
|
||||
|
||||
case BuildFlag_InternalFastISel:
|
||||
build_context.fast_isel = true;
|
||||
break;
|
||||
case BuildFlag_InternalIgnoreLazy:
|
||||
build_context.ignore_lazy = true;
|
||||
break;
|
||||
@@ -2268,6 +2273,7 @@ gb_internal void print_show_help(String const arg0, String const &command) {
|
||||
print_usage_line(2, "Sets the build mode.");
|
||||
print_usage_line(2, "Available options:");
|
||||
print_usage_line(3, "-build-mode:exe Builds as an executable.");
|
||||
print_usage_line(3, "-build-mode:test Builds as an executable that executes tests.");
|
||||
print_usage_line(3, "-build-mode:dll Builds as a dynamically linked library.");
|
||||
print_usage_line(3, "-build-mode:shared Builds as a dynamically linked library.");
|
||||
print_usage_line(3, "-build-mode:lib Builds as a statically linked library.");
|
||||
@@ -2973,13 +2979,19 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(run_args_start_idx != -1) {
|
||||
if (run_args_start_idx != -1) {
|
||||
last_non_run_arg = run_args_start_idx;
|
||||
|
||||
if (run_args_start_idx == 2) {
|
||||
// missing src path on argv[2], invocation: odin [run|test] --
|
||||
usage(args[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(isize i = run_args_start_idx+1; i < args.count; ++i) {
|
||||
array_add(&run_args, args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
args = array_slice(args, 0, last_non_run_arg);
|
||||
run_args_string = string_join_and_quote(heap_allocator(), run_args);
|
||||
|
||||
@@ -3239,6 +3251,21 @@ int main(int arg_count, char const **arg_ptr) {
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(laytan): on riscv64 we want to enforce some features.
|
||||
if (build_context.metrics.arch == TargetArch_riscv64) {
|
||||
String disabled;
|
||||
if (!check_target_feature_is_enabled(str_lit("64bit,f,d,m"), &disabled)) { // 64bit, floats, doubles, integer multiplication.
|
||||
gb_printf_err("missing required target feature: \"%.*s\", enable it by setting a different -microarch or explicitly adding it through -target-features\n", LIT(disabled));
|
||||
gb_exit(1);
|
||||
}
|
||||
|
||||
// NOTE(laytan): some weird errors on LLVM 14 that LLVM 17 fixes.
|
||||
if (LLVM_VERSION_MAJOR < 17) {
|
||||
gb_printf_err("Invalid LLVM version %s, RISC-V targets require at least LLVM 17\n", LLVM_VERSION_STRING);
|
||||
gb_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (build_context.show_debug_messages) {
|
||||
debugf("Selected microarch: %.*s\n", LIT(march));
|
||||
debugf("Default microarch features: %.*s\n", LIT(default_features));
|
||||
|
||||
@@ -684,8 +684,14 @@ gb_internal void find_visual_studio_paths_from_env_vars(Find_Result *result) {
|
||||
? str_lit("lib\\x64\\")
|
||||
: str_lit("lib\\x86\\");
|
||||
|
||||
result->vs_exe_path = mc_concat(vctid, exe);
|
||||
result->vs_library_path = mc_concat(vctid, lib);
|
||||
if (string_ends_with(vctid, str_lit("\\"))) {
|
||||
result->vs_exe_path = mc_concat(vctid, exe);
|
||||
result->vs_library_path = mc_concat(vctid, lib);
|
||||
} else {
|
||||
result->vs_exe_path = mc_concat(vctid, str_lit("\\"), exe);
|
||||
result->vs_library_path = mc_concat(vctid, str_lit("\\"), lib);
|
||||
}
|
||||
|
||||
vs_found = true;
|
||||
}
|
||||
|
||||
|
||||
+45
-10
@@ -1921,6 +1921,9 @@ gb_internal Array<Ast *> parse_enum_field_list(AstFile *f) {
|
||||
f->curr_token.kind != Token_EOF) {
|
||||
CommentGroup *docs = f->lead_comment;
|
||||
CommentGroup *comment = nullptr;
|
||||
|
||||
parse_enforce_tabs(f);
|
||||
|
||||
Ast *name = parse_value(f);
|
||||
Ast *value = nullptr;
|
||||
if (f->curr_token.kind == Token_Eq) {
|
||||
@@ -2259,6 +2262,7 @@ gb_internal Array<Ast *> parse_union_variant_list(AstFile *f) {
|
||||
auto variants = array_make<Ast *>(ast_allocator(f));
|
||||
while (f->curr_token.kind != Token_CloseBrace &&
|
||||
f->curr_token.kind != Token_EOF) {
|
||||
parse_enforce_tabs(f);
|
||||
Ast *type = parse_type(f);
|
||||
if (type->kind != Ast_BadExpr) {
|
||||
array_add(&variants, type);
|
||||
@@ -3560,7 +3564,12 @@ gb_internal Ast *parse_type(AstFile *f) {
|
||||
} else {
|
||||
token = advance_token(f);
|
||||
}
|
||||
syntax_error(token, "Expected a type, got '%.*s'", LIT(prev_token.string));
|
||||
String prev_token_str = prev_token.string;
|
||||
if (prev_token_str == str_lit("\n")) {
|
||||
syntax_error(token, "Expected a type, got newline");
|
||||
} else {
|
||||
syntax_error(token, "Expected a type, got '%.*s'", LIT(prev_token_str));
|
||||
}
|
||||
return ast_bad_expr(f, token, f->curr_token);
|
||||
} else if (type->kind == Ast_ParenExpr &&
|
||||
unparen_expr(type) == nullptr) {
|
||||
@@ -4269,6 +4278,7 @@ gb_internal Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_fl
|
||||
while (f->curr_token.kind != follow &&
|
||||
f->curr_token.kind != Token_Colon &&
|
||||
f->curr_token.kind != Token_EOF) {
|
||||
if (!is_signature) parse_enforce_tabs(f);
|
||||
u32 flags = parse_field_prefixes(f);
|
||||
Ast *param = parse_var_type(f, allow_ellipsis, allow_typeid_token);
|
||||
if (param->kind == Ast_Ellipsis) {
|
||||
@@ -4358,6 +4368,8 @@ gb_internal Ast *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_fl
|
||||
f->curr_token.kind != Token_EOF &&
|
||||
f->curr_token.kind != Token_Semicolon) {
|
||||
CommentGroup *docs = f->lead_comment;
|
||||
|
||||
if (!is_signature) parse_enforce_tabs(f);
|
||||
u32 set_flags = parse_field_prefixes(f);
|
||||
Token tag = {};
|
||||
Array<Ast *> names = parse_ident_list(f, allow_poly_names);
|
||||
@@ -4527,6 +4539,10 @@ gb_internal Ast *parse_if_stmt(AstFile *f) {
|
||||
return ast_bad_stmt(f, f->curr_token, f->curr_token);
|
||||
}
|
||||
|
||||
Ast *top_if_stmt = nullptr;
|
||||
|
||||
Ast *prev_if_stmt = nullptr;
|
||||
if_else_chain:;
|
||||
Token token = expect_token(f, Token_if);
|
||||
Ast *init = nullptr;
|
||||
Ast *cond = nullptr;
|
||||
@@ -4568,12 +4584,24 @@ gb_internal Ast *parse_if_stmt(AstFile *f) {
|
||||
ignore_strict_style = true;
|
||||
}
|
||||
skip_possible_newline_for_literal(f, ignore_strict_style);
|
||||
|
||||
Ast *curr_if_stmt = ast_if_stmt(f, token, init, cond, body, nullptr);
|
||||
if (top_if_stmt == nullptr) {
|
||||
top_if_stmt = curr_if_stmt;
|
||||
}
|
||||
if (prev_if_stmt != nullptr) {
|
||||
prev_if_stmt->IfStmt.else_stmt = curr_if_stmt;
|
||||
}
|
||||
|
||||
if (f->curr_token.kind == Token_else) {
|
||||
Token else_token = expect_token(f, Token_else);
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_if:
|
||||
else_stmt = parse_if_stmt(f);
|
||||
break;
|
||||
// NOTE(bill): Instead of relying on recursive descent for an if-else chain
|
||||
// we can just inline the tail-recursion manually with a simple loop like
|
||||
// construct using a `goto`
|
||||
prev_if_stmt = curr_if_stmt;
|
||||
goto if_else_chain;
|
||||
case Token_OpenBrace:
|
||||
else_stmt = parse_block_stmt(f, false);
|
||||
break;
|
||||
@@ -4588,7 +4616,9 @@ gb_internal Ast *parse_if_stmt(AstFile *f) {
|
||||
}
|
||||
}
|
||||
|
||||
return ast_if_stmt(f, token, init, cond, body, else_stmt);
|
||||
curr_if_stmt->IfStmt.else_stmt = else_stmt;
|
||||
|
||||
return top_if_stmt;
|
||||
}
|
||||
|
||||
gb_internal Ast *parse_when_stmt(AstFile *f) {
|
||||
@@ -5352,6 +5382,11 @@ gb_internal u64 check_vet_flags(AstFile *file) {
|
||||
|
||||
|
||||
gb_internal void parse_enforce_tabs(AstFile *f) {
|
||||
// Checks to see if tabs have been used for indentation
|
||||
if ((check_vet_flags(f) & VetFlag_Tabs) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Token prev = f->prev_token;
|
||||
Token curr = f->curr_token;
|
||||
if (prev.pos.line < curr.pos.line) {
|
||||
@@ -5368,6 +5403,10 @@ gb_internal void parse_enforce_tabs(AstFile *f) {
|
||||
|
||||
isize len = end-it;
|
||||
for (isize i = 0; i < len; i++) {
|
||||
if (it[i] == '/') {
|
||||
// ignore comments
|
||||
break;
|
||||
}
|
||||
if (it[i] == ' ') {
|
||||
syntax_error(curr, "With '-vet-tabs', tabs must be used for indentation");
|
||||
break;
|
||||
@@ -5382,11 +5421,7 @@ gb_internal Array<Ast *> parse_stmt_list(AstFile *f) {
|
||||
while (f->curr_token.kind != Token_case &&
|
||||
f->curr_token.kind != Token_CloseBrace &&
|
||||
f->curr_token.kind != Token_EOF) {
|
||||
|
||||
// Checks to see if tabs have been used for indentation
|
||||
if (check_vet_flags(f) & VetFlag_Tabs) {
|
||||
parse_enforce_tabs(f);
|
||||
}
|
||||
parse_enforce_tabs(f);
|
||||
|
||||
Ast *stmt = parse_stmt(f);
|
||||
if (stmt && stmt->kind != Ast_EmptyStmt) {
|
||||
@@ -6448,7 +6483,7 @@ gb_internal bool parse_file(Parser *p, AstFile *f) {
|
||||
}
|
||||
|
||||
f->total_file_decl_count += calc_decl_count(stmt);
|
||||
if (stmt->kind == Ast_WhenStmt || stmt->kind == Ast_ExprStmt || stmt->kind == Ast_ImportDecl) {
|
||||
if (stmt->kind == Ast_WhenStmt || stmt->kind == Ast_ExprStmt || stmt->kind == Ast_ImportDecl || stmt->kind == Ast_ForeignBlockDecl) {
|
||||
f->delayed_decl_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -82,6 +82,7 @@ enum AstFileFlag : u32 {
|
||||
enum AstDelayQueueKind {
|
||||
AstDelayQueue_Import,
|
||||
AstDelayQueue_Expr,
|
||||
AstDelayQueue_ForeignBlock,
|
||||
AstDelayQueue_COUNT,
|
||||
};
|
||||
|
||||
@@ -885,4 +886,7 @@ gb_internal gb_inline gbAllocator ast_allocator(AstFile *f) {
|
||||
gb_internal Ast *alloc_ast_node(AstFile *f, AstKind kind);
|
||||
|
||||
gb_internal gbString expr_to_string(Ast *expression);
|
||||
gb_internal bool allow_field_separator(AstFile *f);
|
||||
gb_internal bool allow_field_separator(AstFile *f);
|
||||
|
||||
|
||||
gb_internal void parse_enforce_tabs(AstFile *f);
|
||||
+30
-3
@@ -529,6 +529,9 @@ gb_internal gb_inline void yield_thread(void) {
|
||||
_mm_pause();
|
||||
#elif defined(GB_CPU_ARM)
|
||||
__asm__ volatile ("yield" : : : "memory");
|
||||
#elif defined(GB_CPU_RISCV)
|
||||
// I guess?
|
||||
__asm__ volatile ("nop" : : : "memory");
|
||||
#else
|
||||
#error Unknown architecture
|
||||
#endif
|
||||
@@ -839,8 +842,16 @@ gb_internal void futex_signal(Futex *f) {
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
// UL_COMPARE_AND_WAIT_SHARED is only available on macOS 10.15+
|
||||
int WAIT_FLAG;
|
||||
if (__builtin_available(macOS 10.15, *)) {
|
||||
WAIT_FLAG = UL_COMPARE_AND_WAIT_SHARED;
|
||||
} else {
|
||||
WAIT_FLAG = UL_COMPARE_AND_WAIT;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int ret = __ulock_wake(UL_COMPARE_AND_WAIT_SHARED | ULF_NO_ERRNO, f, 0);
|
||||
int ret = __ulock_wake(WAIT_FLAG | ULF_NO_ERRNO, f, 0);
|
||||
if (ret >= 0) {
|
||||
return;
|
||||
}
|
||||
@@ -875,9 +886,17 @@ gb_internal void futex_broadcast(Futex *f) {
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
// UL_COMPARE_AND_WAIT_SHARED is only available on macOS 10.15+
|
||||
int WAIT_FLAG;
|
||||
if (__builtin_available(macOS 10.15, *)) {
|
||||
WAIT_FLAG = UL_COMPARE_AND_WAIT_SHARED;
|
||||
} else {
|
||||
WAIT_FLAG = UL_COMPARE_AND_WAIT;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
enum { ULF_WAKE_ALL = 0x00000100 };
|
||||
int ret = __ulock_wake(UL_COMPARE_AND_WAIT_SHARED | ULF_NO_ERRNO | ULF_WAKE_ALL, f, 0);
|
||||
int ret = __ulock_wake(WAIT_FLAG | ULF_NO_ERRNO | ULF_WAKE_ALL, f, 0);
|
||||
if (ret == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -915,8 +934,16 @@ gb_internal void futex_wait(Futex *f, Footex val) {
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
// UL_COMPARE_AND_WAIT_SHARED is only available on macOS 10.15+
|
||||
int WAIT_FLAG;
|
||||
if (__builtin_available(macOS 10.15, *)) {
|
||||
WAIT_FLAG = UL_COMPARE_AND_WAIT_SHARED;
|
||||
} else {
|
||||
WAIT_FLAG = UL_COMPARE_AND_WAIT;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
int ret = __ulock_wait(UL_COMPARE_AND_WAIT_SHARED | ULF_NO_ERRNO, f, val, 0);
|
||||
int ret = __ulock_wait(WAIT_FLAG | ULF_NO_ERRNO, f, val, 0);
|
||||
if (ret >= 0) {
|
||||
if (*f != val) {
|
||||
return;
|
||||
|
||||
+32
-12
@@ -1474,6 +1474,7 @@ gb_internal i64 matrix_align_of(Type *t, struct TypePath *tp) {
|
||||
|
||||
Type *elem = t->Matrix.elem;
|
||||
i64 row_count = gb_max(t->Matrix.row_count, 1);
|
||||
i64 column_count = gb_max(t->Matrix.column_count, 1);
|
||||
|
||||
bool pop = type_path_push(tp, elem);
|
||||
if (tp->failure) {
|
||||
@@ -1491,7 +1492,7 @@ gb_internal i64 matrix_align_of(Type *t, struct TypePath *tp) {
|
||||
// could be maximally aligned but as a compromise, having no padding will be
|
||||
// beneficial to third libraries that assume no padding
|
||||
|
||||
i64 total_expected_size = row_count*t->Matrix.column_count*elem_size;
|
||||
i64 total_expected_size = row_count*column_count*elem_size;
|
||||
// i64 min_alignment = prev_pow2(elem_align * row_count);
|
||||
i64 min_alignment = prev_pow2(total_expected_size);
|
||||
while (total_expected_size != 0 && (total_expected_size % min_alignment) != 0) {
|
||||
@@ -1523,12 +1524,15 @@ gb_internal i64 matrix_type_stride_in_bytes(Type *t, struct TypePath *tp) {
|
||||
i64 stride_in_bytes = 0;
|
||||
|
||||
// NOTE(bill, 2021-10-25): The alignment strategy here is to have zero padding
|
||||
// It would be better for performance to pad each column so that each column
|
||||
// It would be better for performance to pad each column/row so that each column/row
|
||||
// could be maximally aligned but as a compromise, having no padding will be
|
||||
// beneficial to third libraries that assume no padding
|
||||
i64 row_count = t->Matrix.row_count;
|
||||
stride_in_bytes = elem_size*row_count;
|
||||
|
||||
|
||||
if (t->Matrix.is_row_major) {
|
||||
stride_in_bytes = elem_size*t->Matrix.column_count;
|
||||
} else {
|
||||
stride_in_bytes = elem_size*t->Matrix.row_count;
|
||||
}
|
||||
t->Matrix.stride_in_bytes = stride_in_bytes;
|
||||
return stride_in_bytes;
|
||||
}
|
||||
@@ -2091,6 +2095,9 @@ gb_internal bool is_type_valid_vector_elem(Type *t) {
|
||||
if (is_type_boolean(t)) {
|
||||
return true;
|
||||
}
|
||||
if (t->Basic.kind == Basic_rawptr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2807,8 +2814,14 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple
|
||||
|
||||
case Type_Union:
|
||||
if (x->Union.variants.count == y->Union.variants.count &&
|
||||
x->Union.custom_align == y->Union.custom_align &&
|
||||
x->Union.kind == y->Union.kind) {
|
||||
|
||||
if (x->Union.custom_align != y->Union.custom_align) {
|
||||
if (type_align_of(x) != type_align_of(y)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(bill): zeroth variant is nullptr
|
||||
for_array(i, x->Union.variants) {
|
||||
if (!are_types_identical(x->Union.variants[i], y->Union.variants[i])) {
|
||||
@@ -2824,10 +2837,16 @@ gb_internal bool are_types_identical_internal(Type *x, Type *y, bool check_tuple
|
||||
x->Struct.is_no_copy == y->Struct.is_no_copy &&
|
||||
x->Struct.fields.count == y->Struct.fields.count &&
|
||||
x->Struct.is_packed == y->Struct.is_packed &&
|
||||
x->Struct.custom_align == y->Struct.custom_align &&
|
||||
x->Struct.soa_kind == y->Struct.soa_kind &&
|
||||
x->Struct.soa_count == y->Struct.soa_count &&
|
||||
are_types_identical(x->Struct.soa_elem, y->Struct.soa_elem)) {
|
||||
|
||||
if (x->Struct.custom_align != y->Struct.custom_align) {
|
||||
if (type_align_of(x) != type_align_of(y)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for_array(i, x->Struct.fields) {
|
||||
Entity *xf = x->Struct.fields[i];
|
||||
Entity *yf = y->Struct.fields[i];
|
||||
@@ -2957,10 +2976,7 @@ gb_internal Type *c_vararg_promote_type(Type *type) {
|
||||
GB_ASSERT(type != nullptr);
|
||||
|
||||
Type *core = core_type(type);
|
||||
|
||||
if (core->kind == Type_BitSet) {
|
||||
core = core_type(bit_set_to_int(core));
|
||||
}
|
||||
GB_ASSERT(core->kind != Type_BitSet);
|
||||
|
||||
if (core->kind == Type_Basic) {
|
||||
switch (core->Basic.kind) {
|
||||
@@ -4205,7 +4221,11 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
|
||||
|
||||
case Type_Matrix: {
|
||||
i64 stride_in_bytes = matrix_type_stride_in_bytes(t, path);
|
||||
return stride_in_bytes * t->Matrix.column_count;
|
||||
if (t->Matrix.is_row_major) {
|
||||
return stride_in_bytes * t->Matrix.row_count;
|
||||
} else {
|
||||
return stride_in_bytes * t->Matrix.column_count;
|
||||
}
|
||||
}
|
||||
|
||||
case Type_BitField:
|
||||
|
||||
Reference in New Issue
Block a user