Merge pull request #2470 from odin-lang/separate-int-word-sizes

Separate int size from word/pointer size
This commit is contained in:
gingerBill
2023-06-07 02:20:06 +01:00
committed by GitHub
28 changed files with 405 additions and 226 deletions
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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)
+3 -3
View File
@@ -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 -1
View File
@@ -1,5 +1,5 @@
//+private
//+build wasm32, wasm64
//+build wasm32, wasm64p32
package runtime
import "core:intrinsics"
+1 -1
View File
@@ -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 (
+1 -1
View File
@@ -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 -1
View File
@@ -1,5 +1,5 @@
//+private
//+build wasm32, wasm64
//+build wasm32, wasm64p32
package sync
import "core:intrinsics"
+1 -1
View File
@@ -1,5 +1,5 @@
//+private
//+build wasm32, wasm64
//+build wasm32, wasm64p32
package sync
_current_thread_id :: proc "contextless" () -> int {
+75 -40
View File
@@ -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
View File
@@ -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
View File
@@ -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 &params = 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`
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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);
+41 -7
View File
@@ -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
View File
@@ -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;
+4 -3
View File
@@ -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);
}
+67 -25
View File
@@ -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;
}
+8 -8
View File
@@ -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:
+2 -1
View File
@@ -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
View File
@@ -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);
}
+34 -3
View File
@@ -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
View File
@@ -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;
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js wasm32, js wasm64
//+build js wasm32, js wasm64p32
package wasm_js_interface
foreign import dom_lib "odin_dom"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js wasm32, js wasm64
//+build js wasm32, js wasm64p32
package wasm_js_interface
foreign import dom_lib "odin_dom"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js wasm32, js wasm64
//+build js wasm32, js wasm64p32
package wasm_js_interface
foreign import "odin_env"
+1 -1
View File
@@ -1,4 +1,4 @@
//+build js wasm32, js wasm64
//+build js wasm32, js wasm64p32
package wasm_js_interface
import "core:mem"