From a3fa647bfd579e38337cff173a672159d42f7fd6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 6 Jun 2020 14:52:22 +0100 Subject: [PATCH] Add `package sys/llvm` to expose some of the LLVM intrinsics --- core/sys/llvm/bit_manipulation.odin | 83 ++++++++++++ core/sys/llvm/code_generator.odin | 71 +++++++++++ core/sys/llvm/standard_c_library.odin | 177 ++++++++++++++++++++++++++ 3 files changed, 331 insertions(+) create mode 100644 core/sys/llvm/bit_manipulation.odin create mode 100644 core/sys/llvm/code_generator.odin create mode 100644 core/sys/llvm/standard_c_library.odin diff --git a/core/sys/llvm/bit_manipulation.odin b/core/sys/llvm/bit_manipulation.odin new file mode 100644 index 000000000..39464773d --- /dev/null +++ b/core/sys/llvm/bit_manipulation.odin @@ -0,0 +1,83 @@ +// Bit Manipulation Intrinsics +package sys_llvm + +/* +@(default_calling_convention="none") +foreign _ { + @(link_name="llvm.bitreverse.i8") + bit_reverse_u8 :: proc(u8) -> u8 --- + @(link_name="llvm.bitreverse.i16") + bit_reverse_u16 :: proc(u16) -> u16 --- + @(link_name="llvm.bitreverse.i32") + bit_reverse_u32 :: proc(u32) -> u32 --- + @(link_name="llvm.bitreverse.i64") + bit_reverse_u64 :: proc(u64) -> u64 --- + @(link_name="llvm.bitreverse.i128") + bit_reverse_u128 :: proc(u128) -> u128 --- + + @(link_name="llvm.bswap.i16") + bswap_u16 :: proc(u16) -> u16 --- + @(link_name="llvm.bswap.i32") + bswap_u32 :: proc(u32) -> u32 --- + @(link_name="llvm.bswap.i64") + bswap_u64 :: proc(u64) -> u64 --- + @(link_name="llvm.bswap.i128") + bswap_u128 :: proc(u128) -> u128 --- + + @(link_name="llvm.ctpop.i8") + ctpop_u8 :: proc(u8) -> u8 --- + @(link_name="llvm.ctpop.i16") + ctpop_u16 :: proc(u16) -> u16 --- + @(link_name="llvm.ctpop.i32") + ctpop_u32 :: proc(u32) -> u32 --- + @(link_name="llvm.ctpop.i64") + ctpop_u64 :: proc(u64) -> u64 --- + @(link_name="llvm.ctpop.i128") + ctpop_u128 :: proc(u128) -> u128 --- + + @(link_name="llvm.ctlz.i8") + ctlz_u8 :: proc(u8) -> u8 --- + @(link_name="llvm.ctlz.i16") + ctlz_u16 :: proc(u16) -> u16 --- + @(link_name="llvm.ctlz.i32") + ctlz_u32 :: proc(u32) -> u32 --- + @(link_name="llvm.ctlz.i64") + ctlz_u64 :: proc(u64) -> u64 --- + @(link_name="llvm.ctlz.i128") + ctlz_u128 :: proc(u128) -> u128 --- + + @(link_name="llvm.cttz.i8") + cttz_u8 :: proc(u8) -> u8 --- + @(link_name="llvm.cttz.i16") + cttz_u16 :: proc(u16) -> u16 --- + @(link_name="llvm.cttz.i32") + cttz_u32 :: proc(u32) -> u32 --- + @(link_name="llvm.cttz.i64") + cttz_u64 :: proc(u64) -> u64 --- + @(link_name="llvm.cttz.i128") + cttz_u128 :: proc(u128) -> u128 --- + + + @(link_name="llvm.fshl.i8") + fshl_u8 :: proc(a, b, c: u8) -> u8 --- + @(link_name="llvm.fshl.i16") + fshl_u16 :: proc(a, b, c: u16) -> u16 --- + @(link_name="llvm.fshl.i32") + fshl_u32 :: proc(a, b, c: u32) -> u32 --- + @(link_name="llvm.fshl.i64") + fshl_u64 :: proc(a, b, c: u64) -> u64 --- + @(link_name="llvm.fshl.i128") + fshl_u128 :: proc(a, b, c: u128) -> u128 --- + + @(link_name="llvm.fshr.i8") + fshr_u8 :: proc(a, b, c: u8) -> u8 --- + @(link_name="llvm.fshr.i16") + fshr_u16 :: proc(a, b, c: u16) -> u16 --- + @(link_name="llvm.fshr.i32") + fshr_u32 :: proc(a, b, c: u32) -> u32 --- + @(link_name="llvm.fshr.i64") + fshr_u64 :: proc(a, b, c: u64) -> u64 --- + @(link_name="llvm.fshr.i128") + fshr_u128 :: proc(a, b, c: u128) -> u128 --- +} +*/ diff --git a/core/sys/llvm/code_generator.odin b/core/sys/llvm/code_generator.odin new file mode 100644 index 000000000..7d41ed67b --- /dev/null +++ b/core/sys/llvm/code_generator.odin @@ -0,0 +1,71 @@ +// Code Generator Intrinsics +package sys_llvm + +@(default_calling_convention="none") +foreign _ { + @(link_name="llvm.returnaddress") + return_address :: proc(#const level: u32 = 0) -> rawptr --- + + @(link_name="llvm.addressofreturnaddress") + address_of_return_address :: proc() -> rawptr --- + + @(link_name="llvm.sponentry") + stack_pointer_on_entry :: proc() -> rawptr --- + + @(link_name="llvm.frameaddress") + frame_address :: proc(#const level: u32 = 0) -> rawptr --- + + @(link_name="llvm.stacksave") + stack_save :: proc() -> rawptr --- + + @(link_name="llvm.stackrestore") + stack_restore :: proc(ptr: rawptr) --- + + @(link_name="llvm.get.dynamic.area.offset.i32") + get_dynamic_area_offset_i32 :: proc() -> i32 --- + + @(link_name="llvm.get.dynamic.area.offset.i64") + get_dynamic_area_offset_i64 :: proc() -> i64 --- +} + + +Prefetch_Read_Write :: enum i32 { + Read = 0, + Write = 1, +} + +Prefetch_Locality :: enum i32 { + None = 0, + Low = 1, + Mid = 2, + High = 3, +} + +Prefetch_Cache :: enum i32 { + Instruction = 0, + Data = 1, +} + + +@(default_calling_convention="none") +foreign _ { + @(link_name="llvm.prefetch") + prefetch :: proc(address: rawptr, #const rw: Prefetch_Read_Write, #const locality: Prefetch_Locality, #const cache: Prefetch_Cache) --- +} + + + +@(default_calling_convention="none") +foreign _ { + @(link_name="llvm.pcmarker") + pc_marker :: proc(id: i32) --- + + @(link_name="llvm.readcyclecounter") + read_cycle_counter :: proc() -> u64 --- + + @(link_name="llvm.clear_cache") + clear_cache :: proc(rawptr, rawptr) --- + + @(link_name="llvm.thread.pointer") + thread_pointer :: proc() -> rawptr --- +} diff --git a/core/sys/llvm/standard_c_library.odin b/core/sys/llvm/standard_c_library.odin new file mode 100644 index 000000000..108d1268e --- /dev/null +++ b/core/sys/llvm/standard_c_library.odin @@ -0,0 +1,177 @@ +// Standard C Library Intrinsics +package sys_llvm + +@(default_calling_convention="none") +foreign _ { + when size_of(int) == 4 { + @(link_name="llvm.memcpy.p0i8.p0i8.i32") + memcpy :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) --- + + @(link_name="llvm.memcpy.inline.p0i8.p0i8.i32") + memcpy_inline :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) --- + + @(link_name="llvm.memmove.p0i8.p0i8.i32") + memmove :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) --- + + @(link_name="llvm.memset.p0i8.i32") + memset :: proc(dst: rawptr, val: byte, len: int, is_volatile: bool = false) --- + } else { + @(link_name="llvm.memcpy.p0i8.p0i8.i64") + memcpy :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) --- + + @(link_name="llvm.memcpy.inline.p0i8.p0i8.i64") + memcpy_inline :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) --- + + @(link_name="llvm.memmove.p0i8.p0i8.i64") + memmove :: proc(dst, src: rawptr, len: int, is_volatile: bool = false) --- + + @(link_name="llvm.memset.p0i8.i64") + memset :: proc(dst: rawptr, val: byte, len: int, is_volatile: bool = false) --- + } +} + + +@(default_calling_convention="none") +foreign _ { + @(link_name="llvm.sqrt.f32") + sqrt_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.sqrt.f64") + sqrt_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.powi.f32") + powi_f32 :: proc(val: f32, power: i32) -> f32 --- + @(link_name="llvm.powi.f64") + powi_f64 :: proc(val: f64, power: i32) -> f64 --- + + @(link_name="llvm.sin.f32") + sin_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.sin.f64") + sin_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.cos.f32") + cos_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.cos.f64") + cos_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.pow.f32") + pow_f32 :: proc(val, power: f32) -> f32 --- + @(link_name="llvm.pow.f64") + pow_f64 :: proc(val, power: f64) -> f64 --- + + @(link_name="llvm.exp.f32") + exp_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.exp.f64") + exp_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.exp2.f32") + exp2_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.exp2.f64") + exp2_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.log.f32") + log_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.log.f64") + log_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.log10.f32") + log10_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.log10.f64") + log10_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.log2.f32") + log2_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.log2.f64") + log2_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.fma.f32") + fma_f32 :: proc(a, b, c: f32) -> f32 --- + @(link_name="llvm.fma.f64") + fma_f64 :: proc(a, b, c: f64) -> f64 --- + + @(link_name="llvm.fabs.f32") + fabs_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.fabs.f64") + fabs_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.min_num.f32") + min_num_f32 :: proc(val0, val1: f32) -> f32 --- + @(link_name="llvm.min_num.f64") + min_num_f64 :: proc(val0, val1: f64) -> f64 --- + + @(link_name="llvm.max_num.f32") + max_num_f32 :: proc(val0, val1: f32) -> f32 --- + @(link_name="llvm.max_num.f64") + max_num_f64 :: proc(val0, val1: f64) -> f64 --- + + @(link_name="llvm.minimum.f32") + minimum_f32 :: proc(val0, val1: f32) -> f32 --- + @(link_name="llvm.minimum.f64") + minimum_f64 :: proc(val0, val1: f64) -> f64 --- + + @(link_name="llvm.maximum.f32") + maximum_f32 :: proc(val0, val1: f32) -> f32 --- + @(link_name="llvm.maximum.f64") + maximum_f64 :: proc(val0, val1: f64) -> f64 --- + + @(link_name="llvm.copysign.f32") + copy_sign_f32 :: proc(mag, sgn: f32) -> f32 --- + @(link_name="llvm.copysign.f64") + copy_sign_f64 :: proc(mag, sgn: f64) -> f64 --- + + @(link_name="llvm.floor.f32") + floor_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.floor.f64") + floor_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.ceil.f32") + ceil_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.ceil.f64") + ceil_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.trunc.f32") + trunc_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.trunc.f64") + trunc_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.rint.f32") + rint_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.rint.f64") + rint_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.nearbyint.f32") + nearby_int_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.nearbyint.f64") + nearby_int_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.round.f32") + round_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.round.f64") + round_f64 :: proc(f64) -> f64 --- + + @(link_name="llvm.roundeven.f32") + round_even_f32 :: proc(f32) -> f32 --- + @(link_name="llvm.roundeven.f64") + round_even_f64 :: proc(f64) -> f64 --- + + + @(link_name="llvm.lround.i32.f32") + lround_f32_i32 :: proc(f32) -> i32 --- + @(link_name="llvm.lround.i32.f64") + lround_f64_i32 :: proc(f64) -> i32 --- + + @(link_name="llvm.lround.i64.f32") + lround_f32_i64 :: proc(f32) -> i64 --- + @(link_name="llvm.lround.i64.f64") + lround_f64_i64 :: proc(f64) -> i64 --- + + + @(link_name="llvm.lrint.i32.f32") + lrint_f32_i32 :: proc(f32) -> i32 --- + @(link_name="llvm.lrint.i32.f64") + lrint_f64_i32 :: proc(f64) -> i32 --- + + @(link_name="llvm.lrint.i64.f32") + lrint_f32_i64 :: proc(f32) -> i64 --- + @(link_name="llvm.lrint.i64.f64") + lrint_f64_i64 :: proc(f64) -> i64 --- +}