Start writing LLVM code
This commit is contained in:
parent
7fcb2d22b4
commit
ace033c3f6
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@ -16,7 +16,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt install -y ninja-build mold
|
run: sudo apt install -y llvm llvm-dev ninja-build mold curl libssl-dev libcurl4-openssl-dev
|
||||||
- name: System information
|
- name: System information
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
@ -32,7 +32,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt install -y ninja-build mold
|
run: sudo apt install -y llvm llvm-dev ninja-build mold curl libssl-dev libcurl4-openssl-dev
|
||||||
- name: System information
|
- name: System information
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
@ -48,7 +48,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt install -y ninja-build mold
|
run: sudo apt install -y llvm llvm-dev ninja-build mold curl libssl-dev libcurl4-openssl-dev
|
||||||
- name: System information
|
- name: System information
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
@ -64,7 +64,7 @@ jobs:
|
|||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: sudo apt install -y ninja-build mold
|
run: sudo apt install -y llvm llvm-dev ninja-build mold curl libssl-dev libcurl4-openssl-dev
|
||||||
- name: System information
|
- name: System information
|
||||||
run: |
|
run: |
|
||||||
uname -a
|
uname -a
|
||||||
|
@ -4,6 +4,7 @@ project(nest)
|
|||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
set(CMAKE_C_STANDARD 23)
|
set(CMAKE_C_STANDARD 23)
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
-pedantic
|
-pedantic
|
||||||
-Wall -Wextra -Wpedantic
|
-Wall -Wextra -Wpedantic
|
||||||
@ -16,6 +17,82 @@ include_directories("bootstrap/include")
|
|||||||
|
|
||||||
find_package(LLVM REQUIRED CONFIG)
|
find_package(LLVM REQUIRED CONFIG)
|
||||||
|
|
||||||
|
find_program(LLVM_CONFIG_EXE
|
||||||
|
NAMES llvm-config-19 llvm-config-19.0 llvm-config190 llvm-config19 llvm-config NAMES_PER_DIR
|
||||||
|
PATHS
|
||||||
|
"/mingw64/bin"
|
||||||
|
"/c/msys64/mingw64/bin"
|
||||||
|
"c:/msys64/mingw64/bin"
|
||||||
|
"C:/Libraries/llvm-19.0.0/bin")
|
||||||
|
|
||||||
|
if ("${LLVM_CONFIG_EXE}" STREQUAL "LLVM_CONFIG_EXE-NOTFOUND")
|
||||||
|
if (NOT LLVM_CONFIG_ERROR_MESSAGES STREQUAL "")
|
||||||
|
list(JOIN LLVM_CONFIG_ERROR_MESSAGES "\n" LLVM_CONFIG_ERROR_MESSAGE)
|
||||||
|
message(FATAL_ERROR ${LLVM_CONFIG_ERROR_MESSAGE})
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "unable to find llvm-config")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${LLVM_CONFIG_EXE} --libs
|
||||||
|
OUTPUT_VARIABLE LLVM_LIBRARIES_SPACES
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
string(REPLACE " " ";" LLVM_LIBRARIES "${LLVM_LIBRARIES_SPACES}")
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${LLVM_CONFIG_EXE} --libdir
|
||||||
|
OUTPUT_VARIABLE LLVM_LIBDIRS_SPACES
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
string(REPLACE " " ";" LLVM_LIBDIRS "${LLVM_LIBDIRS_SPACES}")
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${LLVM_CONFIG_EXE} --system-libs
|
||||||
|
OUTPUT_VARIABLE LLVM_SYSTEM_LIBS_SPACES
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
string(REPLACE " " ";" LLVM_SYSTEM_LIBS "${LLVM_SYSTEM_LIBS_SPACES}")
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${LLVM_CONFIG_EXE} --shared-mode
|
||||||
|
OUTPUT_VARIABLE LLVM_LINK_MODE
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
|
||||||
|
if (${LLVM_LINK_MODE} STREQUAL "shared")
|
||||||
|
# We always ask for the system libs corresponding to static linking,
|
||||||
|
# since on some distros LLD is only available as a static library
|
||||||
|
# and we need these libraries to link it successfully
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${LLVM_CONFIG_EXE} --system-libs --link-static
|
||||||
|
OUTPUT_VARIABLE LLVM_STATIC_SYSTEM_LIBS_SPACES
|
||||||
|
ERROR_QUIET # Some installations have no static libs, we just ignore the failure
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
string(REPLACE " " ";" LLVM_STATIC_SYSTEM_LIBS "${LLVM_STATIC_SYSTEM_LIBS_SPACES}")
|
||||||
|
|
||||||
|
set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS} ${LLVM_STATIC_SYSTEM_LIBS})
|
||||||
|
else()
|
||||||
|
set(LLVM_LIBRARIES ${LLVM_LIBRARIES} ${LLVM_SYSTEM_LIBS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${LLVM_CONFIG_EXE} --includedir
|
||||||
|
OUTPUT_VARIABLE LLVM_INCLUDE_DIRS_SPACES
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
|
string(REPLACE " " ";" LLVM_INCLUDE_DIRS "${LLVM_INCLUDE_DIRS_SPACES}")
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
if (MSVC)
|
||||||
|
list(REMOVE_ITEM LLVM_LIBRARIES "zstd.lib")
|
||||||
|
else()
|
||||||
|
list(REMOVE_ITEM LLVM_LIBRARIES "-lzstd")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_library(ZSTD NAMES libzstd.a libzstdstatic.a zstd NAMES_PER_DIR)
|
||||||
|
list(APPEND LLVM_LIBRARIES "${ZSTD}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
link_directories("${LLVM_LIBDIRS}")
|
||||||
|
|
||||||
set(LIBRARY_NAME "std")
|
set(LIBRARY_NAME "std")
|
||||||
set(RUNNER_NAME "runner")
|
set(RUNNER_NAME "runner")
|
||||||
set(COMPILER_NAME "nest")
|
set(COMPILER_NAME "nest")
|
||||||
@ -35,6 +112,7 @@ target_link_libraries(${RUNNER_NAME} PRIVATE ${LIBRARY_NAME})
|
|||||||
add_executable("${COMPILER_NAME}"
|
add_executable("${COMPILER_NAME}"
|
||||||
"bootstrap/nest/main.c"
|
"bootstrap/nest/main.c"
|
||||||
"bootstrap/nest/pdb_image.c"
|
"bootstrap/nest/pdb_image.c"
|
||||||
|
"bootstrap/nest/llvm.cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(${COMPILER_NAME} PRIVATE ${LLVM_DEFINITIONS})
|
target_compile_definitions(${COMPILER_NAME} PRIVATE ${LLVM_DEFINITIONS})
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
#include <std/base.h>
|
#include <std/base.h>
|
||||||
|
|
||||||
typedef enum CompilerBackend : u8
|
typedef enum CompilerBackend : u8
|
||||||
@ -7,4 +9,29 @@ typedef enum CompilerBackend : u8
|
|||||||
COMPILER_BACKEND_COUNT,
|
COMPILER_BACKEND_COUNT,
|
||||||
} CompilerBackend;
|
} CompilerBackend;
|
||||||
|
|
||||||
|
typedef enum CpuArchitecture : u8
|
||||||
|
{
|
||||||
|
CPU_ARCH_X86_64,
|
||||||
|
CPU_ARCH_AARCH64,
|
||||||
|
} CpuArchitecture;
|
||||||
|
|
||||||
|
typedef enum OperatingSystem : u8
|
||||||
|
{
|
||||||
|
OPERATING_SYSTEM_LINUX,
|
||||||
|
OPERATING_SYSTEM_MAC,
|
||||||
|
OPERATING_SYSTEM_WINDOWS,
|
||||||
|
} OperatingSystem;
|
||||||
|
|
||||||
|
STRUCT(Target)
|
||||||
|
{
|
||||||
|
CpuArchitecture cpu;
|
||||||
|
OperatingSystem os;
|
||||||
|
};
|
||||||
|
|
||||||
|
STRUCT(CodegenOptions)
|
||||||
|
{
|
||||||
|
String test_name;
|
||||||
|
Target target;
|
||||||
|
CompilerBackend backend;
|
||||||
|
u8 generate_debug_information;
|
||||||
|
};
|
||||||
|
8
bootstrap/include/nest/llvm.h
Normal file
8
bootstrap/include/nest/llvm.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <nest/base.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
void llvm_codegen(CodegenOptions options);
|
@ -39,6 +39,18 @@ typedef double f64;
|
|||||||
typedef u32 Hash32;
|
typedef u32 Hash32;
|
||||||
typedef u64 Hash64;
|
typedef u64 Hash64;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
#define EXPORT extern "C"
|
||||||
|
#else
|
||||||
|
#define EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__cplusplus) && defined(__linux__)
|
||||||
|
#define NO_EXCEPT __THROW
|
||||||
|
#else
|
||||||
|
#define NO_EXCEPT
|
||||||
|
#endif
|
||||||
|
|
||||||
#define STRUCT_FORWARD_DECL(S) typedef struct S S
|
#define STRUCT_FORWARD_DECL(S) typedef struct S S
|
||||||
#define STRUCT(S) STRUCT_FORWARD_DECL(S); struct S
|
#define STRUCT(S) STRUCT_FORWARD_DECL(S); struct S
|
||||||
#define UNION_FORWARD_DECL(U) typedef union U U
|
#define UNION_FORWARD_DECL(U) typedef union U U
|
||||||
@ -69,6 +81,9 @@ declare_slice_p(char);
|
|||||||
typedef Slice(u8) String;
|
typedef Slice(u8) String;
|
||||||
declare_slice(String);
|
declare_slice(String);
|
||||||
|
|
||||||
|
#define NamedEnumMemberEnum(e, enum_member) e ## _ ## enum_member
|
||||||
|
#define NamedEnumMemberString(e, enum_member) strlit(#enum_member)
|
||||||
|
|
||||||
typedef SliceP(char) CStringSlice;
|
typedef SliceP(char) CStringSlice;
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -92,17 +107,18 @@ FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.poin
|
|||||||
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
|
||||||
#define INFINITY __builtin_inff()
|
#define INFINITY __builtin_inff()
|
||||||
#define NAN __builtin_nanf("")
|
#define NAN __builtin_nanf("")
|
||||||
#define fn static
|
#define fn static
|
||||||
#define method __attribute__((visibility("internal")))
|
#define method __attribute__((visibility("internal")))
|
||||||
#define global static
|
#define global_variable static
|
||||||
#define forceinline __attribute__((always_inline))
|
#define forceinline __attribute__((always_inline))
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
#define breakpoint() __builtin_debugtrap()
|
#define breakpoint() __builtin_debugtrap()
|
||||||
#define fail() trap()
|
#define failed_execution() trap()
|
||||||
|
|
||||||
|
|
||||||
#define trap() bad_exit("Trap reached", __FILE__, __LINE__)
|
#define trap() bad_exit("Trap reached", __FILE__, __LINE__)
|
||||||
#define array_length(arr) sizeof(arr) / sizeof((arr)[0])
|
#define array_length(arr) sizeof(arr) / sizeof((arr)[0])
|
||||||
#define KB(n) ((n) * 1024)
|
#define KB(n) ((n) * 1024)
|
||||||
@ -111,8 +127,8 @@ FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.poin
|
|||||||
#define TB(n) ((u64)(n) * 1024 * 1024 * 1024 * 1024)
|
#define TB(n) ((u64)(n) * 1024 * 1024 * 1024 * 1024)
|
||||||
#define unused(x) (void)(x)
|
#define unused(x) (void)(x)
|
||||||
#define may_be_unused __attribute__((unused))
|
#define may_be_unused __attribute__((unused))
|
||||||
#define trunc(Destination, source) (Destination)(source)
|
#define truncate_value(Destination, source) (Destination)(source)
|
||||||
#define cast(Destination, Source, source) cast_ ## Source ## _to_ ## Destination (source, __FILE__, __LINE__)
|
#define cast_to(Destination, Source, source) cast_ ## Source ## _to_ ## Destination (source, __FILE__, __LINE__)
|
||||||
#define bad_exit(message, file, line) do { print(message " at {cstr}:{u32}\n", file, line); __builtin_trap(); } while(0)
|
#define bad_exit(message, file, line) do { print(message " at {cstr}:{u32}\n", file, line); __builtin_trap(); } while(0)
|
||||||
#define size_until_end(T, field_name) (sizeof(T) - offsetof(T, field_name))
|
#define size_until_end(T, field_name) (sizeof(T) - offsetof(T, field_name))
|
||||||
#define SWAP(a, b) \
|
#define SWAP(a, b) \
|
||||||
@ -122,7 +138,6 @@ FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.poin
|
|||||||
b = temp;\
|
b = temp;\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
#define slice_from_pointer_range(T, start, end) (Slice(T)) { .pointer = start, .length = (u64)(end - start), }
|
#define slice_from_pointer_range(T, start, end) (Slice(T)) { .pointer = start, .length = (u64)(end - start), }
|
||||||
|
|
||||||
#define strlit_len(s) (sizeof(s) - 1)
|
#define strlit_len(s) (sizeof(s) - 1)
|
||||||
@ -137,14 +152,14 @@ FOR_N(_i, 0, ((set)->arr.capacity + 63) / 64) FOR_BIT(it, _i*64, (set)->arr.poin
|
|||||||
|
|
||||||
#define case_to_name(prefix, e) case prefix ## e: return strlit(#e)
|
#define case_to_name(prefix, e) case prefix ## e: return strlit(#e)
|
||||||
|
|
||||||
const may_be_unused global u8 brace_open = '{';
|
const may_be_unused global_variable u8 brace_open = '{';
|
||||||
const may_be_unused global u8 brace_close = '}';
|
const may_be_unused global_variable u8 brace_close = '}';
|
||||||
|
|
||||||
const may_be_unused global u8 parenthesis_open = '(';
|
const may_be_unused global_variable u8 parenthesis_open = '(';
|
||||||
const may_be_unused global u8 parenthesis_close = ')';
|
const may_be_unused global_variable u8 parenthesis_close = ')';
|
||||||
|
|
||||||
const may_be_unused global u8 bracket_open = '[';
|
const may_be_unused global_variable u8 bracket_open = '[';
|
||||||
const may_be_unused global u8 bracket_close = ']';
|
const may_be_unused global_variable u8 bracket_close = ']';
|
||||||
|
|
||||||
#define s_get(s, i) (s).pointer[i]
|
#define s_get(s, i) (s).pointer[i]
|
||||||
#define s_get_pointer(s, i) &((s).pointer[i])
|
#define s_get_pointer(s, i) &((s).pointer[i])
|
||||||
@ -157,22 +172,23 @@ const may_be_unused global u8 bracket_close = ']';
|
|||||||
#define assert(x) unlikely(!(x))
|
#define assert(x) unlikely(!(x))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef __cplusplus
|
||||||
|
// Undefine unreachable if needed to provide a more safe-guard implementation
|
||||||
#ifdef unreachable
|
#ifdef unreachable
|
||||||
#undef unreachable
|
#undef unreachable
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
#define unreachable() bad_exit("Unreachable triggered", __FILE__, __LINE__)
|
#define unreachable() bad_exit("Unreachable triggered", __FILE__, __LINE__)
|
||||||
#else
|
#else
|
||||||
#define unreachable() __builtin_unreachable()
|
#define unreachable() __builtin_unreachable()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef static_assert
|
|
||||||
#undef static_assert
|
|
||||||
#endif
|
|
||||||
#define static_assert(x) _Static_assert((x), "Static assert failed!")
|
#define static_assert(x) _Static_assert((x), "Static assert failed!")
|
||||||
#define alignof(x) _Alignof(x)
|
#define alignof(x) _Alignof(x)
|
||||||
#define auto __auto_type
|
#define auto __auto_type
|
||||||
|
#else
|
||||||
|
#define restrict __restrict
|
||||||
|
#endif
|
||||||
|
|
||||||
#define todo() do { print("TODO at {cstr}:{u32}\n", __FILE__, __LINE__); __builtin_trap(); } while(0)
|
#define todo() do { print("TODO at {cstr}:{u32}\n", __FILE__, __LINE__); __builtin_trap(); } while(0)
|
||||||
|
|
||||||
@ -183,13 +199,13 @@ u8 is_power_of_two(u64 value);
|
|||||||
u8 first_bit_set_32(u32 value);
|
u8 first_bit_set_32(u32 value);
|
||||||
u64 first_bit_set_64(u64 value);
|
u64 first_bit_set_64(u64 value);
|
||||||
|
|
||||||
void* memcpy(void* const restrict dst, const void* const restrict src, usize size);
|
EXPORT void* memcpy(void* const restrict dst, const void* const restrict src, usize size) NO_EXCEPT;
|
||||||
void* memmove(void* const dst, const void* const src, usize n);
|
EXPORT void* memmove(void* const dst, const void* const src, usize n) NO_EXCEPT;
|
||||||
void* memset(void* dst, int n, usize size);
|
EXPORT void* memset(void* dst, int n, usize size) NO_EXCEPT;
|
||||||
int memcmp(const void* a, const void* b, usize n);
|
EXPORT int memcmp(const void* a, const void* b, usize n) NO_EXCEPT;
|
||||||
usize strlen (const char* c_string);
|
EXPORT usize strlen (const char* c_string) NO_EXCEPT;
|
||||||
int strcmp(const char* s1, const char* s2);
|
EXPORT int strcmp(const char* s1, const char* s2) NO_EXCEPT;
|
||||||
int strncmp(const char* s1, const char* s2, usize length);
|
EXPORT int strncmp(const char* s1, const char* s2, usize length) NO_EXCEPT;
|
||||||
|
|
||||||
u8 cast_u32_to_u8(u32 source, const char* name, int line);
|
u8 cast_u32_to_u8(u32 source, const char* name, int line);
|
||||||
u16 cast_u32_to_u16(u32 source, const char* name, int line);
|
u16 cast_u32_to_u16(u32 source, const char* name, int line);
|
||||||
@ -223,8 +239,8 @@ u64 is_alphabetic(u8 ch);
|
|||||||
|
|
||||||
u64 parse_decimal(String string);
|
u64 parse_decimal(String string);
|
||||||
|
|
||||||
global const Hash64 fnv_offset = 14695981039346656037ull;
|
global_variable const Hash64 fnv_offset = 14695981039346656037ull;
|
||||||
global const u64 fnv_prime = 1099511628211ull;
|
global_variable const u64 fnv_prime = 1099511628211ull;
|
||||||
|
|
||||||
Hash32 hash32_fib_end(Hash32 hash);
|
Hash32 hash32_fib_end(Hash32 hash);
|
||||||
Hash32 hash64_fib_end(Hash64 hash);
|
Hash32 hash64_fib_end(Hash64 hash);
|
||||||
|
@ -42,16 +42,16 @@ STRUCT(Arena)
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if __APPLE__
|
#if __APPLE__
|
||||||
const global u64 page_size = KB(16);
|
const global_variable u64 page_size = KB(16);
|
||||||
#else
|
#else
|
||||||
const global u64 page_size = KB(4);
|
const global_variable u64 page_size = KB(4);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
global u64 minimum_granularity = page_size;
|
global_variable u64 minimum_granularity = page_size;
|
||||||
// global u64 middle_granularity = MB(2);
|
// global_variable u64 middle_granularity = MB(2);
|
||||||
global u64 default_size = GB(4);
|
global_variable u64 default_size = GB(4);
|
||||||
|
|
||||||
void print(const char* format, ...);
|
EXPORT void print(const char* format, ...);
|
||||||
void run_command(Arena* arena, CStringSlice arguments, char* envp[]);
|
void run_command(Arena* arena, CStringSlice arguments, char* envp[]);
|
||||||
String file_read(Arena* arena, String path);
|
String file_read(Arena* arena, String path);
|
||||||
|
|
||||||
|
158
bootstrap/nest/llvm.cpp
Normal file
158
bootstrap/nest/llvm.cpp
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#include <std/os.h>
|
||||||
|
#include <nest/base.h>
|
||||||
|
|
||||||
|
#include <llvm/IR/IRBuilder.h>
|
||||||
|
#include <llvm/IR/LLVMContext.h>
|
||||||
|
#include <llvm/IR/Module.h>
|
||||||
|
#include <llvm/IR/Verifier.h>
|
||||||
|
|
||||||
|
#include <llvm/MC/TargetRegistry.h>
|
||||||
|
|
||||||
|
#include <llvm/Support/TargetSelect.h>
|
||||||
|
|
||||||
|
#include <llvm/Target/TargetMachine.h>
|
||||||
|
#include <llvm/Target/TargetOptions.h>
|
||||||
|
|
||||||
|
#define string_ref(lit) StringRef(lit, strlit_len(lit))
|
||||||
|
|
||||||
|
namespace llvm
|
||||||
|
{
|
||||||
|
// #define LLVMAttributeMembers(cb) \
|
||||||
|
// cb(LLVMAttribute, naked), \
|
||||||
|
// cb(LLVMAttribute, noreturn), \
|
||||||
|
// cb(LLVMAttribute, nounwind), \
|
||||||
|
// cb(LLVMAttribute, inreg), \
|
||||||
|
// cb(LLVMAttribute, noalias), \
|
||||||
|
// cb(LLVMAttribute, signext), \
|
||||||
|
// cb(LLVMAttribute, zeroext), \
|
||||||
|
//
|
||||||
|
// typedef enum LLVMAttributeId : u32
|
||||||
|
// {
|
||||||
|
// LLVMAttributeMembers(NamedEnumMemberEnum)
|
||||||
|
// LLVM_ATTRIBUTE_COUNT,
|
||||||
|
// } LLVMAttribute;
|
||||||
|
//
|
||||||
|
// String llvm_attribute_names[] = {
|
||||||
|
// LLVMAttributeMembers(NamedEnumMemberString)
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// STRUCT(LLVMAttributeLookupTable)
|
||||||
|
// {
|
||||||
|
// u32 ids[LLVM_ATTRIBUTE_COUNT];
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// fn u32 llvm_attribute_id(String string)
|
||||||
|
// {
|
||||||
|
// auto result = LLVMGetEnumAttributeKindForName(string_to_c(string), string.length);
|
||||||
|
// static_assert(sizeof(result) == sizeof(u32));
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
#define llvm_initialize_target(target) \
|
||||||
|
LLVMInitialize ## target ## Target();\
|
||||||
|
LLVMInitialize ## target ## TargetInfo();\
|
||||||
|
LLVMInitialize ## target ## TargetMC();\
|
||||||
|
LLVMInitialize ## target ## AsmParser();\
|
||||||
|
LLVMInitialize ## target ## AsmPrinter()
|
||||||
|
|
||||||
|
fn void llvm_initialize_cpu(CpuArchitecture architecture)
|
||||||
|
{
|
||||||
|
// These are meant to be called globally, so if this code is ever threaded, we need to call this code only once
|
||||||
|
switch (architecture)
|
||||||
|
{
|
||||||
|
case CPU_ARCH_X86_64:
|
||||||
|
{
|
||||||
|
llvm_initialize_target(X86);
|
||||||
|
} break;
|
||||||
|
case CPU_ARCH_AARCH64:
|
||||||
|
{
|
||||||
|
llvm_initialize_target(AArch64);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" void llvm_codegen(CodegenOptions options)
|
||||||
|
{
|
||||||
|
llvm_initialize_cpu(options.target.cpu);
|
||||||
|
|
||||||
|
auto context = LLVMContext();
|
||||||
|
auto module = Module(string_ref("first"), context);
|
||||||
|
std::string error_message;
|
||||||
|
|
||||||
|
// TODO: debug builder
|
||||||
|
// TODO: attributes
|
||||||
|
|
||||||
|
{
|
||||||
|
u32 return_bit_count = 32;
|
||||||
|
auto* return_type = IntegerType::get(context, return_bit_count);
|
||||||
|
ArrayRef<Type*> parameter_types = {};
|
||||||
|
u8 is_var_args = 0;
|
||||||
|
auto* function_type = FunctionType::get(return_type, parameter_types, is_var_args);
|
||||||
|
auto function_name = string_ref("main");
|
||||||
|
auto linkage = GlobalValue::LinkageTypes::ExternalLinkage;
|
||||||
|
u32 address_space = 0;
|
||||||
|
auto* function = Function::Create(function_type, linkage, address_space, function_name, &module);
|
||||||
|
|
||||||
|
auto builder = IRBuilder<>(context);
|
||||||
|
auto entry_block_name = string_ref("entry");
|
||||||
|
auto* basic_block = BasicBlock::Create(context, entry_block_name, function, 0);
|
||||||
|
builder.SetInsertPoint(basic_block);
|
||||||
|
u64 return_value_int = 0;
|
||||||
|
u8 is_signed = 0;
|
||||||
|
auto* return_value = ConstantInt::get(context, APInt(return_bit_count, return_value_int, is_signed));
|
||||||
|
builder.CreateRet(return_value);
|
||||||
|
|
||||||
|
{
|
||||||
|
raw_string_ostream message_stream(error_message);
|
||||||
|
|
||||||
|
if (verifyModule(module, &message_stream))
|
||||||
|
{
|
||||||
|
// Failure
|
||||||
|
auto& error_std_string = message_stream.str();
|
||||||
|
auto error_string = String{ .pointer = (u8*)error_std_string.data(), .length = error_std_string.length() };
|
||||||
|
print("Verification for module failed:\n{s}\n", error_string);
|
||||||
|
failed_execution();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make a more correct logic
|
||||||
|
StringRef target_triple;
|
||||||
|
switch (options.target.os)
|
||||||
|
{
|
||||||
|
case OPERATING_SYSTEM_LINUX:
|
||||||
|
target_triple = string_ref("x86_64-unknown-linux-gnu");
|
||||||
|
break;
|
||||||
|
case OPERATING_SYSTEM_MAC:
|
||||||
|
target_triple = string_ref("aarch64-apple-macosx-none");
|
||||||
|
break;
|
||||||
|
case OPERATING_SYSTEM_WINDOWS:
|
||||||
|
target_triple = string_ref("x86_64-windows-gnu");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Target* target = TargetRegistry::lookupTarget(target_triple, error_message);
|
||||||
|
if (!target)
|
||||||
|
{
|
||||||
|
String string = { .pointer = (u8*)error_message.data(), .length = error_message.length() };
|
||||||
|
print("Could not find target: {s}\n", string);
|
||||||
|
failed_execution();
|
||||||
|
}
|
||||||
|
|
||||||
|
module.setTargetTriple(target_triple);
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
auto cpu_model = string_ref("baseline");
|
||||||
|
auto cpu_features = string_ref("");
|
||||||
|
|
||||||
|
TargetOptions target_options;
|
||||||
|
std::optional<Reloc::Model> relocation_model = std::nullopt;
|
||||||
|
std::optional<CodeModel::Model> code_model = std::nullopt;
|
||||||
|
auto codegen_optimization_level = CodeGenOptLevel::None;
|
||||||
|
u8 jit = 0;
|
||||||
|
|
||||||
|
auto* target_machine = target->createTargetMachine(target_triple, cpu_model, cpu_features, target_options, relocation_model, code_model, codegen_optimization_level, jit);
|
||||||
|
auto data_layout = target_machine->createDataLayout();
|
||||||
|
module.setDataLayout(data_layout);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
@ -163,7 +163,7 @@ void entry_point(int argc, char* argv[], char* envp[])
|
|||||||
if (argc < 2)
|
if (argc < 2)
|
||||||
{
|
{
|
||||||
print("Expected some arguments\n");
|
print("Expected some arguments\n");
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
|
|
||||||
Arena* arena = arena_init_default(KB(64));
|
Arena* arena = arena_init_default(KB(64));
|
||||||
@ -187,7 +187,7 @@ void entry_point(int argc, char* argv[], char* envp[])
|
|||||||
|
|
||||||
if (string_starts_with(argument, strlit("build_type=")))
|
if (string_starts_with(argument, strlit("build_type=")))
|
||||||
{
|
{
|
||||||
auto release_start = cast(u32, s32, string_first_ch(argument, '=') + 1);
|
auto release_start = cast_to(u32, s32, string_first_ch(argument, '=') + 1);
|
||||||
auto release_string = s_get_slice(u8, argument, release_start, argument.length);
|
auto release_string = s_get_slice(u8, argument, release_start, argument.length);
|
||||||
|
|
||||||
for (u64 i = 0; i < array_length(release_strings); i += 1)
|
for (u64 i = 0; i < array_length(release_strings); i += 1)
|
||||||
@ -261,7 +261,7 @@ void entry_point(int argc, char* argv[], char* envp[])
|
|||||||
if (command == COMMAND_COUNT && !source_file_path.pointer)
|
if (command == COMMAND_COUNT && !source_file_path.pointer)
|
||||||
{
|
{
|
||||||
print("Expected a command\n");
|
print("Expected a command\n");
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == COMMAND_COUNT)
|
if (command == COMMAND_COUNT)
|
||||||
@ -283,7 +283,6 @@ void entry_point(int argc, char* argv[], char* envp[])
|
|||||||
build_type = CMAKE_BUILD_TYPE_DEBUG;
|
build_type = CMAKE_BUILD_TYPE_DEBUG;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto build_type_string = release_strings[build_type];
|
|
||||||
String compiler_path = strlit("build/nest");
|
String compiler_path = strlit("build/nest");
|
||||||
|
|
||||||
switch (command)
|
switch (command)
|
||||||
@ -291,7 +290,7 @@ void entry_point(int argc, char* argv[], char* envp[])
|
|||||||
case COMMAND_DEBUG:
|
case COMMAND_DEBUG:
|
||||||
if (!source_file_path.pointer)
|
if (!source_file_path.pointer)
|
||||||
{
|
{
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
|
|
||||||
run(arena, envp, compiler_path, preferred_compiler_backend, 1, string_to_c(source_file_path));
|
run(arena, envp, compiler_path, preferred_compiler_backend, 1, string_to_c(source_file_path));
|
||||||
|
@ -320,14 +320,14 @@ u8 log2_alignment(u64 alignment)
|
|||||||
assert(alignment != 0);
|
assert(alignment != 0);
|
||||||
assert((alignment & (alignment - 1)) == 0);
|
assert((alignment & (alignment - 1)) == 0);
|
||||||
u64 left = (sizeof(alignment) * 8) - 1;
|
u64 left = (sizeof(alignment) * 8) - 1;
|
||||||
auto right = cast(u64, s32, __builtin_clzll(alignment));
|
auto right = cast_to(u64, s32, __builtin_clzll(alignment));
|
||||||
auto result = cast(u8, u64, left - right);
|
auto result = cast_to(u8, u64, left - right);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lehmer's generator
|
// Lehmer's generator
|
||||||
// https://lemire.me/blog/2019/03/19/the-fastest-conventional-random-number-generator-that-can-pass-big-crush/
|
// https://lemire.me/blog/2019/03/19/the-fastest-conventional-random-number-generator-that-can-pass-big-crush/
|
||||||
may_be_unused global __uint128_t rn_state;
|
may_be_unused global_variable u128 rn_state;
|
||||||
may_be_unused fn u64 generate_random_number()
|
may_be_unused fn u64 generate_random_number()
|
||||||
{
|
{
|
||||||
rn_state *= 0xda942042e4dd58b5;
|
rn_state *= 0xda942042e4dd58b5;
|
||||||
@ -349,7 +349,7 @@ u64 round_up_to_next_power_of_2(u64 n)
|
|||||||
|
|
||||||
may_be_unused fn u64 absolute_int(s64 n)
|
may_be_unused fn u64 absolute_int(s64 n)
|
||||||
{
|
{
|
||||||
return n < 0 ? cast(u64, s64, -n) : cast(u64, s64, n);
|
return n < 0 ? cast_to(u64, s64, -n) : cast_to(u64, s64, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 parse_decimal(String string)
|
u64 parse_decimal(String string)
|
||||||
@ -582,7 +582,7 @@ fn s32 pow5_bits(const s32 e)
|
|||||||
#define DOUBLE_POW5_INV_TABLE_SIZE 342
|
#define DOUBLE_POW5_INV_TABLE_SIZE 342
|
||||||
#define DOUBLE_POW5_TABLE_SIZE 326
|
#define DOUBLE_POW5_TABLE_SIZE 326
|
||||||
|
|
||||||
global const u8 DIGIT_TABLE[200] = {
|
global_variable const u8 DIGIT_TABLE[200] = {
|
||||||
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
|
'0','0','0','1','0','2','0','3','0','4','0','5','0','6','0','7','0','8','0','9',
|
||||||
'1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
|
'1','0','1','1','1','2','1','3','1','4','1','5','1','6','1','7','1','8','1','9',
|
||||||
'2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
|
'2','0','2','1','2','2','2','3','2','4','2','5','2','6','2','7','2','8','2','9',
|
||||||
@ -595,7 +595,7 @@ global const u8 DIGIT_TABLE[200] = {
|
|||||||
'9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
|
'9','0','9','1','9','2','9','3','9','4','9','5','9','6','9','7','9','8','9','9'
|
||||||
};
|
};
|
||||||
|
|
||||||
global const u64 DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2] =
|
global_variable const u64 DOUBLE_POW5_INV_SPLIT[DOUBLE_POW5_INV_TABLE_SIZE][2] =
|
||||||
{
|
{
|
||||||
{ 1u, 2305843009213693952u }, { 11068046444225730970u, 1844674407370955161u },
|
{ 1u, 2305843009213693952u }, { 11068046444225730970u, 1844674407370955161u },
|
||||||
{ 5165088340638674453u, 1475739525896764129u }, { 7821419487252849886u, 1180591620717411303u },
|
{ 5165088340638674453u, 1475739525896764129u }, { 7821419487252849886u, 1180591620717411303u },
|
||||||
@ -802,7 +802,7 @@ fn u32 log10_pow5(const s32 e) {
|
|||||||
return (((u32) e) * 732923) >> 20;
|
return (((u32) e) * 732923) >> 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
global const u64 DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2] =
|
global_variable const u64 DOUBLE_POW5_SPLIT[DOUBLE_POW5_TABLE_SIZE][2] =
|
||||||
{
|
{
|
||||||
{ 0u, 1152921504606846976u }, { 0u, 1441151880758558720u },
|
{ 0u, 1152921504606846976u }, { 0u, 1441151880758558720u },
|
||||||
{ 0u, 1801439850948198400u }, { 0u, 2251799813685248000u },
|
{ 0u, 1801439850948198400u }, { 0u, 2251799813685248000u },
|
||||||
@ -1288,7 +1288,7 @@ fn void write_float_decimal(String buffer, u64* value, u64 count)
|
|||||||
|
|
||||||
while (i + 2 < count)
|
while (i + 2 < count)
|
||||||
{
|
{
|
||||||
auto c = cast(u8, u64, *value % 100);
|
auto c = cast_to(u8, u64, *value % 100);
|
||||||
*value /= 100;
|
*value /= 100;
|
||||||
auto ptr = digits2(c);
|
auto ptr = digits2(c);
|
||||||
buffer.pointer[count - i - 1] = ptr[1];
|
buffer.pointer[count - i - 1] = ptr[1];
|
||||||
@ -1298,7 +1298,7 @@ fn void write_float_decimal(String buffer, u64* value, u64 count)
|
|||||||
|
|
||||||
while (i < count)
|
while (i < count)
|
||||||
{
|
{
|
||||||
auto c = cast(u8, u64, *value % 10);
|
auto c = cast_to(u8, u64, *value % 10);
|
||||||
*value /= 10;
|
*value /= 10;
|
||||||
buffer.pointer[count - i - 1] = '0' + c;
|
buffer.pointer[count - i - 1] = '0' + c;
|
||||||
|
|
||||||
@ -1494,7 +1494,7 @@ u64 format_float(String buffer, f64 value_double)
|
|||||||
} break;
|
} break;
|
||||||
case FLOAT_FORMAT_DECIMAL:
|
case FLOAT_FORMAT_DECIMAL:
|
||||||
{
|
{
|
||||||
auto dp_offset = result.exponent + cast(s32, u32, olength);
|
auto dp_offset = result.exponent + cast_to(s32, u32, olength);
|
||||||
|
|
||||||
if (dp_offset <= 0)
|
if (dp_offset <= 0)
|
||||||
{
|
{
|
||||||
@ -1559,13 +1559,13 @@ u64 first_bit_set_64(u64 value)
|
|||||||
|
|
||||||
Hash32 hash32_fib_end(Hash32 hash)
|
Hash32 hash32_fib_end(Hash32 hash)
|
||||||
{
|
{
|
||||||
auto result = trunc(Hash32, ((hash + 1) * 11400714819323198485ull) >> 32);
|
auto result = truncate_value(Hash32, ((hash + 1) * 11400714819323198485ull) >> 32);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hash32 hash64_fib_end(Hash64 hash)
|
Hash32 hash64_fib_end(Hash64 hash)
|
||||||
{
|
{
|
||||||
auto result = trunc(Hash32, ((hash + 1) * 11400714819323198485ull) >> 32);
|
auto result = truncate_value(Hash32, ((hash + 1) * 11400714819323198485ull) >> 32);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1637,7 +1637,7 @@ void* memmove(void* const dst, const void* const src, usize n)
|
|||||||
|
|
||||||
void* memset(void* dst, int n, usize size)
|
void* memset(void* dst, int n, usize size)
|
||||||
{
|
{
|
||||||
u8 ch = cast(u8, s32, n);
|
u8 ch = cast_to(u8, s32, n);
|
||||||
auto* destination = (u8*)dst;
|
auto* destination = (u8*)dst;
|
||||||
for (u64 i = 0; i < size; i += 1)
|
for (u64 i = 0; i < size; i += 1)
|
||||||
{
|
{
|
||||||
|
@ -19,12 +19,12 @@ STRUCT(MD5Context)
|
|||||||
#define MD5_H(X, Y, Z) (X ^ Y ^ Z)
|
#define MD5_H(X, Y, Z) (X ^ Y ^ Z)
|
||||||
#define MD5_I(X, Y, Z) (Y ^ (X | ~Z))
|
#define MD5_I(X, Y, Z) (Y ^ (X | ~Z))
|
||||||
|
|
||||||
global u32 md5_s[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
global_variable u32 md5_s[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
|
||||||
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
|
||||||
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
|
||||||
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
|
||||||
|
|
||||||
global u32 md5_k[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
global_variable u32 md5_k[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
||||||
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
|
||||||
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
|
||||||
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
|
||||||
@ -44,7 +44,7 @@ global u32 md5_k[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
|
|||||||
/*
|
/*
|
||||||
* Padding used to make the size (in bits) of the input congruent to 448 mod 512
|
* Padding used to make the size (in bits) of the input congruent to 448 mod 512
|
||||||
*/
|
*/
|
||||||
global u8 md5_padding[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
global_variable u8 md5_padding[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
@ -53,12 +53,12 @@ timestamp()
|
|||||||
|
|
||||||
|
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
global u64 cpu_frequency;
|
global_variable u64 cpu_frequency;
|
||||||
#else
|
#else
|
||||||
#if LINK_LIBC
|
#if LINK_LIBC
|
||||||
global struct timespec cpu_resolution;
|
global_variable struct timespec cpu_resolution;
|
||||||
#else
|
#else
|
||||||
global u64 cpu_frequency;
|
global_variable u64 cpu_frequency;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -180,14 +180,14 @@ String path_base(String string)
|
|||||||
auto maybe_index = string_last_ch(string, '/');
|
auto maybe_index = string_last_ch(string, '/');
|
||||||
if (maybe_index != -1)
|
if (maybe_index != -1)
|
||||||
{
|
{
|
||||||
auto index = cast(u64, s64, maybe_index);
|
auto index = cast_to(u64, s64, maybe_index);
|
||||||
result = s_get_slice(u8, string, index + 1, string.length);
|
result = s_get_slice(u8, string, index + 1, string.length);
|
||||||
}
|
}
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
if (!result.pointer)
|
if (!result.pointer)
|
||||||
{
|
{
|
||||||
auto maybe_index = string_last_ch(string, '\\');
|
auto maybe_index = string_last_ch(string, '\\');
|
||||||
auto index = cast(u64, s64, maybe_index);
|
auto index = cast_to(u64, s64, maybe_index);
|
||||||
result = s_get_slice(u8, string, index + 1, string.length);
|
result = s_get_slice(u8, string, index + 1, string.length);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -201,7 +201,7 @@ String path_no_extension(String string)
|
|||||||
auto maybe_index = string_last_ch(string, '.');
|
auto maybe_index = string_last_ch(string, '.');
|
||||||
if (maybe_index != -1)
|
if (maybe_index != -1)
|
||||||
{
|
{
|
||||||
auto index = cast(u64, s64, maybe_index);
|
auto index = cast_to(u64, s64, maybe_index);
|
||||||
result = s_get_slice(u8, string, 0, index);
|
result = s_get_slice(u8, string, 0, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,7 +650,7 @@ may_be_unused fn void* posix_mmap(void* address, size_t length, int protection_f
|
|||||||
return mmap(address, length, protection_flags, map_flags, fd, offset);
|
return mmap(address, length, protection_flags, map_flags, fd, offset);
|
||||||
#else
|
#else
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
return (void*) syscall6(syscall_x86_64_mmap, (s64)address, cast(s64, u64, length), protection_flags, map_flags, fd, offset);
|
return (void*) syscall6(syscall_x86_64_mmap, (s64)address, cast_to(s64, u64, length), protection_flags, map_flags, fd, offset);
|
||||||
#else
|
#else
|
||||||
#error "Unsupported operating system for static linking"
|
#error "Unsupported operating system for static linking"
|
||||||
#endif
|
#endif
|
||||||
@ -663,7 +663,7 @@ may_be_unused fn int syscall_mprotect(void *address, size_t length, int protecti
|
|||||||
return mprotect(address, length, protection_flags);
|
return mprotect(address, length, protection_flags);
|
||||||
#else
|
#else
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
return cast(s32, s64, syscall3(syscall_x86_64_mprotect, (s64)address, cast(s64, u64, length), protection_flags));
|
return cast_to(s32, s64, syscall3(syscall_x86_64_mprotect, (s64)address, cast_to(s64, u64, length), protection_flags));
|
||||||
#else
|
#else
|
||||||
return mprotect(address, length, protection_flags);
|
return mprotect(address, length, protection_flags);
|
||||||
#endif
|
#endif
|
||||||
@ -676,7 +676,7 @@ may_be_unused fn int syscall_open(const char *file_path, int flags, int mode)
|
|||||||
return open(file_path, flags, mode);
|
return open(file_path, flags, mode);
|
||||||
#else
|
#else
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
return cast(s32, s64, syscall3(syscall_x86_64_open, (s64)file_path, flags, mode));
|
return cast_to(s32, s64, syscall3(syscall_x86_64_open, (s64)file_path, flags, mode));
|
||||||
#else
|
#else
|
||||||
return open(file_path, flags, mode);
|
return open(file_path, flags, mode);
|
||||||
#endif
|
#endif
|
||||||
@ -689,7 +689,7 @@ may_be_unused fn int syscall_close(int fd)
|
|||||||
return close(fd);
|
return close(fd);
|
||||||
#else
|
#else
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
return cast(s32, s64, syscall1(syscall_x86_64_close, fd));
|
return cast_to(s32, s64, syscall1(syscall_x86_64_close, fd));
|
||||||
#else
|
#else
|
||||||
return close(fd);
|
return close(fd);
|
||||||
#endif
|
#endif
|
||||||
@ -702,7 +702,7 @@ fn int syscall_fstat(int fd, struct stat *buffer)
|
|||||||
return fstat(fd, buffer);
|
return fstat(fd, buffer);
|
||||||
#else
|
#else
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
return cast(s32, s64, syscall2(syscall_x86_64_fstat, fd, (s64)buffer));
|
return cast_to(s32, s64, syscall2(syscall_x86_64_fstat, fd, (s64)buffer));
|
||||||
#else
|
#else
|
||||||
return fstat(fd, buffer);
|
return fstat(fd, buffer);
|
||||||
#endif
|
#endif
|
||||||
@ -741,7 +741,7 @@ may_be_unused fn int syscall_mkdir(String path, u32 mode)
|
|||||||
#if LINK_LIBC
|
#if LINK_LIBC
|
||||||
return mkdir((char*)path.pointer, mode);
|
return mkdir((char*)path.pointer, mode);
|
||||||
#else
|
#else
|
||||||
return cast(s32, s64, syscall2(syscall_x86_64_mkdir, (s64)path.pointer, (s64)mode));
|
return cast_to(s32, s64, syscall2(syscall_x86_64_mkdir, (s64)path.pointer, (s64)mode));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,7 +751,7 @@ may_be_unused fn int syscall_rmdir(String path)
|
|||||||
#if LINK_LIBC
|
#if LINK_LIBC
|
||||||
return rmdir((char*)path.pointer);
|
return rmdir((char*)path.pointer);
|
||||||
#else
|
#else
|
||||||
return cast(s32, s64, syscall1(syscall_x86_64_rmdir, (s64)path.pointer));
|
return cast_to(s32, s64, syscall1(syscall_x86_64_rmdir, (s64)path.pointer));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -761,7 +761,7 @@ may_be_unused fn int syscall_unlink(String path)
|
|||||||
#if LINK_LIBC
|
#if LINK_LIBC
|
||||||
return unlink((char*)path.pointer);
|
return unlink((char*)path.pointer);
|
||||||
#else
|
#else
|
||||||
return cast(s32, s64, syscall1(syscall_x86_64_unlink, (s64)path.pointer));
|
return cast_to(s32, s64, syscall1(syscall_x86_64_unlink, (s64)path.pointer));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -770,7 +770,7 @@ may_be_unused fn pid_t syscall_fork()
|
|||||||
#if LINK_LIBC
|
#if LINK_LIBC
|
||||||
return fork();
|
return fork();
|
||||||
#else
|
#else
|
||||||
return cast(s32, s64, syscall0(syscall_x86_64_fork));
|
return cast_to(s32, s64, syscall0(syscall_x86_64_fork));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -789,7 +789,7 @@ may_be_unused fn pid_t syscall_waitpid(pid_t pid, int* status, int options)
|
|||||||
#if LINK_LIBC
|
#if LINK_LIBC
|
||||||
return waitpid(pid, status, options);
|
return waitpid(pid, status, options);
|
||||||
#else
|
#else
|
||||||
return cast(s32, s64, syscall4(syscall_x86_64_wait4, pid, (s64)status, options, 0));
|
return cast_to(s32, s64, syscall4(syscall_x86_64_wait4, pid, (s64)status, options, 0));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -798,7 +798,7 @@ may_be_unused fn int syscall_gettimeofday(struct timeval* tv, struct timezone* t
|
|||||||
#if LINK_LIBC
|
#if LINK_LIBC
|
||||||
return gettimeofday(tv, tz);
|
return gettimeofday(tv, tz);
|
||||||
#else
|
#else
|
||||||
return cast(s32, s64, syscall2(syscall_x86_64_gettimeofday, (s64)tv, (s64)tz));
|
return cast_to(s32, s64, syscall2(syscall_x86_64_gettimeofday, (s64)tv, (s64)tz));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -831,7 +831,7 @@ may_be_unused fn u64 os_timer_get()
|
|||||||
#else
|
#else
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
syscall_gettimeofday(&tv, 0);
|
syscall_gettimeofday(&tv, 0);
|
||||||
auto result = os_timer_freq() * cast(u64, s64, tv.tv_sec) + cast(u64, s64, tv.tv_usec);
|
auto result = os_timer_freq() * cast_to(u64, s64, tv.tv_sec) + cast_to(u64, s64, tv.tv_usec);
|
||||||
return result;
|
return result;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -898,7 +898,7 @@ u64 os_file_get_size(FileDescriptor fd)
|
|||||||
struct stat stat_buffer;
|
struct stat stat_buffer;
|
||||||
int stat_result = syscall_fstat(fd, &stat_buffer);
|
int stat_result = syscall_fstat(fd, &stat_buffer);
|
||||||
assert(stat_result == 0);
|
assert(stat_result == 0);
|
||||||
auto size = cast(u64, s64, stat_buffer.st_size);
|
auto size = cast_to(u64, s64, stat_buffer.st_size);
|
||||||
return size;
|
return size;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -907,11 +907,11 @@ void os_file_write(FileDescriptor fd, String content)
|
|||||||
{
|
{
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
DWORD bytes_written = 0;
|
DWORD bytes_written = 0;
|
||||||
BOOL result = WriteFile(fd, content.pointer, cast(u32, u64, content.length), &bytes_written, 0);
|
BOOL result = WriteFile(fd, content.pointer, cast_to(u32, u64, content.length), &bytes_written, 0);
|
||||||
assert(result != 0);
|
assert(result != 0);
|
||||||
#else
|
#else
|
||||||
auto result = syscall_write(fd, content.pointer, content.length);
|
auto result = syscall_write(fd, content.pointer, content.length);
|
||||||
assert(cast(u64, s64, result) == content.length);
|
assert(cast_to(u64, s64, result) == content.length);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -924,7 +924,7 @@ may_be_unused fn u64 os_file_read(FileDescriptor fd, String buffer, u64 byte_cou
|
|||||||
{
|
{
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
DWORD read = 0;
|
DWORD read = 0;
|
||||||
BOOL result = ReadFile(fd, buffer.pointer, cast(u32, u64, byte_count), &read, 0);
|
BOOL result = ReadFile(fd, buffer.pointer, cast_to(u32, u64, byte_count), &read, 0);
|
||||||
assert(result != 0);
|
assert(result != 0);
|
||||||
bytes_read = read;
|
bytes_read = read;
|
||||||
#else
|
#else
|
||||||
@ -932,7 +932,7 @@ may_be_unused fn u64 os_file_read(FileDescriptor fd, String buffer, u64 byte_cou
|
|||||||
assert(result > 0);
|
assert(result > 0);
|
||||||
if (result > 0)
|
if (result > 0)
|
||||||
{
|
{
|
||||||
bytes_read = cast(u64, s64, result);
|
bytes_read = cast_to(u64, s64, result);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -1090,22 +1090,22 @@ void print(const char* format, ...)
|
|||||||
it += 1;
|
it += 1;
|
||||||
if (*it != '2')
|
if (*it != '2')
|
||||||
{
|
{
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
it += 1;
|
it += 1;
|
||||||
fail();
|
failed_execution();
|
||||||
break;
|
break;
|
||||||
case '6':
|
case '6':
|
||||||
it += 1;
|
it += 1;
|
||||||
if (*it != '4')
|
if (*it != '4')
|
||||||
{
|
{
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
it += 1;
|
it += 1;
|
||||||
value_double = va_arg(args, f64);
|
value_double = va_arg(args, f64);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_i += format_float(s_get_slice(u8, buffer, buffer_i, buffer.length), value_double);
|
buffer_i += format_float(s_get_slice(u8, buffer, buffer_i, buffer.length), value_double);
|
||||||
@ -1215,7 +1215,7 @@ void print(const char* format, ...)
|
|||||||
|
|
||||||
if (*it != brace_close)
|
if (*it != brace_close)
|
||||||
{
|
{
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
|
|
||||||
it += 1;
|
it += 1;
|
||||||
@ -1373,7 +1373,7 @@ void run_command(Arena* arena, CStringSlice arguments, char* envp[])
|
|||||||
if (argument)
|
if (argument)
|
||||||
{
|
{
|
||||||
auto string_len = strlen(argument);
|
auto string_len = strlen(argument);
|
||||||
length += cast(u32, u64, string_len + 1);
|
length += cast_to(u32, u64, string_len + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1416,12 +1416,12 @@ void run_command(Arena* arena, CStringSlice arguments, char* envp[])
|
|||||||
print("Process ran with exit code: {u32:x}\n", exit_code);
|
print("Process ran with exit code: {u32:x}\n", exit_code);
|
||||||
if (exit_code != 0)
|
if (exit_code != 0)
|
||||||
{
|
{
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseHandle(process_information.hProcess);
|
CloseHandle(process_information.hProcess);
|
||||||
@ -1511,7 +1511,7 @@ void run_command(Arena* arena, CStringSlice arguments, char* envp[])
|
|||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
print("Program failed to run!\n");
|
print("Program failed to run!\n");
|
||||||
fail();
|
failed_execution();
|
||||||
}
|
}
|
||||||
auto ms = resolve_timestamp(start_timestamp, end_timestamp, TIME_UNIT_MILLISECONDS);
|
auto ms = resolve_timestamp(start_timestamp, end_timestamp, TIME_UNIT_MILLISECONDS);
|
||||||
auto ticks =
|
auto ticks =
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
// fn void sha1_process_block(Sha1Context* ctx)
|
// fn void sha1_process_block(Sha1Context* ctx)
|
||||||
// {
|
// {
|
||||||
// global const u32 k[4] =
|
// global_variable const u32 k[4] =
|
||||||
// {
|
// {
|
||||||
// 0x5A827999,
|
// 0x5A827999,
|
||||||
// 0x6ED9EBA1,
|
// 0x6ED9EBA1,
|
||||||
|
@ -24,7 +24,7 @@ s64 string_last_ch(String string, u8 ch)
|
|||||||
i -= 1;
|
i -= 1;
|
||||||
if (string.pointer[i] == ch)
|
if (string.pointer[i] == ch)
|
||||||
{
|
{
|
||||||
result = cast(s64, u64, i);
|
result = cast_to(s64, u64, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,8 +13,8 @@ void vb_generic_ensure_capacity(VirtualBuffer(u8)* vb, u32 item_size, u32 item_c
|
|||||||
vb->pointer = os_reserve(0, item_size * UINT32_MAX, (OSReserveProtectionFlags) {}, (OSReserveMapFlags) { .priv = 1, .anon = 1, .noreserve = 1 });
|
vb->pointer = os_reserve(0, item_size * UINT32_MAX, (OSReserveProtectionFlags) {}, (OSReserveMapFlags) { .priv = 1, .anon = 1, .noreserve = 1 });
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 old_page_capacity = cast(u32, u64, align_forward(old_capacity * item_size, minimum_granularity));
|
u32 old_page_capacity = cast_to(u32, u64, align_forward(old_capacity * item_size, minimum_granularity));
|
||||||
u32 new_page_capacity = cast(u32, u64, align_forward(wanted_capacity * item_size, minimum_granularity));
|
u32 new_page_capacity = cast_to(u32, u64, align_forward(wanted_capacity * item_size, minimum_granularity));
|
||||||
|
|
||||||
u32 commit_size = new_page_capacity - old_page_capacity;
|
u32 commit_size = new_page_capacity - old_page_capacity;
|
||||||
void* commit_pointer = vb->pointer + old_page_capacity;
|
void* commit_pointer = vb->pointer + old_page_capacity;
|
||||||
@ -42,7 +42,7 @@ u8* vb_generic_add(VirtualBuffer(u8)* vb, u32 item_size, u32 item_count)
|
|||||||
|
|
||||||
u8* vb_append_bytes(VirtualBuffer(u8*) vb, Slice(u8) bytes)
|
u8* vb_append_bytes(VirtualBuffer(u8*) vb, Slice(u8) bytes)
|
||||||
{
|
{
|
||||||
auto len = cast(u32, u64, bytes.length);
|
auto len = cast_to(u32, u64, bytes.length);
|
||||||
vb_generic_ensure_capacity(vb, sizeof(u8), len);
|
vb_generic_ensure_capacity(vb, sizeof(u8), len);
|
||||||
auto* pointer = vb_generic_add_assume_capacity(vb, sizeof(u8), len);
|
auto* pointer = vb_generic_add_assume_capacity(vb, sizeof(u8), len);
|
||||||
memcpy(pointer, bytes.pointer, len);
|
memcpy(pointer, bytes.pointer, len);
|
||||||
@ -51,7 +51,7 @@ u8* vb_append_bytes(VirtualBuffer(u8*) vb, Slice(u8) bytes)
|
|||||||
|
|
||||||
void vb_copy_string(VirtualBuffer(u8)* buffer, String string)
|
void vb_copy_string(VirtualBuffer(u8)* buffer, String string)
|
||||||
{
|
{
|
||||||
auto length = cast(u32, u64, string.length);
|
auto length = cast_to(u32, u64, string.length);
|
||||||
auto* pointer = vb_add(buffer, length);
|
auto* pointer = vb_add(buffer, length);
|
||||||
memcpy(pointer, string.pointer, length);
|
memcpy(pointer, string.pointer, length);
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ esac
|
|||||||
|
|
||||||
case "$OSTYPE" in
|
case "$OSTYPE" in
|
||||||
linux*) cmake . -B$build_dir -G Ninja -DCMAKE_BUILD_TYPE="$release_mode" -DCMAKE_C_COMPILER="$CLANG_PREFIX/clang" -DCMAKE_CXX_COMPILER="$CLANG_PREFIX/clang++" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" ;;
|
linux*) cmake . -B$build_dir -G Ninja -DCMAKE_BUILD_TYPE="$release_mode" -DCMAKE_C_COMPILER="$CLANG_PREFIX/clang" -DCMAKE_CXX_COMPILER="$CLANG_PREFIX/clang++" -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=mold" -DCMAKE_SHARED_LINKER_FLAGS="-fuse-ld=mold" ;;
|
||||||
darwin*) cmake . -B$build_dir -G Ninja -DCMAKE_BUILD_TYPE="$release_mode" -DCMAKE_C_COMPILER="$CLANG_PREFIX/clang" -DCMAKE_CXX_COMPILER="$CLANG_PREFIX/clang++" -DCMAKE_PREFIX_PATH=$(brew --prefix llvm) ;;
|
darwin*) cmake . -B$build_dir -G Ninja -DCMAKE_BUILD_TYPE="$release_mode" -DCMAKE_C_COMPILER="$CLANG_PREFIX/clang" -DCMAKE_CXX_COMPILER="$CLANG_PREFIX/clang++" "-DCMAKE_PREFIX_PATH=$(brew --prefix zstd);$(brew --prefix llvm)" ;;
|
||||||
*) exit 1 ;;
|
*) exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user