mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-25 23:14:59 -07:00
Merge pull request #2470 from odin-lang/separate-int-word-sizes
Separate int size from word/pointer size
This commit is contained in:
+1
-1
@@ -56,7 +56,7 @@ Allocator :: struct {
|
||||
DEFAULT_ALIGNMENT :: 2*align_of(rawptr)
|
||||
|
||||
DEFAULT_PAGE_SIZE ::
|
||||
64 * 1024 when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64 else
|
||||
64 * 1024 when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 else
|
||||
16 * 1024 when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 else
|
||||
4 * 1024
|
||||
|
||||
|
||||
@@ -425,7 +425,7 @@ Raw_Map :: struct {
|
||||
// Map_Hash directly, though for consistency sake it's written as if it were
|
||||
// an array of Map_Cell(Map_Hash).
|
||||
data: uintptr, // 8-bytes on 64-bits, 4-bytes on 32-bits
|
||||
len: int, // 8-bytes on 64-bits, 4-bytes on 32-bits
|
||||
len: uintptr, // 8-bytes on 64-bits, 4-bytes on 32-bits
|
||||
allocator: Allocator, // 16-bytes on 64-bits, 8-bytes on 32-bits
|
||||
}
|
||||
|
||||
@@ -471,7 +471,7 @@ Odin_OS_Type :: type_of(ODIN_OS)
|
||||
arm32,
|
||||
arm64,
|
||||
wasm32,
|
||||
wasm64,
|
||||
wasm64p32,
|
||||
}
|
||||
*/
|
||||
Odin_Arch_Type :: type_of(ODIN_ARCH)
|
||||
|
||||
@@ -184,7 +184,7 @@ map_cell_index_static :: #force_inline proc "contextless" (cells: [^]Map_Cell($T
|
||||
// len() for map
|
||||
@(require_results)
|
||||
map_len :: #force_inline proc "contextless" (m: Raw_Map) -> int {
|
||||
return m.len
|
||||
return int(m.len)
|
||||
}
|
||||
|
||||
// cap() for map
|
||||
@@ -207,8 +207,8 @@ map_load_factor :: #force_inline proc "contextless" (log2_capacity: uintptr) ->
|
||||
}
|
||||
|
||||
@(require_results)
|
||||
map_resize_threshold :: #force_inline proc "contextless" (m: Raw_Map) -> int {
|
||||
return int(map_load_factor(map_log2_cap(m)))
|
||||
map_resize_threshold :: #force_inline proc "contextless" (m: Raw_Map) -> uintptr {
|
||||
return map_load_factor(map_log2_cap(m))
|
||||
}
|
||||
|
||||
// The data stores the log2 capacity in the lower six bits. This is primarily
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//+private
|
||||
//+build wasm32, wasm64
|
||||
//+build wasm32, wasm64p32
|
||||
package runtime
|
||||
|
||||
import "core:intrinsics"
|
||||
|
||||
@@ -3,7 +3,7 @@ package runtime
|
||||
import "core:intrinsics"
|
||||
|
||||
@(private="file")
|
||||
IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64
|
||||
IS_WASM :: ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32
|
||||
|
||||
@(private)
|
||||
RUNTIME_LINKAGE :: "strong" when (
|
||||
|
||||
@@ -25,7 +25,7 @@ when ODIN_NO_CRT && ODIN_OS == .Windows {
|
||||
RtlMoveMemory(dst, src, len)
|
||||
return dst
|
||||
}
|
||||
} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64) {
|
||||
} else when ODIN_NO_CRT || (ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32) {
|
||||
@(link_name="memset", linkage="strong", require)
|
||||
memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {
|
||||
if ptr != nil && len != 0 {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build js wasm32
|
||||
//+build js
|
||||
package runtime
|
||||
|
||||
init_default_context_for_js: Context
|
||||
@@ -1,4 +1,4 @@
|
||||
//+build wasm32
|
||||
//+build wasm32, wasm64p32
|
||||
package runtime
|
||||
|
||||
@(private="file")
|
||||
@@ -1,5 +1,5 @@
|
||||
//+private
|
||||
//+build wasm32, wasm64
|
||||
//+build wasm32, wasm64p32
|
||||
package sync
|
||||
|
||||
import "core:intrinsics"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//+private
|
||||
//+build wasm32, wasm64
|
||||
//+build wasm32, wasm64p32
|
||||
package sync
|
||||
|
||||
_current_thread_id :: proc "contextless" () -> int {
|
||||
|
||||
+75
-40
@@ -35,14 +35,12 @@ enum TargetArchKind : u16 {
|
||||
TargetArch_arm32,
|
||||
TargetArch_arm64,
|
||||
TargetArch_wasm32,
|
||||
TargetArch_wasm64,
|
||||
TargetArch_wasm64p32,
|
||||
|
||||
TargetArch_COUNT,
|
||||
};
|
||||
|
||||
enum TargetEndianKind : u8 {
|
||||
TargetEndian_Invalid,
|
||||
|
||||
TargetEndian_Little,
|
||||
TargetEndian_Big,
|
||||
|
||||
@@ -81,11 +79,10 @@ gb_global String target_arch_names[TargetArch_COUNT] = {
|
||||
str_lit("arm32"),
|
||||
str_lit("arm64"),
|
||||
str_lit("wasm32"),
|
||||
str_lit("wasm64"),
|
||||
str_lit("wasm64p32"),
|
||||
};
|
||||
|
||||
gb_global String target_endian_names[TargetEndian_COUNT] = {
|
||||
str_lit(""),
|
||||
str_lit("little"),
|
||||
str_lit("big"),
|
||||
};
|
||||
@@ -97,7 +94,8 @@ gb_global String target_abi_names[TargetABI_COUNT] = {
|
||||
};
|
||||
|
||||
gb_global TargetEndianKind target_endians[TargetArch_COUNT] = {
|
||||
TargetEndian_Invalid,
|
||||
TargetEndian_Little,
|
||||
TargetEndian_Little,
|
||||
TargetEndian_Little,
|
||||
TargetEndian_Little,
|
||||
TargetEndian_Little,
|
||||
@@ -116,7 +114,8 @@ gb_global String const ODIN_VERSION = str_lit(ODIN_VERSION_RAW);
|
||||
struct TargetMetrics {
|
||||
TargetOsKind os;
|
||||
TargetArchKind arch;
|
||||
isize word_size;
|
||||
isize ptr_size;
|
||||
isize int_size;
|
||||
isize max_align;
|
||||
isize max_simd_align;
|
||||
String target_triplet;
|
||||
@@ -237,9 +236,10 @@ struct BuildContext {
|
||||
TargetEndianKind endian_kind;
|
||||
|
||||
// In bytes
|
||||
i64 word_size; // Size of a pointer, must be >= 4
|
||||
i64 max_align; // max alignment, must be >= 1 (and typically >= word_size)
|
||||
i64 max_simd_align; // max alignment, must be >= 1 (and typically >= word_size)
|
||||
i64 ptr_size; // Size of a pointer, must be >= 4
|
||||
i64 int_size; // Size of a int/uint, must be >= 4
|
||||
i64 max_align; // max alignment, must be >= 1 (and typically >= ptr_size)
|
||||
i64 max_simd_align; // max alignment, must be >= 1 (and typically >= ptr_size)
|
||||
|
||||
CommandKind command_kind;
|
||||
String command;
|
||||
@@ -361,13 +361,13 @@ gb_internal isize MAX_ERROR_COLLECTOR_COUNT(void) {
|
||||
gb_global TargetMetrics target_windows_i386 = {
|
||||
TargetOs_windows,
|
||||
TargetArch_i386,
|
||||
4, 4, 8,
|
||||
4, 4, 4, 8,
|
||||
str_lit("i386-pc-windows-msvc"),
|
||||
};
|
||||
gb_global TargetMetrics target_windows_amd64 = {
|
||||
TargetOs_windows,
|
||||
TargetArch_amd64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("x86_64-pc-windows-msvc"),
|
||||
str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"),
|
||||
};
|
||||
@@ -375,21 +375,21 @@ gb_global TargetMetrics target_windows_amd64 = {
|
||||
gb_global TargetMetrics target_linux_i386 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_i386,
|
||||
4, 4, 8,
|
||||
4, 4, 4, 8,
|
||||
str_lit("i386-pc-linux-gnu"),
|
||||
|
||||
};
|
||||
gb_global TargetMetrics target_linux_amd64 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_amd64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("x86_64-pc-linux-gnu"),
|
||||
str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"),
|
||||
};
|
||||
gb_global TargetMetrics target_linux_arm64 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("aarch64-linux-elf"),
|
||||
str_lit("e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"),
|
||||
};
|
||||
@@ -397,7 +397,7 @@ gb_global TargetMetrics target_linux_arm64 = {
|
||||
gb_global TargetMetrics target_linux_arm32 = {
|
||||
TargetOs_linux,
|
||||
TargetArch_arm32,
|
||||
4, 4, 8,
|
||||
4, 4, 4, 8,
|
||||
str_lit("arm-linux-gnu"),
|
||||
str_lit("e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"),
|
||||
};
|
||||
@@ -405,7 +405,7 @@ gb_global TargetMetrics target_linux_arm32 = {
|
||||
gb_global TargetMetrics target_darwin_amd64 = {
|
||||
TargetOs_darwin,
|
||||
TargetArch_amd64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("x86_64-apple-darwin"),
|
||||
str_lit("e-m:o-i64:64-f80:128-n8:16:32:64-S128"),
|
||||
};
|
||||
@@ -413,7 +413,7 @@ gb_global TargetMetrics target_darwin_amd64 = {
|
||||
gb_global TargetMetrics target_darwin_arm64 = {
|
||||
TargetOs_darwin,
|
||||
TargetArch_arm64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("arm64-apple-macosx11.0.0"),
|
||||
str_lit("e-m:o-i64:64-i128:128-n32:64-S128"),
|
||||
};
|
||||
@@ -421,14 +421,14 @@ gb_global TargetMetrics target_darwin_arm64 = {
|
||||
gb_global TargetMetrics target_freebsd_i386 = {
|
||||
TargetOs_freebsd,
|
||||
TargetArch_i386,
|
||||
4, 4, 8,
|
||||
4, 4, 4, 8,
|
||||
str_lit("i386-unknown-freebsd-elf"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_freebsd_amd64 = {
|
||||
TargetOs_freebsd,
|
||||
TargetArch_amd64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("x86_64-unknown-freebsd-elf"),
|
||||
str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"),
|
||||
};
|
||||
@@ -436,7 +436,7 @@ gb_global TargetMetrics target_freebsd_amd64 = {
|
||||
gb_global TargetMetrics target_openbsd_amd64 = {
|
||||
TargetOs_openbsd,
|
||||
TargetArch_amd64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("x86_64-unknown-openbsd-elf"),
|
||||
str_lit("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"),
|
||||
};
|
||||
@@ -444,7 +444,7 @@ gb_global TargetMetrics target_openbsd_amd64 = {
|
||||
gb_global TargetMetrics target_essence_amd64 = {
|
||||
TargetOs_essence,
|
||||
TargetArch_amd64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("x86_64-pc-none-elf"),
|
||||
};
|
||||
|
||||
@@ -452,7 +452,7 @@ gb_global TargetMetrics target_essence_amd64 = {
|
||||
gb_global TargetMetrics target_freestanding_wasm32 = {
|
||||
TargetOs_freestanding,
|
||||
TargetArch_wasm32,
|
||||
4, 8, 16,
|
||||
4, 4, 8, 16,
|
||||
str_lit("wasm32-freestanding-js"),
|
||||
str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
@@ -460,7 +460,7 @@ gb_global TargetMetrics target_freestanding_wasm32 = {
|
||||
gb_global TargetMetrics target_js_wasm32 = {
|
||||
TargetOs_js,
|
||||
TargetArch_wasm32,
|
||||
4, 8, 16,
|
||||
4, 4, 8, 16,
|
||||
str_lit("wasm32-js-js"),
|
||||
str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
@@ -468,24 +468,42 @@ gb_global TargetMetrics target_js_wasm32 = {
|
||||
gb_global TargetMetrics target_wasi_wasm32 = {
|
||||
TargetOs_wasi,
|
||||
TargetArch_wasm32,
|
||||
4, 8, 16,
|
||||
4, 4, 8, 16,
|
||||
str_lit("wasm32-wasi-js"),
|
||||
str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
|
||||
|
||||
gb_global TargetMetrics target_js_wasm64 = {
|
||||
TargetOs_js,
|
||||
TargetArch_wasm64,
|
||||
8, 8, 16,
|
||||
str_lit("wasm64-js-js"),
|
||||
str_lit(""),
|
||||
gb_global TargetMetrics target_freestanding_wasm64p32 = {
|
||||
TargetOs_freestanding,
|
||||
TargetArch_wasm64p32,
|
||||
4, 8, 8, 16,
|
||||
str_lit("wasm32-freestanding-js"),
|
||||
str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_js_wasm64p32 = {
|
||||
TargetOs_js,
|
||||
TargetArch_wasm64p32,
|
||||
4, 8, 8, 16,
|
||||
str_lit("wasm32-js-js"),
|
||||
str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
|
||||
gb_global TargetMetrics target_wasi_wasm64p32 = {
|
||||
TargetOs_wasi,
|
||||
TargetArch_wasm32,
|
||||
4, 8, 8, 16,
|
||||
str_lit("wasm32-wasi-js"),
|
||||
str_lit("e-m:e-p:32:32-i64:64-n32:64-S128"),
|
||||
};
|
||||
|
||||
|
||||
|
||||
gb_global TargetMetrics target_freestanding_amd64_sysv = {
|
||||
TargetOs_freestanding,
|
||||
TargetArch_amd64,
|
||||
8, 8, 16,
|
||||
8, 8, 8, 16,
|
||||
str_lit("x86_64-pc-none-gnu"),
|
||||
str_lit("e-m:w-i64:64-f80:128-n8:16:32:64-S128"),
|
||||
TargetABI_SysV,
|
||||
@@ -501,20 +519,29 @@ struct NamedTargetMetrics {
|
||||
gb_global NamedTargetMetrics named_targets[] = {
|
||||
{ str_lit("darwin_amd64"), &target_darwin_amd64 },
|
||||
{ str_lit("darwin_arm64"), &target_darwin_arm64 },
|
||||
|
||||
{ str_lit("essence_amd64"), &target_essence_amd64 },
|
||||
|
||||
{ str_lit("linux_i386"), &target_linux_i386 },
|
||||
{ str_lit("linux_amd64"), &target_linux_amd64 },
|
||||
{ str_lit("linux_arm64"), &target_linux_arm64 },
|
||||
{ str_lit("linux_arm32"), &target_linux_arm32 },
|
||||
|
||||
{ str_lit("windows_i386"), &target_windows_i386 },
|
||||
{ str_lit("windows_amd64"), &target_windows_amd64 },
|
||||
|
||||
{ str_lit("freebsd_i386"), &target_freebsd_i386 },
|
||||
{ str_lit("freebsd_amd64"), &target_freebsd_amd64 },
|
||||
|
||||
{ str_lit("openbsd_amd64"), &target_openbsd_amd64 },
|
||||
|
||||
{ str_lit("freestanding_wasm32"), &target_freestanding_wasm32 },
|
||||
{ str_lit("wasi_wasm32"), &target_wasi_wasm32 },
|
||||
{ str_lit("js_wasm32"), &target_js_wasm32 },
|
||||
// { str_lit("js_wasm64"), &target_js_wasm64 },
|
||||
|
||||
{ str_lit("freestanding_wasm64p32"), &target_freestanding_wasm64p32 },
|
||||
{ str_lit("js_wasm64p32"), &target_js_wasm64p32 },
|
||||
{ str_lit("wasi_wasm64p32"), &target_wasi_wasm64p32 },
|
||||
|
||||
{ str_lit("freestanding_amd64_sysv"), &target_freestanding_amd64_sysv },
|
||||
};
|
||||
@@ -623,7 +650,7 @@ gb_internal bool find_library_collection_path(String name, String *path) {
|
||||
gb_internal bool is_arch_wasm(void) {
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
case TargetArch_wasm64p32:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -641,7 +668,7 @@ gb_internal bool is_arch_x86(void) {
|
||||
gb_internal bool allow_check_foreign_filepath(void) {
|
||||
switch (build_context.metrics.arch) {
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
case TargetArch_wasm64p32:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1164,16 +1191,24 @@ gb_internal void init_build_context(TargetMetrics *cross_target) {
|
||||
|
||||
GB_ASSERT(metrics->os != TargetOs_Invalid);
|
||||
GB_ASSERT(metrics->arch != TargetArch_Invalid);
|
||||
GB_ASSERT(metrics->word_size > 1);
|
||||
GB_ASSERT(metrics->ptr_size > 1);
|
||||
GB_ASSERT(metrics->int_size > 1);
|
||||
GB_ASSERT(metrics->max_align > 1);
|
||||
GB_ASSERT(metrics->max_simd_align > 1);
|
||||
|
||||
GB_ASSERT(metrics->int_size >= metrics->ptr_size);
|
||||
if (metrics->int_size > metrics->ptr_size) {
|
||||
GB_ASSERT(metrics->int_size == 2*metrics->ptr_size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bc->metrics = *metrics;
|
||||
bc->ODIN_OS = target_os_names[metrics->os];
|
||||
bc->ODIN_ARCH = target_arch_names[metrics->arch];
|
||||
bc->endian_kind = target_endians[metrics->arch];
|
||||
bc->word_size = metrics->word_size;
|
||||
bc->ptr_size = metrics->ptr_size;
|
||||
bc->int_size = metrics->int_size;
|
||||
bc->max_align = metrics->max_align;
|
||||
bc->max_simd_align = metrics->max_simd_align;
|
||||
bc->link_flags = str_lit(" ");
|
||||
@@ -1257,9 +1292,9 @@ gb_internal void init_build_context(TargetMetrics *cross_target) {
|
||||
// link_flags = gb_string_appendc(link_flags, "--export-all ");
|
||||
// link_flags = gb_string_appendc(link_flags, "--export-table ");
|
||||
link_flags = gb_string_appendc(link_flags, "--allow-undefined ");
|
||||
if (bc->metrics.arch == TargetArch_wasm64) {
|
||||
link_flags = gb_string_appendc(link_flags, "-mwasm64 ");
|
||||
}
|
||||
// if (bc->metrics.arch == TargetArch_wasm64) {
|
||||
// link_flags = gb_string_appendc(link_flags, "-mwasm64 ");
|
||||
// }
|
||||
if (bc->no_entry_point) {
|
||||
link_flags = gb_string_appendc(link_flags, "--no-entry ");
|
||||
}
|
||||
|
||||
+7
-9
@@ -971,13 +971,13 @@ gb_internal void init_universal(void) {
|
||||
|
||||
{
|
||||
GlobalEnumValue values[TargetArch_COUNT] = {
|
||||
{"Unknown", TargetArch_Invalid},
|
||||
{"amd64", TargetArch_amd64},
|
||||
{"i386", TargetArch_i386},
|
||||
{"arm32", TargetArch_arm32},
|
||||
{"arm64", TargetArch_arm64},
|
||||
{"wasm32", TargetArch_wasm32},
|
||||
{"wasm64", TargetArch_wasm64},
|
||||
{"Unknown", TargetArch_Invalid},
|
||||
{"amd64", TargetArch_amd64},
|
||||
{"i386", TargetArch_i386},
|
||||
{"arm32", TargetArch_arm32},
|
||||
{"arm64", TargetArch_arm64},
|
||||
{"wasm32", TargetArch_wasm32},
|
||||
{"wasm64p32", TargetArch_wasm64p32},
|
||||
};
|
||||
|
||||
auto fields = add_global_enum_type(str_lit("Odin_Arch_Type"), values, gb_count_of(values));
|
||||
@@ -1000,8 +1000,6 @@ gb_internal void init_universal(void) {
|
||||
|
||||
{
|
||||
GlobalEnumValue values[TargetEndian_COUNT] = {
|
||||
{"Unknown", TargetEndian_Invalid},
|
||||
|
||||
{"Little", TargetEndian_Little},
|
||||
{"Big", TargetEndian_Big},
|
||||
};
|
||||
|
||||
+51
-22
@@ -218,7 +218,7 @@ gb_internal i64 lb_sizeof(LLVMTypeRef type) {
|
||||
case LLVMDoubleTypeKind:
|
||||
return 8;
|
||||
case LLVMPointerTypeKind:
|
||||
return build_context.word_size;
|
||||
return build_context.ptr_size;
|
||||
case LLVMStructTypeKind:
|
||||
{
|
||||
unsigned field_count = LLVMCountStructElementTypes(type);
|
||||
@@ -275,7 +275,7 @@ gb_internal i64 lb_alignof(LLVMTypeRef type) {
|
||||
case LLVMIntegerTypeKind:
|
||||
{
|
||||
unsigned w = LLVMGetIntTypeWidth(type);
|
||||
return gb_clamp((w + 7)/8, 1, build_context.word_size);
|
||||
return gb_clamp((w + 7)/8, 1, build_context.ptr_size);
|
||||
}
|
||||
case LLVMHalfTypeKind:
|
||||
return 2;
|
||||
@@ -284,7 +284,7 @@ gb_internal i64 lb_alignof(LLVMTypeRef type) {
|
||||
case LLVMDoubleTypeKind:
|
||||
return 8;
|
||||
case LLVMPointerTypeKind:
|
||||
return build_context.word_size;
|
||||
return build_context.ptr_size;
|
||||
case LLVMStructTypeKind:
|
||||
{
|
||||
if (LLVMIsPackedStruct(type)) {
|
||||
@@ -326,7 +326,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)
|
||||
#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)
|
||||
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)
|
||||
@@ -388,7 +388,7 @@ namespace lbAbi386 {
|
||||
}
|
||||
|
||||
if (build_context.metrics.os == TargetOs_windows &&
|
||||
build_context.word_size == 8 &&
|
||||
build_context.ptr_size == 8 &&
|
||||
lb_is_type_kind(type, LLVMIntegerTypeKind) &&
|
||||
type == LLVMIntTypeInContext(c, 128)) {
|
||||
// NOTE(bill): Because Windows AMD64 is weird
|
||||
@@ -1217,7 +1217,7 @@ namespace lbAbiWasm {
|
||||
The approach taken optimizes for passing things in multiple
|
||||
registers/arguments if possible rather than by pointer.
|
||||
*/
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention);
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention, Type *original_type);
|
||||
gb_internal LB_ABI_COMPUTE_RETURN_TYPE(compute_return_type);
|
||||
|
||||
enum {MAX_DIRECT_STRUCT_SIZE = 32};
|
||||
@@ -1225,7 +1225,7 @@ namespace lbAbiWasm {
|
||||
gb_internal LB_ABI_INFO(abi_info) {
|
||||
lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType);
|
||||
ft->ctx = c;
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention);
|
||||
ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention, original_type);
|
||||
ft->ret = compute_return_type(ft, c, return_type, return_is_defined, return_is_tuple);
|
||||
ft->calling_convention = calling_convention;
|
||||
return ft;
|
||||
@@ -1315,15 +1315,42 @@ namespace lbAbiWasm {
|
||||
return lb_arg_type_indirect(type, nullptr);
|
||||
}
|
||||
|
||||
gb_internal lbArgType pseudo_slice(LLVMContextRef c, LLVMTypeRef type, ProcCallingConvention calling_convention) {
|
||||
if (build_context.metrics.ptr_size < build_context.metrics.int_size &&
|
||||
type_can_be_direct(type, calling_convention)) {
|
||||
LLVMTypeRef types[2] = {
|
||||
LLVMStructGetTypeAtIndex(type, 0),
|
||||
// ignore padding
|
||||
LLVMStructGetTypeAtIndex(type, 2)
|
||||
};
|
||||
LLVMTypeRef new_type = LLVMStructTypeInContext(c, types, gb_count_of(types), false);
|
||||
return lb_arg_type_direct(type, new_type, nullptr, nullptr);
|
||||
} else {
|
||||
return is_struct(c, type, calling_convention);
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention) {
|
||||
gb_internal Array<lbArgType> compute_arg_types(LLVMContextRef c, LLVMTypeRef *arg_types, unsigned arg_count, ProcCallingConvention calling_convention,
|
||||
Type *original_type) {
|
||||
auto args = array_make<lbArgType>(lb_function_type_args_allocator(), arg_count);
|
||||
|
||||
for (unsigned i = 0; i < arg_count; i++) {
|
||||
GB_ASSERT(original_type->kind == Type_Proc);
|
||||
GB_ASSERT(cast(isize)arg_count <= original_type->Proc.param_count);
|
||||
auto const ¶ms = original_type->Proc.params->Tuple.variables;
|
||||
|
||||
for (unsigned i = 0, j = 0; i < arg_count; i++, j++) {
|
||||
while (params[j]->kind != Entity_Variable) {
|
||||
j++;
|
||||
}
|
||||
Type *ptype = params[j]->type;
|
||||
LLVMTypeRef t = arg_types[i];
|
||||
LLVMTypeKind kind = LLVMGetTypeKind(t);
|
||||
if (kind == LLVMStructTypeKind || kind == LLVMArrayTypeKind) {
|
||||
args[i] = is_struct(c, t, calling_convention);
|
||||
if (is_type_slice(ptype) || is_type_string(ptype)) {
|
||||
args[i] = pseudo_slice(c, t, calling_convention);
|
||||
} else {
|
||||
args[i] = is_struct(c, t, calling_convention);
|
||||
}
|
||||
} else {
|
||||
args[i] = non_struct(c, t, false);
|
||||
}
|
||||
@@ -1460,32 +1487,33 @@ 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);
|
||||
return lbAbiAmd64Win64::abi_info(c, 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);
|
||||
return lbAbiAmd64SysV::abi_info(c, 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);
|
||||
return lbAbiAmd64Win64::abi_info(c, 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);
|
||||
return lbAbiAmd64Win64::abi_info(c, 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);
|
||||
return lbAbiAmd64SysV::abi_info(c, 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);
|
||||
return lbAbiAmd64SysV::abi_info(c, 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);
|
||||
return lbAbi386::abi_info(c, 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);
|
||||
return lbAbiArm32::abi_info(c, 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);
|
||||
return lbAbiArm64::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention, original_type);
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
return lbAbiWasm::abi_info(c, arg_types, arg_count, return_type, return_is_defined, return_is_tuple, calling_convention);
|
||||
return lbAbiWasm::abi_info(c, 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);
|
||||
}
|
||||
|
||||
GB_PANIC("Unsupported ABI");
|
||||
@@ -1499,7 +1527,8 @@ gb_internal LB_ABI_INFO(lb_get_abi_info) {
|
||||
arg_types, arg_count,
|
||||
return_type, return_is_defined,
|
||||
ALLOW_SPLIT_MULTI_RETURNS && return_is_tuple && is_calling_convention_odin(calling_convention),
|
||||
calling_convention);
|
||||
calling_convention,
|
||||
base_type(original_type));
|
||||
|
||||
|
||||
// NOTE(bill): this is handled here rather than when developing the type in `lb_type_internal_for_procedures_raw`
|
||||
|
||||
@@ -1987,7 +1987,7 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
|
||||
LLVMInitializeAArch64Disassembler();
|
||||
break;
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
case TargetArch_wasm64p32:
|
||||
LLVMInitializeWebAssemblyTargetInfo();
|
||||
LLVMInitializeWebAssemblyTarget();
|
||||
LLVMInitializeWebAssemblyTargetMC();
|
||||
|
||||
@@ -539,7 +539,7 @@ gb_internal void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValu
|
||||
gb_internal LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile);
|
||||
|
||||
gb_internal gb_inline i64 lb_max_zero_init_size(void) {
|
||||
return cast(i64)(4*build_context.word_size);
|
||||
return cast(i64)(4*build_context.int_size);
|
||||
}
|
||||
|
||||
gb_internal LLVMTypeRef OdinLLVMGetArrayElementType(LLVMTypeRef type);
|
||||
|
||||
@@ -131,6 +131,25 @@ gb_internal lbValue lb_const_ptr_cast(lbModule *m, lbValue value, Type *t) {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
gb_internal LLVMValueRef llvm_const_string_internal(lbModule *m, Type *t, LLVMValueRef data, LLVMValueRef len) {
|
||||
if (build_context.metrics.ptr_size < build_context.metrics.int_size) {
|
||||
LLVMValueRef values[3] = {
|
||||
data,
|
||||
LLVMConstNull(lb_type(m, t_i32)),
|
||||
len,
|
||||
};
|
||||
return llvm_const_named_struct_internal(lb_type(m, t), values, 3);
|
||||
} else {
|
||||
LLVMValueRef values[2] = {
|
||||
data,
|
||||
len,
|
||||
};
|
||||
return llvm_const_named_struct_internal(lb_type(m, t), values, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gb_internal LLVMValueRef llvm_const_named_struct(lbModule *m, Type *t, LLVMValueRef *values, isize value_count_) {
|
||||
LLVMTypeRef struct_type = lb_type(m, t);
|
||||
GB_ASSERT(LLVMGetTypeKind(struct_type) == LLVMStructTypeKind);
|
||||
@@ -180,17 +199,33 @@ gb_internal LLVMValueRef llvm_const_array(LLVMTypeRef elem_type, LLVMValueRef *v
|
||||
return LLVMConstArray(elem_type, values, value_count);
|
||||
}
|
||||
|
||||
gb_internal LLVMValueRef llvm_const_slice_internal(lbModule *m, LLVMValueRef data, LLVMValueRef len) {
|
||||
if (build_context.metrics.ptr_size < build_context.metrics.int_size) {
|
||||
GB_ASSERT(build_context.metrics.ptr_size == 4);
|
||||
GB_ASSERT(build_context.metrics.int_size == 8);
|
||||
LLVMValueRef vals[3] = {
|
||||
data,
|
||||
LLVMConstNull(lb_type(m, t_u32)),
|
||||
len,
|
||||
};
|
||||
return LLVMConstStructInContext(m->ctx, vals, gb_count_of(vals), false);
|
||||
} else {
|
||||
LLVMValueRef vals[2] = {
|
||||
data,
|
||||
len,
|
||||
};
|
||||
return LLVMConstStructInContext(m->ctx, vals, gb_count_of(vals), false);
|
||||
}
|
||||
}
|
||||
gb_internal LLVMValueRef llvm_const_slice(lbModule *m, lbValue data, lbValue len) {
|
||||
GB_ASSERT(is_type_pointer(data.type) || is_type_multi_pointer(data.type));
|
||||
GB_ASSERT(are_types_identical(len.type, t_int));
|
||||
LLVMValueRef vals[2] = {
|
||||
data.value,
|
||||
len.value,
|
||||
};
|
||||
return LLVMConstStructInContext(m->ctx, vals, gb_count_of(vals), false);
|
||||
|
||||
return llvm_const_slice_internal(m, data.value, len.value);
|
||||
}
|
||||
|
||||
|
||||
|
||||
gb_internal lbValue lb_const_nil(lbModule *m, Type *type) {
|
||||
LLVMValueRef v = LLVMConstNull(lb_type(m, type));
|
||||
return lbValue{v, type};
|
||||
@@ -643,10 +678,9 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
|
||||
ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
|
||||
}
|
||||
LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), value.value_string.len, true);
|
||||
LLVMValueRef values[2] = {ptr, str_len};
|
||||
GB_ASSERT(is_type_string(original_type));
|
||||
|
||||
res.value = llvm_const_named_struct(m, original_type, values, 2);
|
||||
res.value = llvm_const_string_internal(m, original_type, ptr, str_len);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
+35
-34
@@ -52,8 +52,8 @@ gb_internal LLVMMetadataRef lb_debug_type_internal_proc(lbModule *m, Type *type)
|
||||
|
||||
GB_ASSERT(type != t_invalid);
|
||||
|
||||
/* unsigned const word_size = cast(unsigned)build_context.word_size;
|
||||
unsigned const word_bits = cast(unsigned)(8*build_context.word_size); */
|
||||
/* unsigned const ptr_size = cast(unsigned)build_context.ptr_size;
|
||||
unsigned const ptr_bits = cast(unsigned)(8*build_context.ptr_size); */
|
||||
|
||||
GB_ASSERT(type->kind == Type_Proc);
|
||||
unsigned parameter_count = 1;
|
||||
@@ -131,8 +131,9 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
|
||||
GB_ASSERT(type != t_invalid);
|
||||
|
||||
/* unsigned const word_size = cast(unsigned)build_context.word_size; */
|
||||
unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
|
||||
/* unsigned const ptr_size = cast(unsigned)build_context.ptr_size; */
|
||||
unsigned const int_bits = cast(unsigned)(8*build_context.int_size);
|
||||
unsigned const ptr_bits = cast(unsigned)(8*build_context.ptr_size);
|
||||
|
||||
switch (type->kind) {
|
||||
case Type_Basic:
|
||||
@@ -162,12 +163,12 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
case Basic_f32: return lb_debug_type_basic_type(m, str_lit("f32"), 32, LLVMDWARFTypeEncoding_Float);
|
||||
case Basic_f64: return lb_debug_type_basic_type(m, str_lit("f64"), 64, LLVMDWARFTypeEncoding_Float);
|
||||
|
||||
case Basic_int: return lb_debug_type_basic_type(m, str_lit("int"), word_bits, LLVMDWARFTypeEncoding_Signed);
|
||||
case Basic_uint: return lb_debug_type_basic_type(m, str_lit("uint"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
|
||||
case Basic_uintptr: return lb_debug_type_basic_type(m, str_lit("uintptr"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
|
||||
case Basic_int: return lb_debug_type_basic_type(m, str_lit("int"), int_bits, LLVMDWARFTypeEncoding_Signed);
|
||||
case Basic_uint: return lb_debug_type_basic_type(m, str_lit("uint"), int_bits, LLVMDWARFTypeEncoding_Unsigned);
|
||||
case Basic_uintptr: return lb_debug_type_basic_type(m, str_lit("uintptr"), ptr_bits, LLVMDWARFTypeEncoding_Unsigned);
|
||||
|
||||
case Basic_typeid:
|
||||
return lb_debug_type_basic_type(m, str_lit("typeid"), word_bits, LLVMDWARFTypeEncoding_Unsigned);
|
||||
return lb_debug_type_basic_type(m, str_lit("typeid"), ptr_bits, LLVMDWARFTypeEncoding_Unsigned);
|
||||
|
||||
// Endian Specific Types
|
||||
case Basic_i16le: return lb_debug_type_basic_type(m, str_lit("i16le"), 16, LLVMDWARFTypeEncoding_Signed, LLVMDIFlagLittleEndian);
|
||||
@@ -251,26 +252,26 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
case Basic_rawptr:
|
||||
{
|
||||
LLVMMetadataRef void_type = lb_debug_type_basic_type(m, str_lit("void"), 8, LLVMDWARFTypeEncoding_Unsigned);
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, void_type, word_bits, word_bits, LLVMDWARFTypeEncoding_Address, "rawptr", 6);
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, void_type, ptr_bits, ptr_bits, LLVMDWARFTypeEncoding_Address, "rawptr", 6);
|
||||
}
|
||||
case Basic_string:
|
||||
{
|
||||
LLVMMetadataRef elements[2] = {};
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), t_u8_ptr, 0);
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, word_bits);
|
||||
return lb_debug_basic_struct(m, str_lit("string"), 2*word_bits, word_bits, elements, gb_count_of(elements));
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, int_bits);
|
||||
return lb_debug_basic_struct(m, str_lit("string"), 2*int_bits, int_bits, elements, gb_count_of(elements));
|
||||
}
|
||||
case Basic_cstring:
|
||||
{
|
||||
LLVMMetadataRef char_type = lb_debug_type_basic_type(m, str_lit("char"), 8, LLVMDWARFTypeEncoding_Unsigned);
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, char_type, word_bits, word_bits, 0, "cstring", 7);
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, char_type, ptr_bits, ptr_bits, 0, "cstring", 7);
|
||||
}
|
||||
case Basic_any:
|
||||
{
|
||||
LLVMMetadataRef elements[2] = {};
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0);
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("id"), t_typeid, word_bits);
|
||||
return lb_debug_basic_struct(m, str_lit("any"), 2*word_bits, word_bits, elements, gb_count_of(elements));
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("id"), t_typeid, ptr_bits);
|
||||
return lb_debug_basic_struct(m, str_lit("any"), 2*ptr_bits, ptr_bits, elements, gb_count_of(elements));
|
||||
}
|
||||
|
||||
// Untyped types
|
||||
@@ -292,11 +293,11 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
GB_PANIC("Type_Named should be handled in lb_debug_type separately");
|
||||
|
||||
case Type_SoaPointer:
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->SoaPointer.elem), word_bits, word_bits, 0, nullptr, 0);
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->SoaPointer.elem), int_bits, int_bits, 0, nullptr, 0);
|
||||
case Type_Pointer:
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->Pointer.elem), word_bits, word_bits, 0, nullptr, 0);
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->Pointer.elem), ptr_bits, ptr_bits, 0, nullptr, 0);
|
||||
case Type_MultiPointer:
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->MultiPointer.elem), word_bits, word_bits, 0, nullptr, 0);
|
||||
return LLVMDIBuilderCreatePointerType(m->debug_builder, lb_debug_type(m, type->MultiPointer.elem), ptr_bits, ptr_bits, 0, nullptr, 0);
|
||||
|
||||
case Type_Array: {
|
||||
LLVMMetadataRef subscripts[1] = {};
|
||||
@@ -416,7 +417,7 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
case Type_Proc:
|
||||
{
|
||||
LLVMMetadataRef proc_underlying_type = lb_debug_type_internal_proc(m, type);
|
||||
LLVMMetadataRef pointer_type = LLVMDIBuilderCreatePointerType(m->debug_builder, proc_underlying_type, word_bits, word_bits, 0, nullptr, 0);
|
||||
LLVMMetadataRef pointer_type = LLVMDIBuilderCreatePointerType(m->debug_builder, proc_underlying_type, ptr_bits, ptr_bits, 0, nullptr, 0);
|
||||
gbString name = type_to_string(type, temporary_allocator());
|
||||
return LLVMDIBuilderCreateTypedef(m->debug_builder, pointer_type, name, gb_string_length(name), nullptr, 0, nullptr, cast(u32)(8*type_align_of(type)));
|
||||
}
|
||||
@@ -447,10 +448,11 @@ gb_internal LLVMMetadataRef lb_debug_type_internal(lbModule *m, Type *type) {
|
||||
unsigned element_count = 0;
|
||||
LLVMMetadataRef elements[2] = {};
|
||||
Type *base_integer = type->RelativeSlice.base_integer;
|
||||
unsigned base_bits = cast(unsigned)(8*type_size_of(base_integer));
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data_offset"), base_integer, 0);
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("len"), base_integer, 8*type_size_of(base_integer));
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("len"), base_integer, base_bits);
|
||||
gbString name = type_to_string(type, temporary_allocator());
|
||||
return LLVMDIBuilderCreateStructType(m->debug_builder, nullptr, name, gb_string_length(name), nullptr, 0, 2*word_bits, word_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0);
|
||||
return LLVMDIBuilderCreateStructType(m->debug_builder, nullptr, name, gb_string_length(name), nullptr, 0, 2*base_bits, base_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0);
|
||||
}
|
||||
|
||||
case Type_Matrix: {
|
||||
@@ -616,8 +618,7 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
|
||||
}
|
||||
|
||||
gb_internal void lb_debug_complete_types(lbModule *m) {
|
||||
/* unsigned const word_size = cast(unsigned)build_context.word_size; */
|
||||
unsigned const word_bits = cast(unsigned)(8*build_context.word_size);
|
||||
unsigned const int_bits = cast(unsigned)(8*build_context.int_size);
|
||||
|
||||
for_array(debug_incomplete_type_index, m->debug_incomplete_types) {
|
||||
TEMPORARY_ALLOCATOR_GUARD();
|
||||
@@ -691,27 +692,27 @@ gb_internal void lb_debug_complete_types(lbModule *m) {
|
||||
element_count = 2;
|
||||
elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->Slice.elem), 0*word_bits);
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->Slice.elem), 0*int_bits);
|
||||
#else
|
||||
// FIX HACK TODO(bill): For some reason this causes a crash in *nix systems due to the reference counting
|
||||
// of the debug type information
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*word_bits);
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*int_bits);
|
||||
#endif
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*word_bits);
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*int_bits);
|
||||
break;
|
||||
case Type_DynamicArray:
|
||||
element_count = 4;
|
||||
elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
|
||||
#if defined(GB_SYSTEM_WINDOWS)
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->DynamicArray.elem), 0*word_bits);
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), alloc_type_pointer(bt->DynamicArray.elem), 0*int_bits);
|
||||
#else
|
||||
// FIX HACK TODO(bill): For some reason this causes a crash in *nix systems due to the reference counting
|
||||
// of the debug type information
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*word_bits);
|
||||
elements[0] = lb_debug_struct_field(m, str_lit("data"), t_rawptr, 0*int_bits);
|
||||
#endif
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*word_bits);
|
||||
elements[2] = lb_debug_struct_field(m, str_lit("cap"), t_int, 2*word_bits);
|
||||
elements[3] = lb_debug_struct_field(m, str_lit("allocator"), t_allocator, 3*word_bits);
|
||||
elements[1] = lb_debug_struct_field(m, str_lit("len"), t_int, 1*int_bits);
|
||||
elements[2] = lb_debug_struct_field(m, str_lit("cap"), t_int, 2*int_bits);
|
||||
elements[3] = lb_debug_struct_field(m, str_lit("allocator"), t_allocator, 3*int_bits);
|
||||
break;
|
||||
|
||||
case Type_Map:
|
||||
@@ -737,7 +738,7 @@ gb_internal void lb_debug_complete_types(lbModule *m) {
|
||||
element_count = cast(unsigned)(bt->Struct.fields.count + element_offset);
|
||||
elements = gb_alloc_array(temporary_allocator(), LLVMMetadataRef, element_count);
|
||||
|
||||
isize field_size_bits = 8*type_size_of(bt) - element_offset*word_bits;
|
||||
isize field_size_bits = 8*type_size_of(bt) - element_offset*int_bits;
|
||||
|
||||
switch (bt->Struct.soa_kind) {
|
||||
case StructSoa_Slice:
|
||||
@@ -756,7 +757,7 @@ gb_internal void lb_debug_complete_types(lbModule *m) {
|
||||
".len", 4,
|
||||
file, 0,
|
||||
8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
|
||||
field_size_bits + 0*word_bits,
|
||||
field_size_bits + 0*int_bits,
|
||||
LLVMDIFlagZero, lb_debug_type(m, t_int)
|
||||
);
|
||||
elements[1] = LLVMDIBuilderCreateMemberType(
|
||||
@@ -764,7 +765,7 @@ gb_internal void lb_debug_complete_types(lbModule *m) {
|
||||
".cap", 4,
|
||||
file, 0,
|
||||
8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
|
||||
field_size_bits + 1*word_bits,
|
||||
field_size_bits + 1*int_bits,
|
||||
LLVMDIFlagZero, lb_debug_type(m, t_int)
|
||||
);
|
||||
elements[2] = LLVMDIBuilderCreateMemberType(
|
||||
@@ -772,7 +773,7 @@ gb_internal void lb_debug_complete_types(lbModule *m) {
|
||||
".allocator", 10,
|
||||
file, 0,
|
||||
8*cast(u64)type_size_of(t_int), 8*cast(u32)type_align_of(t_int),
|
||||
field_size_bits + 2*word_bits,
|
||||
field_size_bits + 2*int_bits,
|
||||
LLVMDIFlagZero, lb_debug_type(m, t_allocator)
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -518,7 +518,7 @@ gb_internal bool lb_is_matrix_simdable(Type *t) {
|
||||
return true;
|
||||
case TargetArch_i386:
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
case TargetArch_wasm64p32:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -4230,11 +4230,12 @@ gb_internal lbAddr lb_build_addr_compound_lit(lbProcedure *p, Ast *expr) {
|
||||
lbValue count = {};
|
||||
count.type = t_int;
|
||||
|
||||
unsigned len_index = lb_convert_struct_index(p->module, type, 1);
|
||||
if (lb_is_const(slice)) {
|
||||
unsigned indices[1] = {1};
|
||||
unsigned indices[1] = {len_index};
|
||||
count.value = LLVMConstExtractValue(slice.value, indices, gb_count_of(indices));
|
||||
} else {
|
||||
count.value = LLVMBuildExtractValue(p->builder, slice.value, 1, "");
|
||||
count.value = LLVMBuildExtractValue(p->builder, slice.value, len_index, "");
|
||||
}
|
||||
lb_fill_slice(p, v, data, count);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token);
|
||||
gb_internal LLVMValueRef llvm_const_string_internal(lbModule *m, Type *t, LLVMValueRef data, LLVMValueRef len);
|
||||
|
||||
gb_global Entity *lb_global_type_info_data_entity = {};
|
||||
gb_global lbAddr lb_global_type_info_member_types = {};
|
||||
@@ -1579,7 +1580,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);
|
||||
lbFunctionType *ft = lb_get_abi_info(m->ctx, params, param_count, ret, ret != nullptr, return_is_tuple, type->Proc.calling_convention, type);
|
||||
{
|
||||
for_array(j, ft->args) {
|
||||
auto arg = ft->args[j];
|
||||
@@ -1626,6 +1627,8 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
|
||||
GB_ASSERT(type != t_invalid);
|
||||
|
||||
bool bigger_int = build_context.ptr_size != build_context.int_size;
|
||||
|
||||
switch (type->kind) {
|
||||
case Type_Basic:
|
||||
switch (type->Basic.kind) {
|
||||
@@ -1760,10 +1763,10 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
case Basic_int: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size);
|
||||
case Basic_uint: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size);
|
||||
case Basic_int: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.int_size);
|
||||
case Basic_uint: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.int_size);
|
||||
|
||||
case Basic_uintptr: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size);
|
||||
case Basic_uintptr: return LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.ptr_size);
|
||||
|
||||
case Basic_rawptr: return LLVMPointerType(LLVMInt8TypeInContext(ctx), 0);
|
||||
case Basic_string:
|
||||
@@ -1774,11 +1777,23 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
return type;
|
||||
}
|
||||
type = LLVMStructCreateNamed(ctx, name);
|
||||
LLVMTypeRef fields[2] = {
|
||||
LLVMPointerType(lb_type(m, t_u8), 0),
|
||||
lb_type(m, t_int),
|
||||
};
|
||||
LLVMStructSetBody(type, fields, 2, false);
|
||||
|
||||
if (build_context.metrics.ptr_size < build_context.metrics.int_size) {
|
||||
GB_ASSERT(build_context.metrics.ptr_size == 4);
|
||||
GB_ASSERT(build_context.metrics.int_size == 8);
|
||||
LLVMTypeRef fields[3] = {
|
||||
LLVMPointerType(lb_type(m, t_u8), 0),
|
||||
lb_type(m, t_i32),
|
||||
lb_type(m, t_int),
|
||||
};
|
||||
LLVMStructSetBody(type, fields, 3, false);
|
||||
} else {
|
||||
LLVMTypeRef fields[2] = {
|
||||
LLVMPointerType(lb_type(m, t_u8), 0),
|
||||
lb_type(m, t_int),
|
||||
};
|
||||
LLVMStructSetBody(type, fields, 2, false);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
case Basic_cstring: return LLVMPointerType(LLVMInt8TypeInContext(ctx), 0);
|
||||
@@ -1798,7 +1813,7 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
return type;
|
||||
}
|
||||
|
||||
case Basic_typeid: return LLVMIntTypeInContext(m->ctx, 8*cast(unsigned)build_context.word_size);
|
||||
case Basic_typeid: return LLVMIntTypeInContext(m->ctx, 8*cast(unsigned)build_context.ptr_size);
|
||||
|
||||
// Endian Specific Types
|
||||
case Basic_i16le: return LLVMInt16TypeInContext(ctx);
|
||||
@@ -1922,23 +1937,43 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
|
||||
case Type_Slice:
|
||||
{
|
||||
LLVMTypeRef fields[2] = {
|
||||
LLVMPointerType(lb_type(m, type->Slice.elem), 0), // data
|
||||
lb_type(m, t_int), // len
|
||||
};
|
||||
return LLVMStructTypeInContext(ctx, fields, 2, false);
|
||||
if (bigger_int) {
|
||||
LLVMTypeRef fields[3] = {
|
||||
LLVMPointerType(lb_type(m, type->Slice.elem), 0), // data
|
||||
lb_type_padding_filler(m, build_context.ptr_size, build_context.ptr_size), // padding
|
||||
lb_type(m, t_int), // len
|
||||
};
|
||||
return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false);
|
||||
} else {
|
||||
LLVMTypeRef fields[2] = {
|
||||
LLVMPointerType(lb_type(m, type->Slice.elem), 0), // data
|
||||
lb_type(m, t_int), // len
|
||||
};
|
||||
return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Type_DynamicArray:
|
||||
{
|
||||
LLVMTypeRef fields[4] = {
|
||||
LLVMPointerType(lb_type(m, type->DynamicArray.elem), 0), // data
|
||||
lb_type(m, t_int), // len
|
||||
lb_type(m, t_int), // cap
|
||||
lb_type(m, t_allocator), // allocator
|
||||
};
|
||||
return LLVMStructTypeInContext(ctx, fields, 4, false);
|
||||
if (bigger_int) {
|
||||
LLVMTypeRef fields[5] = {
|
||||
LLVMPointerType(lb_type(m, type->DynamicArray.elem), 0), // data
|
||||
lb_type_padding_filler(m, build_context.ptr_size, build_context.ptr_size), // padding
|
||||
lb_type(m, t_int), // len
|
||||
lb_type(m, t_int), // cap
|
||||
lb_type(m, t_allocator), // allocator
|
||||
};
|
||||
return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false);
|
||||
} else {
|
||||
LLVMTypeRef fields[4] = {
|
||||
LLVMPointerType(lb_type(m, type->DynamicArray.elem), 0), // data
|
||||
lb_type(m, t_int), // len
|
||||
lb_type(m, t_int), // cap
|
||||
lb_type(m, t_allocator), // allocator
|
||||
};
|
||||
return LLVMStructTypeInContext(ctx, fields, gb_count_of(fields), false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2145,9 +2180,17 @@ gb_internal LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
||||
case Type_SoaPointer:
|
||||
{
|
||||
unsigned field_count = 2;
|
||||
if (bigger_int) {
|
||||
field_count = 3;
|
||||
}
|
||||
LLVMTypeRef *fields = gb_alloc_array(permanent_allocator(), LLVMTypeRef, field_count);
|
||||
fields[0] = LLVMPointerType(lb_type(m, type->Pointer.elem), 0);
|
||||
fields[1] = LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.word_size);
|
||||
if (bigger_int) {
|
||||
fields[1] = lb_type_padding_filler(m, build_context.ptr_size, build_context.ptr_size);
|
||||
fields[2] = LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.int_size);
|
||||
} else {
|
||||
fields[1] = LLVMIntTypeInContext(ctx, 8*cast(unsigned)build_context.int_size);
|
||||
}
|
||||
return LLVMStructTypeInContext(ctx, fields, field_count, false);
|
||||
}
|
||||
|
||||
@@ -2503,10 +2546,9 @@ gb_internal lbValue lb_find_or_add_entity_string(lbModule *m, String const &str)
|
||||
ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
|
||||
}
|
||||
LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true);
|
||||
LLVMValueRef values[2] = {ptr, str_len};
|
||||
|
||||
lbValue res = {};
|
||||
res.value = llvm_const_named_struct(m, t_string, values, 2);
|
||||
res.value = llvm_const_string_internal(m, t_string, ptr, str_len);
|
||||
res.type = t_string;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ gb_internal void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue sr
|
||||
char const *name = "llvm.memmove";
|
||||
if (LLVMIsConstant(len.value)) {
|
||||
i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
|
||||
if (const_len <= 4*build_context.word_size) {
|
||||
if (const_len <= 4*build_context.int_size) {
|
||||
name = "llvm.memmove.inline";
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ gb_internal void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValu
|
||||
char const *name = "llvm.memcpy";
|
||||
if (LLVMIsConstant(len.value)) {
|
||||
i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
|
||||
if (const_len <= 4*build_context.word_size) {
|
||||
if (const_len <= 4*build_context.int_size) {
|
||||
name = "llvm.memcpy.inline";
|
||||
}
|
||||
}
|
||||
@@ -2890,7 +2890,7 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
{
|
||||
char const *name = "llvm.wasm.memory.grow";
|
||||
LLVMTypeRef types[1] = {
|
||||
lb_type(p->module, t_uintptr),
|
||||
lb_type(p->module, t_i32),
|
||||
};
|
||||
|
||||
LLVMValueRef args[2] = {};
|
||||
@@ -2898,24 +2898,24 @@ gb_internal lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValu
|
||||
args[1] = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_uintptr).value;
|
||||
|
||||
lbValue res = {};
|
||||
res.type = tv.type;
|
||||
res.type = t_i32;
|
||||
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||
return res;
|
||||
return lb_emit_conv(p, res, tv.type);
|
||||
}
|
||||
case BuiltinProc_wasm_memory_size:
|
||||
{
|
||||
char const *name = "llvm.wasm.memory.size";
|
||||
LLVMTypeRef types[1] = {
|
||||
lb_type(p->module, t_uintptr),
|
||||
lb_type(p->module, t_i32),
|
||||
};
|
||||
|
||||
LLVMValueRef args[1] = {};
|
||||
args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value;
|
||||
|
||||
lbValue res = {};
|
||||
res.type = tv.type;
|
||||
res.type = t_i32;
|
||||
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||
return res;
|
||||
return lb_emit_conv(p, res, tv.type);
|
||||
}
|
||||
|
||||
case BuiltinProc_wasm_memory_atomic_wait32:
|
||||
|
||||
@@ -1812,7 +1812,7 @@ gb_internal void lb_build_return_stmt_internal(lbProcedure *p, lbValue res) {
|
||||
if (res.value != nullptr) {
|
||||
LLVMValueRef res_val = res.value;
|
||||
i64 sz = type_size_of(res.type);
|
||||
if (LLVMIsALoadInst(res_val) && sz > build_context.word_size) {
|
||||
if (LLVMIsALoadInst(res_val) && sz > build_context.int_size) {
|
||||
lbValue ptr = lb_address_from_load_or_generate_local(p, res);
|
||||
lb_mem_copy_non_overlapping(p, p->return_ptr.addr, ptr, lb_const_int(p->module, t_int, sz));
|
||||
} else {
|
||||
@@ -2471,6 +2471,7 @@ gb_internal void lb_build_stmt(lbProcedure *p, Ast *node) {
|
||||
}
|
||||
GB_ASSERT(lval_index == lvals.count);
|
||||
|
||||
|
||||
for_array(i, vd->names) {
|
||||
Ast *name = vd->names[i];
|
||||
if (!is_blank_ident(name) && !lvals_preused[i]) {
|
||||
|
||||
+13
-13
@@ -68,21 +68,21 @@ gb_internal lbValue lb_typeid(lbModule *m, Type *type) {
|
||||
}
|
||||
|
||||
u64 data = 0;
|
||||
if (build_context.word_size == 4) {
|
||||
if (build_context.ptr_size == 4) {
|
||||
GB_ASSERT(id <= (1u<<24u));
|
||||
data |= (id &~ (1u<<24)) << 0u; // index
|
||||
data |= (kind &~ (1u<<5)) << 24u; // kind
|
||||
data |= (named &~ (1u<<1)) << 29u; // kind
|
||||
data |= (special &~ (1u<<1)) << 30u; // kind
|
||||
data |= (reserved &~ (1u<<1)) << 31u; // kind
|
||||
data |= (named &~ (1u<<1)) << 29u; // named
|
||||
data |= (special &~ (1u<<1)) << 30u; // special
|
||||
data |= (reserved &~ (1u<<1)) << 31u; // reserved
|
||||
} else {
|
||||
GB_ASSERT(build_context.word_size == 8);
|
||||
GB_ASSERT(build_context.ptr_size == 8);
|
||||
GB_ASSERT(id <= (1ull<<56u));
|
||||
data |= (id &~ (1ull<<56)) << 0ul; // index
|
||||
data |= (kind &~ (1ull<<5)) << 56ull; // kind
|
||||
data |= (named &~ (1ull<<1)) << 61ull; // kind
|
||||
data |= (special &~ (1ull<<1)) << 62ull; // kind
|
||||
data |= (reserved &~ (1ull<<1)) << 63ull; // kind
|
||||
data |= (named &~ (1ull<<1)) << 61ull; // named
|
||||
data |= (special &~ (1ull<<1)) << 62ull; // special
|
||||
data |= (reserved &~ (1ull<<1)) << 63ull; // reserved
|
||||
}
|
||||
|
||||
lbValue res = {};
|
||||
@@ -157,11 +157,11 @@ gb_internal void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup
|
||||
global_type_info_data_entity_count = type->Array.count;
|
||||
|
||||
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
||||
LLVMValueRef values[2] = {
|
||||
LLVMConstInBoundsGEP2(lb_type(m, lb_global_type_info_data_entity->type), lb_global_type_info_data_ptr(m).value, indices, gb_count_of(indices)),
|
||||
LLVMConstInt(lb_type(m, t_int), type->Array.count, true),
|
||||
};
|
||||
LLVMValueRef slice = llvm_const_named_struct_internal(lb_type(m, type_deref(global_type_table.type)), values, gb_count_of(values));
|
||||
LLVMValueRef data = LLVMConstInBoundsGEP2(lb_type(m, lb_global_type_info_data_entity->type), lb_global_type_info_data_ptr(m).value, indices, gb_count_of(indices));
|
||||
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), type->Array.count, true);
|
||||
Type *t = type_deref(global_type_table.type);
|
||||
GB_ASSERT(is_type_slice(t));
|
||||
LLVMValueRef slice = llvm_const_slice_internal(m, data, len);
|
||||
|
||||
LLVMSetInitializer(global_type_table.value, slice);
|
||||
}
|
||||
|
||||
@@ -929,7 +929,38 @@ gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t)
|
||||
gb_internal i32 lb_convert_struct_index(lbModule *m, Type *t, i32 index) {
|
||||
if (t->kind == Type_Struct) {
|
||||
auto field_remapping = lb_get_struct_remapping(m, t);
|
||||
index = field_remapping[index];
|
||||
return field_remapping[index];
|
||||
} else if (build_context.ptr_size != build_context.int_size) {
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
if (t->Basic.kind != Basic_string) {
|
||||
break;
|
||||
}
|
||||
/*fallthrough*/
|
||||
case Type_Slice:
|
||||
GB_ASSERT(build_context.ptr_size*2 == build_context.int_size);
|
||||
switch (index) {
|
||||
case 0: return 0; // data
|
||||
case 1: return 2; // len
|
||||
}
|
||||
break;
|
||||
case Type_DynamicArray:
|
||||
GB_ASSERT(build_context.ptr_size*2 == build_context.int_size);
|
||||
switch (index) {
|
||||
case 0: return 0; // data
|
||||
case 1: return 2; // len
|
||||
case 2: return 3; // cap
|
||||
case 3: return 4; // allocator
|
||||
}
|
||||
break;
|
||||
case Type_SoaPointer:
|
||||
GB_ASSERT(build_context.ptr_size*2 == build_context.int_size);
|
||||
switch (index) {
|
||||
case 0: return 0; // data
|
||||
case 1: return 2; // offset
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index;
|
||||
}
|
||||
@@ -1563,7 +1594,7 @@ gb_internal lbValue lb_map_data_uintptr(lbProcedure *p, lbValue value) {
|
||||
GB_ASSERT(is_type_map(value.type) || are_types_identical(value.type, t_raw_map));
|
||||
lbValue data = lb_emit_struct_ev(p, value, 0);
|
||||
u64 mask_value = 0;
|
||||
if (build_context.word_size == 4) {
|
||||
if (build_context.ptr_size == 4) {
|
||||
mask_value = 0xfffffffful & ~(MAP_CACHE_LINE_SIZE-1);
|
||||
} else {
|
||||
mask_value = 0xffffffffffffffffull & ~(MAP_CACHE_LINE_SIZE-1);
|
||||
@@ -1659,7 +1690,7 @@ gb_internal lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValu
|
||||
break;
|
||||
case TargetArch_i386:
|
||||
case TargetArch_wasm32:
|
||||
case TargetArch_wasm64:
|
||||
case TargetArch_wasm64p32:
|
||||
is_possible = false;
|
||||
break;
|
||||
}
|
||||
|
||||
+49
-42
@@ -3417,13 +3417,16 @@ gb_internal i64 type_size_of(Type *t) {
|
||||
if (t->kind == Type_Basic) {
|
||||
GB_ASSERT_MSG(is_type_typed(t), "%s", type_to_string(t));
|
||||
switch (t->Basic.kind) {
|
||||
case Basic_string: size = 2*build_context.word_size; break;
|
||||
case Basic_cstring: size = build_context.word_size; break;
|
||||
case Basic_any: size = 2*build_context.word_size; break;
|
||||
case Basic_typeid: size = build_context.word_size; break;
|
||||
case Basic_string: size = 2*build_context.int_size; break;
|
||||
case Basic_cstring: size = build_context.ptr_size; break;
|
||||
case Basic_any: size = 2*build_context.ptr_size; break;
|
||||
case Basic_typeid: size = build_context.ptr_size; break;
|
||||
|
||||
case Basic_int: case Basic_uint: case Basic_uintptr: case Basic_rawptr:
|
||||
size = build_context.word_size;
|
||||
case Basic_int: case Basic_uint:
|
||||
size = build_context.int_size;
|
||||
break;
|
||||
case Basic_uintptr: case Basic_rawptr:
|
||||
size = build_context.ptr_size;
|
||||
break;
|
||||
default:
|
||||
size = t->Basic.size;
|
||||
@@ -3477,13 +3480,15 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
case Type_Basic: {
|
||||
GB_ASSERT(is_type_typed(t));
|
||||
switch (t->Basic.kind) {
|
||||
case Basic_string: return build_context.word_size;
|
||||
case Basic_cstring: return build_context.word_size;
|
||||
case Basic_any: return build_context.word_size;
|
||||
case Basic_typeid: return build_context.word_size;
|
||||
case Basic_string: return build_context.int_size;
|
||||
case Basic_cstring: return build_context.ptr_size;
|
||||
case Basic_any: return build_context.ptr_size;
|
||||
case Basic_typeid: return build_context.ptr_size;
|
||||
|
||||
case Basic_int: case Basic_uint: case Basic_uintptr: case Basic_rawptr:
|
||||
return build_context.word_size;
|
||||
case Basic_int: case Basic_uint:
|
||||
return build_context.int_size;
|
||||
case Basic_uintptr: case Basic_rawptr:
|
||||
return build_context.ptr_size;
|
||||
|
||||
case Basic_complex32: case Basic_complex64: case Basic_complex128:
|
||||
return type_size_of_internal(t, path) / 2;
|
||||
@@ -3516,10 +3521,10 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
|
||||
case Type_DynamicArray:
|
||||
// data, count, capacity, allocator
|
||||
return build_context.word_size;
|
||||
return build_context.int_size;
|
||||
|
||||
case Type_Slice:
|
||||
return build_context.word_size;
|
||||
return build_context.int_size;
|
||||
|
||||
|
||||
case Type_Tuple: {
|
||||
@@ -3534,7 +3539,7 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
} break;
|
||||
|
||||
case Type_Map:
|
||||
return build_context.word_size;
|
||||
return build_context.ptr_size;
|
||||
case Type_Enum:
|
||||
return type_align_of_internal(t->Enum.base_type, path);
|
||||
|
||||
@@ -3614,10 +3619,10 @@ gb_internal i64 type_align_of_internal(Type *t, TypePath *path) {
|
||||
return type_align_of_internal(t->RelativeSlice.base_integer, path);
|
||||
|
||||
case Type_SoaPointer:
|
||||
return build_context.word_size;
|
||||
return build_context.int_size;
|
||||
}
|
||||
|
||||
// NOTE(bill): Things that are bigger than build_context.word_size, are actually comprised of smaller types
|
||||
// NOTE(bill): Things that are bigger than build_context.ptr_size, are actually comprised of smaller types
|
||||
// TODO(bill): Is this correct for 128-bit types (integers)?
|
||||
return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, build_context.max_align);
|
||||
}
|
||||
@@ -3699,24 +3704,26 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
|
||||
return size;
|
||||
}
|
||||
switch (kind) {
|
||||
case Basic_string: return 2*build_context.word_size;
|
||||
case Basic_cstring: return build_context.word_size;
|
||||
case Basic_any: return 2*build_context.word_size;
|
||||
case Basic_typeid: return build_context.word_size;
|
||||
case Basic_string: return 2*build_context.int_size;
|
||||
case Basic_cstring: return build_context.ptr_size;
|
||||
case Basic_any: return 2*build_context.ptr_size;
|
||||
case Basic_typeid: return build_context.ptr_size;
|
||||
|
||||
case Basic_int: case Basic_uint: case Basic_uintptr: case Basic_rawptr:
|
||||
return build_context.word_size;
|
||||
case Basic_int: case Basic_uint:
|
||||
return build_context.int_size;
|
||||
case Basic_uintptr: case Basic_rawptr:
|
||||
return build_context.ptr_size;
|
||||
}
|
||||
} break;
|
||||
|
||||
case Type_Pointer:
|
||||
return build_context.word_size;
|
||||
return build_context.ptr_size;
|
||||
|
||||
case Type_MultiPointer:
|
||||
return build_context.word_size;
|
||||
return build_context.ptr_size;
|
||||
|
||||
case Type_SoaPointer:
|
||||
return build_context.word_size*2;
|
||||
return build_context.int_size*2;
|
||||
|
||||
case Type_Array: {
|
||||
i64 count, align, size, alignment;
|
||||
@@ -3749,11 +3756,11 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
|
||||
} break;
|
||||
|
||||
case Type_Slice: // ptr + len
|
||||
return 2 * build_context.word_size;
|
||||
return 2 * build_context.int_size;
|
||||
|
||||
case Type_DynamicArray:
|
||||
// data + len + cap + allocator(procedure+data)
|
||||
return (3 + 2)*build_context.word_size;
|
||||
return 3*build_context.int_size + 2*build_context.ptr_size;
|
||||
|
||||
case Type_Map:
|
||||
/*
|
||||
@@ -3763,7 +3770,7 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
|
||||
allocator: runtime.Allocator, // 2 words
|
||||
}
|
||||
*/
|
||||
return (1 + 1 + 2)*build_context.word_size;
|
||||
return (1 + 1 + 2)*build_context.ptr_size;
|
||||
|
||||
case Type_Tuple: {
|
||||
i64 count, align, size;
|
||||
@@ -3889,7 +3896,7 @@ gb_internal i64 type_size_of_internal(Type *t, TypePath *path) {
|
||||
}
|
||||
|
||||
// Catch all
|
||||
return build_context.word_size;
|
||||
return build_context.ptr_size;
|
||||
}
|
||||
|
||||
gb_internal i64 type_offset_of(Type *t, i32 index) {
|
||||
@@ -3909,32 +3916,32 @@ gb_internal i64 type_offset_of(Type *t, i32 index) {
|
||||
} else if (t->kind == Type_Basic) {
|
||||
if (t->Basic.kind == Basic_string) {
|
||||
switch (index) {
|
||||
case 0: return 0; // data
|
||||
case 1: return build_context.word_size; // len
|
||||
case 0: return 0; // data
|
||||
case 1: return build_context.int_size; // len
|
||||
}
|
||||
} else if (t->Basic.kind == Basic_any) {
|
||||
switch (index) {
|
||||
case 0: return 0; // type_info
|
||||
case 1: return build_context.word_size; // data
|
||||
case 0: return 0; // type_info
|
||||
case 1: return build_context.ptr_size; // data
|
||||
}
|
||||
}
|
||||
} else if (t->kind == Type_Slice) {
|
||||
switch (index) {
|
||||
case 0: return 0; // data
|
||||
case 1: return 1*build_context.word_size; // len
|
||||
case 2: return 2*build_context.word_size; // cap
|
||||
case 0: return 0; // data
|
||||
case 1: return 1*build_context.int_size; // len
|
||||
case 2: return 2*build_context.int_size; // cap
|
||||
}
|
||||
} else if (t->kind == Type_DynamicArray) {
|
||||
switch (index) {
|
||||
case 0: return 0; // data
|
||||
case 1: return 1*build_context.word_size; // len
|
||||
case 2: return 2*build_context.word_size; // cap
|
||||
case 3: return 3*build_context.word_size; // allocator
|
||||
case 0: return 0; // data
|
||||
case 1: return 1*build_context.int_size; // len
|
||||
case 2: return 2*build_context.int_size; // cap
|
||||
case 3: return 3*build_context.int_size; // allocator
|
||||
}
|
||||
} else if (t->kind == Type_Union) {
|
||||
/* i64 s = */ type_size_of(t);
|
||||
switch (index) {
|
||||
case -1: return align_formula(t->Union.variant_block_size, build_context.word_size); // __type_info
|
||||
case -1: return align_formula(t->Union.variant_block_size, build_context.ptr_size); // __type_info
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
//+build js wasm32, js wasm64
|
||||
//+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import dom_lib "odin_dom"
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
//+build js wasm32, js wasm64
|
||||
//+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import dom_lib "odin_dom"
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
//+build js wasm32, js wasm64
|
||||
//+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
foreign import "odin_env"
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
//+build js wasm32, js wasm64
|
||||
//+build js wasm32, js wasm64p32
|
||||
package wasm_js_interface
|
||||
|
||||
import "core:mem"
|
||||
|
||||
Reference in New Issue
Block a user