mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-10 15:03:22 +00:00
Added BMI and BMI2 intrinsics.
The BMI ones mostly aren't particularly interesting--they're mostly trivially representable in-language--but PDEP and PEXT from BMI2 could be.
This commit is contained in:
79
core/simd/x86/bmi.odin
Normal file
79
core/simd/x86/bmi.odin
Normal file
@@ -0,0 +1,79 @@
|
||||
#+build i386, amd64
|
||||
package simd_x86
|
||||
|
||||
import "base:intrinsics"
|
||||
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_andn_u32 :: #force_inline proc "c" (a, b: u32) -> u32 {
|
||||
return a &~ b
|
||||
}
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_andn_u64 :: #force_inline proc "c" (a, b: u64) -> u64 {
|
||||
return a &~ b
|
||||
}
|
||||
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_bextr_u32 :: #force_inline proc "c" (a, start, len: u32) -> u32 {
|
||||
return bextr_u32(a, (start & 0xff) | (len << 8))
|
||||
}
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_bextr_u64 :: #force_inline proc "c" (a: u64, start, len: u32) -> u64 {
|
||||
return bextr_u64(a, cast(u64)((start & 0xff) | (len << 8)))
|
||||
}
|
||||
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_bextr2_u32 :: #force_inline proc "c" (a, control: u32) -> u32 {
|
||||
return bextr_u32(a, control)
|
||||
}
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_bextr2_u64 :: #force_inline proc "c" (a, control: u64) -> u64 {
|
||||
return bextr_u64(a, control)
|
||||
}
|
||||
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_blsi_u32 :: #force_inline proc "c" (a: u32) -> u32 {
|
||||
return a & -a
|
||||
}
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_blsi_u64 :: #force_inline proc "c" (a: u64) -> u64 {
|
||||
return a & -a
|
||||
}
|
||||
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_blsmsk_u32 :: #force_inline proc "c" (a: u32) -> u32 {
|
||||
return a ~ (a-1)
|
||||
}
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_blsmsk_u64 :: #force_inline proc "c" (a: u64) -> u64 {
|
||||
return a ~ (a-1)
|
||||
}
|
||||
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_blsr_u32 :: #force_inline proc "c" (a: u32) -> u32 {
|
||||
return a & (a-1)
|
||||
}
|
||||
@(require_results, enable_target_feature="bmi")
|
||||
_blsr_u64 :: #force_inline proc "c" (a: u64) -> u64 {
|
||||
return a & (a-1)
|
||||
}
|
||||
|
||||
@(require_results, enable_target_feature = "bmi")
|
||||
_tzcnt_u16 :: #force_inline proc "c" (a: u16) -> u16 {
|
||||
return intrinsics.count_trailing_zeros(a)
|
||||
}
|
||||
@(require_results, enable_target_feature = "bmi")
|
||||
_tzcnt_u32 :: #force_inline proc "c" (a: u32) -> u32 {
|
||||
return intrinsics.count_trailing_zeros(a)
|
||||
}
|
||||
@(require_results, enable_target_feature = "bmi")
|
||||
_tzcnt_u64 :: #force_inline proc "c" (a: u64) -> u64 {
|
||||
return intrinsics.count_trailing_zeros(a)
|
||||
}
|
||||
|
||||
@(private, default_calling_convention = "none")
|
||||
foreign _ {
|
||||
@(link_name = "llvm.x86.bmi.bextr.32")
|
||||
bextr_u32 :: proc(a, control: u32) -> u32 ---
|
||||
@(link_name = "llvm.x86.bmi.bextr.64")
|
||||
bextr_u64 :: proc(a, control: u64) -> u64 ---
|
||||
}
|
||||
46
core/simd/x86/bmi2.odin
Normal file
46
core/simd/x86/bmi2.odin
Normal file
@@ -0,0 +1,46 @@
|
||||
#+build i386, amd64
|
||||
package simd_x86
|
||||
|
||||
@(require_results, enable_target_feature = "bmi2")
|
||||
_bzhi_u32 :: #force_inline proc "c" (a, index: u32) -> u32 {
|
||||
return bzhi_u32(a, index)
|
||||
}
|
||||
@(require_results, enable_target_feature = "bmi2")
|
||||
_bzhi_u64 :: #force_inline proc "c" (a, index: u64) -> u64 {
|
||||
return bzhi_u64(a, index)
|
||||
}
|
||||
|
||||
@(require_results, enable_target_feature = "bmi2")
|
||||
_pdep_u32 :: #force_inline proc "c" (a, mask: u32) -> u32 {
|
||||
return pdep_u32(a, mask)
|
||||
}
|
||||
@(require_results, enable_target_feature = "bmi2")
|
||||
_pdep_u64 :: #force_inline proc "c" (a, mask: u64) -> u64 {
|
||||
return pdep_u64(a, mask)
|
||||
}
|
||||
|
||||
@(require_results, enable_target_feature = "bmi2")
|
||||
_pext_u32 :: #force_inline proc "c" (a, mask: u32) -> u32 {
|
||||
return pext_u32(a, mask)
|
||||
}
|
||||
@(require_results, enable_target_feature = "bmi2")
|
||||
_pext_u64 :: #force_inline proc "c" (a, mask: u64) -> u64 {
|
||||
return pext_u64(a, mask)
|
||||
}
|
||||
|
||||
|
||||
@(private, default_calling_convention = "none")
|
||||
foreign _ {
|
||||
@(link_name = "llvm.x86.bmi.bzhi.32")
|
||||
bzhi_u32 :: proc(a, index: u32) -> u32 ---
|
||||
@(link_name = "llvm.x86.bmi.bzhi.64")
|
||||
bzhi_u64 :: proc(a, index: u64) -> u64 ---
|
||||
@(link_name = "llvm.x86.bmi.pdep.32")
|
||||
pdep_u32 :: proc(a, mask: u32) -> u32 ---
|
||||
@(link_name = "llvm.x86.bmi.pdep.64")
|
||||
pdep_u64 :: proc(a, mask: u64) -> u64 ---
|
||||
@(link_name = "llvm.x86.bmi.pext.32")
|
||||
pext_u32 :: proc(a, mask: u32) -> u32 ---
|
||||
@(link_name = "llvm.x86.bmi.pext.64")
|
||||
pext_u64 :: proc(a, mask: u64) -> u64 ---
|
||||
}
|
||||
Reference in New Issue
Block a user