Merge remote-tracking branch 'upstream/master' into windows-cross-compile

This commit is contained in:
A1029384756 committed 2026-10-05 08:31:04 -04:00
commit ba04d81d40
187 files changed
+33377 -16504

No files matched your search

+3 -3
View File
@@ -6,7 +6,7 @@ jobs:
name: NetBSD Build, Check, and Test
runs-on: ubuntu-latest
env:
PKGSRC_BRANCH: 2026Q1
PKGSRC_BRANCH: 2026Q3
steps:
- uses: actions/checkout@v4
- name: Build, Check, and Test
@@ -102,8 +102,8 @@ jobs:
run: |
wget https://apt.llvm.org/llvm.sh
chmod +x llvm.sh
sudo ./llvm.sh 20
echo "/usr/lib/llvm-20/bin" >> $GITHUB_PATH
sudo ./llvm.sh 22
echo "/usr/lib/llvm-22/bin" >> $GITHUB_PATH
- name: Build Odin
run: ./build_odin.sh release
- name: Odin version
+17 -2
View File
@@ -718,7 +718,11 @@ when MAP_ENABLED {
delete_key :: proc(m: ^$T/map[$K]$V, key: K) -> (deleted_key: K, deleted_value: V) {
if m != nil {
key := key
old_k, old_v, ok := map_erase_dynamic((^Raw_Map)(m), map_info(T), uintptr(&key))
when ODIN_OPTIMIZATION_MODE >= .Size {
old_k, old_v, ok := map_erase_static(m, &key)
} else {
old_k, old_v, ok := map_erase_dynamic((^Raw_Map)(m), map_info(T), uintptr(&key))
}
if ok {
deleted_key = (^K)(old_k)^
deleted_value = (^V)(old_v)^
@@ -1652,7 +1656,18 @@ when MAP_ENABLED {
// `card` returns the number of bits that are set in a bit_set—its cardinality
@builtin
card :: proc "contextless" (s: $S/bit_set[$E; $U]) -> int {
return int(intrinsics.count_ones(transmute(intrinsics.type_bit_set_underlying_type(S))s))
Backing :: intrinsics.type_bit_set_underlying_type(S)
when intrinsics.type_is_array(Backing) {
// bit_set backed by an array of integers: sum the population count of each element
backing := transmute(Backing)s
count := 0
for elem in backing {
count += int(intrinsics.count_ones(elem))
}
return count
} else {
return int(intrinsics.count_ones(transmute(Backing)s))
}
}
+1
View File
@@ -156,6 +156,7 @@ complain if they're missing.
Required if maps are used
* `default_hasher`
* `default_hasher_fixed`
* `default_hasher_cstring`
* `default_hasher_string`
+195 -118
View File
@@ -53,35 +53,45 @@ map_cell_info :: intrinsics.type_map_cell_info
// Same as the above procedure but at runtime with the cell Map_Cell_Info value.
@(require_results)
map_cell_index_dynamic :: #force_inline proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, index: uintptr) -> uintptr {
// Micro-optimize the common cases to save on integer division.
elements_per_cell := uintptr(info.elements_per_cell)
size_of_cell := uintptr(info.size_of_cell)
switch elements_per_cell {
case 1:
return base + (index * size_of_cell)
case 2:
cell_index := index >> 1
data_index := index & 1
size_of_type := uintptr(info.size_of_type)
return base + (cell_index * size_of_cell) + (data_index * size_of_type)
case:
cell_index := index / elements_per_cell
data_index := index % elements_per_cell
size_of_type := uintptr(info.size_of_type)
return base + (cell_index * size_of_cell) + (data_index * size_of_type)
}
}
map_cell_index_dynamic :: #force_inline proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, index: uintptr) -> uintptr #no_bounds_check {
#assert(MAP_CACHE_LINE_SIZE == 64)
// Same as above procedure but with compile-time constant index.
@(require_results)
map_cell_index_dynamic_const :: proc "contextless" (base: uintptr, #no_alias info: ^Map_Cell_Info, $INDEX: uintptr) -> uintptr {
elements_per_cell := uintptr(info.elements_per_cell)
size_of_cell := uintptr(info.size_of_cell)
size_of_type := uintptr(info.size_of_type)
cell_index := INDEX / elements_per_cell
data_index := INDEX % elements_per_cell
return base + (cell_index * size_of_cell) + (data_index * size_of_type)
// ceil(2^64 / N) for each N = MAP_CACHE_LINE_SIZE / size_of(T) > 1
@(static, rodata)
MAP_CELL_RECIPROCALS := [MAP_CACHE_LINE_SIZE+1]u64{
2 = (1<<64 + 1) / 2,
3 = (1<<64 + 2) / 3,
4 = (1<<64 + 3) / 4,
5 = (1<<64 + 4) / 5,
6 = (1<<64 + 5) / 6,
7 = (1<<64 + 6) / 7,
8 = (1<<64 + 7) / 8,
9 = (1<<64 + 8) / 9,
10 = (1<<64 + 9) / 10,
12 = (1<<64 + 11) / 12,
16 = (1<<64 + 15) / 16,
21 = (1<<64 + 20) / 21,
32 = (1<<64 + 31) / 32,
64 = (1<<64 + 63) / 64,
}
// cell_index*size_of_cell + data_index*size_of_type == index*size_of_type + cell_index*padding
n := info.elements_per_cell
stride := info.size_of_cell if n == 1 else info.size_of_type
padding := info.size_of_cell - n*stride
offset := index*stride
if padding != 0 {
r := MAP_CELL_RECIPROCALS[n]
when size_of(uintptr) == 8 {
cell_index := uintptr((u128(index)*u128(r)) >> 64) // NOTE(bill): on many platforms, this use of `u128` is actually a single instruction
} else {
lo := u64(index)*(r & 0xffff_ffff)
cell_index := uintptr((u64(index)*(r >> 32) + (lo >> 32)) >> 32)
}
offset += cell_index*padding
}
return base + offset
}
// We always round the capacity to a power of two so this becomes [16]Foo, which
@@ -184,7 +194,7 @@ map_hash_is_empty :: #force_inline proc "contextless" (hash: Map_Hash) -> bool {
}
@(require_results)
map_hash_is_deleted :: #force_no_inline proc "contextless" (hash: Map_Hash) -> bool {
map_hash_is_deleted :: #force_inline proc "contextless" (hash: Map_Hash) -> bool {
// The MSB indicates a tombstone
return hash & TOMBSTONE_MASK != 0
}
@@ -199,19 +209,14 @@ map_seed :: #force_inline proc "contextless" (m: Raw_Map) -> uintptr {
return map_seed_from_map_data(map_data(m))
}
// splitmix for uintptr
@(require_results)
map_seed_from_map_data :: #force_inline proc "contextless" (data: uintptr) -> uintptr {
when size_of(uintptr) == size_of(u64) {
mix := data + 0x9e3779b97f4a7c15
mix = (mix ~ (mix >> 30)) * 0xbf58476d1ce4e5b9
mix = (mix ~ (mix >> 27)) * 0x94d049bb133111eb
return mix ~ (mix >> 31)
p := u128(data) * 0x94d049bb133111eb
return uintptr(p) ~ uintptr(p >> 64)
} else {
mix := data + 0x9e3779b9
mix = (mix ~ (mix >> 16)) * 0x21f0aaad
mix = (mix ~ (mix >> 15)) * 0x735a2d97
return mix ~ (mix >> 15)
p := u64(data) * 0x735a2d97
return uintptr(p) ~ uintptr(p >> 32)
}
}
@@ -248,7 +253,7 @@ map_kvh_data_dynamic :: proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Inf
sk = map_cell_index_dynamic(hs_, INFO_HS, capacity) // Skip past hs to get start of sk
// Need to skip past two elements in the scratch key space to get to the start
// of the scratch value space, of which there's only two elements as well.
sv = map_cell_index_dynamic_const(sk, info.ks, 2)
sv = map_cell_index_dynamic(sk, info.ks, 2)
hs = ([^]Map_Hash)(hs_)
return
@@ -546,36 +551,57 @@ map_reserve_dynamic :: #force_no_inline proc "odin" (#no_alias m: ^Raw_Map, #no_
}
resized := map_alloc_dynamic(info, log2_min_cap, m.allocator, loc) or_return
ks, vs, hs, _, _ := map_kvh_data_dynamic(m^, info)
// Cache these loads to avoid hitting them in the for loop.
n := m.len
for i in 0..<old_capacity {
hash := hs[i]
if map_hash_is_empty(hash) {
continue
}
if map_hash_is_deleted(hash) {
continue
}
k := map_cell_index_dynamic(ks, info.ks, i)
v := map_cell_index_dynamic(vs, info.vs, i)
hash = info.key_hasher(rawptr(k), map_seed(resized))
_ = map_insert_hash_dynamic(&resized, info, hash, k, v)
// Only need to do this comparison on each actually added pair, so do not
// fold it into the for loop comparator as a micro-optimization.
n -= 1
if n == 0 {
break
}
}
map_rehash_dynamic(m^, &resized, info)
map_free_dynamic(m^, info, loc) or_return
m.data = resized.data
return nil
}
// NOTE(bill): `dst` must be newly allocated, as it is assumed to have no tombstones
map_rehash_dynamic :: proc "odin" (src: Raw_Map, #no_alias dst: ^Raw_Map, #no_alias info: ^Map_Info) {
ks, vs, hs, _, _ := map_kvh_data_dynamic(src, info)
dks, dvs, dhs, _, _ := map_kvh_data_dynamic(dst^, info)
mask := (uintptr(1) << map_log2_cap(dst^)) - 1
seed := map_seed(dst^)
size_of_k := info.ks.size_of_type
size_of_v := info.vs.size_of_type
n := src.len
for i in 0..<uintptr(1) << map_log2_cap(src) {
if n == 0 {
break
}
if !map_hash_is_valid(hs[i]) {
continue
}
n -= 1
k := map_cell_index_dynamic(ks, info.ks, i)
v := map_cell_index_dynamic(vs, info.vs, i)
h := info.key_hasher(rawptr(k), seed)
pos := h & mask
distance := uintptr(0)
for {
element_hash := dhs[pos]
if map_hash_is_empty(element_hash) || distance > map_probe_distance(dst^, element_hash, pos) {
break
}
pos = (pos + 1) & mask
distance += 1
}
if map_hash_is_empty(dhs[pos]) {
intrinsics.mem_copy_non_overlapping(rawptr(map_cell_index_dynamic(dks, info.ks, pos)), rawptr(k), size_of_k)
intrinsics.mem_copy_non_overlapping(rawptr(map_cell_index_dynamic(dvs, info.vs, pos)), rawptr(v), size_of_v)
dhs[pos] = h
} else {
_ = map_insert_hash_dynamic(dst, info, h, k, v)
}
}
}
@(require_results)
map_shrink_dynamic :: #force_no_inline proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, loc := #caller_location) -> (did_shrink: bool, err: Allocator_Error) {
@@ -606,32 +632,7 @@ map_shrink_dynamic :: #force_no_inline proc "odin" (#no_alias m: ^Raw_Map, #no_a
}
shrunk := map_alloc_dynamic(info, log2_capacity_new, m.allocator) or_return
capacity := uintptr(1) << log2_capacity_new
ks, vs, hs, _, _ := map_kvh_data_dynamic(m^, info)
n := m.len
for i in 0..<capacity {
hash := hs[i]
if map_hash_is_empty(hash) {
continue
}
if map_hash_is_deleted(hash) {
continue
}
k := map_cell_index_dynamic(ks, info.ks, i)
v := map_cell_index_dynamic(vs, info.vs, i)
hash = info.key_hasher(rawptr(k), map_seed(shrunk))
_ = map_insert_hash_dynamic(&shrunk, info, hash, k, v)
// Only need to do this comparison on each actually added pair, so do not
// fold it into the for loop comparator as a micro-optimization.
n -= 1
if n == 0 {
break
}
}
map_rehash_dynamic(m^, &shrunk, info)
map_free_dynamic(m^, info, loc) or_return
m.data = shrunk.data
@@ -673,6 +674,33 @@ map_lookup_dynamic :: #force_no_inline proc "contextless" (m: Raw_Map, #no_alias
d += 1
}
}
@(require_results)
map_lookup_static :: #force_inline proc "contextless" (m: $T/map[$K]$V, key: ^K) -> (index: uintptr, ok: bool) {
rm := transmute(Raw_Map)m
if rm.len == 0 {
return
}
info := intrinsics.type_map_info(T)
h := info.key_hasher(key, map_seed(rm))
pos := map_desired_position(rm, h)
distance := uintptr(0)
mask := (uintptr(1) << map_log2_cap(rm)) - 1
ks, _, hs := map_kvh_data_static(m)
for {
element_hash := hs[pos]
if map_hash_is_empty(element_hash) {
return
} else if distance > map_probe_distance(rm, element_hash, pos) {
return
} else if element_hash == h && info.key_equal(key, rawptr(map_cell_index_static(ks, pos))) {
return pos, true
}
pos = (pos + 1) & mask
distance += 1
}
}
@(require_results)
map_exists_dynamic :: #force_no_inline proc "contextless" (m: Raw_Map, #no_alias info: ^Map_Info, k: uintptr) -> (ok: bool) {
if map_len(m) == 0 {
@@ -703,28 +731,38 @@ map_exists_dynamic :: #force_no_inline proc "contextless" (m: Raw_Map, #no_alias
map_erase_dynamic :: #force_no_inline proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, k: uintptr) -> (old_k, old_v: uintptr, ok: bool) {
index := map_lookup_dynamic(m^, info, k) or_return
ks, vs, hs, _, _ := map_kvh_data_dynamic(m^, info)
hs[index] |= TOMBSTONE_MASK
old_k = map_cell_index_dynamic(ks, info.ks, index)
old_v = map_cell_index_dynamic(vs, info.vs, index)
m.len -= 1
ok = true
mask := (uintptr(1)<<map_log2_cap(m^)) - 1
curr_index := uintptr(index)
next_index := (curr_index + 1) & mask
// if the next element is empty or has zero probe distance, then any lookup
// will always fail on the next, so we can clear both of them
hash := hs[next_index]
if map_hash_is_empty(hash) || map_probe_distance(m^, hash, next_index) == 0 {
hs[curr_index] = 0
} else {
hs[curr_index] |= TOMBSTONE_MASK
}
map_erase_slot(m^, hs, index)
return
}
@(require_results)
map_erase_static :: #force_inline proc "contextless" (m: ^$T/map[$K]$V, key: ^K) -> (old_k, old_v: uintptr, ok: bool) {
index := map_lookup_static(m^, key) or_return
ks, vs, hs := map_kvh_data_static(m^)
old_k = uintptr(map_cell_index_static(ks, index))
old_v = uintptr(map_cell_index_static(vs, index))
(^Raw_Map)(m).len -= 1
ok = true
map_erase_slot((^Raw_Map)(m)^, hs, index)
return
}
map_erase_slot :: #force_inline proc "contextless" (m: Raw_Map, hs: [^]Map_Hash, index: uintptr) {
mask := (uintptr(1)<<map_log2_cap(m)) - 1
next_index := (index + 1) & mask
hash := hs[next_index]
if map_hash_is_empty(hash) || map_probe_distance(m, hash, next_index) == 0 {
hs[index] = 0
} else {
hs[index] |= TOMBSTONE_MASK
}
}
map_clear_dynamic :: #force_inline proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info) {
if m.data == 0 {
return
@@ -963,33 +1001,72 @@ default_hasher :: #force_inline proc "contextless" (data: rawptr, seed: uintptr,
return uintptr(h) | uintptr(uintptr(h) == 0)
}
default_hasher_string :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr {
str := (^[]byte)(data)
return default_hasher(raw_data(str^), seed, len(str))
}
default_hasher_cstring :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr {
h := u64(seed) + INITIAL_HASH_SEED
if ptr := (^[^]byte)(data)^; ptr != nil {
for ptr[0] != 0 {
h = (h ~ u64(ptr[0])) * 0x100000001b3
ptr = ptr[1:]
default_hasher_fixed :: #force_inline proc "contextless" (data: rawptr, seed: uintptr, N: int) -> uintptr {
@(require_results)
hash_fold :: #force_inline proc "contextless" (x, y: uintptr) -> uintptr {
when size_of(uintptr) == 8 {
p := u128(x) * u128(y)
return uintptr(p) ~ uintptr(p >> 64)
} else {
p := u64(x) * u64(y)
return uintptr(p) ~ uintptr(p >> 32)
}
}
HASH_K0 :: 0x9e3779b97f4a7c15 when size_of(uintptr) == 8 else 0x9e3779b9
HASH_K1 :: 0xbf58476d1ce4e5b9 when size_of(uintptr) == 8 else 0x85ebca6b
W :: size_of(uintptr)
p := uintptr(data)
h := uintptr(N)
switch {
case N >= W:
for i := 0; i+W <= N; i += W {
h = hash_fold(h ~ intrinsics.unaligned_load((^uintptr)(p + uintptr(i))), HASH_K0)
}
if N % W != 0 {
h = hash_fold(h ~ intrinsics.unaligned_load((^uintptr)(p + uintptr(N-W))), HASH_K0)
}
case N >= 4:
lo := intrinsics.unaligned_load((^u32)(p))
hi := intrinsics.unaligned_load((^u32)(p + uintptr(N-4)))
h = hash_fold(h ~ uintptr(u64(lo) | u64(hi) << 32), HASH_K0)
case N > 0:
b := ([^]u8)(p)
h = hash_fold(h ~ (uintptr(b[0]) | uintptr(b[N/2]) << 8 | uintptr(b[N-1]) << 16), HASH_K0)
}
// the seed goes in after the key is mixed, so no key pattern can line up with the difference between two maps' seeds
h = hash_fold(h ~ seed, HASH_K1)
h &= HASH_MASK
return uintptr(h) | uintptr(uintptr(h) == 0)
return h | uintptr(h == 0)
}
default_hasher_string :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr {
str := (^[]byte)(data)
return default_hasher_fixed(raw_data(str^), seed, len(str))
}
default_hasher_cstring :: proc "contextless" (data: rawptr, seed: uintptr) -> uintptr {
ptr := (^[^]byte)(data)^
n := 0
if ptr != nil {
for ptr[n] != 0 {
n += 1
}
}
return default_hasher_fixed(ptr, seed, n)
}
default_hasher_f64 :: proc "contextless" (f: f64, seed: uintptr) -> uintptr {
f := f
buf: [size_of(f)]u8
if f == 0 {
return default_hasher(&buf, seed, size_of(buf))
return default_hasher_fixed(&buf, seed, size_of(buf))
}
if f != f {
// TODO(bill): What should the logic be for NaNs?
return default_hasher(&f, seed, size_of(f))
return default_hasher_fixed(&f, seed, size_of(f))
}
return default_hasher(&f, seed, size_of(f))
return default_hasher_fixed(&f, seed, size_of(f))
}
default_hasher_complex128 :: proc "contextless" (x, y: f64, seed: uintptr) -> uintptr {
BIN
View File
Binary file not shown.
+96 -19
View File
@@ -49,32 +49,109 @@ uint_least32_t :: builtin.u32
int_least64_t :: builtin.i64
uint_least64_t :: builtin.u64
// Same on Windows, Linux, and FreeBSD
// 7.18.1.3 Fastest minimum-width integer types
// Linux (glibc only, musl matches BSD spec)
// https://sourceware.org/cgit/glibc/tree/stdlib/stdint.h
// *BSD
// https://cgit.freebsd.org/src/tree/sys/x86/include/_types.h
// https://cgit.freebsd.org/src/tree/sys/i386/include/_types.h
// Darwin
// https://github.com/apple-oss-distributions/Libc/blob/main/include/stdint.h
//
when ODIN_ARCH == .i386 {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD { // https://cgit.freebsd.org/src/tree/sys/i386/include/_types.h
int_fast8_t :: builtin.i32
uint_fast8_t :: builtin.u32
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
} else when ODIN_OS == .Darwin { // https://github.com/apple-oss-distributions/Libc/blob/main/include/stdint.h#L39
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i16
uint_fast16_t :: builtin.u16
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
} else {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
}
int_fast64_t :: builtin.i64
uint_fast64_t :: builtin.u64
} else when ODIN_ARCH == .amd64 {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: long
uint_fast16_t :: ulong
int_fast32_t :: long
uint_fast32_t :: ulong
when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD { // https://cgit.freebsd.org/src/tree/sys/x86/include/_types.h#n66
int_fast8_t :: builtin.i32
uint_fast8_t :: builtin.u32
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
} else when ODIN_OS == .Darwin {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i16
uint_fast16_t :: builtin.u16
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
} else when ODIN_OS == .Windows {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
} else when ODIN_OS == .Linux {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: long // todo: musl is i32 to match BSD spec. No way to target it yet
uint_fast16_t :: ulong
int_fast32_t :: long
uint_fast32_t :: ulong
} else {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
}
int_fast64_t :: builtin.i64
uint_fast64_t :: builtin.u64
} else {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i16
uint_fast16_t :: builtin.u16
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
when ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD {
int_fast8_t :: builtin.i32
uint_fast8_t :: builtin.u32
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
} else when ODIN_OS == .Darwin {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i16
uint_fast16_t :: builtin.u16
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
} else when ODIN_OS == .Linux {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: long // todo: musl is i32 to match BSD spec. No way to target it yet
uint_fast16_t :: ulong
int_fast32_t :: long
uint_fast32_t :: ulong
} else {
int_fast8_t :: builtin.i8
uint_fast8_t :: builtin.u8
int_fast16_t :: builtin.i32
uint_fast16_t :: builtin.u32
int_fast32_t :: builtin.i32
uint_fast32_t :: builtin.u32
}
int_fast64_t :: builtin.i64
uint_fast64_t :: builtin.u64
}
+1 -1
View File
@@ -38,7 +38,7 @@ when ODIN_OS == .Windows {
FILENAME_MAX :: 260
L_tmpnam :: 15 // "\\" + 12 + NUL
L_tmpnam :: 15 // `"\\" + 12 + NUL`
SEEK_SET :: 0
SEEK_CUR :: 1
+87 -53
View File
@@ -3,9 +3,7 @@ package container_dynamic_bit_array
import "base:builtin"
import "base:intrinsics"
/*
Note that these constants are dependent on the backing being a u64.
*/
// Note that these constants are dependent on the backing being a u64.
@(private="file")
INDEX_SHIFT :: 6
@@ -27,27 +25,29 @@ Bit_Array_Iterator :: struct {
word_idx: int,
bit_idx: uint,
}
/*
Wraps a `Bit_Array` into an Iterator
Wraps a `Bit_Array` into an `Bit_Array_Iterator`.
Inputs:
- ba: Pointer to the Bit_Array
- ba: Pointer to the `Bit_Array`
Returns:
- it: Iterator struct
- it: `Bit_Array_Iterator`
*/
make_iterator :: proc (ba: ^Bit_Array) -> (it: Bit_Array_Iterator) {
return Bit_Array_Iterator { array = ba }
}
/*
Returns the next bit, including its set-state. ok=false once exhausted
Returns the next bit, including its set-state. ok=false once exhausted.
Inputs:
- it: The iterator that holds the state.
Returns:
- set: `true` if the bit at `index` is set.
- index: The next bit of the Bit_Array referenced by `it`.
- index: The next bit of the `Bit_Array` referenced by `it`.
- ok: `true` if the iterator can continue, `false` if the iterator is done
*/
iterate_by_all :: proc (it: ^Bit_Array_Iterator) -> (set: bool, index: int, ok: bool) {
@@ -65,34 +65,37 @@ iterate_by_all :: proc (it: ^Bit_Array_Iterator) -> (set: bool, index: int, ok:
return set, index, true
}
/*
Returns the next Set Bit, for example if `0b1010`, then the iterator will return index={1, 3} over two calls.
Returns the next *set* bit, for example if `0b1010`, then the iterator will return index={1, 3} over two calls.
Inputs:
- it: The iterator that holds the state.
Returns:
- index: The next *set* bit of the Bit_Array referenced by `it`.
- index: The next *set* bit of the `Bit_Array` referenced by `it`.
- ok: `true` if the iterator can continue, `false` if the iterator is done
*/
iterate_by_set :: proc (it: ^Bit_Array_Iterator) -> (index: int, ok: bool) {
return iterate_internal_(it, true)
return iterate_internal(it, true)
}
/*
Returns the next Unset Bit, for example if `0b1010`, then the iterator will return index={0, 2} over two calls.
Returns the next *unset* bit, for example if `0b1010`, then the iterator will return index={0, 2} over two calls.
Inputs:
- it: The iterator that holds the state.
Returns:
- index: The next *unset* bit of the Bit_Array referenced by `it`.
- index: The next *unset* bit of the `Bit_Array` referenced by `it`.
- ok: `true` if the iterator can continue, `false` if the iterator is done
*/
iterate_by_unset:: proc (it: ^Bit_Array_Iterator) -> (index: int, ok: bool) {
return iterate_internal_(it, false)
return iterate_internal(it, false)
}
/*
Iterates through set/unset bits
Iterates through set/unset bits.
*Private*
@@ -101,11 +104,11 @@ Inputs:
- ITERATE_SET_BITS: `true` for returning only set bits, false for returning only unset bits
Returns:
- index: The next *unset* bit of the Bit_Array referenced by `it`.
- index: The next *unset* bit of the `Bit_Array` referenced by `it`.
- ok: `true` if the iterator can continue, `false` if the iterator is done
*/
@(private="file")
iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) -> (index: int, ok: bool) {
iterate_internal :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) -> (index: int, ok: bool) {
word := it.array.bits[it.word_idx] if builtin.len(it.array.bits) > it.word_idx else 0
when ! ITERATE_SET_BITS { word = ~word }
@@ -137,19 +140,20 @@ iterate_internal_ :: proc (it: ^Bit_Array_Iterator, $ITERATE_SET_BITS: bool) ->
}
return index, index < it.array.length + it.array.bias
}
/*
Gets the state of a bit in the bit-array
Gets the state of a bit in the `Bit_Array`.
Inputs:
- ba: Pointer to the Bit_Array
- ba: Pointer to the `Bit_Array`
- index: Which bit in the array
Returns:
- res: `true` if the bit at `index` is set.
- ok: Whether the index was valid. Returns `false` if the index is smaller than the bias.
*/
get :: proc(ba: ^Bit_Array, #any_int index: uint) -> (res: bool, ok: bool) #optional_ok {
idx := int(index) - ba.bias
get :: proc(ba: ^Bit_Array, #any_int index: int) -> (res: bool, ok: bool) #optional_ok {
idx := index - ba.bias
if ba == nil || int(index) < ba.bias { return false, false }
@@ -167,28 +171,30 @@ get :: proc(ba: ^Bit_Array, #any_int index: uint) -> (res: bool, ok: bool) #opti
return res, true
}
/*
Gets the state of a bit in the bit-array
Gets the state of a bit in the `Bit_Array`.
*Bypasses all Checks*
Inputs:
- ba: Pointer to the Bit_Array
- ba: Pointer to the `Bit_Array`
- index: Which bit in the array
Returns:
- `true` if bit is set
*/
unsafe_get :: #force_inline proc(ba: ^Bit_Array, #any_int index: uint) -> bool #no_bounds_check {
return bool((ba.bits[index >> INDEX_SHIFT] >> uint(index & INDEX_MASK)) & 1)
unsafe_get :: #force_inline proc(ba: ^Bit_Array, #any_int index: int) -> bool #no_bounds_check {
return bool((ba.bits[index >> INDEX_SHIFT] >> (uint(index) & INDEX_MASK)) & 1)
}
/*
Sets the state of a bit in the bit-array
Sets the state of a bit in the `Bit_Array`.
*Conditionally Allocates (Resizes backing data when `index > len(ba.bits)`)*
Inputs:
- ba: Pointer to the Bit_Array
- ba: Pointer to the `Bit_Array`
- index: Which bit in the array
- set_to: `true` sets the bit on, `false` to turn it off
- allocator: (default is context.allocator)
@@ -196,9 +202,9 @@ Inputs:
Returns:
- ok: Whether the set was successful, `false` on allocation failure or bad index
*/
set :: proc(ba: ^Bit_Array, #any_int index: uint, set_to: bool = true, allocator := context.allocator) -> (ok: bool) {
set :: proc(ba: ^Bit_Array, #any_int index: int, set_to: bool = true, allocator := context.allocator) -> (ok: bool) {
idx := int(index) - ba.bias
idx := index - ba.bias
if ba == nil || int(index) < ba.bias { return false }
context.allocator = allocator
@@ -218,41 +224,44 @@ set :: proc(ba: ^Bit_Array, #any_int index: uint, set_to: bool = true, allocator
return true
}
/*
Sets the state of a bit in the bit-array
Sets the state of a bit in the `Bit_Array`.
*Bypasses all checks*
Inputs:
- ba: Pointer to the Bit_Array
- ba: Pointer to the `Bit_Array`
- index: Which bit in the array
*/
unsafe_set :: proc(ba: ^Bit_Array, bit: int) #no_bounds_check {
ba.bits[bit >> INDEX_SHIFT] |= 1 << uint(bit & INDEX_MASK)
}
/*
Unsets the state of a bit in the bit-array. (Convienence wrapper for `set`)
Unsets the state of a bit in the `Bit_Array`. (Convienence wrapper for `set`)
*Conditionally Allocates (Resizes backing data when `index > len(ba.bits)`)*
Inputs:
- ba: Pointer to the Bit_Array
- ba: Pointer to the `Bit_Array`
- index: Which bit in the array
- allocator: (default is context.allocator)
Returns:
- ok: Whether the unset was successful, `false` on allocation failure or bad index
*/
unset :: #force_inline proc(ba: ^Bit_Array, #any_int index: uint, allocator := context.allocator) -> (ok: bool) {
unset :: #force_inline proc(ba: ^Bit_Array, #any_int index: int, allocator := context.allocator) -> (ok: bool) {
return set(ba, index, false, allocator)
}
/*
Unsets the state of a bit in the bit-array
*Bypasses all Checks*
/*
Unsets the state of a bit in the `Bit_Array`.
*Bypasses all checks*
Inputs:
- ba: Pointer to the Bit_Array
- ba: Pointer to the `Bit_Array`
- index: Which bit in the array
*/
unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check {
@@ -260,7 +269,7 @@ unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check {
}
/*
A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative).
A helper function to create a `Bit_Array` with optional bias, in case your smallest index is non-zero (including negative).
The range of bits created by this procedure is `min_index..<max_index`, and the
array will be able to expand beyond `max_index` if needed.
@@ -273,10 +282,11 @@ Inputs:
- allocator: (default is context.allocator)
Returns:
- ba: Allocates a bit_Array, backing data is set to `max-min / 64` indices, rounded up (eg 65 - 0 allocates for [2]u64).
- ba: Allocates a `Bit_Array`, backing data is set to `max-min / 64` indices, rounded up (eg 65 - 0 allocates for [2]u64).
*/
create :: proc(max_index: int, min_index: int = 0, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) #optional_ok {
create :: proc(max_index: int, min_index: int = 0, allocator := context.allocator, loc := #caller_location) -> (res: ^Bit_Array, ok: bool) #optional_ok {
size_in_bits := max_index - min_index
assert(max_index >= min_index, loc=loc)
if size_in_bits < 0 { return {}, false }
@@ -290,7 +300,27 @@ create :: proc(max_index: int, min_index: int = 0, allocator := context.allocato
}
/*
A helper function to initialize a Bit Array with optional bias, in case your smallest index is non-zero (including negative).
A helper function to create a `Bit_Array` from an enum `E`.
The range of bits created by this procedure is `min(E)..<max(E)`, and the
array will be able to expand beyond `max(E)` if needed.
*Allocates (`new(Bit_Array) & make(ba.bits)`)*
Inputs:
- e: an `enum`
- min_index: minimum starting index (used as a bias)
- allocator: (default is context.allocator)
Returns:
- ba: Allocates a `Bit_Array`, backing data is set to `max-min / 64` indices, rounded up (eg 65 - 0 allocates for [2]u64).
*/
create_from_enum :: proc($T: typeid, allocator := context.allocator) -> (res: ^Bit_Array, ok: bool) where intrinsics.type_is_enum(T) #optional_ok {
return create(int(max(T)), int(min(T)), allocator)
}
/*
A helper function to initialize a `Bit_Array` with optional bias, in case your smallest index is non-zero (including negative).
The range of bits created by this procedure is `min_index..<max_index`, and the
array will be able to expand beyond `max_index` if needed.
@@ -321,20 +351,21 @@ init :: proc(res: ^Bit_Array, max_index: int, min_index: int = 0, allocator := c
}
/*
Sets all values in the Bit_Array to zero.
Sets all values in the `Bit_Array` to zero.
Inputs:
- ba: The target Bit_Array
- ba: The target `Bit_Array`
*/
clear :: proc(ba: ^Bit_Array) {
if ba == nil { return }
intrinsics.mem_zero(raw_data(ba.bits), builtin.len(ba.bits) * NUM_BITS / 8)
}
/*
Gets the length of set and unset valid bits in the Bit_Array.
Gets the length of set and unset valid bits in the `Bit_Array`.
Inputs:
- ba: The target Bit_Array
- ba: The target `Bit_Array`
Returns:
- length: The length of valid bits.
@@ -343,11 +374,12 @@ len :: proc(ba: ^Bit_Array) -> (length: int) {
if ba == nil { return }
return ba.length
}
/*
Shrinks the Bit_Array's backing storage to the smallest possible size.
Shrinks the `Bit_Array`'s backing storage to the smallest possible size.
Inputs:
- ba: The target Bit_Array
- ba: The target `Bit_Array`
*/
shrink :: proc(ba: ^Bit_Array) #no_bounds_check {
if ba == nil { return }
@@ -372,22 +404,24 @@ shrink :: proc(ba: ^Bit_Array) #no_bounds_check {
resize(&ba.bits, legs_needed)
builtin.shrink(&ba.bits)
}
/*
Deallocates the Bit_Array and its backing storage
Deallocates the `Bit_Array` and its backing storage
Inputs:
- ba: The target Bit_Array
- ba: The target `Bit_Array`
*/
destroy :: proc(ba: ^Bit_Array) {
if ba == nil { return }
delete(ba.bits)
if ba.free_pointer { // Only free if this Bit_Array was created using `create`, not when on the stack.
if ba.free_pointer { // Only free if this `Bit_Array` was created using `create`, not when on the stack.
free(ba)
}
}
/*
Resizes the Bit Array. For internal use. Provisions needed capacity+1
If you want to reserve the memory for a given-sized Bit Array up front, you can use `create`.
Resizes the `Bit_Array`. For internal use. Provisions needed capacity+1
If you want to reserve the memory for a given-sized `Bit_Array` up front, you can use `create`.
*/
@(private="file")
resize_if_needed :: proc(ba: ^Bit_Array, legs: int, allocator := context.allocator) -> (ok: bool) {
+18 -17
View File
@@ -8,20 +8,18 @@ Example:
package test
import "core:fmt"
import "core:container/bit_array"
import ba "core:container/bit_array"
main :: proc() {
using bit_array
bits: Bit_Array
bits: ba.Bit_Array
// returns `true`
fmt.println(set(&bits, 42))
fmt.println(ba.set(&bits, 42))
// returns `false`, `false`, because this Bit Array wasn't created to allow negative indices.
was_set, was_retrieved := get(&bits, -1)
was_set, was_retrieved := ba.get(&bits, -1)
fmt.println(was_set, was_retrieved)
destroy(&bits)
ba.destroy(&bits)
}
A `Bit_Array` can optionally allow for negative indices, if the minimum value was given during creation.
@@ -29,7 +27,7 @@ Example:
package test
import "core:fmt"
import "core:container/bit_array"
import ba "core:container/bit_array"
main :: proc() {
Foo :: enum int {
@@ -38,17 +36,20 @@ Example:
Leaves = 69105,
}
using bit_array
bits := ba.create_from_enum(Foo)
defer ba.destroy(bits)
bits := create(int(max(Foo)), int(min(Foo)))
defer destroy(bits)
assert(bits.bias == int(Foo.Negative_Test))
assert(bits.length == abs(int(min(Foo))) + int(max(Foo)))
fmt.printf("Set(Bar): %v\n", set(bits, Foo.Bar))
fmt.printf("Get(Bar): %v, %v\n", get(bits, Foo.Bar))
fmt.printf("Set(Negative_Test): %v\n", set(bits, Foo.Negative_Test))
fmt.printf("Get(Leaves): %v, %v\n", get(bits, Foo.Leaves))
fmt.printf("Get(Negative_Test): %v, %v\n", get(bits, Foo.Negative_Test))
fmt.printf("Freed.\n")
fmt.printfln("Set(Bar): %v", ba.set(bits, Foo.Bar))
fmt.printfln("Get(Bar): %v", ba.get(bits, Foo.Bar))
fmt.printfln("Set(Negative_Test): %v", ba.set(bits, Foo.Negative_Test))
fmt.printfln("Get(Leaves): %v", ba.get(bits, Foo.Leaves))
fmt.printfln("Get(Leaves): %v", ba.unsafe_get(bits, Foo.Leaves))
fmt.printfln("Get(Negative_Test): %v", ba.get(bits, Foo.Negative_Test))
fmt.printfln("Unset(Negative_Test): %v", ba.unset(bits, Foo.Negative_Test))
assert(ba.get(bits, Foo.Negative_Test) == false)
}
*/
package container_dynamic_bit_array
+1 -1
View File
@@ -70,7 +70,7 @@ MAX_SHIFT :: PLATFORM_BITS>>1
}
*/
Array :: struct($T: typeid, $SHIFT: uint) where 0 < SHIFT, SHIFT <= MAX_SHIFT {
chunks: [(1 << (_LOG2_PLATFORM_BITS - intrinsics.constant_log2(SHIFT))) + 1][^]T,
chunks: [PLATFORM_BITS - SHIFT + 1][^]T,
len: int,
allocator: runtime.Allocator,
}
+1 -1
View File
@@ -162,7 +162,7 @@ dsa_sign_internal :: proc(
ctx: []byte,
rnd: []byte,
priv_key: ^Private_Key,
external_mu: []byte = nil
external_mu: []byte = nil,
) -> bool {
params := priv_key.params
switch params {
+1 -1
View File
@@ -4,7 +4,7 @@
Where AEAD stands for Authenticated Encryption with Additional Data.
See:
- [[ https://www.ietf.org/archive/id/draft-irtf-cfrg-aegis-aead-12.txt ]]
- [[ https://www.rfc-editor.org/rfc/rfc10032 ]]
*/
package aegis
+193 -22
View File
@@ -4,8 +4,16 @@
A secondary param can be used to supply a custom alphabet to `encode` and a matching decoding table to `decode`.
If none is supplied it just uses the standard Base64 alphabet.
In case your specific version does not use padding, you may
truncate it from the encoded output.
By default `encode` emits padding. Encode options can omit it: with
`{.No_Padding}` the output is the canonical unpadded ("raw") form of
RFC 4648 section 3.2, and `encoded_len` reports the shorter length.
By default `decode` is lenient, accepting padded and unpadded input and not
checking the trailing padding bits. Decode options can enable strict
(RFC 4648 section 3.5) canonical decoding: `{.Strict}` requires correct
padding and zero trailing bits, while `{.Strict, .No_Padding}` accepts only
canonical unpadded input.
*/
package encoding_base64
@@ -122,16 +130,42 @@ Error :: union #shared_nil {
Decode_Error :: enum {
None,
Invalid_Character,
Invalid_Padding,
Non_Canonical,
}
encode :: proc(data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocator) -> (encoded: string, err: runtime.Allocator_Error) #optional_allocator_error {
out_length := encoded_len(data)
// Decode_Option selects optional validation performed by the decode routines.
Decode_Option :: enum {
// Strict requires canonical input as described in RFC 4648 section 3.5:
// trailing padding bits must be zero, padding must be exact, and padding
// characters may only appear at the end.
Strict,
// No_Padding rejects the padding character, requiring unpadded input.
No_Padding,
}
// Decode_Options is a set of Decode_Option values.
Decode_Options :: bit_set[Decode_Option; u8]
// Encode_Option selects optional behavior of the encode routines.
Encode_Option :: enum {
// No_Padding omits the padding character from the output (RFC 4648
// section 3.2), producing the canonical unpadded ("raw") form.
// Combine with ENC_URL_TABLE for unpadded base64url, as used by JOSE.
No_Padding,
}
// Encode_Options is a set of Encode_Option values.
Encode_Options :: bit_set[Encode_Option; u8]
encode :: proc(data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocator, options := Encode_Options{}) -> (encoded: string, err: runtime.Allocator_Error) #optional_allocator_error {
out_length := encoded_len(data, options)
if out_length == 0 {
return
}
out := make([]byte, out_length, allocator) or_return
_, ioerr := encode_impl(out, data, ENC_TBL)
_, ioerr := encode_impl(out, data, ENC_TBL, options)
assert(ioerr == nil, "encode should not IO error")
assert(len(out) == out_length, "buffer resized, `encoded_len` was wrong")
@@ -140,25 +174,25 @@ encode :: proc(data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocato
return
}
encode_into_buf :: proc(dst, data: []byte, ENC_TBL := ENC_TABLE) -> (encoded: []byte, err: Error) {
out_length := encoded_len(data)
encode_into_buf :: proc(dst, data: []byte, ENC_TBL := ENC_TABLE, options := Encode_Options{}) -> (encoded: []byte, err: Error) {
out_length := encoded_len(data, options)
if out_length == 0 {
return
}
return encode_impl(dst, data, ENC_TBL)
return encode_impl(dst, data, ENC_TBL, options)
}
encode_into :: proc(w: io.Writer, data: []byte, ENC_TBL := ENC_TABLE) -> io.Error {
_, err := encode_impl(w, data, ENC_TBL)
encode_into :: proc(w: io.Writer, data: []byte, ENC_TBL := ENC_TABLE, options := Encode_Options{}) -> io.Error {
_, err := encode_impl(w, data, ENC_TBL, options)
return err
}
@(private)
encode_impl :: proc(dst: $T, data: []byte, ENC_TBL := ENC_TABLE) -> ([]byte, io.Error) where T == io.Writer || T == []byte {
encode_impl :: proc(dst: $T, data: []byte, ENC_TBL := ENC_TABLE, options := Encode_Options{}) -> ([]byte, io.Error) where T == io.Writer || T == []byte {
length := len(data)
when T == []byte {
out_length := encoded_len(data)
out_length := encoded_len(data, options)
if len(dst) < out_length {
return nil, io.Error.Short_Buffer
}
@@ -170,7 +204,9 @@ encode_impl :: proc(dst: $T, data: []byte, ENC_TBL := ENC_TABLE) -> ([]byte, io.
buf: [4]byte
}
c0, c1, c2, block: int
// c0, c1, c2 are the group's input bytes; -1 marks a missing byte, which
// is how a partial (final) group is identified.
c0, c1, c2, block, write: int
for i := 0; i < length; i += 3 {
#no_bounds_check {
c0, c1, c2 = int(data[i]), -1, -1
@@ -178,18 +214,44 @@ encode_impl :: proc(dst: $T, data: []byte, ENC_TBL := ENC_TABLE) -> ([]byte, io.
if i + 1 < length { c1 = int(data[i + 1]) }
if i + 2 < length { c2 = int(data[i + 2]) }
// Pack the group into a 24-bit value, most significant input
// byte first; missing bytes contribute zero bits, as RFC 4648
// section 4 requires.
block = (c0 << 16) | (max(c1, 0) << 8) | max(c2, 0)
// Characters the final block carries once padding is dropped:
// four for a full group, two (one input byte) or three (two
// input bytes) for a partial one.
emit := 4
if c1 == -1 {
emit = 2
} else if c2 == -1 {
emit = 3
}
// Padded output still writes a full four-character block, with
// PADDING where the group ran out of input bytes.
write = emit
if .No_Padding not_in options {
write = 4
}
// The output characters, most significant six bits first;
// PADDING replaces the characters a partial group lacks.
buf[0] = ENC_TBL[block >> 18 & 63]
buf[1] = ENC_TBL[block >> 12 & 63]
buf[2] = c1 == -1 ? PADDING : ENC_TBL[block >> 6 & 63]
buf[3] = c2 == -1 ? PADDING : ENC_TBL[block & 63]
if write > 2 {
buf[2] = c1 == -1 ? PADDING : ENC_TBL[block >> 6 & 63]
if write > 3 {
buf[3] = c2 == -1 ? PADDING : ENC_TBL[block & 63]
}
}
when T == []byte {
buf = buf[4:]
buf = buf[write:]
}
}
when T == io.Writer {
if _, err := io.write_full(dst, buf[:]); err != nil {
if _, err := io.write_full(dst, buf[:write]); err != nil {
return nil, err
}
}
@@ -202,16 +264,117 @@ encode_impl :: proc(dst: $T, data: []byte, ENC_TBL := ENC_TABLE) -> ([]byte, io.
}
}
encoded_len :: proc(data: []byte) -> int {
encoded_len :: proc(data: []byte, options := Encode_Options{}) -> int {
length := len(data)
if length == 0 {
return 0
}
return ((4 * length / 3) + 3) &~ 3
padded := ((4 * length / 3) + 3) &~ 3
if .No_Padding not_in options {
return padded
}
switch length % 3 {
case 1:
return padded - 2
case 2:
return padded - 1
}
return padded
}
decode :: proc(data: string, DEC_TBL := DEC_TABLE, dst: []byte = nil, allocator := context.allocator) -> (decoded: []byte, err: Error) {
@(private)
validate_strict_decode :: proc(data: string, dec_tbl: [256]i8, options: Decode_Options) -> Decode_Error {
if options == {} {
return .None
}
n := len(data)
if n == 0 {
return .None
}
si := n
pad: int
if .No_Padding in options {
for i in 0 ..< n {
if data[i] == PADDING {
return .Invalid_Padding
}
}
} else {
for si > 0 && data[si - 1] == PADDING {
si -= 1
pad += 1
}
if pad > 2 {
return .Invalid_Padding
}
for j in 0 ..< si {
if data[j] == PADDING {
return .Invalid_Padding
}
}
}
rem := si % 4
if .No_Padding in options && rem == 1 {
return .Invalid_Padding
}
if .Strict in options {
if .No_Padding not_in options {
if n % 4 != 0 {
return .Invalid_Padding
}
switch rem {
case 0:
if pad != 0 {
return .Invalid_Padding
}
case 2:
if pad != 2 {
return .Invalid_Padding
}
case 3:
if pad != 1 {
return .Invalid_Padding
}
case:
return .Invalid_Padding
}
}
switch rem {
case 2:
c := dec_tbl[data[si - 1]]
if c < 0 {
return .Invalid_Character
}
if (c & 0x0f) != 0 {
return .Non_Canonical
}
case 3:
c := dec_tbl[data[si - 1]]
if c < 0 {
return .Invalid_Character
}
if (c & 0x03) != 0 {
return .Non_Canonical
}
}
}
return .None
}
decode :: proc(data: string, DEC_TBL := DEC_TABLE, dst: []byte = nil, allocator := context.allocator, options := Decode_Options{}) -> (decoded: []byte, err: Error) {
if derr := validate_strict_decode(data, DEC_TBL, options); derr != .None {
return nil, derr
}
out_length := decoded_len(data)
if out_length == 0 {
return nil, nil
@@ -231,7 +394,11 @@ decode :: proc(data: string, DEC_TBL := DEC_TABLE, dst: []byte = nil, allocator
return
}
decode_into_buf :: proc(dst: []byte, data: string, DEC_TBL := DEC_TABLE) -> (decoded: []byte, err: Error) {
decode_into_buf :: proc(dst: []byte, data: string, DEC_TBL := DEC_TABLE, options := Decode_Options{}) -> (decoded: []byte, err: Error) {
if derr := validate_strict_decode(data, DEC_TBL, options); derr != .None {
return nil, derr
}
out_length := decoded_len(data)
if out_length == 0 {
return
@@ -240,7 +407,11 @@ decode_into_buf :: proc(dst: []byte, data: string, DEC_TBL := DEC_TABLE) -> (dec
return decode_impl(dst, data, DEC_TBL)
}
decode_into :: proc(w: io.Writer, data: string, DEC_TBL := DEC_TABLE) -> Error {
decode_into :: proc(w: io.Writer, data: string, DEC_TBL := DEC_TABLE, options := Decode_Options{}) -> Error {
if derr := validate_strict_decode(data, DEC_TBL, options); derr != .None {
return derr
}
_, err := decode_impl(w, data, DEC_TBL)
return err
}
+2 -2
View File
@@ -615,8 +615,8 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er
return marshal_into(e, any{v.data, vti.id})
case runtime.Type_Info_Bit_Set:
// Store bit_set as big endian just like the protocol.
do_byte_swap := !reflect.bit_set_is_big_endian(v)
// Convert the bit set storage to a native integer before encoding.
do_byte_swap := reflect.bit_set_is_big_endian(v) != (ODIN_ENDIAN == .Big)
switch ti.size * 8 {
case 0:
return _encode_u8(e.writer, 0)
+1 -1
View File
@@ -905,7 +905,7 @@ _assign_int :: proc(val: any, i: $T) -> bool {
case:
ti := type_info_of(v.id)
if _, ok := ti.variant.(runtime.Type_Info_Bit_Set); ok {
do_byte_swap := !reflect.bit_set_is_big_endian(v)
do_byte_swap := reflect.bit_set_is_big_endian(v) != (ODIN_ENDIAN == .Big)
switch ti.size * 8 {
case 0: // no-op.
case 8:
+3
View File
@@ -297,6 +297,9 @@ _read_record :: proc(r: ^Reader, dst: ^[dynamic]string, allocator := context.all
append(&r.raw_buffer, ..rune_buf[:rune_len])
}
if err == .EOF && len(r.raw_buffer) > 0 {
err = nil
}
return r.raw_buffer[:], err
}
unreachable()
-1
View File
@@ -358,7 +358,6 @@ unmarshal_string_token :: proc(p: ^Parser, val: any, token: Token, ti: ^reflect.
return false, nil
}
@(private)
unmarshal_value :: proc(p: ^Parser, v: any) -> (err: Unmarshal_Error) {
UNSUPPORTED_TYPE := Unsupported_Type_Error{v.id, p.curr_token}
token := p.curr_token
+71 -2
View File
@@ -1461,8 +1461,17 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) {
_fmt_float_as(fi, v, bit_size, verb, 'E', 6)
case 'h', 'H':
prev_fi := fi^
defer fi^ = prev_fi
prev_hash := fi.hash
defer fi.hash = prev_hash
prev_zero := fi.zero
defer fi.zero = prev_zero
prev_plus := fi.plus
defer fi.plus = prev_plus
prev_width := fi.width
defer fi.width = prev_width
prev_width_set := fi.width_set
defer fi.width_set = prev_width_set
fi.hash = false
fi.zero = true
fi.plus = false
@@ -1815,6 +1824,14 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "", verb: rune = 'v') {
fmt_bit_set(fi, val, info.name, verb)
case runtime.Type_Info_Bit_Set:
if info.underlying != nil {
#partial switch _ in runtime.type_info_base(info.underlying).variant {
case runtime.Type_Info_Array:
fmt_bit_set_array(fi, v, type_info, name, verb)
return
}
}
bits: u128
bit_size := u128(8*type_info.size)
@@ -1914,6 +1931,58 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "", verb: rune = 'v') {
}
}
// Formats an array-of-integers backed bit_set (e.g. `bit_set[E; [4]u64]`).
// The bits are stored as a little-endian sequence in memory (bit `b` is bit `b%8` of byte `b/8`),
// so they can be scanned directly regardless of how many array elements back the set.
fmt_bit_set_array :: proc(fi: ^Info, v: any, type_info: ^runtime.Type_Info, name: string, verb: rune) {
info := type_info.variant.(runtime.Type_Info_Bit_Set)
bit_size := int(8*type_info.size)
et := runtime.type_info_base(info.elem)
e, is_enum := et.variant.(runtime.Type_Info_Enum)
if verb != 'w' {
if name != "" {
io.write_string(fi.writer, name, &fi.n)
} else {
reflect.write_type(fi.writer, type_info, &fi.n)
}
}
io.write_byte(fi.writer, '{', &fi.n)
defer io.write_byte(fi.writer, '}', &fi.n)
bytes := ([^]u8)(v.data)
commas := 0
loop: for bit_index in 0..<bit_size {
if (bytes[bit_index/8] >> uint(bit_index & 7)) & 1 == 0 {
continue
}
i := i64(bit_index) + info.lower
if commas > 0 {
io.write_string(fi.writer, ", ", &fi.n)
}
if is_enum {
enum_name: string
if ti_named, is_named := info.elem.variant.(runtime.Type_Info_Named); is_named {
enum_name = ti_named.name
}
for ev, evi in e.values {
if u64(ev) == u64(i) {
if verb == 'w' {
io.write_string(fi.writer, enum_name, &fi.n)
io.write_byte(fi.writer, '.', &fi.n)
}
io.write_string(fi.writer, e.names[evi], &fi.n)
commas += 1
continue loop
}
}
}
io.write_i64(fi.writer, i, 10, &fi.n)
commas += 1
}
}
// Writes the specified number of indents to the provided Info structure
//
// Inputs:
+2 -2
View File
@@ -179,7 +179,7 @@ XXH3_reset_internal :: proc(state: ^XXH3_state, seed: XXH64_hash, secret: []u8,
XXH3_consume_stripes :: #force_inline proc(
acc: []xxh_u64, stripes_so_far: ^uint, stripes_per_block: uint, input: []u8,
number_of_stripes: uint, secret: []u8, secret_limit: uint,
f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) {
f_acc512: XXH3_accumulate_512_f, f_scramble: XXH3_scramble_accumulator_f) #no_bounds_check {
assert(number_of_stripes <= stripes_per_block) /* can handle max 1 scramble per invocation */
assert(stripes_so_far^ < stripes_per_block)
@@ -206,7 +206,7 @@ XXH3_consume_stripes :: #force_inline proc(
XXH3_update :: #force_inline proc(
state: ^XXH3_state, input: []u8,
f_acc512: XXH3_accumulate_512_f,
f_scramble: XXH3_scramble_accumulator_f) -> (err: Error) {
f_scramble: XXH3_scramble_accumulator_f) -> (err: Error) #no_bounds_check {
input := input
length := len(input)
+3 -3
View File
@@ -833,9 +833,9 @@ internal_int_prime_strong_lucas_selfridge :: proc(a: ^Int, allocator := context.
/*
Performs one Fermat test.
If "a" were prime then b**a == b (mod a) since the order of
the multiplicative sub-group would be phi(a) = a-1. That means
it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
If "a" were prime then `b**a == b (mod a)` since the order of
the multiplicative sub-group would be `phi(a) = a-1`. That means
it would be the same as `b**(a mod (a-1)) == b**1 == b (mod a)`.
Returns `true` if the congruence holds, or `false` otherwise.
+7 -7
View File
@@ -227,15 +227,15 @@ _private_int_mul_toom :: proc(dest, a, b: ^Int, allocator := context.allocator)
}
/*
product = |a| * |b| using Karatsuba Multiplication using three half size multiplications.
`product = |a| * |b|` using Karatsuba Multiplication using three half size multiplications.
Let `B` represent the radix [e.g. 2**_DIGIT_BITS] and let `n` represent
Let `B` represent the radix [e.g. `2**_DIGIT_BITS`] and let `n` represent
half of the number of digits in the min(a,b)
`a` = `a1` * `B`**`n` + `a0`
`b` = `b`1 * `B`**`n` + `b0`
`a = a1 * B**n + a0`
`b = b1 * B**n + b0`
Then, a * b => 1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
Then, `a * b => a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0`
Note that a1b1 and a0b0 are used twice and only need to be computed once.
So in total three half size (half # of digit) multiplications are performed,
@@ -248,8 +248,8 @@ _private_int_mul_toom :: proc(dest, a, b: ^Int, allocator := context.allocator)
Note also that the call to `internal_mul` can end up back in this function
if the a0, a1, b0, or b1 are above the threshold.
This is known as divide-and-conquer and leads to the famous O(N**lg(3)) or O(N**1.584)
work which is asymptopically lower than the standard O(N**2) that the
This is known as divide-and-conquer and leads to the famous `O(N**lg(3))` or `O(N**1.584)`
work which is asymptopically lower than the standard `O(N**2)` that the
baseline/comba methods use. Generally though, the overhead of this method doesn't pay off
until a certain size is reached, of around 80 used DIGITs.
*/
+2 -2
View File
@@ -760,10 +760,10 @@ mix :: proc{
@(require_results) mix_f64 :: proc "c" (x, y, t: f64) -> f64 { return x*(1-t) + y*t }
@(require_results) mix_vec2 :: proc "c" (x, y, t: vec2) -> vec2 { return {mix(x.x, y.x, t.x), mix(x.y, y.y, t.y)} }
@(require_results) mix_vec3 :: proc "c" (x, y, t: vec3) -> vec3 { return {mix(x.x, y.x, t.x), mix(x.y, y.y, t.y), mix(x.z, y.z, t.z)} }
@(require_results) mix_vec4 :: proc "c" (x, y, t: vec4) -> vec4 { return {mix(x.x, y.x, t.x), mix(x.y, y.y, y.y), mix(x.z, y.z, t.z), mix(x.w, y.w, t.w)} }
@(require_results) mix_vec4 :: proc "c" (x, y, t: vec4) -> vec4 { return {mix(x.x, y.x, t.x), mix(x.y, y.y, t.y), mix(x.z, y.z, t.z), mix(x.w, y.w, t.w)} }
@(require_results) mix_dvec2 :: proc "c" (x, y, t: dvec2) -> dvec2 { return {mix(x.x, y.x, t.x), mix(x.y, y.y, t.y)} }
@(require_results) mix_dvec3 :: proc "c" (x, y, t: dvec3) -> dvec3 { return {mix(x.x, y.x, t.x), mix(x.y, y.y, t.y), mix(x.z, y.z, t.z)} }
@(require_results) mix_dvec4 :: proc "c" (x, y, t: dvec4) -> dvec4 { return {mix(x.x, y.x, t.x), mix(x.y, y.y, y.y), mix(x.z, y.z, t.z), mix(x.w, y.w, t.w)} }
@(require_results) mix_dvec4 :: proc "c" (x, y, t: dvec4) -> dvec4 { return {mix(x.x, y.x, t.x), mix(x.y, y.y, t.y), mix(x.z, y.z, t.z), mix(x.w, y.w, t.w)} }
lerp :: proc{
lerp_f32,
+3 -4
View File
@@ -388,11 +388,11 @@ tan :: proc{
tan_f64, tan_f64le, tan_f64be,
}
@(require_results) lerp :: proc "contextless" (a, b: $T, t: $E) -> (x: T) { return a*(1-t) + b*t }
@(require_results) saturate :: proc "contextless" (a: $T) -> (x: T) { return clamp(a, 0, 1) }
@(require_results) lerp :: #force_inline proc "contextless" (a, b: $T, t: $E) -> (x: T) { return a*(1-t) + b*t }
@(require_results) saturate :: #force_inline proc "contextless" (a: $T) -> (x: T) { return clamp(a, 0, 1) }
@(require_results)
unlerp :: proc "contextless" (a, b, x: $T) -> (t: T) where intrinsics.type_is_float(T), !intrinsics.type_is_array(T) {
unlerp :: #force_inline proc "contextless" (a, b, x: $T) -> (t: T) where intrinsics.type_is_float(T), !intrinsics.type_is_array(T) {
return (x-a)/(b-a)
}
@@ -424,7 +424,6 @@ wrap :: proc "contextless" (x, y: $T) -> T where intrinsics.type_is_numeric(T),
}
@(require_results)
angle_diff :: proc "contextless" (a, b: $T) -> T where intrinsics.type_is_numeric(T), !intrinsics.type_is_array(T) {
dist := wrap(b - a, TAU)
return wrap(dist*2, TAU) - dist
}
+8 -8
View File
@@ -91,11 +91,11 @@ float32_exponential :: proc(lambda: f32, gen := context.random_generator) -> f32
//
// Required: alpha > 0 and beta > 0
//
// math.pow(x, alpha-1) * math.exp(-x / beta)
// pdf(x) = --------------------------------------------
// math.gamma(alpha) * math.pow(beta, alpha)
// math.pow(x, alpha-1) * math.exp(-x / beta)
// pdf(x) = --------------------------------------------
// math.gamma(alpha) * math.pow(beta, alpha)
//
// mean is alpha*beta, variance is math.pow(alpha*beta, 2)
// mean is `alpha*beta`, variance is `math.pow(alpha*beta, 2)`
@(require_results)
float64_gamma :: proc(alpha, beta: f64, gen := context.random_generator) -> f64 {
if alpha <= 0 || beta <= 0 {
@@ -157,11 +157,11 @@ float64_gamma :: proc(alpha, beta: f64, gen := context.random_generator) -> f64
//
// Required: alpha > 0 and beta > 0
//
// math.pow(x, alpha-1) * math.exp(-x / beta)
// pdf(x) = --------------------------------------------
// math.gamma(alpha) * math.pow(beta, alpha)
// math.pow(x, alpha-1) * math.exp(-x / beta)
// pdf(x) = --------------------------------------------
// math.gamma(alpha) * math.pow(beta, alpha)
//
// mean is alpha*beta, variance is math.pow(alpha*beta, 2)
// mean is `alpha*beta`, variance is `math.pow(alpha*beta, 2)`
@(require_results)
float32_gamma :: proc(alpha, beta: f32, gen := context.random_generator) -> f32 {
return f32(float64_gamma(f64(alpha), f64(beta), gen))
+5 -5
View File
@@ -1024,7 +1024,7 @@ make_multi_pointer :: proc(
$T: typeid/[^]$E,
#any_int len: int,
allocator := context.allocator,
loc := #caller_location
loc := #caller_location,
) -> (mp: T, err: Allocator_Error) {
return runtime.make_multi_pointer(T, len, allocator, loc)
}
@@ -1040,7 +1040,7 @@ make_soa_slice :: proc(
$T: typeid/#soa[]$E,
#any_int len: int,
allocator := context.allocator,
loc := #caller_location
loc := #caller_location,
) -> (array: T, err: Allocator_Error) {
return runtime.make_soa_slice(T, len, allocator, loc)
}
@@ -1055,7 +1055,7 @@ its backing allocator, and initial length and capacity of `0`.
make_soa_dynamic_array :: proc(
$T: typeid/#soa[dynamic]$E,
allocator := context.allocator,
loc := #caller_location
loc := #caller_location,
) -> (array: T, err: Allocator_Error) {
return runtime.make_soa_dynamic_array(T, allocator, loc)
}
@@ -1071,7 +1071,7 @@ make_soa_dynamic_array_len :: proc(
$T: typeid/#soa[dynamic]$E,
#any_int len: int,
allocator := context.allocator,
loc := #caller_location
loc := #caller_location,
) -> (array: T, err: Allocator_Error) {
return runtime.make_soa_dynamic_array_len(T, len, allocator, loc)
}
@@ -1089,7 +1089,7 @@ make_soa_dynamic_array_len_cap :: proc(
#any_int len: int,
#any_int cap: int,
allocator := context.allocator,
loc := #caller_location
loc := #caller_location,
) -> (array: T, err: Allocator_Error) {
return runtime.make_soa_dynamic_array_len_cap(T, len, cap, allocator, loc)
}
+9 -9
View File
@@ -262,7 +262,7 @@ arena_alloc_bytes_non_zeroed :: proc(
a: ^Arena,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> ([]byte, Allocator_Error) {
if a.data == nil {
panic("Allocation on uninitialized Arena allocator.", loc)
@@ -654,7 +654,7 @@ scratch_resize :: proc(
old_size: int,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> (rawptr, Allocator_Error) {
bytes, err := scratch_resize_bytes(s, byte_slice(old_memory, old_size), size, alignment, loc)
return raw_data(bytes), err
@@ -682,7 +682,7 @@ scratch_resize_bytes :: proc(
old_data: []byte,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> ([]byte, Allocator_Error) {
bytes, err := scratch_resize_bytes_non_zeroed(s, old_data, size, alignment, loc)
if bytes != nil && size > len(old_data) {
@@ -714,7 +714,7 @@ scratch_resize_non_zeroed :: proc(
old_size: int,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> (rawptr, Allocator_Error) {
bytes, err := scratch_resize_bytes_non_zeroed(s, byte_slice(old_memory, old_size), size, alignment, loc)
return raw_data(bytes), err
@@ -742,7 +742,7 @@ scratch_resize_bytes_non_zeroed :: proc(
old_data: []byte,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> ([]byte, Allocator_Error) {
old_memory := raw_data(old_data)
old_size := len(old_data)
@@ -883,7 +883,7 @@ stack_alloc :: proc(
s: ^Stack,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> (rawptr, Allocator_Error) {
bytes, err := stack_alloc_bytes(s, size, alignment, loc)
return raw_data(bytes), err
@@ -901,7 +901,7 @@ stack_alloc_bytes :: proc(
s: ^Stack,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> ([]byte, Allocator_Error) {
bytes, err := stack_alloc_bytes_non_zeroed(s, size, alignment, loc)
if bytes != nil {
@@ -922,7 +922,7 @@ stack_alloc_non_zeroed :: proc(
s: ^Stack,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> (rawptr, Allocator_Error) {
bytes, err := stack_alloc_bytes_non_zeroed(s, size, alignment, loc)
return raw_data(bytes), err
@@ -940,7 +940,7 @@ stack_alloc_bytes_non_zeroed :: proc(
s: ^Stack,
size: int,
alignment := DEFAULT_ALIGNMENT,
loc := #caller_location
loc := #caller_location,
) -> ([]byte, Allocator_Error) {
if s.data == nil {
panic("Allocation on an uninitialized Stack allocator.", loc)
+8 -8
View File
@@ -100,7 +100,7 @@ accept_poly :: #force_inline proc(
p: $T,
cb: $C/proc(op: ^Operation, p: T),
timeout: time.Duration = NO_TIMEOUT,
l: ^Event_Loop = nil
l: ^Event_Loop = nil,
) -> ^Operation where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
op := prep_accept(socket, _poly_cb(C, T), timeout, l)
@@ -582,7 +582,7 @@ recv :: #force_inline proc(
cb: Callback,
all := false,
timeout: time.Duration = NO_TIMEOUT,
l: ^Event_Loop = nil
l: ^Event_Loop = nil,
) -> ^Operation {
op := prep_recv(socket, bufs, cb, all, timeout, l)
exec(op)
@@ -1053,7 +1053,7 @@ read_poly :: #force_inline proc(
cb: $C/proc(op: ^Operation, p: T),
all := false,
timeout: time.Duration = NO_TIMEOUT,
l: ^Event_Loop = nil
l: ^Event_Loop = nil,
) -> ^Operation where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
op := prep_read(handle, offset, buf, _poly_cb(C, T), all=all, timeout=timeout, l=l)
@@ -1092,7 +1092,7 @@ read_poly2 :: #force_inline proc(
cb: $C/proc(op: ^Operation, p: T, p2: T2),
all := false,
timeout: time.Duration = NO_TIMEOUT,
l: ^Event_Loop = nil
l: ^Event_Loop = nil,
) -> ^Operation where size_of(T) + size_of(T2) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
op := prep_read(handle, offset, buf, _poly_cb2(C, T, T2), all, timeout, l)
@@ -1132,7 +1132,7 @@ read_poly3 :: #force_inline proc(
cb: $C/proc(op: ^Operation, p: T, p2: T2, p3: T3),
all := false,
timeout: time.Duration = NO_TIMEOUT,
l: ^Event_Loop = nil
l: ^Event_Loop = nil,
) -> ^Operation where size_of(T) + size_of(T2) + size_of(T3) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
op := prep_read(handle, offset, buf, _poly_cb3(C, T, T2, T3), all, timeout, l)
@@ -1270,7 +1270,7 @@ write_poly :: #force_inline proc(
cb: $C/proc(op: ^Operation, p: T),
all := true,
timeout: time.Duration = NO_TIMEOUT,
l: ^Event_Loop = nil
l: ^Event_Loop = nil,
) -> ^Operation where size_of(T) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
op := prep_write(handle, offset, buf, _poly_cb(C, T), all=all, timeout=timeout, l=l)
@@ -1309,7 +1309,7 @@ write_poly2 :: #force_inline proc(
cb: $C/proc(op: ^Operation, p: T, p2: T2),
all := true,
timeout: time.Duration = NO_TIMEOUT,
l: ^Event_Loop = nil
l: ^Event_Loop = nil,
) -> ^Operation where size_of(T) + size_of(T2) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
op := prep_write(handle, offset, buf, _poly_cb2(C, T, T2), all, timeout, l)
@@ -1349,7 +1349,7 @@ write_poly3 :: #force_inline proc(
cb: $C/proc(op: ^Operation, p: T, p2: T2, p3: T3),
all := true,
timeout: time.Duration = NO_TIMEOUT,
l: ^Event_Loop = nil
l: ^Event_Loop = nil,
) -> ^Operation where size_of(T) + size_of(T2) + size_of(T3) <= size_of(rawptr) * MAX_USER_ARGUMENTS {
op := prep_write(handle, offset, buf, _poly_cb3(C, T, T2, T3), all, timeout, l)
+4 -4
View File
@@ -24,12 +24,12 @@ import "core:strings"
/*
Expects an IPv4 address with no leading or trailing whitespace:
- a.b.c.d
- a.b.c.d:port
- [a.b.c.d]:port
- `a.b.c.d`
- `a.b.c.d:port`
- `[a.b.c.d]:port`
If the IP address is bracketed, the port must be present and valid (though it will be ignored):
- [a.b.c.d] will be treated as a parsing failure.
- `[a.b.c.d]` will be treated as a parsing failure.
The port, if present, is required to be a base 10 number in the range 0-65535, inclusive.
+1 -2
View File
@@ -934,8 +934,7 @@ parse_for_stmt :: proc(p: ^Parser) -> ^ast.Stmt {
next_token := peek_token(p)
if next_token.kind == .In || next_token.kind == .Comma {
cond = parse_simple_stmt(p, {.In})
if as, ok := cond.derived_stmt.(^ast.Assign_Stmt); ok {
assert(as.op.kind == .In)
if as, ok := cond.derived_stmt.(^ast.Assign_Stmt); ok && as.op.kind == .In {
is_range = true
}
break general_conds
+33
View File
@@ -913,6 +913,39 @@ win32_utf8_to_utf16 :: proc(s: string, allocator: runtime.Allocator) -> (ws: []u
return
}
// Used for `SHFILEOPSTRUCTW`, which requires double-null-terminated strings (`PCZZWSTR`).
@(private="package", require_results)
win32_utf8_to_pczzwstr :: proc(s: string, allocator: runtime.Allocator) -> (ws: win32.PCZZWSTR, err: Error) {
if len(s) < 1 {
// We still need to provide a double-null-terminated empty string.
t := make([]u16, 2, allocator) or_return
ws = cast(win32.PCZZWSTR)raw_data(t)
return
}
b := transmute([]byte)s
cstr := raw_data(b)
n := win32.MultiByteToWideChar(win32.CP_UTF8, win32.MB_ERR_INVALID_CHARS, cstr, i32(len(s)), nil, 0)
if n == 0 {
err = _get_platform_error()
return
}
text := make([]u16, n+2, allocator) or_return
n1 := win32.MultiByteToWideChar(win32.CP_UTF8, win32.MB_ERR_INVALID_CHARS, cstr, i32(len(s)), raw_data(text), n)
if n1 == 0 {
err = _get_platform_error()
delete(text, allocator)
return
}
text[n+1] = 0
text[n] = 0
ws = cast(win32.PCZZWSTR)raw_data(text)
return
}
@(private="package", require_results)
win32_wstring_to_utf8 :: proc(s: cstring16, allocator: runtime.Allocator) -> (res: string, err: runtime.Allocator_Error) {
if s == nil || s == "" {
+10 -10
View File
@@ -90,19 +90,19 @@ _remove_all :: proc(path: string) -> Error {
if !_is_absolute_path(path) {
abs_path = _get_absolute_path(path, temp_allocator) or_return
}
dir := win32_utf8_to_wstring(abs_path, temp_allocator) or_return
empty: [1]u16
// NOTE: The path `dir` must be double-null-terminated (`PCZZWSTR`).
dir := win32_utf8_to_pczzwstr(abs_path, temp_allocator) or_return
file_op := win32.SHFILEOPSTRUCTW {
nil,
win32.FO_DELETE,
dir,
cstring16(&empty[0]),
nil,
win32.FOF_NOCONFIRMATION | win32.FOF_NOERRORUI | win32.FOF_SILENT,
false,
nil,
cstring16(&empty[0]),
nil,
}
res := win32.SHFileOperationW(&file_op)
if res != 0 {
@@ -213,16 +213,18 @@ has_long_path_support :: proc "contextless" () -> bool {
@(require_results)
_fix_long_path_slice :: proc(path: string, allocator: runtime.Allocator) -> ([]u16, runtime.Allocator_Error) {
return win32_utf8_to_utf16(_fix_long_path_internal(path), allocator)
temp_allocator := TEMP_ALLOCATOR_GUARD({allocator})
return win32_utf8_to_utf16(_fix_long_path_internal(path, temp_allocator), allocator)
}
@(require_results)
_fix_long_path :: proc(path: string, allocator: runtime.Allocator) -> (win32.wstring, runtime.Allocator_Error) {
return win32_utf8_to_wstring(_fix_long_path_internal(path), allocator)
temp_allocator := TEMP_ALLOCATOR_GUARD({allocator})
return win32_utf8_to_wstring(_fix_long_path_internal(path, temp_allocator), allocator)
}
@(require_results)
_fix_long_path_internal :: proc(path: string) -> string {
_fix_long_path_internal :: proc(path: string, allocator: runtime.Allocator) -> string {
if has_long_path_support() {
return path
}
@@ -244,10 +246,8 @@ _fix_long_path_internal :: proc(path: string) -> string {
return path
}
temp_allocator := TEMP_ALLOCATOR_GUARD({})
PREFIX :: `\\?`
path_buf := make([]byte, len(PREFIX)+len(path)+1, temp_allocator)
path_buf := make([]byte, len(PREFIX)+len(path)+1, allocator)
copy(path_buf, PREFIX)
n := len(path)
r, w := 0, len(PREFIX)
File diff suppressed because it is too large. Load diff
+1 -1
View File
@@ -430,7 +430,7 @@ gen_one_builder :: proc(sb: ^strings.Builder, opname, verb: string, has_rt, has_
fmt.sbprintf(sb, "\n%s :: proc(%s)%s {{\n", verb, join(hl[:]), has_r ? " -> Id" : "")
if has_r { strings.write_string(sb, "\tr := alloc_id(b)\n") }
fmt.sbprintf(sb, "\tappend(&b.ops, inst_%s(%s))\n", opname, join(call[:]))
fmt.sbprintf(sb, "\tappend_elem(&b.ops, inst_%s(%s))\n", opname, join(call[:]))
if has_r { strings.write_string(sb, "\treturn r\n") }
strings.write_string(sb, "}\n")
}
File diff suppressed because it is too large. Load diff
@@ -451,7 +451,7 @@ write_inst_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
strings.write_string(sb, " }\n")
}
// emit_ procedure: append(instructions, inst_<...>(args)). Not contextless —
// emit_ procedure: append_elem(instructions, inst_<...>(args)). Not contextless —
// append needs context. arm32 has no encoder-level emit_* helpers, so these
// simply wrap the inst_ builder.
write_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
@@ -467,7 +467,7 @@ write_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
for p in ps {
fmt.sbprintf(sb, ", %s: %s", p.name, p.type)
}
strings.write_string(sb, ") { append(instructions, ")
strings.write_string(sb, ") { append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_byte(sb, '(')
for p, i in ps {
File diff suppressed because it is too large. Load diff
@@ -686,7 +686,7 @@ write_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
for n := pad - len(entry.proc_name); n > 0; n -= 1 { strings.write_byte(sb, ' ') }
strings.write_string(sb, " :: #force_inline proc(")
strings.write_string(sb, strings.to_string(pstr))
strings.write_string(sb, ") { append(instructions, ")
strings.write_string(sb, ") { append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_byte(sb, '(')
strings.write_string(sb, strings.to_string(astr))
File diff suppressed because it is too large. Load diff
@@ -506,7 +506,7 @@ generate_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
for n := pad - len(entry.proc_name); n > 0; n -= 1 { strings.write_byte(sb, ' ') }
strings.write_string(sb, " :: #force_inline proc(")
strings.write_string(sb, params)
strings.write_string(sb, ") { append(instructions, ")
strings.write_string(sb, ") { append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_string(sb, "(")
for i in 0..<sig.count {
+163 -163
View File
@@ -24,330 +24,330 @@ package rexcode_mos6502
inst_adc_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ADC, imm) }
inst_adc_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ADC, m) }
emit_adc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ADC, imm)) }
emit_adc_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.ADC, m)) }
emit_adc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ADC, imm)) }
emit_adc_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.ADC, m)) }
inst_and_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.AND, imm) }
inst_and_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.AND, m) }
emit_and_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.AND, imm)) }
emit_and_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.AND, m)) }
emit_and_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.AND, imm)) }
emit_and_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.AND, m)) }
inst_asl_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.ASL) }
inst_asl_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ASL, m) }
emit_asl_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_a(.ASL)) }
emit_asl_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.ASL, m)) }
emit_asl_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_a(.ASL)) }
emit_asl_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.ASL, m)) }
inst_bit_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.BIT, m) }
inst_bit_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.BIT, imm) }
emit_bit_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.BIT, m)) }
emit_bit_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.BIT, imm)) }
emit_bit_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.BIT, m)) }
emit_bit_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.BIT, imm)) }
inst_cmp_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.CMP, imm) }
inst_cmp_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.CMP, m) }
emit_cmp_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.CMP, imm)) }
emit_cmp_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.CMP, m)) }
emit_cmp_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.CMP, imm)) }
emit_cmp_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.CMP, m)) }
inst_cpx_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.CPX, imm) }
inst_cpx_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.CPX, m) }
emit_cpx_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.CPX, imm)) }
emit_cpx_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.CPX, m)) }
emit_cpx_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.CPX, imm)) }
emit_cpx_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.CPX, m)) }
inst_cpy_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.CPY, imm) }
inst_cpy_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.CPY, m) }
emit_cpy_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.CPY, imm)) }
emit_cpy_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.CPY, m)) }
emit_cpy_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.CPY, imm)) }
emit_cpy_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.CPY, m)) }
inst_dec_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.DEC, m) }
inst_dec_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.DEC) }
emit_dec_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.DEC, m)) }
emit_dec_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_a(.DEC)) }
emit_dec_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.DEC, m)) }
emit_dec_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_a(.DEC)) }
inst_dex_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.DEX) }
emit_dex_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.DEX)) }
emit_dex_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.DEX)) }
inst_dey_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.DEY) }
emit_dey_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.DEY)) }
emit_dey_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.DEY)) }
inst_eor_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.EOR, imm) }
inst_eor_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.EOR, m) }
emit_eor_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.EOR, imm)) }
emit_eor_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.EOR, m)) }
emit_eor_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.EOR, imm)) }
emit_eor_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.EOR, m)) }
inst_inc_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.INC, m) }
inst_inc_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.INC) }
emit_inc_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.INC, m)) }
emit_inc_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_a(.INC)) }
emit_inc_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.INC, m)) }
emit_inc_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_a(.INC)) }
inst_inx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.INX) }
emit_inx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.INX)) }
emit_inx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.INX)) }
inst_iny_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.INY) }
emit_iny_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.INY)) }
emit_iny_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.INY)) }
inst_lsr_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.LSR) }
inst_lsr_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LSR, m) }
emit_lsr_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_a(.LSR)) }
emit_lsr_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.LSR, m)) }
emit_lsr_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_a(.LSR)) }
emit_lsr_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.LSR, m)) }
inst_ora_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ORA, imm) }
inst_ora_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ORA, m) }
emit_ora_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ORA, imm)) }
emit_ora_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.ORA, m)) }
emit_ora_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ORA, imm)) }
emit_ora_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.ORA, m)) }
inst_rol_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.ROL) }
inst_rol_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ROL, m) }
emit_rol_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_a(.ROL)) }
emit_rol_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.ROL, m)) }
emit_rol_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_a(.ROL)) }
emit_rol_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.ROL, m)) }
inst_ror_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.ROR) }
inst_ror_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ROR, m) }
emit_ror_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_a(.ROR)) }
emit_ror_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.ROR, m)) }
emit_ror_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_a(.ROR)) }
emit_ror_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.ROR, m)) }
inst_sbc_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.SBC, imm) }
inst_sbc_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SBC, m) }
emit_sbc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.SBC, imm)) }
emit_sbc_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SBC, m)) }
emit_sbc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.SBC, imm)) }
emit_sbc_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SBC, m)) }
inst_bcc_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BCC, label_id) }
emit_bcc_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BCC, label_id)) }
emit_bcc_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BCC, label_id)) }
inst_bcs_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BCS, label_id) }
emit_bcs_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BCS, label_id)) }
emit_bcs_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BCS, label_id)) }
inst_beq_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BEQ, label_id) }
emit_beq_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BEQ, label_id)) }
emit_beq_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BEQ, label_id)) }
inst_bmi_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BMI, label_id) }
emit_bmi_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BMI, label_id)) }
emit_bmi_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BMI, label_id)) }
inst_bne_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BNE, label_id) }
emit_bne_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BNE, label_id)) }
emit_bne_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BNE, label_id)) }
inst_bpl_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BPL, label_id) }
emit_bpl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BPL, label_id)) }
emit_bpl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BPL, label_id)) }
inst_bvc_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BVC, label_id) }
emit_bvc_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BVC, label_id)) }
emit_bvc_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BVC, label_id)) }
inst_bvs_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BVS, label_id) }
emit_bvs_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BVS, label_id)) }
emit_bvs_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BVS, label_id)) }
inst_jmp_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.JMP, m) }
emit_jmp_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.JMP, m)) }
emit_jmp_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.JMP, m)) }
inst_jsr_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.JSR, m) }
emit_jsr_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.JSR, m)) }
emit_jsr_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.JSR, m)) }
inst_rti_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.RTI) }
emit_rti_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.RTI)) }
emit_rti_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.RTI)) }
inst_rts_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.RTS) }
emit_rts_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.RTS)) }
emit_rts_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.RTS)) }
inst_brk_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.BRK) }
emit_brk_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.BRK)) }
emit_brk_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.BRK)) }
inst_clc_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLC) }
emit_clc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CLC)) }
emit_clc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CLC)) }
inst_cld_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLD) }
emit_cld_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CLD)) }
emit_cld_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CLD)) }
inst_cli_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLI) }
emit_cli_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CLI)) }
emit_cli_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CLI)) }
inst_clv_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLV) }
emit_clv_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CLV)) }
emit_clv_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CLV)) }
inst_sec_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SEC) }
emit_sec_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.SEC)) }
emit_sec_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.SEC)) }
inst_sed_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SED) }
emit_sed_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.SED)) }
emit_sed_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.SED)) }
inst_sei_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SEI) }
emit_sei_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.SEI)) }
emit_sei_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.SEI)) }
inst_lda_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.LDA, imm) }
inst_lda_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LDA, m) }
emit_lda_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.LDA, imm)) }
emit_lda_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.LDA, m)) }
emit_lda_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.LDA, imm)) }
emit_lda_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.LDA, m)) }
inst_ldx_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.LDX, imm) }
inst_ldx_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LDX, m) }
emit_ldx_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.LDX, imm)) }
emit_ldx_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.LDX, m)) }
emit_ldx_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.LDX, imm)) }
emit_ldx_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.LDX, m)) }
inst_ldy_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.LDY, imm) }
inst_ldy_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LDY, m) }
emit_ldy_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.LDY, imm)) }
emit_ldy_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.LDY, m)) }
emit_ldy_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.LDY, imm)) }
emit_ldy_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.LDY, m)) }
inst_sta_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.STA, m) }
emit_sta_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.STA, m)) }
emit_sta_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.STA, m)) }
inst_stx_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.STX, m) }
emit_stx_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.STX, m)) }
emit_stx_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.STX, m)) }
inst_sty_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.STY, m) }
emit_sty_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.STY, m)) }
emit_sty_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.STY, m)) }
inst_pha_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHA) }
emit_pha_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.PHA)) }
emit_pha_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.PHA)) }
inst_php_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHP) }
emit_php_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.PHP)) }
emit_php_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.PHP)) }
inst_pla_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLA) }
emit_pla_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.PLA)) }
emit_pla_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.PLA)) }
inst_plp_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLP) }
emit_plp_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.PLP)) }
emit_plp_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.PLP)) }
inst_tax_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TAX) }
emit_tax_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.TAX)) }
emit_tax_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.TAX)) }
inst_tay_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TAY) }
emit_tay_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.TAY)) }
emit_tay_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.TAY)) }
inst_tsx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TSX) }
emit_tsx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.TSX)) }
emit_tsx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.TSX)) }
inst_txa_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TXA) }
emit_txa_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.TXA)) }
emit_txa_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.TXA)) }
inst_txs_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TXS) }
emit_txs_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.TXS)) }
emit_txs_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.TXS)) }
inst_tya_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TYA) }
emit_tya_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.TYA)) }
emit_tya_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.TYA)) }
inst_nop_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.NOP) }
emit_nop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.NOP)) }
emit_nop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.NOP)) }
inst_lax_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LAX, m) }
emit_lax_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.LAX, m)) }
emit_lax_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.LAX, m)) }
inst_dcp_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.DCP, m) }
emit_dcp_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.DCP, m)) }
emit_dcp_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.DCP, m)) }
inst_isc_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ISC, m) }
emit_isc_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.ISC, m)) }
emit_isc_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.ISC, m)) }
inst_rla_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RLA, m) }
emit_rla_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RLA, m)) }
emit_rla_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RLA, m)) }
inst_rra_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RRA, m) }
emit_rra_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RRA, m)) }
emit_rra_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RRA, m)) }
inst_slo_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SLO, m) }
emit_slo_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SLO, m)) }
emit_slo_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SLO, m)) }
inst_sre_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SRE, m) }
emit_sre_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SRE, m)) }
emit_sre_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SRE, m)) }
inst_alr_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ALR, imm) }
emit_alr_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ALR, imm)) }
emit_alr_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ALR, imm)) }
inst_anc_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ANC, imm) }
emit_anc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ANC, imm)) }
emit_anc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ANC, imm)) }
inst_arr_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ARR, imm) }
emit_arr_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ARR, imm)) }
emit_arr_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ARR, imm)) }
inst_axs_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.AXS, imm) }
emit_axs_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.AXS, imm)) }
emit_axs_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.AXS, imm)) }
inst_las_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LAS, m) }
emit_las_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.LAS, m)) }
emit_las_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.LAS, m)) }
inst_ane_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ANE, imm) }
emit_ane_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ANE, imm)) }
emit_ane_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ANE, imm)) }
inst_lxa_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.LXA, imm) }
emit_lxa_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.LXA, imm)) }
emit_lxa_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.LXA, imm)) }
inst_sha_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SHA, m) }
emit_sha_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SHA, m)) }
emit_sha_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SHA, m)) }
inst_shx_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SHX, m) }
emit_shx_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SHX, m)) }
emit_shx_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SHX, m)) }
inst_shy_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SHY, m) }
emit_shy_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SHY, m)) }
emit_shy_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SHY, m)) }
inst_tas_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.TAS, m) }
emit_tas_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.TAS, m)) }
emit_tas_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.TAS, m)) }
inst_jam_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.JAM) }
emit_jam_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.JAM)) }
emit_jam_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.JAM)) }
inst_usbc_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.USBC, imm) }
emit_usbc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.USBC, imm)) }
emit_usbc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.USBC, imm)) }
inst_dop_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.DOP, imm) }
inst_dop_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.DOP, m) }
emit_dop_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.DOP, imm)) }
emit_dop_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.DOP, m)) }
emit_dop_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.DOP, imm)) }
emit_dop_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.DOP, m)) }
inst_top_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.TOP, m) }
emit_top_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.TOP, m)) }
emit_top_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.TOP, m)) }
inst_bra_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BRA, label_id) }
emit_bra_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BRA, label_id)) }
emit_bra_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BRA, label_id)) }
inst_ina_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.INA) }
emit_ina_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_a(.INA)) }
emit_ina_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_a(.INA)) }
inst_dea_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.DEA) }
emit_dea_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_a(.DEA)) }
emit_dea_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_a(.DEA)) }
inst_phx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHX) }
emit_phx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.PHX)) }
emit_phx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.PHX)) }
inst_phy_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHY) }
emit_phy_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.PHY)) }
emit_phy_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.PHY)) }
inst_plx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLX) }
emit_plx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.PLX)) }
emit_plx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.PLX)) }
inst_ply_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLY) }
emit_ply_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.PLY)) }
emit_ply_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.PLY)) }
inst_stz_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.STZ, m) }
emit_stz_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.STZ, m)) }
emit_stz_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.STZ, m)) }
inst_trb_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.TRB, m) }
emit_trb_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.TRB, m)) }
emit_trb_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.TRB, m)) }
inst_tsb_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.TSB, m) }
emit_tsb_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.TSB, m)) }
emit_tsb_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.TSB, m)) }
inst_stp_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.STP) }
emit_stp_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.STP)) }
emit_stp_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.STP)) }
inst_wai_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.WAI) }
emit_wai_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.WAI)) }
emit_wai_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.WAI)) }
inst_rmb0_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RMB0, m) }
emit_rmb0_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RMB0, m)) }
emit_rmb0_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RMB0, m)) }
inst_rmb1_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RMB1, m) }
emit_rmb1_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RMB1, m)) }
emit_rmb1_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RMB1, m)) }
inst_rmb2_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RMB2, m) }
emit_rmb2_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RMB2, m)) }
emit_rmb2_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RMB2, m)) }
inst_rmb3_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RMB3, m) }
emit_rmb3_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RMB3, m)) }
emit_rmb3_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RMB3, m)) }
inst_rmb4_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RMB4, m) }
emit_rmb4_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RMB4, m)) }
emit_rmb4_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RMB4, m)) }
inst_rmb5_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RMB5, m) }
emit_rmb5_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RMB5, m)) }
emit_rmb5_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RMB5, m)) }
inst_rmb6_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RMB6, m) }
emit_rmb6_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RMB6, m)) }
emit_rmb6_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RMB6, m)) }
inst_rmb7_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.RMB7, m) }
emit_rmb7_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.RMB7, m)) }
emit_rmb7_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.RMB7, m)) }
inst_smb0_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SMB0, m) }
emit_smb0_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SMB0, m)) }
emit_smb0_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SMB0, m)) }
inst_smb1_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SMB1, m) }
emit_smb1_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SMB1, m)) }
emit_smb1_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SMB1, m)) }
inst_smb2_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SMB2, m) }
emit_smb2_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SMB2, m)) }
emit_smb2_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SMB2, m)) }
inst_smb3_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SMB3, m) }
emit_smb3_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SMB3, m)) }
emit_smb3_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SMB3, m)) }
inst_smb4_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SMB4, m) }
emit_smb4_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SMB4, m)) }
emit_smb4_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SMB4, m)) }
inst_smb5_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SMB5, m) }
emit_smb5_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SMB5, m)) }
emit_smb5_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SMB5, m)) }
inst_smb6_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SMB6, m) }
emit_smb6_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SMB6, m)) }
emit_smb6_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SMB6, m)) }
inst_smb7_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SMB7, m) }
emit_smb7_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SMB7, m)) }
emit_smb7_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SMB7, m)) }
inst_bbr0_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBR0, zp, label_id) }
emit_bbr0_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBR0, zp, label_id)) }
emit_bbr0_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBR0, zp, label_id)) }
inst_bbr1_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBR1, zp, label_id) }
emit_bbr1_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBR1, zp, label_id)) }
emit_bbr1_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBR1, zp, label_id)) }
inst_bbr2_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBR2, zp, label_id) }
emit_bbr2_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBR2, zp, label_id)) }
emit_bbr2_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBR2, zp, label_id)) }
inst_bbr3_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBR3, zp, label_id) }
emit_bbr3_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBR3, zp, label_id)) }
emit_bbr3_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBR3, zp, label_id)) }
inst_bbr4_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBR4, zp, label_id) }
emit_bbr4_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBR4, zp, label_id)) }
emit_bbr4_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBR4, zp, label_id)) }
inst_bbr5_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBR5, zp, label_id) }
emit_bbr5_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBR5, zp, label_id)) }
emit_bbr5_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBR5, zp, label_id)) }
inst_bbr6_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBR6, zp, label_id) }
emit_bbr6_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBR6, zp, label_id)) }
emit_bbr6_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBR6, zp, label_id)) }
inst_bbr7_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBR7, zp, label_id) }
emit_bbr7_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBR7, zp, label_id)) }
emit_bbr7_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBR7, zp, label_id)) }
inst_bbs0_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBS0, zp, label_id) }
emit_bbs0_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBS0, zp, label_id)) }
emit_bbs0_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBS0, zp, label_id)) }
inst_bbs1_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBS1, zp, label_id) }
emit_bbs1_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBS1, zp, label_id)) }
emit_bbs1_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBS1, zp, label_id)) }
inst_bbs2_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBS2, zp, label_id) }
emit_bbs2_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBS2, zp, label_id)) }
emit_bbs2_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBS2, zp, label_id)) }
inst_bbs3_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBS3, zp, label_id) }
emit_bbs3_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBS3, zp, label_id)) }
emit_bbs3_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBS3, zp, label_id)) }
inst_bbs4_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBS4, zp, label_id) }
emit_bbs4_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBS4, zp, label_id)) }
emit_bbs4_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBS4, zp, label_id)) }
inst_bbs5_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBS5, zp, label_id) }
emit_bbs5_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBS5, zp, label_id)) }
emit_bbs5_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBS5, zp, label_id)) }
inst_bbs6_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBS6, zp, label_id) }
emit_bbs6_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBS6, zp, label_id)) }
emit_bbs6_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBS6, zp, label_id)) }
inst_bbs7_zp_rel :: #force_inline proc "contextless" (zp: u8, label_id: u32) -> Instruction { return inst_zp_rel(.BBS7, zp, label_id) }
emit_bbs7_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append(instructions, inst_zp_rel(.BBS7, zp, label_id)) }
emit_bbs7_zp_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, zp: u8, label_id: u32) { append_elem(instructions, inst_zp_rel(.BBS7, zp, label_id)) }
inst_sxy_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SXY) }
emit_sxy_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.SXY)) }
emit_sxy_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.SXY)) }
inst_sax_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SAX) }
inst_sax_m :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SAX, m) }
emit_sax_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.SAX)) }
emit_sax_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_m(.SAX, m)) }
emit_sax_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.SAX)) }
emit_sax_m :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_m(.SAX, m)) }
inst_say_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SAY) }
emit_say_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.SAY)) }
emit_say_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.SAY)) }
inst_cla_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLA) }
emit_cla_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CLA)) }
emit_cla_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CLA)) }
inst_clx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLX) }
emit_clx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CLX)) }
emit_clx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CLX)) }
inst_cly_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLY) }
emit_cly_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CLY)) }
emit_cly_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CLY)) }
inst_csh_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CSH) }
emit_csh_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CSH)) }
emit_csh_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CSH)) }
inst_csl_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CSL) }
emit_csl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.CSL)) }
emit_csl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.CSL)) }
inst_set_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SET) }
emit_set_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_none(.SET)) }
emit_set_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_none(.SET)) }
inst_st0_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ST0, imm) }
emit_st0_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ST0, imm)) }
emit_st0_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ST0, imm)) }
inst_st1_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ST1, imm) }
emit_st1_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ST1, imm)) }
emit_st1_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ST1, imm)) }
inst_st2_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.ST2, imm) }
emit_st2_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.ST2, imm)) }
emit_st2_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.ST2, imm)) }
inst_tam_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.TAM, imm) }
emit_tam_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.TAM, imm)) }
emit_tam_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.TAM, imm)) }
inst_tma_imm8 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return inst_i(.TMA, imm) }
emit_tma_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_i(.TMA, imm)) }
emit_tma_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_i(.TMA, imm)) }
inst_tst_tst :: #force_inline proc "contextless" (imm: i64, m: Memory) -> Instruction { return Instruction{mnemonic = .TST, operand_count = 2, length = 0, ops = {op_imm8(imm), op_mem(m), {}}} }
emit_tst_tst :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, m: Memory) { append(instructions, Instruction{mnemonic = .TST, operand_count = 2, length = 0, ops = {op_imm8(imm), op_mem(m), {}}}) }
emit_tst_tst :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, m: Memory) { append_elem(instructions, Instruction{mnemonic = .TST, operand_count = 2, length = 0, ops = {op_imm8(imm), op_mem(m), {}}}) }
inst_bsr_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return inst_rel(.BSR, label_id) }
emit_bsr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_rel(.BSR, label_id)) }
emit_bsr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_rel(.BSR, label_id)) }
inst_tii_block :: #force_inline proc "contextless" (src, dst, length_val: u16) -> Instruction { return inst_block(.TII, src, dst, length_val) }
emit_tii_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append(instructions, inst_block(.TII, src, dst, length_val)) }
emit_tii_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append_elem(instructions, inst_block(.TII, src, dst, length_val)) }
inst_tdd_block :: #force_inline proc "contextless" (src, dst, length_val: u16) -> Instruction { return inst_block(.TDD, src, dst, length_val) }
emit_tdd_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append(instructions, inst_block(.TDD, src, dst, length_val)) }
emit_tdd_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append_elem(instructions, inst_block(.TDD, src, dst, length_val)) }
inst_tin_block :: #force_inline proc "contextless" (src, dst, length_val: u16) -> Instruction { return inst_block(.TIN, src, dst, length_val) }
emit_tin_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append(instructions, inst_block(.TIN, src, dst, length_val)) }
emit_tin_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append_elem(instructions, inst_block(.TIN, src, dst, length_val)) }
inst_tia_block :: #force_inline proc "contextless" (src, dst, length_val: u16) -> Instruction { return inst_block(.TIA, src, dst, length_val) }
emit_tia_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append(instructions, inst_block(.TIA, src, dst, length_val)) }
emit_tia_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append_elem(instructions, inst_block(.TIA, src, dst, length_val)) }
inst_tai_block :: #force_inline proc "contextless" (src, dst, length_val: u16) -> Instruction { return inst_block(.TAI, src, dst, length_val) }
emit_tai_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append(instructions, inst_block(.TAI, src, dst, length_val)) }
emit_tai_block :: #force_inline proc(instructions: ^[dynamic]Instruction, src, dst, length_val: u16) { append_elem(instructions, inst_block(.TAI, src, dst, length_val)) }
// =============================================================================
// Overload Groups
@@ -297,7 +297,7 @@ shape_inst_body :: proc(sb: ^strings.Builder, e: Proc_Entry) {
// emit_ body: append the corresponding inst_ result.
shape_emit_body :: proc(sb: ^strings.Builder, e: Proc_Entry) {
strings.write_string(sb, "append(instructions, ")
strings.write_string(sb, "append_elem(instructions, ")
shape_inst_body(sb, e)
strings.write_string(sb, ")")
}
+122 -122
View File
@@ -33,247 +33,247 @@ package rexcode_mos65816
inst_adc_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ADC, m) }
inst_adc_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.ADC, i64(imm)) }
inst_adc_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.ADC, i64(imm)) }
emit_adc_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_adc_mem(m)) }
emit_adc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_adc_imm8(imm)) }
emit_adc_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_adc_imm16(imm)) }
emit_adc_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_adc_mem(m)) }
emit_adc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_adc_imm8(imm)) }
emit_adc_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_adc_imm16(imm)) }
inst_and_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.AND, m) }
inst_and_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.AND, i64(imm)) }
inst_and_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.AND, i64(imm)) }
emit_and_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_and_mem(m)) }
emit_and_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_and_imm8(imm)) }
emit_and_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_and_imm16(imm)) }
emit_and_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_and_mem(m)) }
emit_and_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_and_imm8(imm)) }
emit_and_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_and_imm16(imm)) }
inst_asl_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.ASL) }
inst_asl_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ASL, m) }
emit_asl_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_asl_a()) }
emit_asl_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_asl_mem(m)) }
emit_asl_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_asl_a()) }
emit_asl_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_asl_mem(m)) }
inst_bit_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.BIT, m) }
inst_bit_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.BIT, i64(imm)) }
inst_bit_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.BIT, i64(imm)) }
emit_bit_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_bit_mem(m)) }
emit_bit_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_bit_imm8(imm)) }
emit_bit_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_bit_imm16(imm)) }
emit_bit_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_bit_mem(m)) }
emit_bit_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_bit_imm8(imm)) }
emit_bit_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_bit_imm16(imm)) }
inst_cmp_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.CMP, m) }
inst_cmp_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.CMP, i64(imm)) }
inst_cmp_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.CMP, i64(imm)) }
emit_cmp_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_cmp_mem(m)) }
emit_cmp_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_cmp_imm8(imm)) }
emit_cmp_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_cmp_imm16(imm)) }
emit_cmp_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_cmp_mem(m)) }
emit_cmp_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_cmp_imm8(imm)) }
emit_cmp_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_cmp_imm16(imm)) }
inst_cpx_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.CPX, i64(imm)) }
inst_cpx_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.CPX, i64(imm)) }
inst_cpx_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.CPX, m) }
emit_cpx_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_cpx_imm8(imm)) }
emit_cpx_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_cpx_imm16(imm)) }
emit_cpx_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_cpx_mem(m)) }
emit_cpx_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_cpx_imm8(imm)) }
emit_cpx_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_cpx_imm16(imm)) }
emit_cpx_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_cpx_mem(m)) }
inst_cpy_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.CPY, i64(imm)) }
inst_cpy_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.CPY, i64(imm)) }
inst_cpy_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.CPY, m) }
emit_cpy_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_cpy_imm8(imm)) }
emit_cpy_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_cpy_imm16(imm)) }
emit_cpy_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_cpy_mem(m)) }
emit_cpy_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_cpy_imm8(imm)) }
emit_cpy_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_cpy_imm16(imm)) }
emit_cpy_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_cpy_mem(m)) }
inst_dec_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.DEC) }
inst_dec_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.DEC, m) }
emit_dec_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_dec_a()) }
emit_dec_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_dec_mem(m)) }
emit_dec_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_dec_a()) }
emit_dec_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_dec_mem(m)) }
inst_dex_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.DEX) }
emit_dex_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_dex_none()) }
emit_dex_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_dex_none()) }
inst_dey_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.DEY) }
emit_dey_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_dey_none()) }
emit_dey_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_dey_none()) }
inst_eor_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.EOR, m) }
inst_eor_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.EOR, i64(imm)) }
inst_eor_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.EOR, i64(imm)) }
emit_eor_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_eor_mem(m)) }
emit_eor_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_eor_imm8(imm)) }
emit_eor_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_eor_imm16(imm)) }
emit_eor_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_eor_mem(m)) }
emit_eor_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_eor_imm8(imm)) }
emit_eor_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_eor_imm16(imm)) }
inst_inc_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.INC) }
inst_inc_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.INC, m) }
emit_inc_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_inc_a()) }
emit_inc_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_inc_mem(m)) }
emit_inc_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_inc_a()) }
emit_inc_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_inc_mem(m)) }
inst_inx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.INX) }
emit_inx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_inx_none()) }
emit_inx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_inx_none()) }
inst_iny_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.INY) }
emit_iny_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_iny_none()) }
emit_iny_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_iny_none()) }
inst_lsr_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.LSR) }
inst_lsr_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LSR, m) }
emit_lsr_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_lsr_a()) }
emit_lsr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_lsr_mem(m)) }
emit_lsr_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_lsr_a()) }
emit_lsr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_lsr_mem(m)) }
inst_ora_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ORA, m) }
inst_ora_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.ORA, i64(imm)) }
inst_ora_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.ORA, i64(imm)) }
emit_ora_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_ora_mem(m)) }
emit_ora_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_ora_imm8(imm)) }
emit_ora_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_ora_imm16(imm)) }
emit_ora_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_ora_mem(m)) }
emit_ora_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_ora_imm8(imm)) }
emit_ora_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_ora_imm16(imm)) }
inst_rol_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.ROL) }
inst_rol_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ROL, m) }
emit_rol_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_rol_a()) }
emit_rol_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_rol_mem(m)) }
emit_rol_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_rol_a()) }
emit_rol_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_rol_mem(m)) }
inst_ror_a :: #force_inline proc "contextless" () -> Instruction { return inst_a(.ROR) }
inst_ror_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.ROR, m) }
emit_ror_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_ror_a()) }
emit_ror_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_ror_mem(m)) }
emit_ror_a :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_ror_a()) }
emit_ror_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_ror_mem(m)) }
inst_sbc_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.SBC, m) }
inst_sbc_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.SBC, i64(imm)) }
inst_sbc_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.SBC, i64(imm)) }
emit_sbc_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_sbc_mem(m)) }
emit_sbc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_sbc_imm8(imm)) }
emit_sbc_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_sbc_imm16(imm)) }
emit_sbc_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_sbc_mem(m)) }
emit_sbc_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_sbc_imm8(imm)) }
emit_sbc_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_sbc_imm16(imm)) }
inst_lda_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LDA, m) }
inst_lda_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.LDA, i64(imm)) }
inst_lda_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.LDA, i64(imm)) }
emit_lda_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_lda_mem(m)) }
emit_lda_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_lda_imm8(imm)) }
emit_lda_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_lda_imm16(imm)) }
emit_lda_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_lda_mem(m)) }
emit_lda_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_lda_imm8(imm)) }
emit_lda_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_lda_imm16(imm)) }
inst_ldx_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.LDX, i64(imm)) }
inst_ldx_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.LDX, i64(imm)) }
inst_ldx_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LDX, m) }
emit_ldx_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_ldx_imm8(imm)) }
emit_ldx_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_ldx_imm16(imm)) }
emit_ldx_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_ldx_mem(m)) }
emit_ldx_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_ldx_imm8(imm)) }
emit_ldx_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_ldx_imm16(imm)) }
emit_ldx_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_ldx_mem(m)) }
inst_ldy_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.LDY, i64(imm)) }
inst_ldy_imm16 :: #force_inline proc "contextless" (imm: i16) -> Instruction { return inst_i16(.LDY, i64(imm)) }
inst_ldy_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.LDY, m) }
emit_ldy_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_ldy_imm8(imm)) }
emit_ldy_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append(instructions, inst_ldy_imm16(imm)) }
emit_ldy_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_ldy_mem(m)) }
emit_ldy_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_ldy_imm8(imm)) }
emit_ldy_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i16) { append_elem(instructions, inst_ldy_imm16(imm)) }
emit_ldy_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_ldy_mem(m)) }
inst_sta_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.STA, m) }
emit_sta_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_sta_mem(m)) }
emit_sta_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_sta_mem(m)) }
inst_stx_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.STX, m) }
emit_stx_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_stx_mem(m)) }
emit_stx_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_stx_mem(m)) }
inst_sty_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.STY, m) }
emit_sty_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_sty_mem(m)) }
emit_sty_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_sty_mem(m)) }
inst_tax_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TAX) }
emit_tax_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tax_none()) }
emit_tax_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tax_none()) }
inst_tay_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TAY) }
emit_tay_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tay_none()) }
emit_tay_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tay_none()) }
inst_tsx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TSX) }
emit_tsx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tsx_none()) }
emit_tsx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tsx_none()) }
inst_txa_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TXA) }
emit_txa_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_txa_none()) }
emit_txa_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_txa_none()) }
inst_txs_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TXS) }
emit_txs_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_txs_none()) }
emit_txs_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_txs_none()) }
inst_tya_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TYA) }
emit_tya_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tya_none()) }
emit_tya_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tya_none()) }
inst_pha_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHA) }
emit_pha_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_pha_none()) }
emit_pha_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_pha_none()) }
inst_php_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHP) }
emit_php_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_php_none()) }
emit_php_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_php_none()) }
inst_pla_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLA) }
emit_pla_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_pla_none()) }
emit_pla_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_pla_none()) }
inst_plp_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLP) }
emit_plp_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_plp_none()) }
emit_plp_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_plp_none()) }
inst_jmp_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.JMP, m) }
emit_jmp_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_jmp_mem(m)) }
emit_jmp_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_jmp_mem(m)) }
inst_jsr_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.JSR, m) }
emit_jsr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_jsr_mem(m)) }
emit_jsr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_jsr_mem(m)) }
inst_rti_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.RTI) }
emit_rti_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_rti_none()) }
emit_rti_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_rti_none()) }
inst_rts_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.RTS) }
emit_rts_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_rts_none()) }
emit_rts_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_rts_none()) }
inst_brk_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.BRK, i64(imm)) }
emit_brk_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_brk_imm8(imm)) }
emit_brk_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_brk_imm8(imm)) }
inst_nop_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.NOP) }
emit_nop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_nop_none()) }
emit_nop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_nop_none()) }
inst_bcc_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BCC, label) }
emit_bcc_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_bcc_rel(label)) }
emit_bcc_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_bcc_rel(label)) }
inst_bcs_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BCS, label) }
emit_bcs_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_bcs_rel(label)) }
emit_bcs_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_bcs_rel(label)) }
inst_beq_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BEQ, label) }
emit_beq_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_beq_rel(label)) }
emit_beq_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_beq_rel(label)) }
inst_bmi_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BMI, label) }
emit_bmi_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_bmi_rel(label)) }
emit_bmi_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_bmi_rel(label)) }
inst_bne_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BNE, label) }
emit_bne_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_bne_rel(label)) }
emit_bne_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_bne_rel(label)) }
inst_bpl_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BPL, label) }
emit_bpl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_bpl_rel(label)) }
emit_bpl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_bpl_rel(label)) }
inst_bvc_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BVC, label) }
emit_bvc_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_bvc_rel(label)) }
emit_bvc_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_bvc_rel(label)) }
inst_bvs_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BVS, label) }
emit_bvs_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_bvs_rel(label)) }
emit_bvs_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_bvs_rel(label)) }
inst_clc_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLC) }
emit_clc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_clc_none()) }
emit_clc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_clc_none()) }
inst_cld_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLD) }
emit_cld_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_cld_none()) }
emit_cld_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_cld_none()) }
inst_cli_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLI) }
emit_cli_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_cli_none()) }
emit_cli_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_cli_none()) }
inst_clv_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.CLV) }
emit_clv_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_clv_none()) }
emit_clv_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_clv_none()) }
inst_sec_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SEC) }
emit_sec_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_sec_none()) }
emit_sec_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_sec_none()) }
inst_sed_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SED) }
emit_sed_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_sed_none()) }
emit_sed_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_sed_none()) }
inst_sei_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SEI) }
emit_sei_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_sei_none()) }
emit_sei_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_sei_none()) }
inst_bra_rel :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel(.BRA, label) }
emit_bra_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_bra_rel(label)) }
emit_bra_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_bra_rel(label)) }
inst_stz_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.STZ, m) }
emit_stz_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_stz_mem(m)) }
emit_stz_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_stz_mem(m)) }
inst_trb_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.TRB, m) }
emit_trb_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_trb_mem(m)) }
emit_trb_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_trb_mem(m)) }
inst_tsb_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.TSB, m) }
emit_tsb_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_tsb_mem(m)) }
emit_tsb_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_tsb_mem(m)) }
inst_phx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHX) }
emit_phx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_phx_none()) }
emit_phx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_phx_none()) }
inst_phy_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHY) }
emit_phy_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_phy_none()) }
emit_phy_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_phy_none()) }
inst_plx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLX) }
emit_plx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_plx_none()) }
emit_plx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_plx_none()) }
inst_ply_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLY) }
emit_ply_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_ply_none()) }
emit_ply_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_ply_none()) }
inst_stp_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.STP) }
emit_stp_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_stp_none()) }
emit_stp_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_stp_none()) }
inst_wai_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.WAI) }
emit_wai_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_wai_none()) }
emit_wai_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_wai_none()) }
inst_brl_rel_long :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel_long(.BRL, label) }
emit_brl_rel_long :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_brl_rel_long(label)) }
emit_brl_rel_long :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_brl_rel_long(label)) }
inst_cop_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.COP, i64(imm)) }
emit_cop_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_cop_imm8(imm)) }
emit_cop_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_cop_imm8(imm)) }
inst_jml_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.JML, m) }
emit_jml_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_jml_mem(m)) }
emit_jml_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_jml_mem(m)) }
inst_jsl_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.JSL, m) }
emit_jsl_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_jsl_mem(m)) }
emit_jsl_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_jsl_mem(m)) }
inst_mvn_banks :: #force_inline proc "contextless" (src_bank, dst_bank: u8) -> Instruction { return inst_block_move(.MVN, src_bank, dst_bank) }
emit_mvn_banks :: #force_inline proc(instructions: ^[dynamic]Instruction, src_bank, dst_bank: u8) { append(instructions, inst_mvn_banks(src_bank, dst_bank)) }
emit_mvn_banks :: #force_inline proc(instructions: ^[dynamic]Instruction, src_bank, dst_bank: u8) { append_elem(instructions, inst_mvn_banks(src_bank, dst_bank)) }
inst_mvp_banks :: #force_inline proc "contextless" (src_bank, dst_bank: u8) -> Instruction { return inst_block_move(.MVP, src_bank, dst_bank) }
emit_mvp_banks :: #force_inline proc(instructions: ^[dynamic]Instruction, src_bank, dst_bank: u8) { append(instructions, inst_mvp_banks(src_bank, dst_bank)) }
emit_mvp_banks :: #force_inline proc(instructions: ^[dynamic]Instruction, src_bank, dst_bank: u8) { append_elem(instructions, inst_mvp_banks(src_bank, dst_bank)) }
inst_pea_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.PEA, m) }
emit_pea_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_pea_mem(m)) }
emit_pea_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_pea_mem(m)) }
inst_pei_mem :: #force_inline proc "contextless" (m: Memory) -> Instruction { return inst_m(.PEI, m) }
emit_pei_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append(instructions, inst_pei_mem(m)) }
emit_pei_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, m: Memory) { append_elem(instructions, inst_pei_mem(m)) }
inst_per_rel_long :: #force_inline proc "contextless" (label: u32) -> Instruction { return inst_rel_long(.PER, label) }
emit_per_rel_long :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_per_rel_long(label)) }
emit_per_rel_long :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_per_rel_long(label)) }
inst_phb_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHB) }
emit_phb_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_phb_none()) }
emit_phb_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_phb_none()) }
inst_phd_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHD) }
emit_phd_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_phd_none()) }
emit_phd_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_phd_none()) }
inst_phk_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PHK) }
emit_phk_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_phk_none()) }
emit_phk_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_phk_none()) }
inst_plb_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLB) }
emit_plb_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_plb_none()) }
emit_plb_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_plb_none()) }
inst_pld_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.PLD) }
emit_pld_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_pld_none()) }
emit_pld_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_pld_none()) }
inst_rep_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.REP, i64(imm)) }
emit_rep_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_rep_imm8(imm)) }
emit_rep_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_rep_imm8(imm)) }
inst_sep_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.SEP, i64(imm)) }
emit_sep_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_sep_imm8(imm)) }
emit_sep_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_sep_imm8(imm)) }
inst_rtl_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.RTL) }
emit_rtl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_rtl_none()) }
emit_rtl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_rtl_none()) }
inst_tcd_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TCD) }
emit_tcd_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tcd_none()) }
emit_tcd_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tcd_none()) }
inst_tdc_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TDC) }
emit_tdc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tdc_none()) }
emit_tdc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tdc_none()) }
inst_tcs_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TCS) }
emit_tcs_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tcs_none()) }
emit_tcs_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tcs_none()) }
inst_tsc_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TSC) }
emit_tsc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tsc_none()) }
emit_tsc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tsc_none()) }
inst_txy_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TXY) }
emit_txy_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_txy_none()) }
emit_txy_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_txy_none()) }
inst_tyx_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.TYX) }
emit_tyx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_tyx_none()) }
emit_tyx_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_tyx_none()) }
inst_wdm_imm8 :: #force_inline proc "contextless" (imm: i8) -> Instruction { return inst_i8(.WDM, i64(imm)) }
emit_wdm_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append(instructions, inst_wdm_imm8(imm)) }
emit_wdm_imm8 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i8) { append_elem(instructions, inst_wdm_imm8(imm)) }
inst_xba_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.XBA) }
emit_xba_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_xba_none()) }
emit_xba_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_xba_none()) }
inst_xce_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.XCE) }
emit_xce_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_xce_none()) }
emit_xce_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_xce_none()) }
// =============================================================================
// Overload Groups
@@ -335,7 +335,7 @@ generate_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, mnemonic_str
strings.write_string(sb, ", ")
strings.write_string(sb, params)
}
strings.write_string(sb, ") { append(instructions, ")
strings.write_string(sb, ") { append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_string(sb, "(")
strings.write_string(sb, kind_args(entry.kind))
File diff suppressed because it is too large. Load diff
@@ -364,7 +364,7 @@ generate_inst_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
strings.write_string(sb, " }\n")
}
// emit_<mnem>_<suffix> :: #force_inline proc(instructions, params) { append(instructions, inst_<...>(args)) }
// emit_<mnem>_<suffix> :: #force_inline proc(instructions, params) { append_elem(instructions, inst_<...>(args)) }
generate_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
ops := entry.ops
names := param_names(ops[:entry.count])
@@ -380,7 +380,7 @@ generate_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
strings.write_string(sb, ": ")
strings.write_string(sb, op_param_type(entry.ops[i]))
}
strings.write_string(sb, ") { append(instructions, ")
strings.write_string(sb, ") { append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_string(sb, "(")
for i in 0..<entry.count {
+222 -222
View File
@@ -20,449 +20,449 @@ package rexcode_ppc_vle
// =============================================================================
inst_se_illegal_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_ILLEGAL, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_illegal_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_illegal_none()) }
emit_se_illegal_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_illegal_none()) }
inst_se_isync_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_ISYNC, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_isync_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_isync_none()) }
emit_se_isync_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_isync_none()) }
inst_se_sc_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_SC, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_sc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_sc_none()) }
emit_se_sc_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_sc_none()) }
inst_se_blr_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_BLR, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_blr_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_blr_none()) }
emit_se_blr_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_blr_none()) }
inst_se_blrl_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_BLRL, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_blrl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_blrl_none()) }
emit_se_blrl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_blrl_none()) }
inst_se_bctr_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_BCTR, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_bctr_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_bctr_none()) }
emit_se_bctr_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_bctr_none()) }
inst_se_bctrl_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_BCTRL, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_bctrl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_bctrl_none()) }
emit_se_bctrl_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_bctrl_none()) }
inst_se_rfi_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_RFI, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_rfi_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_rfi_none()) }
emit_se_rfi_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_rfi_none()) }
inst_se_rfci_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_RFCI, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_rfci_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_rfci_none()) }
emit_se_rfci_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_rfci_none()) }
inst_se_rfdi_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_RFDI, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_rfdi_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_rfdi_none()) }
emit_se_rfdi_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_rfdi_none()) }
inst_se_rfmci_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_RFMCI, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_rfmci_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_rfmci_none()) }
emit_se_rfmci_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_rfmci_none()) }
inst_se_rfgi_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .SE_RFGI, operand_count = 0, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {{}, {}, {}, {}}} }
emit_se_rfgi_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_se_rfgi_none()) }
emit_se_rfgi_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_se_rfgi_none()) }
inst_se_not_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_NOT, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_not_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_not_r(rd)) }
emit_se_not_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_not_r(rd)) }
inst_se_neg_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_NEG, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_neg_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_neg_r(rd)) }
emit_se_neg_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_neg_r(rd)) }
inst_se_mflr_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_MFLR, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_mflr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_mflr_r(rd)) }
emit_se_mflr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_mflr_r(rd)) }
inst_se_mtlr_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_MTLR, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_mtlr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_mtlr_r(rd)) }
emit_se_mtlr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_mtlr_r(rd)) }
inst_se_mfctr_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_MFCTR, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_mfctr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_mfctr_r(rd)) }
emit_se_mfctr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_mfctr_r(rd)) }
inst_se_mtctr_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_MTCTR, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_mtctr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_mtctr_r(rd)) }
emit_se_mtctr_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_mtctr_r(rd)) }
inst_se_extzb_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_EXTZB, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_extzb_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_extzb_r(rd)) }
emit_se_extzb_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_extzb_r(rd)) }
inst_se_extsb_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_EXTSB, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_extsb_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_extsb_r(rd)) }
emit_se_extsb_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_extsb_r(rd)) }
inst_se_extzh_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_EXTZH, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_extzh_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_extzh_r(rd)) }
emit_se_extzh_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_extzh_r(rd)) }
inst_se_extsh_r :: #force_inline proc "contextless" (rd: Register) -> Instruction { return Instruction{mnemonic = .SE_EXTSH, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), {}, {}, {}}} }
emit_se_extsh_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append(instructions, inst_se_extsh_r(rd)) }
emit_se_extsh_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register) { append_elem(instructions, inst_se_extsh_r(rd)) }
inst_se_mr_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_MR, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_mr_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_mr_r_r(rd, r2)) }
emit_se_mr_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_mr_r_r(rd, r2)) }
inst_se_mtar_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_MTAR, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_mtar_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_mtar_r_r(rd, r2)) }
emit_se_mtar_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_mtar_r_r(rd, r2)) }
inst_se_mfar_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_MFAR, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_mfar_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_mfar_r_r(rd, r2)) }
emit_se_mfar_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_mfar_r_r(rd, r2)) }
inst_se_add_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_ADD, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_add_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_add_r_r(rd, r2)) }
emit_se_add_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_add_r_r(rd, r2)) }
inst_se_mullw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_MULLW, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_mullw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_mullw_r_r(rd, r2)) }
emit_se_mullw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_mullw_r_r(rd, r2)) }
inst_se_sub_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_SUB, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_sub_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_sub_r_r(rd, r2)) }
emit_se_sub_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_sub_r_r(rd, r2)) }
inst_se_subf_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_SUBF, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_subf_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_subf_r_r(rd, r2)) }
emit_se_subf_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_subf_r_r(rd, r2)) }
inst_se_cmp_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_CMP, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_cmp_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_cmp_r_r(rd, r2)) }
emit_se_cmp_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_cmp_r_r(rd, r2)) }
inst_se_cmpl_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_CMPL, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_cmpl_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_cmpl_r_r(rd, r2)) }
emit_se_cmpl_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_cmpl_r_r(rd, r2)) }
inst_se_cmph_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_CMPH, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_cmph_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_cmph_r_r(rd, r2)) }
emit_se_cmph_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_cmph_r_r(rd, r2)) }
inst_se_cmphl_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_CMPHL, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_cmphl_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_cmphl_r_r(rd, r2)) }
emit_se_cmphl_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_cmphl_r_r(rd, r2)) }
inst_se_srw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_SRW, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_srw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_srw_r_r(rd, r2)) }
emit_se_srw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_srw_r_r(rd, r2)) }
inst_se_sraw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_SRAW, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_sraw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_sraw_r_r(rd, r2)) }
emit_se_sraw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_sraw_r_r(rd, r2)) }
inst_se_slw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_SLW, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_slw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_slw_r_r(rd, r2)) }
emit_se_slw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_slw_r_r(rd, r2)) }
inst_se_or_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_OR, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_or_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_or_r_r(rd, r2)) }
emit_se_or_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_or_r_r(rd, r2)) }
inst_se_andc_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_ANDC, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_andc_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_andc_r_r(rd, r2)) }
emit_se_andc_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_andc_r_r(rd, r2)) }
inst_se_and_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_AND, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_and_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_and_r_r(rd, r2)) }
emit_se_and_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_and_r_r(rd, r2)) }
inst_se_and_dot_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_AND_DOT, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_and_dot_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_and_dot_r_r(rd, r2)) }
emit_se_and_dot_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_and_dot_r_r(rd, r2)) }
inst_se_addi_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_ADDI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_addi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_addi_r_imm(rd, imm)) }
emit_se_addi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_addi_r_imm(rd, imm)) }
inst_se_cmpli_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_CMPLI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_cmpli_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_cmpli_r_imm(rd, imm)) }
emit_se_cmpli_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_cmpli_r_imm(rd, imm)) }
inst_se_subi_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_SUBI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_subi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_subi_r_imm(rd, imm)) }
emit_se_subi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_subi_r_imm(rd, imm)) }
inst_se_subi_dot_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_SUBI_DOT, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_subi_dot_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_subi_dot_r_imm(rd, imm)) }
emit_se_subi_dot_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_subi_dot_r_imm(rd, imm)) }
inst_se_cmpi_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_CMPI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_cmpi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_cmpi_r_imm(rd, imm)) }
emit_se_cmpi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_cmpi_r_imm(rd, imm)) }
inst_se_bmaski_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_BMASKI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_bmaski_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_bmaski_r_imm(rd, imm)) }
emit_se_bmaski_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_bmaski_r_imm(rd, imm)) }
inst_se_andi_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_ANDI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_andi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_andi_r_imm(rd, imm)) }
emit_se_andi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_andi_r_imm(rd, imm)) }
inst_se_nop_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .SE_NOP, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_se_nop_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_se_nop_r_r(rd, r2)) }
emit_se_nop_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_se_nop_r_r(rd, r2)) }
inst_se_li_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_LI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_li_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_li_r_imm(rd, imm)) }
emit_se_li_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_li_r_imm(rd, imm)) }
inst_se_bclri_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_BCLRI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_bclri_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_bclri_r_imm(rd, imm)) }
emit_se_bclri_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_bclri_r_imm(rd, imm)) }
inst_se_bgeni_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_BGENI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_bgeni_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_bgeni_r_imm(rd, imm)) }
emit_se_bgeni_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_bgeni_r_imm(rd, imm)) }
inst_se_bseti_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_BSETI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_bseti_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_bseti_r_imm(rd, imm)) }
emit_se_bseti_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_bseti_r_imm(rd, imm)) }
inst_se_btsti_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_BTSTI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_btsti_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_btsti_r_imm(rd, imm)) }
emit_se_btsti_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_btsti_r_imm(rd, imm)) }
inst_se_srwi_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_SRWI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_srwi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_srwi_r_imm(rd, imm)) }
emit_se_srwi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_srwi_r_imm(rd, imm)) }
inst_se_srawi_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_SRAWI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_srawi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_srawi_r_imm(rd, imm)) }
emit_se_srawi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_srawi_r_imm(rd, imm)) }
inst_se_slwi_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .SE_SLWI, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_se_slwi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_se_slwi_r_imm(rd, imm)) }
emit_se_slwi_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_se_slwi_r_imm(rd, imm)) }
inst_se_lbz_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .SE_LBZ, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_se_lbz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_se_lbz_r_mem(rd, mem)) }
emit_se_lbz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_se_lbz_r_mem(rd, mem)) }
inst_se_stb_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .SE_STB, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_se_stb_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_se_stb_r_mem(rd, mem)) }
emit_se_stb_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_se_stb_r_mem(rd, mem)) }
inst_se_lhz_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .SE_LHZ, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_se_lhz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_se_lhz_r_mem(rd, mem)) }
emit_se_lhz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_se_lhz_r_mem(rd, mem)) }
inst_se_sth_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .SE_STH, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_se_sth_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_se_sth_r_mem(rd, mem)) }
emit_se_sth_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_se_sth_r_mem(rd, mem)) }
inst_se_lwz_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .SE_LWZ, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_se_lwz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_se_lwz_r_mem(rd, mem)) }
emit_se_lwz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_se_lwz_r_mem(rd, mem)) }
inst_se_stw_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .SE_STW, operand_count = 2, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_se_stw_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_se_stw_r_mem(rd, mem)) }
emit_se_stw_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_se_stw_r_mem(rd, mem)) }
inst_se_bge_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BGE, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bge_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bge_rel(target)) }
emit_se_bge_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bge_rel(target)) }
inst_se_bnl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BNL, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bnl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bnl_rel(target)) }
emit_se_bnl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bnl_rel(target)) }
inst_se_ble_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BLE, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_ble_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_ble_rel(target)) }
emit_se_ble_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_ble_rel(target)) }
inst_se_bng_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BNG, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bng_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bng_rel(target)) }
emit_se_bng_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bng_rel(target)) }
inst_se_bne_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BNE, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bne_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bne_rel(target)) }
emit_se_bne_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bne_rel(target)) }
inst_se_bns_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BNS, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bns_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bns_rel(target)) }
emit_se_bns_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bns_rel(target)) }
inst_se_bnu_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BNU, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bnu_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bnu_rel(target)) }
emit_se_bnu_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bnu_rel(target)) }
inst_se_bf_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BF, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bf_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bf_rel(target)) }
emit_se_bf_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bf_rel(target)) }
inst_se_blt_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BLT, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_blt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_blt_rel(target)) }
emit_se_blt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_blt_rel(target)) }
inst_se_bgt_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BGT, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bgt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bgt_rel(target)) }
emit_se_bgt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bgt_rel(target)) }
inst_se_beq_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BEQ, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_beq_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_beq_rel(target)) }
emit_se_beq_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_beq_rel(target)) }
inst_se_bso_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BSO, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bso_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bso_rel(target)) }
emit_se_bso_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bso_rel(target)) }
inst_se_bun_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BUN, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bun_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bun_rel(target)) }
emit_se_bun_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bun_rel(target)) }
inst_se_bt_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BT, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bt_rel(target)) }
emit_se_bt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bt_rel(target)) }
inst_se_bc_bo_crb_rel :: #force_inline proc "contextless" (imm: i64, imm2: i64, target: u32) -> Instruction { return Instruction{mnemonic = .SE_BC, operand_count = 3, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), op_label(target), {}}} }
emit_se_bc_bo_crb_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64, target: u32) { append(instructions, inst_se_bc_bo_crb_rel(imm, imm2, target)) }
emit_se_bc_bo_crb_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64, target: u32) { append_elem(instructions, inst_se_bc_bo_crb_rel(imm, imm2, target)) }
inst_se_b_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_B, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_b_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_b_rel(target)) }
emit_se_b_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_b_rel(target)) }
inst_se_bl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .SE_BL, operand_count = 1, length = 2, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_se_bl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_se_bl_rel(target)) }
emit_se_bl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_se_bl_rel(target)) }
inst_e_lbzu_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LBZU, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lbzu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lbzu_r_r(rd, r2)) }
emit_e_lbzu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lbzu_r_r(rd, r2)) }
inst_e_lhau_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LHAU, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lhau_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lhau_r_r(rd, r2)) }
emit_e_lhau_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lhau_r_r(rd, r2)) }
inst_e_lhzu_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LHZU, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lhzu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lhzu_r_r(rd, r2)) }
emit_e_lhzu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lhzu_r_r(rd, r2)) }
inst_e_lmw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LMW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lmw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lmw_r_r(rd, r2)) }
emit_e_lmw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lmw_r_r(rd, r2)) }
inst_e_lwzu_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LWZU, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lwzu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lwzu_r_r(rd, r2)) }
emit_e_lwzu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lwzu_r_r(rd, r2)) }
inst_e_stbu_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STBU, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stbu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stbu_r_r(rd, r2)) }
emit_e_stbu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stbu_r_r(rd, r2)) }
inst_e_sthu_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STHU, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_sthu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_sthu_r_r(rd, r2)) }
emit_e_sthu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_sthu_r_r(rd, r2)) }
inst_e_stwu_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STWU, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stwu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stwu_r_r(rd, r2)) }
emit_e_stwu_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stwu_r_r(rd, r2)) }
inst_e_stmw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STMW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stmw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stmw_r_r(rd, r2)) }
emit_e_stmw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stmw_r_r(rd, r2)) }
inst_e_lmvgprw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LMVGPRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lmvgprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lmvgprw_r_r(rd, r2)) }
emit_e_lmvgprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lmvgprw_r_r(rd, r2)) }
inst_e_ldmvgprw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LDMVGPRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_ldmvgprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_ldmvgprw_r_r(rd, r2)) }
emit_e_ldmvgprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_ldmvgprw_r_r(rd, r2)) }
inst_e_stmvgprw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STMVGPRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stmvgprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stmvgprw_r_r(rd, r2)) }
emit_e_stmvgprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stmvgprw_r_r(rd, r2)) }
inst_e_lmvsprw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LMVSPRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lmvsprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lmvsprw_r_r(rd, r2)) }
emit_e_lmvsprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lmvsprw_r_r(rd, r2)) }
inst_e_ldmvsprw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LDMVSPRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_ldmvsprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_ldmvsprw_r_r(rd, r2)) }
emit_e_ldmvsprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_ldmvsprw_r_r(rd, r2)) }
inst_e_stmvsprw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STMVSPRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stmvsprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stmvsprw_r_r(rd, r2)) }
emit_e_stmvsprw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stmvsprw_r_r(rd, r2)) }
inst_e_lmvsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LMVSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lmvsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lmvsrrw_r_r(rd, r2)) }
emit_e_lmvsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lmvsrrw_r_r(rd, r2)) }
inst_e_ldmvsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LDMVSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_ldmvsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_ldmvsrrw_r_r(rd, r2)) }
emit_e_ldmvsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_ldmvsrrw_r_r(rd, r2)) }
inst_e_stmvsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STMVSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stmvsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stmvsrrw_r_r(rd, r2)) }
emit_e_stmvsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stmvsrrw_r_r(rd, r2)) }
inst_e_lmvcsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LMVCSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lmvcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lmvcsrrw_r_r(rd, r2)) }
emit_e_lmvcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lmvcsrrw_r_r(rd, r2)) }
inst_e_ldmvcsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LDMVCSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_ldmvcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_ldmvcsrrw_r_r(rd, r2)) }
emit_e_ldmvcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_ldmvcsrrw_r_r(rd, r2)) }
inst_e_stmvcsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STMVCSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stmvcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stmvcsrrw_r_r(rd, r2)) }
emit_e_stmvcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stmvcsrrw_r_r(rd, r2)) }
inst_e_lmvdsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LMVDSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lmvdsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lmvdsrrw_r_r(rd, r2)) }
emit_e_lmvdsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lmvdsrrw_r_r(rd, r2)) }
inst_e_ldmvdsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LDMVDSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_ldmvdsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_ldmvdsrrw_r_r(rd, r2)) }
emit_e_ldmvdsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_ldmvdsrrw_r_r(rd, r2)) }
inst_e_stmvdsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STMVDSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stmvdsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stmvdsrrw_r_r(rd, r2)) }
emit_e_stmvdsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stmvdsrrw_r_r(rd, r2)) }
inst_e_lmvmcsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_LMVMCSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_lmvmcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_lmvmcsrrw_r_r(rd, r2)) }
emit_e_lmvmcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_lmvmcsrrw_r_r(rd, r2)) }
inst_e_stmvmcsrrw_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register) -> Instruction { return Instruction{mnemonic = .E_STMVMCSRRW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), {}, {}}} }
emit_e_stmvmcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append(instructions, inst_e_stmvmcsrrw_r_r(rd, r2)) }
emit_e_stmvmcsrrw_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register) { append_elem(instructions, inst_e_stmvmcsrrw_r_r(rd, r2)) }
inst_e_add16i_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ADD16I, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_add16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_add16i_r_r_imm(rd, r2, imm)) }
emit_e_add16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_add16i_r_r_imm(rd, r2, imm)) }
inst_e_la_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .E_LA, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_e_la_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_e_la_r_mem(rd, mem)) }
emit_e_la_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_e_la_r_mem(rd, mem)) }
inst_e_sub16i_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_SUB16I, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_sub16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_sub16i_r_r_imm(rd, r2, imm)) }
emit_e_sub16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_sub16i_r_r_imm(rd, r2, imm)) }
inst_e_lbz_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .E_LBZ, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_e_lbz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_e_lbz_r_mem(rd, mem)) }
emit_e_lbz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_e_lbz_r_mem(rd, mem)) }
inst_e_stb_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .E_STB, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_e_stb_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_e_stb_r_mem(rd, mem)) }
emit_e_stb_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_e_stb_r_mem(rd, mem)) }
inst_e_lha_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .E_LHA, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_e_lha_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_e_lha_r_mem(rd, mem)) }
emit_e_lha_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_e_lha_r_mem(rd, mem)) }
inst_e_lwz_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .E_LWZ, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_e_lwz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_e_lwz_r_mem(rd, mem)) }
emit_e_lwz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_e_lwz_r_mem(rd, mem)) }
inst_e_stw_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .E_STW, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_e_stw_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_e_stw_r_mem(rd, mem)) }
emit_e_stw_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_e_stw_r_mem(rd, mem)) }
inst_e_lhz_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .E_LHZ, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_e_lhz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_e_lhz_r_mem(rd, mem)) }
emit_e_lhz_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_e_lhz_r_mem(rd, mem)) }
inst_e_sth_r_mem :: #force_inline proc "contextless" (rd: Register, mem: Memory) -> Instruction { return Instruction{mnemonic = .E_STH, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_mem(mem), {}, {}}} }
emit_e_sth_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append(instructions, inst_e_sth_r_mem(rd, mem)) }
emit_e_sth_r_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, mem: Memory) { append_elem(instructions, inst_e_sth_r_mem(rd, mem)) }
inst_e_rlwimi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_RLWIMI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_rlwimi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_rlwimi_r_r_r(rd, r2, r3)) }
emit_e_rlwimi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_rlwimi_r_r_r(rd, r2, r3)) }
inst_e_inslwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_INSLWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_inslwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_inslwi_r_r_r(rd, r2, r3)) }
emit_e_inslwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_inslwi_r_r_r(rd, r2, r3)) }
inst_e_insrwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_INSRWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_insrwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_insrwi_r_r_r(rd, r2, r3)) }
emit_e_insrwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_insrwi_r_r_r(rd, r2, r3)) }
inst_e_rotlwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_ROTLWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_rotlwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_rotlwi_r_r_r(rd, r2, r3)) }
emit_e_rotlwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_rotlwi_r_r_r(rd, r2, r3)) }
inst_e_rotrwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_ROTRWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_rotrwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_rotrwi_r_r_r(rd, r2, r3)) }
emit_e_rotrwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_rotrwi_r_r_r(rd, r2, r3)) }
inst_e_clrlwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_CLRLWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_clrlwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_clrlwi_r_r_r(rd, r2, r3)) }
emit_e_clrlwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_clrlwi_r_r_r(rd, r2, r3)) }
inst_e_clrrwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_CLRRWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_clrrwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_clrrwi_r_r_r(rd, r2, r3)) }
emit_e_clrrwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_clrrwi_r_r_r(rd, r2, r3)) }
inst_e_rlwinm_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_RLWINM, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_rlwinm_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_rlwinm_r_r_r(rd, r2, r3)) }
emit_e_rlwinm_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_rlwinm_r_r_r(rd, r2, r3)) }
inst_e_extlwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_EXTLWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_extlwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_extlwi_r_r_r(rd, r2, r3)) }
emit_e_extlwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_extlwi_r_r_r(rd, r2, r3)) }
inst_e_extrwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_EXTRWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_extrwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_extrwi_r_r_r(rd, r2, r3)) }
emit_e_extrwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_extrwi_r_r_r(rd, r2, r3)) }
inst_e_clrlslwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_CLRLSLWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_clrlslwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_clrlslwi_r_r_r(rd, r2, r3)) }
emit_e_clrlslwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_clrlslwi_r_r_r(rd, r2, r3)) }
inst_e_cmph_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_CMPH, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_cmph_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_cmph_r_r_r(rd, r2, r3)) }
emit_e_cmph_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_cmph_r_r_r(rd, r2, r3)) }
inst_e_sc_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_SC, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_sc_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_sc_r_r_r(rd, r2, r3)) }
emit_e_sc_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_sc_r_r_r(rd, r2, r3)) }
inst_e_cmphl_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_CMPHL, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_cmphl_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_cmphl_r_r_r(rd, r2, r3)) }
emit_e_cmphl_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_cmphl_r_r_r(rd, r2, r3)) }
inst_e_crandc_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRANDC, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crandc_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crandc_bo_crb(imm, imm2)) }
emit_e_crandc_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crandc_bo_crb(imm, imm2)) }
inst_e_crnand_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRNAND, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crnand_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crnand_bo_crb(imm, imm2)) }
emit_e_crnand_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crnand_bo_crb(imm, imm2)) }
inst_e_crnot_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRNOT, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crnot_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crnot_bo_crb(imm, imm2)) }
emit_e_crnot_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crnot_bo_crb(imm, imm2)) }
inst_e_crnor_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRNOR, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crnor_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crnor_bo_crb(imm, imm2)) }
emit_e_crnor_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crnor_bo_crb(imm, imm2)) }
inst_e_crclr_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRCLR, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crclr_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crclr_bo_crb(imm, imm2)) }
emit_e_crclr_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crclr_bo_crb(imm, imm2)) }
inst_e_crxor_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRXOR, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crxor_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crxor_bo_crb(imm, imm2)) }
emit_e_crxor_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crxor_bo_crb(imm, imm2)) }
inst_e_mcrf_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_MCRF, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_mcrf_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_mcrf_bo_crb(imm, imm2)) }
emit_e_mcrf_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_mcrf_bo_crb(imm, imm2)) }
inst_e_slwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_SLWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_slwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_slwi_r_r_r(rd, r2, r3)) }
emit_e_slwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_slwi_r_r_r(rd, r2, r3)) }
inst_e_slwi_dot_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_SLWI_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_slwi_dot_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_slwi_dot_r_r_r(rd, r2, r3)) }
emit_e_slwi_dot_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_slwi_dot_r_r_r(rd, r2, r3)) }
inst_e_crand_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRAND, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crand_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crand_bo_crb(imm, imm2)) }
emit_e_crand_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crand_bo_crb(imm, imm2)) }
inst_e_rlw_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_RLW, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_rlw_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_rlw_r_r_r(rd, r2, r3)) }
emit_e_rlw_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_rlw_r_r_r(rd, r2, r3)) }
inst_e_rlw_dot_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_RLW_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_rlw_dot_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_rlw_dot_r_r_r(rd, r2, r3)) }
emit_e_rlw_dot_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_rlw_dot_r_r_r(rd, r2, r3)) }
inst_e_crset_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRSET, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crset_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crset_bo_crb(imm, imm2)) }
emit_e_crset_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crset_bo_crb(imm, imm2)) }
inst_e_creqv_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CREQV, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_creqv_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_creqv_bo_crb(imm, imm2)) }
emit_e_creqv_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_creqv_bo_crb(imm, imm2)) }
inst_e_rlwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_RLWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_rlwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_rlwi_r_r_r(rd, r2, r3)) }
emit_e_rlwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_rlwi_r_r_r(rd, r2, r3)) }
inst_e_rlwi_dot_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_RLWI_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_rlwi_dot_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_rlwi_dot_r_r_r(rd, r2, r3)) }
emit_e_rlwi_dot_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_rlwi_dot_r_r_r(rd, r2, r3)) }
inst_e_crorc_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRORC, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crorc_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crorc_bo_crb(imm, imm2)) }
emit_e_crorc_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crorc_bo_crb(imm, imm2)) }
inst_e_crmove_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CRMOVE, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_crmove_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_crmove_bo_crb(imm, imm2)) }
emit_e_crmove_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_crmove_bo_crb(imm, imm2)) }
inst_e_cror_bo_crb :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .E_CROR, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), {}, {}}} }
emit_e_cror_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_e_cror_bo_crb(imm, imm2)) }
emit_e_cror_bo_crb :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_e_cror_bo_crb(imm, imm2)) }
inst_e_srwi_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_SRWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_srwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_srwi_r_r_r(rd, r2, r3)) }
emit_e_srwi_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_srwi_r_r_r(rd, r2, r3)) }
inst_e_srwi_dot_r_r_r :: #force_inline proc "contextless" (rd: Register, r2: Register, r3: Register) -> Instruction { return Instruction{mnemonic = .E_SRWI_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_reg(r3), {}}} }
emit_e_srwi_dot_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append(instructions, inst_e_srwi_dot_r_r_r(rd, r2, r3)) }
emit_e_srwi_dot_r_r_r :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, r3: Register) { append_elem(instructions, inst_e_srwi_dot_r_r_r(rd, r2, r3)) }
inst_e_bdnz_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BDNZ, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bdnz_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bdnz_rel(target)) }
emit_e_bdnz_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bdnz_rel(target)) }
inst_e_bdnzl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BDNZL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bdnzl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bdnzl_rel(target)) }
emit_e_bdnzl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bdnzl_rel(target)) }
inst_e_bdz_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BDZ, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bdz_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bdz_rel(target)) }
emit_e_bdz_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bdz_rel(target)) }
inst_e_bdzl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BDZL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bdzl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bdzl_rel(target)) }
emit_e_bdzl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bdzl_rel(target)) }
inst_e_cmpi_crf_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_CMPI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_cmpi_crf_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_cmpi_crf_r_imm(rd, r2, imm)) }
emit_e_cmpi_crf_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_cmpi_crf_r_imm(rd, r2, imm)) }
inst_e_cmpwi_crf_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_CMPWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_cmpwi_crf_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_cmpwi_crf_r_imm(rd, r2, imm)) }
emit_e_cmpwi_crf_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_cmpwi_crf_r_imm(rd, r2, imm)) }
inst_e_cmpli_crf_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_CMPLI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_cmpli_crf_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_cmpli_crf_r_imm(rd, r2, imm)) }
emit_e_cmpli_crf_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_cmpli_crf_r_imm(rd, r2, imm)) }
inst_e_cmplwi_crf_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_CMPLWI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_cmplwi_crf_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_cmplwi_crf_r_imm(rd, r2, imm)) }
emit_e_cmplwi_crf_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_cmplwi_crf_r_imm(rd, r2, imm)) }
inst_e_addi_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ADDI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_addi_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_addi_r_r_imm(rd, r2, imm)) }
emit_e_addi_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_addi_r_r_imm(rd, r2, imm)) }
inst_e_subi_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_SUBI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_subi_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_subi_r_r_imm(rd, r2, imm)) }
emit_e_subi_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_subi_r_r_imm(rd, r2, imm)) }
inst_e_addi_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ADDI_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_addi_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_addi_dot_r_r_imm(rd, r2, imm)) }
emit_e_addi_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_addi_dot_r_r_imm(rd, r2, imm)) }
inst_e_addic_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ADDIC, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_addic_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_addic_r_r_imm(rd, r2, imm)) }
emit_e_addic_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_addic_r_r_imm(rd, r2, imm)) }
inst_e_subic_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_SUBIC, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_subic_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_subic_r_r_imm(rd, r2, imm)) }
emit_e_subic_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_subic_r_r_imm(rd, r2, imm)) }
inst_e_addic_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ADDIC_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_addic_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_addic_dot_r_r_imm(rd, r2, imm)) }
emit_e_addic_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_addic_dot_r_r_imm(rd, r2, imm)) }
inst_e_subic_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_SUBIC_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_subic_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_subic_dot_r_r_imm(rd, r2, imm)) }
emit_e_subic_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_subic_dot_r_r_imm(rd, r2, imm)) }
inst_e_mulli_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_MULLI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_mulli_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_mulli_r_r_imm(rd, r2, imm)) }
emit_e_mulli_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_mulli_r_r_imm(rd, r2, imm)) }
inst_e_subfic_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_SUBFIC, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_subfic_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_subfic_r_r_imm(rd, r2, imm)) }
emit_e_subfic_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_subfic_r_r_imm(rd, r2, imm)) }
inst_e_subfic_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_SUBFIC_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_subfic_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_subfic_dot_r_r_imm(rd, r2, imm)) }
emit_e_subfic_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_subfic_dot_r_r_imm(rd, r2, imm)) }
inst_e_andi_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ANDI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_andi_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_andi_r_r_imm(rd, r2, imm)) }
emit_e_andi_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_andi_r_r_imm(rd, r2, imm)) }
inst_e_andi_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ANDI_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_andi_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_andi_dot_r_r_imm(rd, r2, imm)) }
emit_e_andi_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_andi_dot_r_r_imm(rd, r2, imm)) }
inst_e_nop_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_NOP, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_nop_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_nop_r_r_imm(rd, r2, imm)) }
emit_e_nop_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_nop_r_r_imm(rd, r2, imm)) }
inst_e_ori_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ORI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_ori_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_ori_r_r_imm(rd, r2, imm)) }
emit_e_ori_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_ori_r_r_imm(rd, r2, imm)) }
inst_e_ori_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ORI_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_ori_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_ori_dot_r_r_imm(rd, r2, imm)) }
emit_e_ori_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_ori_dot_r_r_imm(rd, r2, imm)) }
inst_e_xori_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_XORI, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_xori_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_xori_r_r_imm(rd, r2, imm)) }
emit_e_xori_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_xori_r_r_imm(rd, r2, imm)) }
inst_e_xori_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_XORI_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_xori_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_xori_dot_r_r_imm(rd, r2, imm)) }
emit_e_xori_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_xori_dot_r_r_imm(rd, r2, imm)) }
inst_e_lis_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_LIS, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_e_lis_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_e_lis_r_imm(rd, imm)) }
emit_e_lis_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_e_lis_r_imm(rd, imm)) }
inst_e_and2is_dot_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_AND2IS_DOT, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_e_and2is_dot_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_e_and2is_dot_r_imm(rd, imm)) }
emit_e_and2is_dot_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_e_and2is_dot_r_imm(rd, imm)) }
inst_e_or2is_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_OR2IS, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_e_or2is_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_e_or2is_r_imm(rd, imm)) }
emit_e_or2is_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_e_or2is_r_imm(rd, imm)) }
inst_e_and2i_dot_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_AND2I_DOT, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_e_and2i_dot_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_e_and2i_dot_r_imm(rd, imm)) }
emit_e_and2i_dot_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_e_and2i_dot_r_imm(rd, imm)) }
inst_e_or2i_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_OR2I, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_e_or2i_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_e_or2i_r_imm(rd, imm)) }
emit_e_or2i_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_e_or2i_r_imm(rd, imm)) }
inst_e_cmphl16i_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_CMPHL16I, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_cmphl16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_cmphl16i_r_r_imm(rd, r2, imm)) }
emit_e_cmphl16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_cmphl16i_r_r_imm(rd, r2, imm)) }
inst_e_cmph16i_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_CMPH16I, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_cmph16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_cmph16i_r_r_imm(rd, r2, imm)) }
emit_e_cmph16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_cmph16i_r_r_imm(rd, r2, imm)) }
inst_e_cmpl16i_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_CMPL16I, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_cmpl16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_cmpl16i_r_r_imm(rd, r2, imm)) }
emit_e_cmpl16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_cmpl16i_r_r_imm(rd, r2, imm)) }
inst_e_mull2i_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_MULL2I, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_mull2i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_mull2i_r_r_imm(rd, r2, imm)) }
emit_e_mull2i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_mull2i_r_r_imm(rd, r2, imm)) }
inst_e_cmp16i_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_CMP16I, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_cmp16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_cmp16i_r_r_imm(rd, r2, imm)) }
emit_e_cmp16i_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_cmp16i_r_r_imm(rd, r2, imm)) }
inst_e_sub2is_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_SUB2IS, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_sub2is_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_sub2is_r_r_imm(rd, r2, imm)) }
emit_e_sub2is_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_sub2is_r_r_imm(rd, r2, imm)) }
inst_e_add2is_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ADD2IS, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_add2is_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_add2is_r_r_imm(rd, r2, imm)) }
emit_e_add2is_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_add2is_r_r_imm(rd, r2, imm)) }
inst_e_sub2i_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_SUB2I_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_sub2i_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_sub2i_dot_r_r_imm(rd, r2, imm)) }
emit_e_sub2i_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_sub2i_dot_r_r_imm(rd, r2, imm)) }
inst_e_add2i_dot_r_r_imm :: #force_inline proc "contextless" (rd: Register, r2: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_ADD2I_DOT, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_reg(r2), op_imm(imm), {}}} }
emit_e_add2i_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append(instructions, inst_e_add2i_dot_r_r_imm(rd, r2, imm)) }
emit_e_add2i_dot_r_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, r2: Register, imm: i64) { append_elem(instructions, inst_e_add2i_dot_r_r_imm(rd, r2, imm)) }
inst_e_li_r_imm :: #force_inline proc "contextless" (rd: Register, imm: i64) -> Instruction { return Instruction{mnemonic = .E_LI, operand_count = 2, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_reg(rd), op_imm(imm), {}, {}}} }
emit_e_li_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append(instructions, inst_e_li_r_imm(rd, imm)) }
emit_e_li_r_imm :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: Register, imm: i64) { append_elem(instructions, inst_e_li_r_imm(rd, imm)) }
inst_e_b_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_B, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_b_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_b_rel(target)) }
emit_e_b_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_b_rel(target)) }
inst_e_bl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bl_rel(target)) }
emit_e_bl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bl_rel(target)) }
inst_e_bge_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BGE, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bge_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bge_rel(target)) }
emit_e_bge_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bge_rel(target)) }
inst_e_bgel_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BGEL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bgel_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bgel_rel(target)) }
emit_e_bgel_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bgel_rel(target)) }
inst_e_bnl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bnl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bnl_rel(target)) }
emit_e_bnl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bnl_rel(target)) }
inst_e_bnll_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNLL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bnll_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bnll_rel(target)) }
emit_e_bnll_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bnll_rel(target)) }
inst_e_blt_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BLT, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_blt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_blt_rel(target)) }
emit_e_blt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_blt_rel(target)) }
inst_e_bltl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BLTL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bltl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bltl_rel(target)) }
emit_e_bltl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bltl_rel(target)) }
inst_e_bgt_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BGT, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bgt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bgt_rel(target)) }
emit_e_bgt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bgt_rel(target)) }
inst_e_bgtl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BGTL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bgtl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bgtl_rel(target)) }
emit_e_bgtl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bgtl_rel(target)) }
inst_e_ble_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BLE, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_ble_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_ble_rel(target)) }
emit_e_ble_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_ble_rel(target)) }
inst_e_blel_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BLEL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_blel_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_blel_rel(target)) }
emit_e_blel_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_blel_rel(target)) }
inst_e_bng_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNG, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bng_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bng_rel(target)) }
emit_e_bng_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bng_rel(target)) }
inst_e_bngl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNGL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bngl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bngl_rel(target)) }
emit_e_bngl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bngl_rel(target)) }
inst_e_bne_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNE, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bne_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bne_rel(target)) }
emit_e_bne_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bne_rel(target)) }
inst_e_bnel_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNEL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bnel_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bnel_rel(target)) }
emit_e_bnel_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bnel_rel(target)) }
inst_e_beq_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BEQ, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_beq_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_beq_rel(target)) }
emit_e_beq_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_beq_rel(target)) }
inst_e_beql_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BEQL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_beql_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_beql_rel(target)) }
emit_e_beql_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_beql_rel(target)) }
inst_e_bso_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BSO, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bso_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bso_rel(target)) }
emit_e_bso_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bso_rel(target)) }
inst_e_bsol_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BSOL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bsol_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bsol_rel(target)) }
emit_e_bsol_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bsol_rel(target)) }
inst_e_bun_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BUN, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bun_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bun_rel(target)) }
emit_e_bun_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bun_rel(target)) }
inst_e_bunl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BUNL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bunl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bunl_rel(target)) }
emit_e_bunl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bunl_rel(target)) }
inst_e_bns_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNS, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bns_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bns_rel(target)) }
emit_e_bns_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bns_rel(target)) }
inst_e_bnsl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNSL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bnsl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bnsl_rel(target)) }
emit_e_bnsl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bnsl_rel(target)) }
inst_e_bnu_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNU, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bnu_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bnu_rel(target)) }
emit_e_bnu_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bnu_rel(target)) }
inst_e_bnul_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BNUL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bnul_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bnul_rel(target)) }
emit_e_bnul_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bnul_rel(target)) }
inst_e_bc_bo_crb_rel :: #force_inline proc "contextless" (imm: i64, imm2: i64, target: u32) -> Instruction { return Instruction{mnemonic = .E_BC, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), op_label(target), {}}} }
emit_e_bc_bo_crb_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64, target: u32) { append(instructions, inst_e_bc_bo_crb_rel(imm, imm2, target)) }
emit_e_bc_bo_crb_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64, target: u32) { append_elem(instructions, inst_e_bc_bo_crb_rel(imm, imm2, target)) }
inst_e_bcl_bo_crb_rel :: #force_inline proc "contextless" (imm: i64, imm2: i64, target: u32) -> Instruction { return Instruction{mnemonic = .E_BCL, operand_count = 3, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_imm(imm), op_imm(imm2), op_label(target), {}}} }
emit_e_bcl_bo_crb_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64, target: u32) { append(instructions, inst_e_bcl_bo_crb_rel(imm, imm2, target)) }
emit_e_bcl_bo_crb_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64, target: u32) { append_elem(instructions, inst_e_bcl_bo_crb_rel(imm, imm2, target)) }
inst_e_bf_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BF, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bf_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bf_rel(target)) }
emit_e_bf_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bf_rel(target)) }
inst_e_bfl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BFL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bfl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bfl_rel(target)) }
emit_e_bfl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bfl_rel(target)) }
inst_e_bt_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BT, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_bt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_bt_rel(target)) }
emit_e_bt_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_bt_rel(target)) }
inst_e_btl_rel :: #force_inline proc "contextless" (target: u32) -> Instruction { return Instruction{mnemonic = .E_BTL, operand_count = 1, length = 4, mode = .PPC32_VLE, form_id = 1, ops = {op_label(target), {}, {}, {}}} }
emit_e_btl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append(instructions, inst_e_btl_rel(target)) }
emit_e_btl_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, target: u32) { append_elem(instructions, inst_e_btl_rel(target)) }
// =============================================================================
// Overload Groups
@@ -420,7 +420,7 @@ generate_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, max_name_pad
strings.write_string(sb, ": ")
strings.write_string(sb, operand_odin_type(entry.sig.types[i]))
}
strings.write_string(sb, ") { append(instructions, ")
strings.write_string(sb, ") { append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_string(sb, "(")
for i in 0..<entry.sig.count {
+542 -194
View File
@@ -21,393 +21,567 @@ package rexcode_riscv
// =============================================================================
inst_lui_gpr_imm20 :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .LUI, operand_count = 2, length = 4, ops = {op_gpr(rd), op_imm(imm, 4), {}, {}}} }
emit_lui_gpr_imm20 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_lui_gpr_imm20(rd, imm)) }
emit_lui_gpr_imm20 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_lui_gpr_imm20(rd, imm)) }
inst_auipc_gpr_imm20 :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .AUIPC, operand_count = 2, length = 4, ops = {op_gpr(rd), op_imm(imm, 4), {}, {}}} }
emit_auipc_gpr_imm20 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_auipc_gpr_imm20(rd, imm)) }
emit_auipc_gpr_imm20 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_auipc_gpr_imm20(rd, imm)) }
inst_jal_gpr_label :: #force_inline proc "contextless" (rd: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .JAL, operand_count = 2, length = 4, ops = {op_gpr(rd), op_label(label, 4), {}, {}}} }
emit_jal_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, label: u32) { append(instructions, inst_jal_gpr_label(rd, label)) }
emit_jal_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, label: u32) { append_elem(instructions, inst_jal_gpr_label(rd, label)) }
inst_jalr_gpr_gpr_imm12 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .JALR, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_jalr_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_jalr_gpr_gpr_imm12(rd, rs1, imm)) }
emit_jalr_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_jalr_gpr_gpr_imm12(rd, rs1, imm)) }
inst_beq_gpr_gpr_label :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .BEQ, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_label(label, 2), {}}} }
emit_beq_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append(instructions, inst_beq_gpr_gpr_label(rd, rs1, label)) }
emit_beq_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append_elem(instructions, inst_beq_gpr_gpr_label(rd, rs1, label)) }
inst_bne_gpr_gpr_label :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .BNE, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_label(label, 2), {}}} }
emit_bne_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append(instructions, inst_bne_gpr_gpr_label(rd, rs1, label)) }
emit_bne_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append_elem(instructions, inst_bne_gpr_gpr_label(rd, rs1, label)) }
inst_blt_gpr_gpr_label :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .BLT, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_label(label, 2), {}}} }
emit_blt_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append(instructions, inst_blt_gpr_gpr_label(rd, rs1, label)) }
emit_blt_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append_elem(instructions, inst_blt_gpr_gpr_label(rd, rs1, label)) }
inst_bge_gpr_gpr_label :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .BGE, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_label(label, 2), {}}} }
emit_bge_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append(instructions, inst_bge_gpr_gpr_label(rd, rs1, label)) }
emit_bge_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append_elem(instructions, inst_bge_gpr_gpr_label(rd, rs1, label)) }
inst_bltu_gpr_gpr_label :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .BLTU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_label(label, 2), {}}} }
emit_bltu_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append(instructions, inst_bltu_gpr_gpr_label(rd, rs1, label)) }
emit_bltu_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append_elem(instructions, inst_bltu_gpr_gpr_label(rd, rs1, label)) }
inst_bgeu_gpr_gpr_label :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .BGEU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_label(label, 2), {}}} }
emit_bgeu_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append(instructions, inst_bgeu_gpr_gpr_label(rd, rs1, label)) }
emit_bgeu_gpr_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, label: u32) { append_elem(instructions, inst_bgeu_gpr_gpr_label(rd, rs1, label)) }
inst_lb_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LB, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_lb_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_lb_gpr_mem(rd, mem)) }
emit_lb_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_lb_gpr_mem(rd, mem)) }
inst_lh_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LH, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_lh_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_lh_gpr_mem(rd, mem)) }
emit_lh_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_lh_gpr_mem(rd, mem)) }
inst_lw_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LW, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_lw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_lw_gpr_mem(rd, mem)) }
emit_lw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_lw_gpr_mem(rd, mem)) }
inst_lbu_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LBU, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_lbu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_lbu_gpr_mem(rd, mem)) }
emit_lbu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_lbu_gpr_mem(rd, mem)) }
inst_lhu_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LHU, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_lhu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_lhu_gpr_mem(rd, mem)) }
emit_lhu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_lhu_gpr_mem(rd, mem)) }
inst_sb_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .SB, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_sb_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_sb_gpr_mem(rd, mem)) }
emit_sb_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_sb_gpr_mem(rd, mem)) }
inst_sh_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .SH, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_sh_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_sh_gpr_mem(rd, mem)) }
emit_sh_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_sh_gpr_mem(rd, mem)) }
inst_sw_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .SW, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_sw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_sw_gpr_mem(rd, mem)) }
emit_sw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_sw_gpr_mem(rd, mem)) }
inst_lwu_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LWU, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_lwu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_lwu_gpr_mem(rd, mem)) }
emit_lwu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_lwu_gpr_mem(rd, mem)) }
inst_ld_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LD, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_ld_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_ld_gpr_mem(rd, mem)) }
emit_ld_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_ld_gpr_mem(rd, mem)) }
inst_sd_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .SD, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_sd_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_sd_gpr_mem(rd, mem)) }
emit_sd_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_sd_gpr_mem(rd, mem)) }
inst_addi_gpr_gpr_imm12 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .ADDI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_addi_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_addi_gpr_gpr_imm12(rd, rs1, imm)) }
emit_addi_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_addi_gpr_gpr_imm12(rd, rs1, imm)) }
inst_slti_gpr_gpr_imm12 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SLTI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_slti_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_slti_gpr_gpr_imm12(rd, rs1, imm)) }
emit_slti_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_slti_gpr_gpr_imm12(rd, rs1, imm)) }
inst_sltiu_gpr_gpr_imm12 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SLTIU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_sltiu_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_sltiu_gpr_gpr_imm12(rd, rs1, imm)) }
emit_sltiu_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_sltiu_gpr_gpr_imm12(rd, rs1, imm)) }
inst_xori_gpr_gpr_imm12 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .XORI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_xori_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_xori_gpr_gpr_imm12(rd, rs1, imm)) }
emit_xori_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_xori_gpr_gpr_imm12(rd, rs1, imm)) }
inst_ori_gpr_gpr_imm12 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .ORI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_ori_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_ori_gpr_gpr_imm12(rd, rs1, imm)) }
emit_ori_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_ori_gpr_gpr_imm12(rd, rs1, imm)) }
inst_andi_gpr_gpr_imm12 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .ANDI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_andi_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_andi_gpr_gpr_imm12(rd, rs1, imm)) }
emit_andi_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_andi_gpr_gpr_imm12(rd, rs1, imm)) }
inst_slli_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SLLI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_slli_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_slli_gpr_gpr_imm6(rd, rs1, imm)) }
emit_slli_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_slli_gpr_gpr_imm6(rd, rs1, imm)) }
inst_srli_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SRLI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_srli_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_srli_gpr_gpr_imm6(rd, rs1, imm)) }
emit_srli_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_srli_gpr_gpr_imm6(rd, rs1, imm)) }
inst_srai_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SRAI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_srai_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_srai_gpr_gpr_imm6(rd, rs1, imm)) }
emit_srai_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_srai_gpr_gpr_imm6(rd, rs1, imm)) }
inst_addiw_gpr_gpr_imm12 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .ADDIW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_addiw_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_addiw_gpr_gpr_imm12(rd, rs1, imm)) }
emit_addiw_gpr_gpr_imm12 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_addiw_gpr_gpr_imm12(rd, rs1, imm)) }
inst_slliw_gpr_gpr_imm5 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SLLIW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_slliw_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_slliw_gpr_gpr_imm5(rd, rs1, imm)) }
emit_slliw_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_slliw_gpr_gpr_imm5(rd, rs1, imm)) }
inst_srliw_gpr_gpr_imm5 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SRLIW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_srliw_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_srliw_gpr_gpr_imm5(rd, rs1, imm)) }
emit_srliw_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_srliw_gpr_gpr_imm5(rd, rs1, imm)) }
inst_sraiw_gpr_gpr_imm5 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SRAIW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_sraiw_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_sraiw_gpr_gpr_imm5(rd, rs1, imm)) }
emit_sraiw_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_sraiw_gpr_gpr_imm5(rd, rs1, imm)) }
inst_add_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .ADD, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_add_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_add_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_add_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_add_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sub_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SUB, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sub_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_sub_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_sub_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sub_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sll_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SLL, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sll_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_sll_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_sll_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sll_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_slt_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SLT, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_slt_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_slt_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_slt_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_slt_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sltu_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SLTU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sltu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_sltu_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_sltu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sltu_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_xor_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .XOR, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_xor_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_xor_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_xor_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_xor_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_srl_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SRL, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_srl_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_srl_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_srl_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_srl_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sra_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SRA, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sra_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_sra_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_sra_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sra_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_or_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .OR, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_or_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_or_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_or_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_or_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_and_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .AND, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_and_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_and_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_and_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_and_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_addw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .ADDW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_addw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_addw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_addw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_addw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_subw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SUBW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_subw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_subw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_subw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_subw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sllw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SLLW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sllw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_sllw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_sllw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sllw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_srlw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SRLW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_srlw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_srlw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_srlw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_srlw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sraw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SRAW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sraw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_sraw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_sraw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sraw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_fence_fence_fence :: #force_inline proc "contextless" (imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .FENCE, operand_count = 2, length = 4, ops = {op_imm(imm, 1), op_imm(imm2, 1), {}, {}}} }
emit_fence_fence_fence :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append(instructions, inst_fence_fence_fence(imm, imm2)) }
emit_fence_fence_fence :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64, imm2: i64) { append_elem(instructions, inst_fence_fence_fence(imm, imm2)) }
inst_fence_i_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.FENCE_I) }
emit_fence_i_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_fence_i_none()) }
emit_fence_i_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_fence_i_none()) }
inst_ecall_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.ECALL) }
emit_ecall_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_ecall_none()) }
emit_ecall_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_ecall_none()) }
inst_ebreak_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.EBREAK) }
emit_ebreak_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_ebreak_none()) }
emit_ebreak_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_ebreak_none()) }
inst_csrrw_gpr_csr_gpr :: #force_inline proc "contextless" (rd: GPR, imm: i64, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CSRRW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_imm(imm, 2), op_gpr(rs1), {}}} }
emit_csrrw_gpr_csr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, rs1: GPR) { append(instructions, inst_csrrw_gpr_csr_gpr(rd, imm, rs1)) }
emit_csrrw_gpr_csr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, rs1: GPR) { append_elem(instructions, inst_csrrw_gpr_csr_gpr(rd, imm, rs1)) }
inst_csrrs_gpr_csr_gpr :: #force_inline proc "contextless" (rd: GPR, imm: i64, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CSRRS, operand_count = 3, length = 4, ops = {op_gpr(rd), op_imm(imm, 2), op_gpr(rs1), {}}} }
emit_csrrs_gpr_csr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, rs1: GPR) { append(instructions, inst_csrrs_gpr_csr_gpr(rd, imm, rs1)) }
emit_csrrs_gpr_csr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, rs1: GPR) { append_elem(instructions, inst_csrrs_gpr_csr_gpr(rd, imm, rs1)) }
inst_csrrc_gpr_csr_gpr :: #force_inline proc "contextless" (rd: GPR, imm: i64, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CSRRC, operand_count = 3, length = 4, ops = {op_gpr(rd), op_imm(imm, 2), op_gpr(rs1), {}}} }
emit_csrrc_gpr_csr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, rs1: GPR) { append(instructions, inst_csrrc_gpr_csr_gpr(rd, imm, rs1)) }
emit_csrrc_gpr_csr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, rs1: GPR) { append_elem(instructions, inst_csrrc_gpr_csr_gpr(rd, imm, rs1)) }
inst_csrrwi_gpr_csr_zimm5 :: #force_inline proc "contextless" (rd: GPR, imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .CSRRWI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_imm(imm, 2), op_imm(imm2, 1), {}}} }
emit_csrrwi_gpr_csr_zimm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, imm2: i64) { append(instructions, inst_csrrwi_gpr_csr_zimm5(rd, imm, imm2)) }
emit_csrrwi_gpr_csr_zimm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, imm2: i64) { append_elem(instructions, inst_csrrwi_gpr_csr_zimm5(rd, imm, imm2)) }
inst_csrrsi_gpr_csr_zimm5 :: #force_inline proc "contextless" (rd: GPR, imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .CSRRSI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_imm(imm, 2), op_imm(imm2, 1), {}}} }
emit_csrrsi_gpr_csr_zimm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, imm2: i64) { append(instructions, inst_csrrsi_gpr_csr_zimm5(rd, imm, imm2)) }
emit_csrrsi_gpr_csr_zimm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, imm2: i64) { append_elem(instructions, inst_csrrsi_gpr_csr_zimm5(rd, imm, imm2)) }
inst_csrrci_gpr_csr_zimm5 :: #force_inline proc "contextless" (rd: GPR, imm: i64, imm2: i64) -> Instruction { return Instruction{mnemonic = .CSRRCI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_imm(imm, 2), op_imm(imm2, 1), {}}} }
emit_csrrci_gpr_csr_zimm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, imm2: i64) { append(instructions, inst_csrrci_gpr_csr_zimm5(rd, imm, imm2)) }
emit_csrrci_gpr_csr_zimm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64, imm2: i64) { append_elem(instructions, inst_csrrci_gpr_csr_zimm5(rd, imm, imm2)) }
inst_mul_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MUL, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_mul_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_mul_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_mul_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_mul_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_mulh_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MULH, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_mulh_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_mulh_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_mulh_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_mulh_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_mulhsu_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MULHSU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_mulhsu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_mulhsu_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_mulhsu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_mulhsu_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_mulhu_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MULHU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_mulhu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_mulhu_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_mulhu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_mulhu_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_div_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .DIV, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_div_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_div_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_div_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_div_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_divu_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .DIVU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_divu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_divu_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_divu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_divu_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_rem_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .REM, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_rem_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_rem_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_rem_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_rem_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_remu_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .REMU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_remu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_remu_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_remu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_remu_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_mulw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MULW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_mulw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_mulw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_mulw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_mulw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_divw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .DIVW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_divw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_divw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_divw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_divw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_divuw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .DIVUW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_divuw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_divuw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_divuw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_divuw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_remw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .REMW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_remw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_remw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_remw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_remw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_remuw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .REMUW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_remuw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append(instructions, inst_remuw_gpr_gpr_gpr(rd, rs1, rs2)) }
emit_remuw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_remuw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_lr_w_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LR_W, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_lr_w_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_lr_w_gpr_mem(rd, mem)) }
emit_lr_w_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_lr_w_gpr_mem(rd, mem)) }
inst_sc_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .SC_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_sc_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_sc_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_sc_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_sc_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoswap_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOSWAP_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoswap_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoswap_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoswap_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoswap_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoadd_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOADD_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoadd_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoadd_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoadd_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoadd_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoxor_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOXOR_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoxor_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoxor_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoxor_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoxor_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoand_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOAND_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoand_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoand_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoand_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoand_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoor_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOOR_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoor_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoor_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoor_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoor_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amomin_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOMIN_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amomin_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amomin_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amomin_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amomin_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amomax_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOMAX_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amomax_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amomax_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amomax_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amomax_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amominu_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOMINU_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amominu_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amominu_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amominu_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amominu_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_amomaxu_w_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOMAXU_W, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amomaxu_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amomaxu_w_gpr_gpr_mem(rd, rs1, mem)) }
emit_amomaxu_w_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amomaxu_w_gpr_gpr_mem(rd, rs1, mem)) }
inst_lr_d_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .LR_D, operand_count = 2, length = 4, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_lr_d_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_lr_d_gpr_mem(rd, mem)) }
emit_lr_d_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_lr_d_gpr_mem(rd, mem)) }
inst_sc_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .SC_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_sc_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_sc_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_sc_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_sc_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoswap_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOSWAP_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoswap_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoswap_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoswap_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoswap_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoadd_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOADD_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoadd_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoadd_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoadd_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoadd_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoxor_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOXOR_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoxor_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoxor_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoxor_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoxor_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoand_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOAND_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoand_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoand_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoand_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoand_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amoor_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOOR_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amoor_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amoor_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amoor_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amoor_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amomin_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOMIN_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amomin_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amomin_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amomin_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amomin_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amomax_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOMAX_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amomax_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amomax_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amomax_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amomax_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amominu_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOMINU_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amominu_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amominu_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amominu_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amominu_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_amomaxu_d_gpr_gpr_mem :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .AMOMAXU_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_mem(mem), {}}} }
emit_amomaxu_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append(instructions, inst_amomaxu_d_gpr_gpr_mem(rd, rs1, mem)) }
emit_amomaxu_d_gpr_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, mem: Memory) { append_elem(instructions, inst_amomaxu_d_gpr_gpr_mem(rd, rs1, mem)) }
inst_flw_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .FLW, operand_count = 2, length = 4, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_flw_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append(instructions, inst_flw_fpr_mem(rd, mem)) }
emit_flw_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_flw_fpr_mem(rd, mem)) }
inst_fsw_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .FSW, operand_count = 2, length = 4, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_fsw_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append(instructions, inst_fsw_fpr_mem(rd, mem)) }
emit_fsw_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_fsw_fpr_mem(rd, mem)) }
inst_fmadd_s_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FMADD_S, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fmadd_s_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append(instructions, inst_fmadd_s_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
emit_fmadd_s_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fmadd_s_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fmsub_s_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FMSUB_S, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fmsub_s_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append(instructions, inst_fmsub_s_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
emit_fmsub_s_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fmsub_s_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fnmsub_s_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FNMSUB_S, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fnmsub_s_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append(instructions, inst_fnmsub_s_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
emit_fnmsub_s_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fnmsub_s_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fnmadd_s_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FNMADD_S, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fnmadd_s_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append(instructions, inst_fnmadd_s_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
emit_fnmadd_s_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fnmadd_s_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fadd_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FADD_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fadd_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fadd_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fadd_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fadd_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsub_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSUB_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsub_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fsub_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fsub_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsub_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmul_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMUL_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmul_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fmul_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fmul_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmul_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fdiv_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FDIV_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fdiv_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fdiv_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fdiv_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fdiv_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsqrt_s_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FSQRT_S, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fsqrt_s_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append(instructions, inst_fsqrt_s_fpr_fpr(rd, rs1)) }
emit_fsqrt_s_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fsqrt_s_fpr_fpr(rd, rs1)) }
inst_fsgnj_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJ_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnj_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fsgnj_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fsgnj_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnj_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsgnjn_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJN_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnjn_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fsgnjn_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fsgnjn_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnjn_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsgnjx_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJX_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnjx_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fsgnjx_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fsgnjx_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnjx_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmin_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMIN_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmin_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fmin_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fmin_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmin_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmax_s_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMAX_S, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmax_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fmax_s_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fmax_s_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmax_s_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fcvt_w_s_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_W_S, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_w_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fcvt_w_s_gpr_fpr(rd, rs1)) }
emit_fcvt_w_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_w_s_gpr_fpr(rd, rs1)) }
inst_fcvt_wu_s_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_WU_S, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_wu_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fcvt_wu_s_gpr_fpr(rd, rs1)) }
emit_fcvt_wu_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_wu_s_gpr_fpr(rd, rs1)) }
inst_fmv_x_w_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FMV_X_W, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fmv_x_w_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fmv_x_w_gpr_fpr(rd, rs1)) }
emit_fmv_x_w_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fmv_x_w_gpr_fpr(rd, rs1)) }
inst_feq_s_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FEQ_S, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_feq_s_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append(instructions, inst_feq_s_gpr_fpr_fpr(rd, rs1, rs2)) }
emit_feq_s_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_feq_s_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_flt_s_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FLT_S, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_flt_s_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append(instructions, inst_flt_s_gpr_fpr_fpr(rd, rs1, rs2)) }
emit_flt_s_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_flt_s_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_fle_s_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FLE_S, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fle_s_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fle_s_gpr_fpr_fpr(rd, rs1, rs2)) }
emit_fle_s_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fle_s_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_fclass_s_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCLASS_S, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fclass_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fclass_s_gpr_fpr(rd, rs1)) }
emit_fclass_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fclass_s_gpr_fpr(rd, rs1)) }
inst_fcvt_s_w_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_S_W, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_s_w_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fcvt_s_w_fpr_gpr(rd, rs1)) }
emit_fcvt_s_w_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_s_w_fpr_gpr(rd, rs1)) }
inst_fcvt_s_wu_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_S_WU, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_s_wu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fcvt_s_wu_fpr_gpr(rd, rs1)) }
emit_fcvt_s_wu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_s_wu_fpr_gpr(rd, rs1)) }
inst_fmv_w_x_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FMV_W_X, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fmv_w_x_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fmv_w_x_fpr_gpr(rd, rs1)) }
emit_fmv_w_x_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fmv_w_x_fpr_gpr(rd, rs1)) }
inst_fcvt_l_s_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_L_S, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_l_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fcvt_l_s_gpr_fpr(rd, rs1)) }
emit_fcvt_l_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_l_s_gpr_fpr(rd, rs1)) }
inst_fcvt_lu_s_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_LU_S, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_lu_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fcvt_lu_s_gpr_fpr(rd, rs1)) }
emit_fcvt_lu_s_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_lu_s_gpr_fpr(rd, rs1)) }
inst_fcvt_s_l_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_S_L, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_s_l_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fcvt_s_l_fpr_gpr(rd, rs1)) }
emit_fcvt_s_l_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_s_l_fpr_gpr(rd, rs1)) }
inst_fcvt_s_lu_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_S_LU, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_s_lu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fcvt_s_lu_fpr_gpr(rd, rs1)) }
emit_fcvt_s_lu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_s_lu_fpr_gpr(rd, rs1)) }
inst_fld_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .FLD, operand_count = 2, length = 4, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_fld_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append(instructions, inst_fld_fpr_mem(rd, mem)) }
emit_fld_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_fld_fpr_mem(rd, mem)) }
inst_fsd_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .FSD, operand_count = 2, length = 4, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_fsd_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append(instructions, inst_fsd_fpr_mem(rd, mem)) }
emit_fsd_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_fsd_fpr_mem(rd, mem)) }
inst_fmadd_d_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FMADD_D, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fmadd_d_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append(instructions, inst_fmadd_d_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
emit_fmadd_d_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fmadd_d_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fmsub_d_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FMSUB_D, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fmsub_d_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append(instructions, inst_fmsub_d_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
emit_fmsub_d_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fmsub_d_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fnmsub_d_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FNMSUB_D, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fnmsub_d_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append(instructions, inst_fnmsub_d_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
emit_fnmsub_d_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fnmsub_d_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fnmadd_d_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FNMADD_D, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fnmadd_d_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append(instructions, inst_fnmadd_d_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
emit_fnmadd_d_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fnmadd_d_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fadd_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FADD_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fadd_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fadd_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fadd_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fadd_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsub_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSUB_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsub_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fsub_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fsub_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsub_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmul_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMUL_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmul_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fmul_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fmul_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmul_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fdiv_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FDIV_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fdiv_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fdiv_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fdiv_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fdiv_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsqrt_d_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FSQRT_D, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fsqrt_d_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append(instructions, inst_fsqrt_d_fpr_fpr(rd, rs1)) }
emit_fsqrt_d_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fsqrt_d_fpr_fpr(rd, rs1)) }
inst_fsgnj_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJ_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnj_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fsgnj_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fsgnj_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnj_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsgnjn_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJN_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnjn_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fsgnjn_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fsgnjn_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnjn_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsgnjx_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJX_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnjx_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fsgnjx_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fsgnjx_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnjx_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmin_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMIN_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmin_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fmin_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fmin_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmin_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmax_d_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMAX_D, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmax_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fmax_d_fpr_fpr_fpr(rd, rs1, rs2)) }
emit_fmax_d_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmax_d_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fcvt_s_d_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_S_D, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_s_d_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append(instructions, inst_fcvt_s_d_fpr_fpr(rd, rs1)) }
emit_fcvt_s_d_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fcvt_s_d_fpr_fpr(rd, rs1)) }
inst_fcvt_d_s_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_D_S, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_d_s_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append(instructions, inst_fcvt_d_s_fpr_fpr(rd, rs1)) }
emit_fcvt_d_s_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fcvt_d_s_fpr_fpr(rd, rs1)) }
inst_feq_d_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FEQ_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_feq_d_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append(instructions, inst_feq_d_gpr_fpr_fpr(rd, rs1, rs2)) }
emit_feq_d_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_feq_d_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_flt_d_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FLT_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_flt_d_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append(instructions, inst_flt_d_gpr_fpr_fpr(rd, rs1, rs2)) }
emit_flt_d_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_flt_d_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_fle_d_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FLE_D, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fle_d_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append(instructions, inst_fle_d_gpr_fpr_fpr(rd, rs1, rs2)) }
emit_fle_d_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fle_d_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_fclass_d_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCLASS_D, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fclass_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fclass_d_gpr_fpr(rd, rs1)) }
emit_fclass_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fclass_d_gpr_fpr(rd, rs1)) }
inst_fcvt_w_d_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_W_D, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_w_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fcvt_w_d_gpr_fpr(rd, rs1)) }
emit_fcvt_w_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_w_d_gpr_fpr(rd, rs1)) }
inst_fcvt_wu_d_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_WU_D, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_wu_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fcvt_wu_d_gpr_fpr(rd, rs1)) }
emit_fcvt_wu_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_wu_d_gpr_fpr(rd, rs1)) }
inst_fcvt_d_w_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_D_W, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_d_w_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fcvt_d_w_fpr_gpr(rd, rs1)) }
emit_fcvt_d_w_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_d_w_fpr_gpr(rd, rs1)) }
inst_fcvt_d_wu_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_D_WU, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_d_wu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fcvt_d_wu_fpr_gpr(rd, rs1)) }
emit_fcvt_d_wu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_d_wu_fpr_gpr(rd, rs1)) }
inst_fcvt_l_d_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_L_D, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_l_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fcvt_l_d_gpr_fpr(rd, rs1)) }
emit_fcvt_l_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_l_d_gpr_fpr(rd, rs1)) }
inst_fcvt_lu_d_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_LU_D, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_lu_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fcvt_lu_d_gpr_fpr(rd, rs1)) }
emit_fcvt_lu_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_lu_d_gpr_fpr(rd, rs1)) }
inst_fcvt_d_l_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_D_L, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_d_l_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fcvt_d_l_fpr_gpr(rd, rs1)) }
emit_fcvt_d_l_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_d_l_fpr_gpr(rd, rs1)) }
inst_fcvt_d_lu_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_D_LU, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_d_lu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fcvt_d_lu_fpr_gpr(rd, rs1)) }
emit_fcvt_d_lu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_d_lu_fpr_gpr(rd, rs1)) }
inst_fmv_x_d_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FMV_X_D, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fmv_x_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append(instructions, inst_fmv_x_d_gpr_fpr(rd, rs1)) }
emit_fmv_x_d_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fmv_x_d_gpr_fpr(rd, rs1)) }
inst_fmv_d_x_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FMV_D_X, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fmv_d_x_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append(instructions, inst_fmv_d_x_fpr_gpr(rd, rs1)) }
emit_fmv_d_x_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fmv_d_x_fpr_gpr(rd, rs1)) }
inst_c_nop_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .C_NOP, operand_count = 0, length = 2} }
emit_c_nop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_c_nop_none()) }
emit_c_nop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_c_nop_none()) }
inst_c_ebreak_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{mnemonic = .C_EBREAK, operand_count = 0, length = 2} }
emit_c_ebreak_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_c_ebreak_none()) }
emit_c_ebreak_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_c_ebreak_none()) }
inst_c_addi4spn_gpr_gpr_imm8u :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_ADDI4SPN, operand_count = 3, length = 2, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 2), {}}} }
emit_c_addi4spn_gpr_gpr_imm8u :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append(instructions, inst_c_addi4spn_gpr_gpr_imm8u(rd, rs1, imm)) }
emit_c_addi4spn_gpr_gpr_imm8u :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_c_addi4spn_gpr_gpr_imm8u(rd, rs1, imm)) }
inst_c_lw_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_LW, operand_count = 2, length = 2, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_c_lw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_c_lw_gpr_mem(rd, mem)) }
emit_c_lw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_c_lw_gpr_mem(rd, mem)) }
inst_c_ld_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_LD, operand_count = 2, length = 2, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_c_ld_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_c_ld_gpr_mem(rd, mem)) }
emit_c_ld_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_c_ld_gpr_mem(rd, mem)) }
inst_c_sw_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_SW, operand_count = 2, length = 2, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_c_sw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_c_sw_gpr_mem(rd, mem)) }
emit_c_sw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_c_sw_gpr_mem(rd, mem)) }
inst_c_sd_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_SD, operand_count = 2, length = 2, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_c_sd_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_c_sd_gpr_mem(rd, mem)) }
emit_c_sd_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_c_sd_gpr_mem(rd, mem)) }
inst_c_flw_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_FLW, operand_count = 2, length = 2, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_c_flw_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_c_flw_fpr_mem(rd, mem)) }
inst_c_fsw_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_FSW, operand_count = 2, length = 2, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_c_fsw_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_c_fsw_fpr_mem(rd, mem)) }
inst_c_fld_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_FLD, operand_count = 2, length = 2, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_c_fld_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append(instructions, inst_c_fld_fpr_mem(rd, mem)) }
emit_c_fld_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_c_fld_fpr_mem(rd, mem)) }
inst_c_fsd_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_FSD, operand_count = 2, length = 2, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_c_fsd_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append(instructions, inst_c_fsd_fpr_mem(rd, mem)) }
emit_c_fsd_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_c_fsd_fpr_mem(rd, mem)) }
inst_c_addi_gpr_imm6s :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_ADDI, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_addi_gpr_imm6s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_addi_gpr_imm6s(rd, imm)) }
emit_c_addi_gpr_imm6s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_addi_gpr_imm6s(rd, imm)) }
inst_c_addiw_gpr_imm6s :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_ADDIW, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_addiw_gpr_imm6s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_addiw_gpr_imm6s(rd, imm)) }
emit_c_addiw_gpr_imm6s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_addiw_gpr_imm6s(rd, imm)) }
inst_c_li_gpr_imm6s :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_LI, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_li_gpr_imm6s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_li_gpr_imm6s(rd, imm)) }
emit_c_li_gpr_imm6s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_li_gpr_imm6s(rd, imm)) }
inst_c_lui_gpr_imm18s :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_LUI, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_lui_gpr_imm18s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_lui_gpr_imm18s(rd, imm)) }
emit_c_lui_gpr_imm18s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_lui_gpr_imm18s(rd, imm)) }
inst_c_addi16sp_gpr_imm10s :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_ADDI16SP, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_addi16sp_gpr_imm10s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_addi16sp_gpr_imm10s(rd, imm)) }
emit_c_addi16sp_gpr_imm10s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_addi16sp_gpr_imm10s(rd, imm)) }
inst_c_srli_gpr_imm6u :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_SRLI, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_srli_gpr_imm6u :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_srli_gpr_imm6u(rd, imm)) }
emit_c_srli_gpr_imm6u :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_srli_gpr_imm6u(rd, imm)) }
inst_c_srai_gpr_imm6u :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_SRAI, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_srai_gpr_imm6u :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_srai_gpr_imm6u(rd, imm)) }
emit_c_srai_gpr_imm6u :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_srai_gpr_imm6u(rd, imm)) }
inst_c_andi_gpr_imm6s :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_ANDI, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_andi_gpr_imm6s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_andi_gpr_imm6s(rd, imm)) }
emit_c_andi_gpr_imm6s :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_andi_gpr_imm6s(rd, imm)) }
inst_c_sub_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .C_SUB, operand_count = 2, length = 2, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_c_sub_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append(instructions, inst_c_sub_gpr_gpr(rd, rs1)) }
emit_c_sub_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_c_sub_gpr_gpr(rd, rs1)) }
inst_c_xor_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .C_XOR, operand_count = 2, length = 2, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_c_xor_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append(instructions, inst_c_xor_gpr_gpr(rd, rs1)) }
emit_c_xor_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_c_xor_gpr_gpr(rd, rs1)) }
inst_c_or_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .C_OR, operand_count = 2, length = 2, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_c_or_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append(instructions, inst_c_or_gpr_gpr(rd, rs1)) }
emit_c_or_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_c_or_gpr_gpr(rd, rs1)) }
inst_c_and_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .C_AND, operand_count = 2, length = 2, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_c_and_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append(instructions, inst_c_and_gpr_gpr(rd, rs1)) }
emit_c_and_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_c_and_gpr_gpr(rd, rs1)) }
inst_c_subw_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .C_SUBW, operand_count = 2, length = 2, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_c_subw_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append(instructions, inst_c_subw_gpr_gpr(rd, rs1)) }
emit_c_subw_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_c_subw_gpr_gpr(rd, rs1)) }
inst_c_addw_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .C_ADDW, operand_count = 2, length = 2, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_c_addw_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append(instructions, inst_c_addw_gpr_gpr(rd, rs1)) }
emit_c_addw_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_c_addw_gpr_gpr(rd, rs1)) }
inst_c_j_label :: #force_inline proc "contextless" (label: u32) -> Instruction { return Instruction{mnemonic = .C_J, operand_count = 1, length = 2, ops = {op_label(label, 4), {}, {}, {}}} }
emit_c_j_label :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_c_j_label(label)) }
emit_c_j_label :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_c_j_label(label)) }
inst_c_jal_label :: #force_inline proc "contextless" (label: u32) -> Instruction { return Instruction{mnemonic = .C_JAL, operand_count = 1, length = 2, ops = {op_label(label, 4), {}, {}, {}}} }
emit_c_jal_label :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append(instructions, inst_c_jal_label(label)) }
emit_c_jal_label :: #force_inline proc(instructions: ^[dynamic]Instruction, label: u32) { append_elem(instructions, inst_c_jal_label(label)) }
inst_c_beqz_gpr_label :: #force_inline proc "contextless" (rd: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .C_BEQZ, operand_count = 2, length = 2, ops = {op_gpr(rd), op_label(label, 2), {}, {}}} }
emit_c_beqz_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, label: u32) { append(instructions, inst_c_beqz_gpr_label(rd, label)) }
emit_c_beqz_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, label: u32) { append_elem(instructions, inst_c_beqz_gpr_label(rd, label)) }
inst_c_bnez_gpr_label :: #force_inline proc "contextless" (rd: GPR, label: u32) -> Instruction { return Instruction{mnemonic = .C_BNEZ, operand_count = 2, length = 2, ops = {op_gpr(rd), op_label(label, 2), {}, {}}} }
emit_c_bnez_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, label: u32) { append(instructions, inst_c_bnez_gpr_label(rd, label)) }
emit_c_bnez_gpr_label :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, label: u32) { append_elem(instructions, inst_c_bnez_gpr_label(rd, label)) }
inst_c_slli_gpr_imm6u :: #force_inline proc "contextless" (rd: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .C_SLLI, operand_count = 2, length = 2, ops = {op_gpr(rd), op_imm(imm, 2), {}, {}}} }
emit_c_slli_gpr_imm6u :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append(instructions, inst_c_slli_gpr_imm6u(rd, imm)) }
emit_c_slli_gpr_imm6u :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, imm: i64) { append_elem(instructions, inst_c_slli_gpr_imm6u(rd, imm)) }
inst_c_lwsp_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_LWSP, operand_count = 2, length = 2, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_c_lwsp_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_c_lwsp_gpr_mem(rd, mem)) }
emit_c_lwsp_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_c_lwsp_gpr_mem(rd, mem)) }
inst_c_ldsp_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_LDSP, operand_count = 2, length = 2, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_c_ldsp_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_c_ldsp_gpr_mem(rd, mem)) }
emit_c_ldsp_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_c_ldsp_gpr_mem(rd, mem)) }
inst_c_swsp_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_SWSP, operand_count = 2, length = 2, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_c_swsp_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_c_swsp_gpr_mem(rd, mem)) }
emit_c_swsp_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_c_swsp_gpr_mem(rd, mem)) }
inst_c_sdsp_gpr_mem :: #force_inline proc "contextless" (rd: GPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_SDSP, operand_count = 2, length = 2, ops = {op_gpr(rd), op_mem(mem), {}, {}}} }
emit_c_sdsp_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append(instructions, inst_c_sdsp_gpr_mem(rd, mem)) }
emit_c_sdsp_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, mem: Memory) { append_elem(instructions, inst_c_sdsp_gpr_mem(rd, mem)) }
inst_c_fldsp_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_FLDSP, operand_count = 2, length = 2, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_c_fldsp_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append(instructions, inst_c_fldsp_fpr_mem(rd, mem)) }
emit_c_fldsp_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_c_fldsp_fpr_mem(rd, mem)) }
inst_c_fsdsp_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_FSDSP, operand_count = 2, length = 2, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_c_fsdsp_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append(instructions, inst_c_fsdsp_fpr_mem(rd, mem)) }
emit_c_fsdsp_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_c_fsdsp_fpr_mem(rd, mem)) }
inst_c_jr_gpr :: #force_inline proc "contextless" (rd: GPR) -> Instruction { return Instruction{mnemonic = .C_JR, operand_count = 1, length = 2, ops = {op_gpr(rd), {}, {}, {}}} }
emit_c_jr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR) { append(instructions, inst_c_jr_gpr(rd)) }
emit_c_jr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR) { append_elem(instructions, inst_c_jr_gpr(rd)) }
inst_c_jalr_gpr :: #force_inline proc "contextless" (rd: GPR) -> Instruction { return Instruction{mnemonic = .C_JALR, operand_count = 1, length = 2, ops = {op_gpr(rd), {}, {}, {}}} }
emit_c_jalr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR) { append(instructions, inst_c_jalr_gpr(rd)) }
emit_c_jalr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR) { append_elem(instructions, inst_c_jalr_gpr(rd)) }
inst_c_mv_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .C_MV, operand_count = 2, length = 2, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_c_mv_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append(instructions, inst_c_mv_gpr_gpr(rd, rs1)) }
emit_c_mv_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_c_mv_gpr_gpr(rd, rs1)) }
inst_c_add_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .C_ADD, operand_count = 2, length = 2, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_c_add_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append(instructions, inst_c_add_gpr_gpr(rd, rs1)) }
emit_c_add_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_c_add_gpr_gpr(rd, rs1)) }
inst_c_flwsp_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_FLWSP, operand_count = 2, length = 2, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_c_flwsp_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_c_flwsp_fpr_mem(rd, mem)) }
inst_c_fswsp_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .C_FSWSP, operand_count = 2, length = 2, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_c_fswsp_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_c_fswsp_fpr_mem(rd, mem)) }
inst_sh1add_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SH1ADD, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sh1add_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sh1add_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sh2add_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SH2ADD, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sh2add_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sh2add_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sh3add_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SH3ADD, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sh3add_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sh3add_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_add_uw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .ADD_UW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_add_uw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_add_uw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sh1add_uw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SH1ADD_UW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sh1add_uw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sh1add_uw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sh2add_uw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SH2ADD_UW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sh2add_uw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sh2add_uw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_sh3add_uw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .SH3ADD_UW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_sh3add_uw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_sh3add_uw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_slli_uw_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .SLLI_UW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_slli_uw_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_slli_uw_gpr_gpr_imm6(rd, rs1, imm)) }
inst_andn_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .ANDN, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_andn_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_andn_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_orn_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .ORN, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_orn_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_orn_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_xnor_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .XNOR, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_xnor_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_xnor_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_clz_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CLZ, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_clz_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_clz_gpr_gpr(rd, rs1)) }
inst_ctz_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CTZ, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_ctz_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_ctz_gpr_gpr(rd, rs1)) }
inst_cpop_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CPOP, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_cpop_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_cpop_gpr_gpr(rd, rs1)) }
inst_sext_b_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .SEXT_B, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_sext_b_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_sext_b_gpr_gpr(rd, rs1)) }
inst_sext_h_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .SEXT_H, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_sext_h_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_sext_h_gpr_gpr(rd, rs1)) }
inst_zext_h_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .ZEXT_H, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_zext_h_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_zext_h_gpr_gpr(rd, rs1)) }
inst_min_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MIN, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_min_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_min_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_minu_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MINU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_minu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_minu_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_max_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MAX, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_max_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_max_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_maxu_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .MAXU, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_maxu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_maxu_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_rol_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .ROL, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_rol_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_rol_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_ror_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .ROR, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_ror_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_ror_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_rori_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .RORI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_rori_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_rori_gpr_gpr_imm6(rd, rs1, imm)) }
inst_orc_b_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .ORC_B, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_orc_b_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_orc_b_gpr_gpr(rd, rs1)) }
inst_rev8_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .REV8, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_rev8_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_rev8_gpr_gpr(rd, rs1)) }
inst_clzw_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CLZW, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_clzw_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_clzw_gpr_gpr(rd, rs1)) }
inst_ctzw_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CTZW, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_ctzw_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_ctzw_gpr_gpr(rd, rs1)) }
inst_cpopw_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .CPOPW, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_cpopw_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_cpopw_gpr_gpr(rd, rs1)) }
inst_rolw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .ROLW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_rolw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_rolw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_rorw_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .RORW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_rorw_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_rorw_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_roriw_gpr_gpr_imm5 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .RORIW, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_roriw_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_roriw_gpr_gpr_imm5(rd, rs1, imm)) }
inst_clmul_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .CLMUL, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_clmul_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_clmul_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_clmulh_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .CLMULH, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_clmulh_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_clmulh_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_clmulr_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .CLMULR, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_clmulr_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_clmulr_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_bclr_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .BCLR, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_bclr_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_bclr_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_bclri_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .BCLRI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_bclri_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_bclri_gpr_gpr_imm6(rd, rs1, imm)) }
inst_bext_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .BEXT, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_bext_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_bext_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_bexti_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .BEXTI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_bexti_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_bexti_gpr_gpr_imm6(rd, rs1, imm)) }
inst_binv_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .BINV, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_binv_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_binv_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_binvi_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .BINVI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_binvi_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_binvi_gpr_gpr_imm6(rd, rs1, imm)) }
inst_bset_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .BSET, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_bset_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_bset_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_bseti_gpr_gpr_imm6 :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, imm: i64) -> Instruction { return Instruction{mnemonic = .BSETI, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_imm(imm, 1), {}}} }
emit_bseti_gpr_gpr_imm6 :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, imm: i64) { append_elem(instructions, inst_bseti_gpr_gpr_imm6(rd, rs1, imm)) }
inst_czero_eqz_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .CZERO_EQZ, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_czero_eqz_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_czero_eqz_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_czero_nez_gpr_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR, rs2: GPR) -> Instruction { return Instruction{mnemonic = .CZERO_NEZ, operand_count = 3, length = 4, ops = {op_gpr(rd), op_gpr(rs1), op_gpr(rs2), {}}} }
emit_czero_nez_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR, rs2: GPR) { append_elem(instructions, inst_czero_nez_gpr_gpr_gpr(rd, rs1, rs2)) }
inst_flh_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .FLH, operand_count = 2, length = 4, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_flh_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_flh_fpr_mem(rd, mem)) }
inst_fsh_fpr_mem :: #force_inline proc "contextless" (rd: FPR, mem: Memory) -> Instruction { return Instruction{mnemonic = .FSH, operand_count = 2, length = 4, ops = {op_fpr(rd), op_mem(mem), {}, {}}} }
emit_fsh_fpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, mem: Memory) { append_elem(instructions, inst_fsh_fpr_mem(rd, mem)) }
inst_fmadd_h_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FMADD_H, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fmadd_h_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fmadd_h_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fmsub_h_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FMSUB_H, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fmsub_h_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fmsub_h_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fnmsub_h_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FNMSUB_H, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fnmsub_h_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fnmsub_h_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fnmadd_h_fpr_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) -> Instruction { return Instruction{mnemonic = .FNMADD_H, operand_count = 4, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), op_fpr(rs3)}} }
emit_fnmadd_h_fpr_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR, rs3: FPR) { append_elem(instructions, inst_fnmadd_h_fpr_fpr_fpr_fpr(rd, rs1, rs2, rs3)) }
inst_fadd_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FADD_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fadd_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fadd_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsub_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSUB_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsub_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsub_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmul_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMUL_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmul_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmul_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fdiv_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FDIV_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fdiv_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fdiv_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsqrt_h_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FSQRT_H, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fsqrt_h_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fsqrt_h_fpr_fpr(rd, rs1)) }
inst_fsgnj_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJ_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnj_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnj_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsgnjn_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJN_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnjn_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnjn_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fsgnjx_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FSGNJX_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fsgnjx_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fsgnjx_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmin_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMIN_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmin_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmin_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fmax_h_fpr_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FMAX_H, operand_count = 3, length = 4, ops = {op_fpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fmax_h_fpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fmax_h_fpr_fpr_fpr(rd, rs1, rs2)) }
inst_fcvt_w_h_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_W_H, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_w_h_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_w_h_gpr_fpr(rd, rs1)) }
inst_fcvt_wu_h_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_WU_H, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_wu_h_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_wu_h_gpr_fpr(rd, rs1)) }
inst_fcvt_l_h_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_L_H, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_l_h_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_l_h_gpr_fpr(rd, rs1)) }
inst_fcvt_lu_h_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_LU_H, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_lu_h_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fcvt_lu_h_gpr_fpr(rd, rs1)) }
inst_fcvt_h_w_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_H_W, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_h_w_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_h_w_fpr_gpr(rd, rs1)) }
inst_fcvt_h_wu_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_H_WU, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_h_wu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_h_wu_fpr_gpr(rd, rs1)) }
inst_fcvt_h_l_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_H_L, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_h_l_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_h_l_fpr_gpr(rd, rs1)) }
inst_fcvt_h_lu_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FCVT_H_LU, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fcvt_h_lu_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fcvt_h_lu_fpr_gpr(rd, rs1)) }
inst_fcvt_s_h_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_S_H, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_s_h_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fcvt_s_h_fpr_fpr(rd, rs1)) }
inst_fcvt_h_s_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_H_S, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_h_s_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fcvt_h_s_fpr_fpr(rd, rs1)) }
inst_fcvt_d_h_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_D_H, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_d_h_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fcvt_d_h_fpr_fpr(rd, rs1)) }
inst_fcvt_h_d_fpr_fpr :: #force_inline proc "contextless" (rd: FPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCVT_H_D, operand_count = 2, length = 4, ops = {op_fpr(rd), op_fpr(rs1), {}, {}}} }
emit_fcvt_h_d_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: FPR) { append_elem(instructions, inst_fcvt_h_d_fpr_fpr(rd, rs1)) }
inst_fmv_x_h_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FMV_X_H, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fmv_x_h_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fmv_x_h_gpr_fpr(rd, rs1)) }
inst_fmv_h_x_fpr_gpr :: #force_inline proc "contextless" (rd: FPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .FMV_H_X, operand_count = 2, length = 4, ops = {op_fpr(rd), op_gpr(rs1), {}, {}}} }
emit_fmv_h_x_fpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: FPR, rs1: GPR) { append_elem(instructions, inst_fmv_h_x_fpr_gpr(rd, rs1)) }
inst_fclass_h_gpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR) -> Instruction { return Instruction{mnemonic = .FCLASS_H, operand_count = 2, length = 4, ops = {op_gpr(rd), op_fpr(rs1), {}, {}}} }
emit_fclass_h_gpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR) { append_elem(instructions, inst_fclass_h_gpr_fpr(rd, rs1)) }
inst_feq_h_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FEQ_H, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_feq_h_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_feq_h_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_flt_h_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FLT_H, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_flt_h_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_flt_h_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_fle_h_gpr_fpr_fpr :: #force_inline proc "contextless" (rd: GPR, rs1: FPR, rs2: FPR) -> Instruction { return Instruction{mnemonic = .FLE_H, operand_count = 3, length = 4, ops = {op_gpr(rd), op_fpr(rs1), op_fpr(rs2), {}}} }
emit_fle_h_gpr_fpr_fpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: FPR, rs2: FPR) { append_elem(instructions, inst_fle_h_gpr_fpr_fpr(rd, rs1, rs2)) }
inst_mret_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.MRET) }
emit_mret_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_mret_none()) }
inst_sret_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.SRET) }
emit_sret_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_sret_none()) }
inst_wfi_none :: #force_inline proc "contextless" () -> Instruction { return inst_none(.WFI) }
emit_wfi_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_wfi_none()) }
inst_sfence_vma_gpr_gpr :: #force_inline proc "contextless" (rd: GPR, rs1: GPR) -> Instruction { return Instruction{mnemonic = .SFENCE_VMA, operand_count = 2, length = 4, ops = {op_gpr(rd), op_gpr(rs1), {}, {}}} }
emit_sfence_vma_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, rd: GPR, rs1: GPR) { append_elem(instructions, inst_sfence_vma_gpr_gpr(rd, rs1)) }
// =============================================================================
// Overload Groups
@@ -739,6 +913,10 @@ inst_c_sw :: inst_c_sw_gpr_mem
emit_c_sw :: emit_c_sw_gpr_mem
inst_c_sd :: inst_c_sd_gpr_mem
emit_c_sd :: emit_c_sd_gpr_mem
inst_c_flw :: inst_c_flw_fpr_mem
emit_c_flw :: emit_c_flw_fpr_mem
inst_c_fsw :: inst_c_fsw_fpr_mem
emit_c_fsw :: emit_c_fsw_fpr_mem
inst_c_fld :: inst_c_fld_fpr_mem
emit_c_fld :: emit_c_fld_fpr_mem
inst_c_fsd :: inst_c_fsd_fpr_mem
@@ -801,3 +979,173 @@ inst_c_mv :: inst_c_mv_gpr_gpr
emit_c_mv :: emit_c_mv_gpr_gpr
inst_c_add :: inst_c_add_gpr_gpr
emit_c_add :: emit_c_add_gpr_gpr
inst_c_flwsp :: inst_c_flwsp_fpr_mem
emit_c_flwsp :: emit_c_flwsp_fpr_mem
inst_c_fswsp :: inst_c_fswsp_fpr_mem
emit_c_fswsp :: emit_c_fswsp_fpr_mem
inst_sh1add :: inst_sh1add_gpr_gpr_gpr
emit_sh1add :: emit_sh1add_gpr_gpr_gpr
inst_sh2add :: inst_sh2add_gpr_gpr_gpr
emit_sh2add :: emit_sh2add_gpr_gpr_gpr
inst_sh3add :: inst_sh3add_gpr_gpr_gpr
emit_sh3add :: emit_sh3add_gpr_gpr_gpr
inst_add_uw :: inst_add_uw_gpr_gpr_gpr
emit_add_uw :: emit_add_uw_gpr_gpr_gpr
inst_sh1add_uw :: inst_sh1add_uw_gpr_gpr_gpr
emit_sh1add_uw :: emit_sh1add_uw_gpr_gpr_gpr
inst_sh2add_uw :: inst_sh2add_uw_gpr_gpr_gpr
emit_sh2add_uw :: emit_sh2add_uw_gpr_gpr_gpr
inst_sh3add_uw :: inst_sh3add_uw_gpr_gpr_gpr
emit_sh3add_uw :: emit_sh3add_uw_gpr_gpr_gpr
inst_slli_uw :: inst_slli_uw_gpr_gpr_imm6
emit_slli_uw :: emit_slli_uw_gpr_gpr_imm6
inst_andn :: inst_andn_gpr_gpr_gpr
emit_andn :: emit_andn_gpr_gpr_gpr
inst_orn :: inst_orn_gpr_gpr_gpr
emit_orn :: emit_orn_gpr_gpr_gpr
inst_xnor :: inst_xnor_gpr_gpr_gpr
emit_xnor :: emit_xnor_gpr_gpr_gpr
inst_clz :: inst_clz_gpr_gpr
emit_clz :: emit_clz_gpr_gpr
inst_ctz :: inst_ctz_gpr_gpr
emit_ctz :: emit_ctz_gpr_gpr
inst_cpop :: inst_cpop_gpr_gpr
emit_cpop :: emit_cpop_gpr_gpr
inst_sext_b :: inst_sext_b_gpr_gpr
emit_sext_b :: emit_sext_b_gpr_gpr
inst_sext_h :: inst_sext_h_gpr_gpr
emit_sext_h :: emit_sext_h_gpr_gpr
inst_zext_h :: inst_zext_h_gpr_gpr
emit_zext_h :: emit_zext_h_gpr_gpr
inst_min :: inst_min_gpr_gpr_gpr
emit_min :: emit_min_gpr_gpr_gpr
inst_minu :: inst_minu_gpr_gpr_gpr
emit_minu :: emit_minu_gpr_gpr_gpr
inst_max :: inst_max_gpr_gpr_gpr
emit_max :: emit_max_gpr_gpr_gpr
inst_maxu :: inst_maxu_gpr_gpr_gpr
emit_maxu :: emit_maxu_gpr_gpr_gpr
inst_rol :: inst_rol_gpr_gpr_gpr
emit_rol :: emit_rol_gpr_gpr_gpr
inst_ror :: inst_ror_gpr_gpr_gpr
emit_ror :: emit_ror_gpr_gpr_gpr
inst_rori :: inst_rori_gpr_gpr_imm6
emit_rori :: emit_rori_gpr_gpr_imm6
inst_orc_b :: inst_orc_b_gpr_gpr
emit_orc_b :: emit_orc_b_gpr_gpr
inst_rev8 :: inst_rev8_gpr_gpr
emit_rev8 :: emit_rev8_gpr_gpr
inst_clzw :: inst_clzw_gpr_gpr
emit_clzw :: emit_clzw_gpr_gpr
inst_ctzw :: inst_ctzw_gpr_gpr
emit_ctzw :: emit_ctzw_gpr_gpr
inst_cpopw :: inst_cpopw_gpr_gpr
emit_cpopw :: emit_cpopw_gpr_gpr
inst_rolw :: inst_rolw_gpr_gpr_gpr
emit_rolw :: emit_rolw_gpr_gpr_gpr
inst_rorw :: inst_rorw_gpr_gpr_gpr
emit_rorw :: emit_rorw_gpr_gpr_gpr
inst_roriw :: inst_roriw_gpr_gpr_imm5
emit_roriw :: emit_roriw_gpr_gpr_imm5
inst_clmul :: inst_clmul_gpr_gpr_gpr
emit_clmul :: emit_clmul_gpr_gpr_gpr
inst_clmulh :: inst_clmulh_gpr_gpr_gpr
emit_clmulh :: emit_clmulh_gpr_gpr_gpr
inst_clmulr :: inst_clmulr_gpr_gpr_gpr
emit_clmulr :: emit_clmulr_gpr_gpr_gpr
inst_bclr :: inst_bclr_gpr_gpr_gpr
emit_bclr :: emit_bclr_gpr_gpr_gpr
inst_bclri :: inst_bclri_gpr_gpr_imm6
emit_bclri :: emit_bclri_gpr_gpr_imm6
inst_bext :: inst_bext_gpr_gpr_gpr
emit_bext :: emit_bext_gpr_gpr_gpr
inst_bexti :: inst_bexti_gpr_gpr_imm6
emit_bexti :: emit_bexti_gpr_gpr_imm6
inst_binv :: inst_binv_gpr_gpr_gpr
emit_binv :: emit_binv_gpr_gpr_gpr
inst_binvi :: inst_binvi_gpr_gpr_imm6
emit_binvi :: emit_binvi_gpr_gpr_imm6
inst_bset :: inst_bset_gpr_gpr_gpr
emit_bset :: emit_bset_gpr_gpr_gpr
inst_bseti :: inst_bseti_gpr_gpr_imm6
emit_bseti :: emit_bseti_gpr_gpr_imm6
inst_czero_eqz :: inst_czero_eqz_gpr_gpr_gpr
emit_czero_eqz :: emit_czero_eqz_gpr_gpr_gpr
inst_czero_nez :: inst_czero_nez_gpr_gpr_gpr
emit_czero_nez :: emit_czero_nez_gpr_gpr_gpr
inst_flh :: inst_flh_fpr_mem
emit_flh :: emit_flh_fpr_mem
inst_fsh :: inst_fsh_fpr_mem
emit_fsh :: emit_fsh_fpr_mem
inst_fmadd_h :: inst_fmadd_h_fpr_fpr_fpr_fpr
emit_fmadd_h :: emit_fmadd_h_fpr_fpr_fpr_fpr
inst_fmsub_h :: inst_fmsub_h_fpr_fpr_fpr_fpr
emit_fmsub_h :: emit_fmsub_h_fpr_fpr_fpr_fpr
inst_fnmsub_h :: inst_fnmsub_h_fpr_fpr_fpr_fpr
emit_fnmsub_h :: emit_fnmsub_h_fpr_fpr_fpr_fpr
inst_fnmadd_h :: inst_fnmadd_h_fpr_fpr_fpr_fpr
emit_fnmadd_h :: emit_fnmadd_h_fpr_fpr_fpr_fpr
inst_fadd_h :: inst_fadd_h_fpr_fpr_fpr
emit_fadd_h :: emit_fadd_h_fpr_fpr_fpr
inst_fsub_h :: inst_fsub_h_fpr_fpr_fpr
emit_fsub_h :: emit_fsub_h_fpr_fpr_fpr
inst_fmul_h :: inst_fmul_h_fpr_fpr_fpr
emit_fmul_h :: emit_fmul_h_fpr_fpr_fpr
inst_fdiv_h :: inst_fdiv_h_fpr_fpr_fpr
emit_fdiv_h :: emit_fdiv_h_fpr_fpr_fpr
inst_fsqrt_h :: inst_fsqrt_h_fpr_fpr
emit_fsqrt_h :: emit_fsqrt_h_fpr_fpr
inst_fsgnj_h :: inst_fsgnj_h_fpr_fpr_fpr
emit_fsgnj_h :: emit_fsgnj_h_fpr_fpr_fpr
inst_fsgnjn_h :: inst_fsgnjn_h_fpr_fpr_fpr
emit_fsgnjn_h :: emit_fsgnjn_h_fpr_fpr_fpr
inst_fsgnjx_h :: inst_fsgnjx_h_fpr_fpr_fpr
emit_fsgnjx_h :: emit_fsgnjx_h_fpr_fpr_fpr
inst_fmin_h :: inst_fmin_h_fpr_fpr_fpr
emit_fmin_h :: emit_fmin_h_fpr_fpr_fpr
inst_fmax_h :: inst_fmax_h_fpr_fpr_fpr
emit_fmax_h :: emit_fmax_h_fpr_fpr_fpr
inst_fcvt_w_h :: inst_fcvt_w_h_gpr_fpr
emit_fcvt_w_h :: emit_fcvt_w_h_gpr_fpr
inst_fcvt_wu_h :: inst_fcvt_wu_h_gpr_fpr
emit_fcvt_wu_h :: emit_fcvt_wu_h_gpr_fpr
inst_fcvt_l_h :: inst_fcvt_l_h_gpr_fpr
emit_fcvt_l_h :: emit_fcvt_l_h_gpr_fpr
inst_fcvt_lu_h :: inst_fcvt_lu_h_gpr_fpr
emit_fcvt_lu_h :: emit_fcvt_lu_h_gpr_fpr
inst_fcvt_h_w :: inst_fcvt_h_w_fpr_gpr
emit_fcvt_h_w :: emit_fcvt_h_w_fpr_gpr
inst_fcvt_h_wu :: inst_fcvt_h_wu_fpr_gpr
emit_fcvt_h_wu :: emit_fcvt_h_wu_fpr_gpr
inst_fcvt_h_l :: inst_fcvt_h_l_fpr_gpr
emit_fcvt_h_l :: emit_fcvt_h_l_fpr_gpr
inst_fcvt_h_lu :: inst_fcvt_h_lu_fpr_gpr
emit_fcvt_h_lu :: emit_fcvt_h_lu_fpr_gpr
inst_fcvt_s_h :: inst_fcvt_s_h_fpr_fpr
emit_fcvt_s_h :: emit_fcvt_s_h_fpr_fpr
inst_fcvt_h_s :: inst_fcvt_h_s_fpr_fpr
emit_fcvt_h_s :: emit_fcvt_h_s_fpr_fpr
inst_fcvt_d_h :: inst_fcvt_d_h_fpr_fpr
emit_fcvt_d_h :: emit_fcvt_d_h_fpr_fpr
inst_fcvt_h_d :: inst_fcvt_h_d_fpr_fpr
emit_fcvt_h_d :: emit_fcvt_h_d_fpr_fpr
inst_fmv_x_h :: inst_fmv_x_h_gpr_fpr
emit_fmv_x_h :: emit_fmv_x_h_gpr_fpr
inst_fmv_h_x :: inst_fmv_h_x_fpr_gpr
emit_fmv_h_x :: emit_fmv_h_x_fpr_gpr
inst_fclass_h :: inst_fclass_h_gpr_fpr
emit_fclass_h :: emit_fclass_h_gpr_fpr
inst_feq_h :: inst_feq_h_gpr_fpr_fpr
emit_feq_h :: emit_feq_h_gpr_fpr_fpr
inst_flt_h :: inst_flt_h_gpr_fpr_fpr
emit_flt_h :: emit_flt_h_gpr_fpr_fpr
inst_fle_h :: inst_fle_h_gpr_fpr_fpr
emit_fle_h :: emit_fle_h_gpr_fpr_fpr
inst_mret :: inst_mret_none
emit_mret :: emit_mret_none
inst_sret :: inst_sret_none
emit_sret :: emit_sret_none
inst_wfi :: inst_wfi_none
emit_wfi :: emit_wfi_none
inst_sfence_vma :: inst_sfence_vma_gpr_gpr
emit_sfence_vma :: emit_sfence_vma_gpr_gpr
@@ -305,7 +305,7 @@ write_emit_body :: proc(sb: ^strings.Builder, entry: Proc_Entry) {
sig := entry.sig
names := param_names(sig)
strings.write_string(sb, "append(instructions, ")
strings.write_string(sb, "append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_byte(sb, '(')
for i in 0..<sig.count {
+116 -116
View File
@@ -19,237 +19,237 @@ package rexcode_rsp
// =============================================================================
inst_add_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .ADD, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_add_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_add_gpr_gpr_gpr(a, b, c)) }
emit_add_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_add_gpr_gpr_gpr(a, b, c)) }
inst_addu_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .ADDU, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_addu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_addu_gpr_gpr_gpr(a, b, c)) }
emit_addu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_addu_gpr_gpr_gpr(a, b, c)) }
inst_sub_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .SUB, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_sub_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_sub_gpr_gpr_gpr(a, b, c)) }
emit_sub_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_sub_gpr_gpr_gpr(a, b, c)) }
inst_subu_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .SUBU, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_subu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_subu_gpr_gpr_gpr(a, b, c)) }
emit_subu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_subu_gpr_gpr_gpr(a, b, c)) }
inst_and_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .AND, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_and_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_and_gpr_gpr_gpr(a, b, c)) }
emit_and_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_and_gpr_gpr_gpr(a, b, c)) }
inst_or_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .OR, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_or_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_or_gpr_gpr_gpr(a, b, c)) }
emit_or_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_or_gpr_gpr_gpr(a, b, c)) }
inst_xor_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .XOR, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_xor_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_xor_gpr_gpr_gpr(a, b, c)) }
emit_xor_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_xor_gpr_gpr_gpr(a, b, c)) }
inst_nor_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .NOR, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_nor_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_nor_gpr_gpr_gpr(a, b, c)) }
emit_nor_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_nor_gpr_gpr_gpr(a, b, c)) }
inst_slt_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .SLT, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_slt_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_slt_gpr_gpr_gpr(a, b, c)) }
emit_slt_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_slt_gpr_gpr_gpr(a, b, c)) }
inst_sltu_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .SLTU, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_sltu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_sltu_gpr_gpr_gpr(a, b, c)) }
emit_sltu_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_sltu_gpr_gpr_gpr(a, b, c)) }
inst_sll_gpr_gpr_imm5 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .SLL, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 1), {}} } }
emit_sll_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_sll_gpr_gpr_imm5(a, b, imm)) }
emit_sll_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_sll_gpr_gpr_imm5(a, b, imm)) }
inst_srl_gpr_gpr_imm5 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .SRL, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 1), {}} } }
emit_srl_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_srl_gpr_gpr_imm5(a, b, imm)) }
emit_srl_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_srl_gpr_gpr_imm5(a, b, imm)) }
inst_sra_gpr_gpr_imm5 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .SRA, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 1), {}} } }
emit_sra_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_sra_gpr_gpr_imm5(a, b, imm)) }
emit_sra_gpr_gpr_imm5 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_sra_gpr_gpr_imm5(a, b, imm)) }
inst_sllv_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .SLLV, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_sllv_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_sllv_gpr_gpr_gpr(a, b, c)) }
emit_sllv_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_sllv_gpr_gpr_gpr(a, b, c)) }
inst_srlv_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .SRLV, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_srlv_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_srlv_gpr_gpr_gpr(a, b, c)) }
emit_srlv_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_srlv_gpr_gpr_gpr(a, b, c)) }
inst_srav_gpr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register) -> Instruction { return Instruction{ mnemonic = .SRAV, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_reg(c), {}} } }
emit_srav_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append(instructions, inst_srav_gpr_gpr_gpr(a, b, c)) }
emit_srav_gpr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register) { append_elem(instructions, inst_srav_gpr_gpr_gpr(a, b, c)) }
inst_addi_gpr_gpr_imm16 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .ADDI, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 2), {}} } }
emit_addi_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_addi_gpr_gpr_imm16(a, b, imm)) }
emit_addi_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_addi_gpr_gpr_imm16(a, b, imm)) }
inst_addiu_gpr_gpr_imm16 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .ADDIU, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 2), {}} } }
emit_addiu_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_addiu_gpr_gpr_imm16(a, b, imm)) }
emit_addiu_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_addiu_gpr_gpr_imm16(a, b, imm)) }
inst_slti_gpr_gpr_imm16 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .SLTI, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 2), {}} } }
emit_slti_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_slti_gpr_gpr_imm16(a, b, imm)) }
emit_slti_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_slti_gpr_gpr_imm16(a, b, imm)) }
inst_sltiu_gpr_gpr_imm16 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .SLTIU, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 2), {}} } }
emit_sltiu_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_sltiu_gpr_gpr_imm16(a, b, imm)) }
emit_sltiu_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_sltiu_gpr_gpr_imm16(a, b, imm)) }
inst_andi_gpr_gpr_imm16 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .ANDI, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 2), {}} } }
emit_andi_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_andi_gpr_gpr_imm16(a, b, imm)) }
emit_andi_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_andi_gpr_gpr_imm16(a, b, imm)) }
inst_ori_gpr_gpr_imm16 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .ORI, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 2), {}} } }
emit_ori_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_ori_gpr_gpr_imm16(a, b, imm)) }
emit_ori_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_ori_gpr_gpr_imm16(a, b, imm)) }
inst_xori_gpr_gpr_imm16 :: #force_inline proc "contextless" (a: Register, b: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .XORI, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_imm(imm, 2), {}} } }
emit_xori_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append(instructions, inst_xori_gpr_gpr_imm16(a, b, imm)) }
emit_xori_gpr_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, imm: i64) { append_elem(instructions, inst_xori_gpr_gpr_imm16(a, b, imm)) }
inst_lui_gpr_imm16 :: #force_inline proc "contextless" (a: Register, imm: i64) -> Instruction { return Instruction{ mnemonic = .LUI, operand_count = 2, length = 4, ops = {op_reg(a), op_imm(imm, 2), {}, {}} } }
emit_lui_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, imm: i64) { append(instructions, inst_lui_gpr_imm16(a, imm)) }
emit_lui_gpr_imm16 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, imm: i64) { append_elem(instructions, inst_lui_gpr_imm16(a, imm)) }
inst_beq_gpr_gpr_rel :: #force_inline proc "contextless" (a: Register, b: Register, label_id: u32) -> Instruction { return Instruction{ mnemonic = .BEQ, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_label(label_id), {}} } }
emit_beq_gpr_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, label_id: u32) { append(instructions, inst_beq_gpr_gpr_rel(a, b, label_id)) }
emit_beq_gpr_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, label_id: u32) { append_elem(instructions, inst_beq_gpr_gpr_rel(a, b, label_id)) }
inst_bne_gpr_gpr_rel :: #force_inline proc "contextless" (a: Register, b: Register, label_id: u32) -> Instruction { return Instruction{ mnemonic = .BNE, operand_count = 3, length = 4, ops = {op_reg(a), op_reg(b), op_label(label_id), {}} } }
emit_bne_gpr_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, label_id: u32) { append(instructions, inst_bne_gpr_gpr_rel(a, b, label_id)) }
emit_bne_gpr_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, label_id: u32) { append_elem(instructions, inst_bne_gpr_gpr_rel(a, b, label_id)) }
inst_blez_gpr_rel :: #force_inline proc "contextless" (a: Register, label_id: u32) -> Instruction { return Instruction{ mnemonic = .BLEZ, operand_count = 2, length = 4, ops = {op_reg(a), op_label(label_id), {}, {}} } }
emit_blez_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append(instructions, inst_blez_gpr_rel(a, label_id)) }
emit_blez_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append_elem(instructions, inst_blez_gpr_rel(a, label_id)) }
inst_bgtz_gpr_rel :: #force_inline proc "contextless" (a: Register, label_id: u32) -> Instruction { return Instruction{ mnemonic = .BGTZ, operand_count = 2, length = 4, ops = {op_reg(a), op_label(label_id), {}, {}} } }
emit_bgtz_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append(instructions, inst_bgtz_gpr_rel(a, label_id)) }
emit_bgtz_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append_elem(instructions, inst_bgtz_gpr_rel(a, label_id)) }
inst_bltz_gpr_rel :: #force_inline proc "contextless" (a: Register, label_id: u32) -> Instruction { return Instruction{ mnemonic = .BLTZ, operand_count = 2, length = 4, ops = {op_reg(a), op_label(label_id), {}, {}} } }
emit_bltz_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append(instructions, inst_bltz_gpr_rel(a, label_id)) }
emit_bltz_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append_elem(instructions, inst_bltz_gpr_rel(a, label_id)) }
inst_bgez_gpr_rel :: #force_inline proc "contextless" (a: Register, label_id: u32) -> Instruction { return Instruction{ mnemonic = .BGEZ, operand_count = 2, length = 4, ops = {op_reg(a), op_label(label_id), {}, {}} } }
emit_bgez_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append(instructions, inst_bgez_gpr_rel(a, label_id)) }
emit_bgez_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append_elem(instructions, inst_bgez_gpr_rel(a, label_id)) }
inst_bltzal_gpr_rel :: #force_inline proc "contextless" (a: Register, label_id: u32) -> Instruction { return Instruction{ mnemonic = .BLTZAL, operand_count = 2, length = 4, ops = {op_reg(a), op_label(label_id), {}, {}} } }
emit_bltzal_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append(instructions, inst_bltzal_gpr_rel(a, label_id)) }
emit_bltzal_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append_elem(instructions, inst_bltzal_gpr_rel(a, label_id)) }
inst_bgezal_gpr_rel :: #force_inline proc "contextless" (a: Register, label_id: u32) -> Instruction { return Instruction{ mnemonic = .BGEZAL, operand_count = 2, length = 4, ops = {op_reg(a), op_label(label_id), {}, {}} } }
emit_bgezal_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append(instructions, inst_bgezal_gpr_rel(a, label_id)) }
emit_bgezal_gpr_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, label_id: u32) { append_elem(instructions, inst_bgezal_gpr_rel(a, label_id)) }
inst_j_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return Instruction{ mnemonic = .J, operand_count = 1, length = 4, ops = {op_label(label_id), {}, {}, {}} } }
emit_j_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_j_rel(label_id)) }
emit_j_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_j_rel(label_id)) }
inst_jal_rel :: #force_inline proc "contextless" (label_id: u32) -> Instruction { return Instruction{ mnemonic = .JAL, operand_count = 1, length = 4, ops = {op_label(label_id), {}, {}, {}} } }
emit_jal_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append(instructions, inst_jal_rel(label_id)) }
emit_jal_rel :: #force_inline proc(instructions: ^[dynamic]Instruction, label_id: u32) { append_elem(instructions, inst_jal_rel(label_id)) }
inst_jr_gpr :: #force_inline proc "contextless" (a: Register) -> Instruction { return Instruction{ mnemonic = .JR, operand_count = 1, length = 4, ops = {op_reg(a), {}, {}, {}} } }
emit_jr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register) { append(instructions, inst_jr_gpr(a)) }
emit_jr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register) { append_elem(instructions, inst_jr_gpr(a)) }
inst_jalr_gpr_gpr :: #force_inline proc "contextless" (a: Register, b: Register) -> Instruction { return Instruction{ mnemonic = .JALR, operand_count = 2, length = 4, ops = {op_reg(a), op_reg(b), {}, {}} } }
emit_jalr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append(instructions, inst_jalr_gpr_gpr(a, b)) }
emit_jalr_gpr_gpr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append_elem(instructions, inst_jalr_gpr_gpr(a, b)) }
inst_lb_gpr_mem :: #force_inline proc "contextless" (a: Register, m: Memory) -> Instruction { return Instruction{ mnemonic = .LB, operand_count = 2, length = 4, ops = {op_reg(a), op_mem(m, 4), {}, {}} } }
emit_lb_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append(instructions, inst_lb_gpr_mem(a, m)) }
emit_lb_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append_elem(instructions, inst_lb_gpr_mem(a, m)) }
inst_lh_gpr_mem :: #force_inline proc "contextless" (a: Register, m: Memory) -> Instruction { return Instruction{ mnemonic = .LH, operand_count = 2, length = 4, ops = {op_reg(a), op_mem(m, 4), {}, {}} } }
emit_lh_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append(instructions, inst_lh_gpr_mem(a, m)) }
emit_lh_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append_elem(instructions, inst_lh_gpr_mem(a, m)) }
inst_lw_gpr_mem :: #force_inline proc "contextless" (a: Register, m: Memory) -> Instruction { return Instruction{ mnemonic = .LW, operand_count = 2, length = 4, ops = {op_reg(a), op_mem(m, 4), {}, {}} } }
emit_lw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append(instructions, inst_lw_gpr_mem(a, m)) }
emit_lw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append_elem(instructions, inst_lw_gpr_mem(a, m)) }
inst_lbu_gpr_mem :: #force_inline proc "contextless" (a: Register, m: Memory) -> Instruction { return Instruction{ mnemonic = .LBU, operand_count = 2, length = 4, ops = {op_reg(a), op_mem(m, 4), {}, {}} } }
emit_lbu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append(instructions, inst_lbu_gpr_mem(a, m)) }
emit_lbu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append_elem(instructions, inst_lbu_gpr_mem(a, m)) }
inst_lhu_gpr_mem :: #force_inline proc "contextless" (a: Register, m: Memory) -> Instruction { return Instruction{ mnemonic = .LHU, operand_count = 2, length = 4, ops = {op_reg(a), op_mem(m, 4), {}, {}} } }
emit_lhu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append(instructions, inst_lhu_gpr_mem(a, m)) }
emit_lhu_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append_elem(instructions, inst_lhu_gpr_mem(a, m)) }
inst_sb_gpr_mem :: #force_inline proc "contextless" (a: Register, m: Memory) -> Instruction { return Instruction{ mnemonic = .SB, operand_count = 2, length = 4, ops = {op_reg(a), op_mem(m, 4), {}, {}} } }
emit_sb_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append(instructions, inst_sb_gpr_mem(a, m)) }
emit_sb_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append_elem(instructions, inst_sb_gpr_mem(a, m)) }
inst_sh_gpr_mem :: #force_inline proc "contextless" (a: Register, m: Memory) -> Instruction { return Instruction{ mnemonic = .SH, operand_count = 2, length = 4, ops = {op_reg(a), op_mem(m, 4), {}, {}} } }
emit_sh_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append(instructions, inst_sh_gpr_mem(a, m)) }
emit_sh_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append_elem(instructions, inst_sh_gpr_mem(a, m)) }
inst_sw_gpr_mem :: #force_inline proc "contextless" (a: Register, m: Memory) -> Instruction { return Instruction{ mnemonic = .SW, operand_count = 2, length = 4, ops = {op_reg(a), op_mem(m, 4), {}, {}} } }
emit_sw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append(instructions, inst_sw_gpr_mem(a, m)) }
emit_sw_gpr_mem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Memory) { append_elem(instructions, inst_sw_gpr_mem(a, m)) }
inst_break_imm20 :: #force_inline proc "contextless" (imm: i64) -> Instruction { return Instruction{ mnemonic = .BREAK, operand_count = 1, length = 4, ops = {op_imm(imm, 4), {}, {}, {}} } }
emit_break_imm20 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append(instructions, inst_break_imm20(imm)) }
emit_break_imm20 :: #force_inline proc(instructions: ^[dynamic]Instruction, imm: i64) { append_elem(instructions, inst_break_imm20(imm)) }
inst_nop_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{ mnemonic = .NOP, operand_count = 0, length = 4, ops = {{}, {}, {}, {}} } }
emit_nop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_nop_none()) }
emit_nop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_nop_none()) }
inst_mfc0_gpr_cp0 :: #force_inline proc "contextless" (a: Register, b: Register) -> Instruction { return Instruction{ mnemonic = .MFC0, operand_count = 2, length = 4, ops = {op_reg(a), op_reg(b), {}, {}} } }
emit_mfc0_gpr_cp0 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append(instructions, inst_mfc0_gpr_cp0(a, b)) }
emit_mfc0_gpr_cp0 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append_elem(instructions, inst_mfc0_gpr_cp0(a, b)) }
inst_mtc0_gpr_cp0 :: #force_inline proc "contextless" (a: Register, b: Register) -> Instruction { return Instruction{ mnemonic = .MTC0, operand_count = 2, length = 4, ops = {op_reg(a), op_reg(b), {}, {}} } }
emit_mtc0_gpr_cp0 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append(instructions, inst_mtc0_gpr_cp0(a, b)) }
emit_mtc0_gpr_cp0 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append_elem(instructions, inst_mtc0_gpr_cp0(a, b)) }
inst_mfc2_gpr_vr :: #force_inline proc "contextless" (a: Register, b: Register) -> Instruction { return Instruction{ mnemonic = .MFC2, operand_count = 2, length = 4, ops = {op_reg(a), op_vr(b), {}, {}} } }
emit_mfc2_gpr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append(instructions, inst_mfc2_gpr_vr(a, b)) }
emit_mfc2_gpr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append_elem(instructions, inst_mfc2_gpr_vr(a, b)) }
inst_mtc2_gpr_vr :: #force_inline proc "contextless" (a: Register, b: Register) -> Instruction { return Instruction{ mnemonic = .MTC2, operand_count = 2, length = 4, ops = {op_reg(a), op_vr(b), {}, {}} } }
emit_mtc2_gpr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append(instructions, inst_mtc2_gpr_vr(a, b)) }
emit_mtc2_gpr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append_elem(instructions, inst_mtc2_gpr_vr(a, b)) }
inst_cfc2_gpr_cp2 :: #force_inline proc "contextless" (a: Register, b: Register) -> Instruction { return Instruction{ mnemonic = .CFC2, operand_count = 2, length = 4, ops = {op_reg(a), op_reg(b), {}, {}} } }
emit_cfc2_gpr_cp2 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append(instructions, inst_cfc2_gpr_cp2(a, b)) }
emit_cfc2_gpr_cp2 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append_elem(instructions, inst_cfc2_gpr_cp2(a, b)) }
inst_ctc2_gpr_cp2 :: #force_inline proc "contextless" (a: Register, b: Register) -> Instruction { return Instruction{ mnemonic = .CTC2, operand_count = 2, length = 4, ops = {op_reg(a), op_reg(b), {}, {}} } }
emit_ctc2_gpr_cp2 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append(instructions, inst_ctc2_gpr_cp2(a, b)) }
emit_ctc2_gpr_cp2 :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register) { append_elem(instructions, inst_ctc2_gpr_cp2(a, b)) }
inst_vmulf_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMULF, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmulf_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmulf_vr_vr_vr(a, b, c, element)) }
emit_vmulf_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmulf_vr_vr_vr(a, b, c, element)) }
inst_vmulu_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMULU, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmulu_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmulu_vr_vr_vr(a, b, c, element)) }
emit_vmulu_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmulu_vr_vr_vr(a, b, c, element)) }
inst_vmudl_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMUDL, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmudl_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmudl_vr_vr_vr(a, b, c, element)) }
emit_vmudl_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmudl_vr_vr_vr(a, b, c, element)) }
inst_vmudm_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMUDM, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmudm_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmudm_vr_vr_vr(a, b, c, element)) }
emit_vmudm_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmudm_vr_vr_vr(a, b, c, element)) }
inst_vmudn_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMUDN, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmudn_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmudn_vr_vr_vr(a, b, c, element)) }
emit_vmudn_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmudn_vr_vr_vr(a, b, c, element)) }
inst_vmudh_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMUDH, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmudh_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmudh_vr_vr_vr(a, b, c, element)) }
emit_vmudh_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmudh_vr_vr_vr(a, b, c, element)) }
inst_vmacf_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMACF, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmacf_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmacf_vr_vr_vr(a, b, c, element)) }
emit_vmacf_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmacf_vr_vr_vr(a, b, c, element)) }
inst_vmacu_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMACU, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmacu_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmacu_vr_vr_vr(a, b, c, element)) }
emit_vmacu_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmacu_vr_vr_vr(a, b, c, element)) }
inst_vmadl_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMADL, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmadl_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmadl_vr_vr_vr(a, b, c, element)) }
emit_vmadl_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmadl_vr_vr_vr(a, b, c, element)) }
inst_vmadm_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMADM, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmadm_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmadm_vr_vr_vr(a, b, c, element)) }
emit_vmadm_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmadm_vr_vr_vr(a, b, c, element)) }
inst_vmadn_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMADN, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmadn_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmadn_vr_vr_vr(a, b, c, element)) }
emit_vmadn_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmadn_vr_vr_vr(a, b, c, element)) }
inst_vmadh_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMADH, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmadh_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmadh_vr_vr_vr(a, b, c, element)) }
emit_vmadh_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmadh_vr_vr_vr(a, b, c, element)) }
inst_vadd_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VADD, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vadd_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vadd_vr_vr_vr(a, b, c, element)) }
emit_vadd_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vadd_vr_vr_vr(a, b, c, element)) }
inst_vsub_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VSUB, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vsub_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vsub_vr_vr_vr(a, b, c, element)) }
emit_vsub_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vsub_vr_vr_vr(a, b, c, element)) }
inst_vabs_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VABS, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vabs_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vabs_vr_vr_vr(a, b, c, element)) }
emit_vabs_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vabs_vr_vr_vr(a, b, c, element)) }
inst_vaddc_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VADDC, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vaddc_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vaddc_vr_vr_vr(a, b, c, element)) }
emit_vaddc_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vaddc_vr_vr_vr(a, b, c, element)) }
inst_vsubc_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VSUBC, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vsubc_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vsubc_vr_vr_vr(a, b, c, element)) }
emit_vsubc_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vsubc_vr_vr_vr(a, b, c, element)) }
inst_vsar_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VSAR, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vsar_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vsar_vr_vr_vr(a, b, c, element)) }
emit_vsar_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vsar_vr_vr_vr(a, b, c, element)) }
inst_vlt_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VLT, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vlt_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vlt_vr_vr_vr(a, b, c, element)) }
emit_vlt_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vlt_vr_vr_vr(a, b, c, element)) }
inst_veq_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VEQ, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_veq_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_veq_vr_vr_vr(a, b, c, element)) }
emit_veq_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_veq_vr_vr_vr(a, b, c, element)) }
inst_vne_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VNE, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vne_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vne_vr_vr_vr(a, b, c, element)) }
emit_vne_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vne_vr_vr_vr(a, b, c, element)) }
inst_vge_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VGE, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vge_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vge_vr_vr_vr(a, b, c, element)) }
emit_vge_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vge_vr_vr_vr(a, b, c, element)) }
inst_vcl_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VCL, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vcl_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vcl_vr_vr_vr(a, b, c, element)) }
emit_vcl_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vcl_vr_vr_vr(a, b, c, element)) }
inst_vch_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VCH, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vch_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vch_vr_vr_vr(a, b, c, element)) }
emit_vch_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vch_vr_vr_vr(a, b, c, element)) }
inst_vcr_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VCR, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vcr_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vcr_vr_vr_vr(a, b, c, element)) }
emit_vcr_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vcr_vr_vr_vr(a, b, c, element)) }
inst_vmrg_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMRG, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vmrg_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vmrg_vr_vr_vr(a, b, c, element)) }
emit_vmrg_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vmrg_vr_vr_vr(a, b, c, element)) }
inst_vand_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VAND, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vand_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vand_vr_vr_vr(a, b, c, element)) }
emit_vand_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vand_vr_vr_vr(a, b, c, element)) }
inst_vnand_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VNAND, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vnand_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vnand_vr_vr_vr(a, b, c, element)) }
emit_vnand_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vnand_vr_vr_vr(a, b, c, element)) }
inst_vor_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VOR, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vor_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vor_vr_vr_vr(a, b, c, element)) }
emit_vor_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vor_vr_vr_vr(a, b, c, element)) }
inst_vnor_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VNOR, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vnor_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vnor_vr_vr_vr(a, b, c, element)) }
emit_vnor_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vnor_vr_vr_vr(a, b, c, element)) }
inst_vxor_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VXOR, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vxor_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vxor_vr_vr_vr(a, b, c, element)) }
emit_vxor_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vxor_vr_vr_vr(a, b, c, element)) }
inst_vnxor_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VNXOR, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vnxor_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vnxor_vr_vr_vr(a, b, c, element)) }
emit_vnxor_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vnxor_vr_vr_vr(a, b, c, element)) }
inst_vrcp_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VRCP, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vrcp_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vrcp_vr_vr_vr(a, b, c, element)) }
emit_vrcp_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vrcp_vr_vr_vr(a, b, c, element)) }
inst_vrcpl_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VRCPL, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vrcpl_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vrcpl_vr_vr_vr(a, b, c, element)) }
emit_vrcpl_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vrcpl_vr_vr_vr(a, b, c, element)) }
inst_vrcph_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VRCPH, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vrcph_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vrcph_vr_vr_vr(a, b, c, element)) }
emit_vrcph_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vrcph_vr_vr_vr(a, b, c, element)) }
inst_vmov_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VMOV, operand_count = 2, length = 4, ops = {op_vr(a), op_vr(b, element), {}, {}} } }
emit_vmov_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, element: u8 = 0) { append(instructions, inst_vmov_vr_vr(a, b, element)) }
emit_vmov_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, element: u8 = 0) { append_elem(instructions, inst_vmov_vr_vr(a, b, element)) }
inst_vrsq_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VRSQ, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vrsq_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vrsq_vr_vr_vr(a, b, c, element)) }
emit_vrsq_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vrsq_vr_vr_vr(a, b, c, element)) }
inst_vrsql_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VRSQL, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vrsql_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vrsql_vr_vr_vr(a, b, c, element)) }
emit_vrsql_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vrsql_vr_vr_vr(a, b, c, element)) }
inst_vrsqh_vr_vr_vr :: #force_inline proc "contextless" (a: Register, b: Register, c: Register, element: u8 = 0) -> Instruction { return Instruction{ mnemonic = .VRSQH, operand_count = 3, length = 4, ops = {op_vr(a), op_vr(b), op_vr(c, element), {}} } }
emit_vrsqh_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append(instructions, inst_vrsqh_vr_vr_vr(a, b, c, element)) }
emit_vrsqh_vr_vr_vr :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, b: Register, c: Register, element: u8 = 0) { append_elem(instructions, inst_vrsqh_vr_vr_vr(a, b, c, element)) }
inst_vnop_none :: #force_inline proc "contextless" () -> Instruction { return Instruction{ mnemonic = .VNOP, operand_count = 0, length = 4, ops = {{}, {}, {}, {}} } }
emit_vnop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append(instructions, inst_vnop_none()) }
emit_vnop_none :: #force_inline proc(instructions: ^[dynamic]Instruction) { append_elem(instructions, inst_vnop_none()) }
inst_lbv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LBV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_lbv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_lbv_vr_vmem(a, m)) }
emit_lbv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_lbv_vr_vmem(a, m)) }
inst_lsv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LSV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_lsv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_lsv_vr_vmem(a, m)) }
emit_lsv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_lsv_vr_vmem(a, m)) }
inst_llv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LLV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_llv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_llv_vr_vmem(a, m)) }
emit_llv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_llv_vr_vmem(a, m)) }
inst_ldv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LDV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_ldv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_ldv_vr_vmem(a, m)) }
emit_ldv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_ldv_vr_vmem(a, m)) }
inst_lqv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LQV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_lqv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_lqv_vr_vmem(a, m)) }
emit_lqv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_lqv_vr_vmem(a, m)) }
inst_lrv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LRV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_lrv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_lrv_vr_vmem(a, m)) }
emit_lrv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_lrv_vr_vmem(a, m)) }
inst_lpv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LPV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_lpv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_lpv_vr_vmem(a, m)) }
emit_lpv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_lpv_vr_vmem(a, m)) }
inst_luv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LUV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_luv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_luv_vr_vmem(a, m)) }
emit_luv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_luv_vr_vmem(a, m)) }
inst_lhv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LHV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_lhv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_lhv_vr_vmem(a, m)) }
emit_lhv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_lhv_vr_vmem(a, m)) }
inst_lfv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LFV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_lfv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_lfv_vr_vmem(a, m)) }
emit_lfv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_lfv_vr_vmem(a, m)) }
inst_lwv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LWV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_lwv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_lwv_vr_vmem(a, m)) }
emit_lwv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_lwv_vr_vmem(a, m)) }
inst_ltv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .LTV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_ltv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_ltv_vr_vmem(a, m)) }
emit_ltv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_ltv_vr_vmem(a, m)) }
inst_sbv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SBV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_sbv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_sbv_vr_vmem(a, m)) }
emit_sbv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_sbv_vr_vmem(a, m)) }
inst_ssv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SSV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_ssv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_ssv_vr_vmem(a, m)) }
emit_ssv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_ssv_vr_vmem(a, m)) }
inst_slv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SLV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_slv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_slv_vr_vmem(a, m)) }
emit_slv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_slv_vr_vmem(a, m)) }
inst_sdv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SDV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_sdv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_sdv_vr_vmem(a, m)) }
emit_sdv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_sdv_vr_vmem(a, m)) }
inst_sqv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SQV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_sqv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_sqv_vr_vmem(a, m)) }
emit_sqv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_sqv_vr_vmem(a, m)) }
inst_srv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SRV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_srv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_srv_vr_vmem(a, m)) }
emit_srv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_srv_vr_vmem(a, m)) }
inst_spv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SPV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_spv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_spv_vr_vmem(a, m)) }
emit_spv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_spv_vr_vmem(a, m)) }
inst_suv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SUV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_suv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_suv_vr_vmem(a, m)) }
emit_suv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_suv_vr_vmem(a, m)) }
inst_shv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SHV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_shv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_shv_vr_vmem(a, m)) }
emit_shv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_shv_vr_vmem(a, m)) }
inst_sfv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SFV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_sfv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_sfv_vr_vmem(a, m)) }
emit_sfv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_sfv_vr_vmem(a, m)) }
inst_swv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .SWV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_swv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_swv_vr_vmem(a, m)) }
emit_swv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_swv_vr_vmem(a, m)) }
inst_stv_vr_vmem :: #force_inline proc "contextless" (a: Register, m: Vector_Mem) -> Instruction { return Instruction{ mnemonic = .STV, operand_count = 2, length = 4, ops = {op_vr(a), op_vmem(m, 16), {}, {}} } }
emit_stv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append(instructions, inst_stv_vr_vmem(a, m)) }
emit_stv_vr_vmem :: #force_inline proc(instructions: ^[dynamic]Instruction, a: Register, m: Vector_Mem) { append_elem(instructions, inst_stv_vr_vmem(a, m)) }
// =============================================================================
// Overload Groups
@@ -408,7 +408,7 @@ generate_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, pad: int) {
strings.write_string(sb, " = 0")
}
}
strings.write_string(sb, ") { append(instructions, ")
strings.write_string(sb, ") { append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_string(sb, "(")
for p, i in params {
File diff suppressed because it is too large. Load diff
@@ -1382,7 +1382,7 @@ generate_emit_helper_call :: proc(sb: ^strings.Builder, entry: Proc_Entry) {
case:
// Unknown pattern - fall back to append with inst_ call
strings.write_string(sb, "append(instructions, ")
strings.write_string(sb, "append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_string(sb, "(")
for i in 0..<sig.count {
@@ -1469,7 +1469,7 @@ generate_emit_proc :: proc(sb: ^strings.Builder, entry: Proc_Entry, max_name_pad
strings.write_string(sb, params)
// Reuse the (class-correct, hint-baked) inst_ builder rather than re-emitting
// the operands -- keeps emit_ in lockstep with inst_ and inherits the hint.
strings.write_string(sb, ") { append(instructions, ")
strings.write_string(sb, ") { append_elem(instructions, ")
strings.write_string(sb, entry.proc_name)
strings.write_string(sb, "(")
for i in 0..<sig.count {
+12
View File
@@ -1,21 +1,33 @@
#+build arm64,arm32
package simd_arm
// AES single round encryption.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaeseq_u8)
@(require_results, enable_target_feature = "aes")
vaeseq_u8 :: #force_inline proc "c" (data, key: uint8x16_t) -> uint8x16_t {
return _vaeseq_u8(data, key)
}
// AES single round decryption.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesdq_u8)
@(require_results, enable_target_feature = "aes")
vaesdq_u8 :: #force_inline proc "c" (data, key: uint8x16_t) -> uint8x16_t {
return _vaesdq_u8(data, key)
}
// AES mix columns.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesmcq_u8)
@(require_results, enable_target_feature = "aes")
vaesmcq_u8 :: #force_inline proc "c" (data: uint8x16_t) -> uint8x16_t {
return _vaesmcq_u8(data)
}
// AES inverse mix columns.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vaesimcq_u8)
@(require_results,enable_target_feature = "aes")
vaesimcq_u8 :: #force_inline proc "c" (data: uint8x16_t) -> uint8x16_t {
return _vaesimcq_u8(data)
File diff suppressed because it is too large. Load diff
+386
View File
@@ -1243,6 +1243,226 @@ vuzpq_p16 :: #force_inline proc "c" (a, b: poly16x8_t) -> poly16x8x2_t {
}
}
// Reverse elements in 16-bit halfwords.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev16_p8)
@(require_results, enable_target_feature = "neon")
vrev16_p8 :: #force_inline proc "c" (a: poly8x8_t) -> poly8x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 1, 0, 3, 2, 5, 4, 7, 6)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(a, a, 1, 0, 3, 2, 5, 4, 7, 6)
return simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Reverse elements in 16-bit halfwords.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev16q_p8)
@(require_results, enable_target_feature = "neon")
vrev16q_p8 :: #force_inline proc "c" (a: poly8x16_t) -> poly8x16_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14)
} else {
a := simd.shuffle(a, a, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(a, a, 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14)
return simd.shuffle(b, b, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Reverse elements in 32-bit words.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32_p8)
@(require_results, enable_target_feature = "neon")
vrev32_p8 :: #force_inline proc "c" (a: poly8x8_t) -> poly8x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 3, 2, 1, 0, 7, 6, 5, 4)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(a, a, 3, 2, 1, 0, 7, 6, 5, 4)
return simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Reverse elements in 32-bit words.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32_p16)
@(require_results, enable_target_feature = "neon")
vrev32_p16 :: #force_inline proc "c" (a: poly16x4_t) -> poly16x4_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 1, 0, 3, 2)
} else {
a := simd.shuffle(a, a, 3, 2, 1, 0)
b := simd.shuffle(a, a, 1, 0, 3, 2)
return simd.shuffle(b, b, 3, 2, 1, 0)
}
}
// Reverse elements in 32-bit words.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32q_p8)
@(require_results, enable_target_feature = "neon")
vrev32q_p8 :: #force_inline proc "c" (a: poly8x16_t) -> poly8x16_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12)
} else {
a := simd.shuffle(a, a, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(a, a, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12)
return simd.shuffle(b, b, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Reverse elements in 32-bit words.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev32q_p16)
@(require_results, enable_target_feature = "neon")
vrev32q_p16 :: #force_inline proc "c" (a: poly16x8_t) -> poly16x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 1, 0, 3, 2, 5, 4, 7, 6)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(a, a, 1, 0, 3, 2, 5, 4, 7, 6)
return simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Reverse elements in 64-bit doublewords.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_p8)
@(require_results, enable_target_feature = "neon")
vrev64_p8 :: #force_inline proc "c" (a: poly8x8_t) -> poly8x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
return simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Reverse elements in 64-bit doublewords.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64_p16)
@(require_results, enable_target_feature = "neon")
vrev64_p16 :: #force_inline proc "c" (a: poly16x4_t) -> poly16x4_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 3, 2, 1, 0)
} else {
a := simd.shuffle(a, a, 3, 2, 1, 0)
b := simd.shuffle(a, a, 3, 2, 1, 0)
return simd.shuffle(b, b, 3, 2, 1, 0)
}
}
// Reverse elements in 64-bit doublewords.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_p8)
@(require_results, enable_target_feature = "neon")
vrev64q_p8 :: #force_inline proc "c" (a: poly8x16_t) -> poly8x16_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8)
} else {
a := simd.shuffle(a, a, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8)
return simd.shuffle(b, b, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Reverse elements in 64-bit doublewords.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrev64q_p16)
@(require_results, enable_target_feature = "neon")
vrev64q_p16 :: #force_inline proc "c" (a: poly16x8_t) -> poly16x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, a, 3, 2, 1, 0, 7, 6, 5, 4)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(a, a, 3, 2, 1, 0, 7, 6, 5, 4)
return simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Transpose vectors.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_p8)
@(require_results, enable_target_feature = "neon")
vtrn_p8 :: #force_inline proc "c" (a, b: poly8x8_t) -> poly8x8x2_t {
when ODIN_ENDIAN == .Little {
c := simd.shuffle(a, b, 0, 8, 2, 10, 4, 12, 6, 14)
d := simd.shuffle(a, b, 1, 9, 3, 11, 5, 13, 7, 15)
return poly8x8x2_t {c, d}
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 0, 8, 2, 10, 4, 12, 6, 14)
d := simd.shuffle(a, b, 1, 9, 3, 11, 5, 13, 7, 15)
c = simd.shuffle(c, c, 7, 6, 5, 4, 3, 2, 1, 0)
d = simd.shuffle(d, d, 7, 6, 5, 4, 3, 2, 1, 0)
return poly8x8x2_t {c, d}
}
}
// Transpose vectors.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn_p16)
@(require_results, enable_target_feature = "neon")
vtrn_p16 :: #force_inline proc "c" (a, b: poly16x4_t) -> poly16x4x2_t {
when ODIN_ENDIAN == .Little {
c := simd.shuffle(a, b, 0, 4, 2, 6)
d := simd.shuffle(a, b, 1, 5, 3, 7)
return poly16x4x2_t {c, d}
} else {
a := simd.shuffle(a, a, 3, 2, 1, 0)
b := simd.shuffle(b, b, 3, 2, 1, 0)
c := simd.shuffle(a, b, 0, 4, 2, 6)
d := simd.shuffle(a, b, 1, 5, 3, 7)
c = simd.shuffle(c, c, 3, 2, 1, 0)
d = simd.shuffle(d, d, 3, 2, 1, 0)
return poly16x4x2_t {c, d}
}
}
// Transpose vectors.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_p8)
@(require_results, enable_target_feature = "neon")
vtrnq_p8 :: #force_inline proc "c" (a, b: poly8x16_t) -> poly8x16x2_t {
when ODIN_ENDIAN == .Little {
c := simd.shuffle(a, b, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30)
d := simd.shuffle(a, b, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31)
return poly8x16x2_t {c, d}
} else {
a := simd.shuffle(a, a, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30)
d := simd.shuffle(a, b, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31)
c = simd.shuffle(c, c, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
d = simd.shuffle(d, d, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
return poly8x16x2_t {c, d}
}
}
// Transpose vectors.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrnq_p16)
@(require_results, enable_target_feature = "neon")
vtrnq_p16 :: #force_inline proc "c" (a, b: poly16x8_t) -> poly16x8x2_t {
when ODIN_ENDIAN == .Little {
c := simd.shuffle(a, b, 0, 8, 2, 10, 4, 12, 6, 14)
d := simd.shuffle(a, b, 1, 9, 3, 11, 5, 13, 7, 15)
return poly16x8x2_t {c, d}
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 0, 8, 2, 10, 4, 12, 6, 14)
d := simd.shuffle(a, b, 1, 9, 3, 11, 5, 13, 7, 15)
c = simd.shuffle(c, c, 7, 6, 5, 4, 3, 2, 1, 0)
d = simd.shuffle(d, d, 7, 6, 5, 4, 3, 2, 1, 0)
return poly16x8x2_t {c, d}
}
}
when ODIN_ARCH == .arm64 {
// Polynomial multiply long
//
@@ -2013,6 +2233,172 @@ when ODIN_ARCH == .arm64 {
return simd.shuffle(c, c, 1, 0)
}
}
// Reverse bit order.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbit_p8)
@(require_results, enable_target_feature = "neon")
vrbit_p8 :: #force_inline proc "c" (a: poly8x8_t) -> poly8x8_t {
return simd.reverse_bits(a)
}
// Reverse bit order.
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vrbitq_p8)
@(require_results, enable_target_feature = "neon")
vrbitq_p8 :: #force_inline proc "c" (a: poly8x16_t) -> poly8x16_t {
return simd.reverse_bits(a)
}
// Transpose vectors (primary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_p8)
@(require_results, enable_target_feature = "neon")
vtrn1_p8 :: #force_inline proc "c" (a, b: poly8x8_t) -> poly8x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 0, 8, 2, 10, 4, 12, 6, 14)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 0, 8, 2, 10, 4, 12, 6, 14)
return simd.shuffle(c, c, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Transpose vectors (primary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1_p16)
@(require_results, enable_target_feature = "neon")
vtrn1_p16 :: #force_inline proc "c" (a, b: poly16x4_t) -> poly16x4_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 0, 4, 2, 6)
} else {
a := simd.shuffle(a, a, 3, 2, 1, 0)
b := simd.shuffle(b, b, 3, 2, 1, 0)
c := simd.shuffle(a, b, 0, 4, 2, 6)
return simd.shuffle(c, c, 3, 2, 1, 0)
}
}
// Transpose vectors (primary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p8)
@(require_results, enable_target_feature = "neon")
vtrn1q_p8 :: #force_inline proc "c" (a, b: poly8x16_t) -> poly8x16_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30)
} else {
a := simd.shuffle(a, a, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30)
return simd.shuffle(c, c, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Transpose vectors (primary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p16)
@(require_results, enable_target_feature = "neon")
vtrn1q_p16 :: #force_inline proc "c" (a, b: poly16x8_t) -> poly16x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 0, 8, 2, 10, 4, 12, 6, 14)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 0, 8, 2, 10, 4, 12, 6, 14)
return simd.shuffle(c, c, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Transpose vectors (primary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn1q_p64)
@(require_results, enable_target_feature = "neon")
vtrn1q_p64 :: #force_inline proc "c" (a, b: poly64x2_t) -> poly64x2_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 0, 2)
} else {
a := simd.shuffle(a, a, 1, 0)
b := simd.shuffle(b, b, 1, 0)
c := simd.shuffle(a, b, 0, 2)
return simd.shuffle(c, c, 1, 0)
}
}
// Transpose vectors (secondary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_p8)
@(require_results, enable_target_feature = "neon")
vtrn2_p8 :: #force_inline proc "c" (a, b: poly8x8_t) -> poly8x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 1, 9, 3, 11, 5, 13, 7, 15)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 1, 9, 3, 11, 5, 13, 7, 15)
return simd.shuffle(c, c, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Transpose vectors (secondary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2_p16)
@(require_results, enable_target_feature = "neon")
vtrn2_p16 :: #force_inline proc "c" (a, b: poly16x4_t) -> poly16x4_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 1, 5, 3, 7)
} else {
a := simd.shuffle(a, a, 3, 2, 1, 0)
b := simd.shuffle(b, b, 3, 2, 1, 0)
c := simd.shuffle(a, b, 1, 5, 3, 7)
return simd.shuffle(c, c, 3, 2, 1, 0)
}
}
// Transpose vectors (secondary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p8)
@(require_results, enable_target_feature = "neon")
vtrn2q_p8 :: #force_inline proc "c" (a, b: poly8x16_t) -> poly8x16_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31)
} else {
a := simd.shuffle(a, a, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31)
return simd.shuffle(c, c, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Transpose vectors (secondary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p16)
@(require_results, enable_target_feature = "neon")
vtrn2q_p16 :: #force_inline proc "c" (a, b: poly16x8_t) -> poly16x8_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 1, 9, 3, 11, 5, 13, 7, 15)
} else {
a := simd.shuffle(a, a, 7, 6, 5, 4, 3, 2, 1, 0)
b := simd.shuffle(b, b, 7, 6, 5, 4, 3, 2, 1, 0)
c := simd.shuffle(a, b, 1, 9, 3, 11, 5, 13, 7, 15)
return simd.shuffle(c, c, 7, 6, 5, 4, 3, 2, 1, 0)
}
}
// Transpose vectors (secondary).
//
// [Arm's documentation](https://developer.arm.com/architectures/instruction-sets/intrinsics/vtrn2q_p64)
@(require_results, enable_target_feature = "neon")
vtrn2q_p64 :: #force_inline proc "c" (a, b: poly64x2_t) -> poly64x2_t {
when ODIN_ENDIAN == .Little {
return simd.shuffle(a, b, 1, 3)
} else {
a := simd.shuffle(a, a, 1, 0)
b := simd.shuffle(b, b, 1, 0)
c := simd.shuffle(a, b, 1, 3)
return simd.shuffle(c, c, 1, 0)
}
}
}
@(private, default_calling_convention = "none")
+2 -6
View File
@@ -200,9 +200,7 @@ _mm256_div_pd :: #force_inline proc "c" (a, b: __m256d) -> __m256d {
// - `0x02`: Round up, toward positive infinity.
// - `0x03`: Truncate the values.
//
// For a complete list of options, check [the LLVM docs][llvm_docs].
//
// [llvm_docs]: https://github.com/llvm-mirror/clang/blob/dcd8d797b20291f1a6b3e0ddda085aa2bbb382a8/lib/Headers/avxintrin.h#L382
// For a complete list of options, check [the LLVM docs](https://github.com/llvm-mirror/clang/blob/dcd8d797b20291f1a6b3e0ddda085aa2bbb382a8/lib/Headers/avxintrin.h#L382).
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_round_pd)
@(require_results, enable_target_feature="avx")
@@ -234,9 +232,7 @@ _mm256_floor_pd :: #force_inline proc "c" (a: __m256d) -> __m256d {
// - `0x02`: Round up, toward positive infinity.
// - `0x03`: Truncate the values.
//
// For a complete list of options, check [the LLVM docs][llvm_docs].
//
// [llvm_docs]: https://github.com/llvm-mirror/clang/blob/dcd8d797b20291f1a6b3e0ddda085aa2bbb382a8/lib/Headers/avxintrin.h#L382
// For a complete list of options, check [the LLVM docs](https://github.com/llvm-mirror/clang/blob/dcd8d797b20291f1a6b3e0ddda085aa2bbb382a8/lib/Headers/avxintrin.h#L382).
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_round_ps)
@(require_results, enable_target_feature="avx")
+125
View File
@@ -0,0 +1,125 @@
#+build i386, amd64
package simd_x86
import "core:simd"
// Shift packed 32-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srlv_epi32)
@(require_results, enable_target_feature="avx2")
_mm_srlv_epi32 :: #force_inline proc "c" (a: __m128i, count: __m128i) -> __m128i {
b := simd.lanes_lt(transmute(simd.u32x4)count, simd.u32x4(8 * size_of(u32)))
c := simd.select(b, transmute(simd.u32x4)count, simd.u32x4(0))
return transmute(__m128i)simd.select(b, simd.shr(transmute(simd.u32x4)a, c), simd.u32x4(0))
}
// Shift packed 64-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srlv_epi64)
@(require_results, enable_target_feature="avx2")
_mm_srlv_epi64 :: #force_inline proc "c" (a: __m128i, count: __m128i) -> __m128i {
b := simd.lanes_lt(transmute(simd.u64x2)count, simd.u64x2(8 * size_of(u64)))
c := simd.select(b, transmute(simd.u64x2)count, simd.u64x2(0))
return transmute(__m128i)simd.select(b, simd.shr(transmute(simd.u64x2)a, c), simd.u64x2(0))
}
// Shift packed 32-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_srlv_epi32)
@(require_results, enable_target_feature="avx2")
_mm256_srlv_epi32 :: #force_inline proc "c" (a: __m256i, count: __m256i) -> __m256i {
b := simd.lanes_lt(transmute(simd.u32x8)count, simd.u32x8(8 * size_of(u32)))
c := simd.select(b, transmute(simd.u32x8)count, simd.u32x8(0))
return transmute(__m256i)simd.select(b, simd.shr(transmute(simd.u32x8)a, c), simd.u32x8(0))
}
// Shift packed 64-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_srlv_epi64)
@(require_results, enable_target_feature="avx2")
_mm256_srlv_epi64 :: #force_inline proc "c" (a: __m256i, count: __m256i) -> __m256i {
b := simd.lanes_lt(transmute(simd.u64x4)count, simd.u64x4(8 * size_of(u64)))
c := simd.select(b, transmute(simd.u64x4)count, simd.u64x4(0))
return transmute(__m256i)simd.select(b, simd.shr(transmute(simd.u64x4)a, c), simd.u64x4(0))
}
// Shift packed 32-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sllv_epi32)
@(require_results, enable_target_feature="avx2")
_mm_sllv_epi32 :: #force_inline proc "c" (a: __m128i, count: __m128i) -> __m128i {
b := simd.lanes_lt(transmute(simd.u32x4)count, simd.u32x4(8 * size_of(u32)))
c := simd.select(b, transmute(simd.u32x4)count, simd.u32x4(0))
return transmute(__m128i)simd.select(b, simd.shl(transmute(simd.u32x4)a, c), simd.u32x4(0))
}
// Shift packed 64-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sllv_epi64)
@(require_results, enable_target_feature="avx2")
_mm_sllv_epi64 :: #force_inline proc "c" (a: __m128i, count: __m128i) -> __m128i {
b := simd.lanes_lt(transmute(simd.u64x2)count, simd.u64x2(8 * size_of(u64)))
c := simd.select(b, transmute(simd.u64x2)count, simd.u64x2(0))
return transmute(__m128i)simd.select(b, simd.shl(transmute(simd.u64x2)a, c), simd.u64x2(0))
}
// Shift packed 32-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sllv_epi32)
@(require_results, enable_target_feature="avx2")
_mm256_sllv_epi32 :: #force_inline proc "c" (a: __m256i, count: __m256i) -> __m256i {
b := simd.lanes_lt(transmute(simd.u32x8)count, simd.u32x8(8 * size_of(u32)))
c := simd.select(b, transmute(simd.u32x8)count, simd.u32x8(0))
return transmute(__m256i)simd.select(b, simd.shl(transmute(simd.u32x8)a, c), simd.u32x8(0))
}
// Shift packed 64-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sllv_epi64)
@(require_results, enable_target_feature="avx2")
_mm256_sllv_epi64 :: #force_inline proc "c" (a: __m256i, count: __m256i) -> __m256i {
b := simd.lanes_lt(transmute(simd.u64x4)count, simd.u64x4(8 * size_of(u64)))
c := simd.select(b, transmute(simd.u64x4)count, simd.u64x4(0))
return transmute(__m256i)simd.select(b, simd.shl(transmute(simd.u64x4)a, c), simd.u64x4(0))
}
// Compute the bitwise AND of 256 bits (representing integer data) in `a` and `b`, and store the result in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_and_si256)
@(require_results, enable_target_feature="avx2")
_mm256_and_si256 :: #force_inline proc "c" (a, b: __m256i) -> __m256i {
return simd.bit_and(a, b)
}
// Compute the bitwise NOT of 256 bits (representing integer data) in `a` and then AND with `b`, and store the result in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_andnot_si256)
@(require_results, enable_target_feature="avx2")
_mm256_andnot_si256 :: #force_inline proc "c" (a, b: __m256i) -> __m256i {
c := __m256i(-1)
return simd.bit_and(simd.bit_xor(a, c), b)
}
// Compute the bitwise OR of 256 bits (representing integer data) in `a` and `b`, and store the result in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_or_si256)
@(require_results, enable_target_feature="avx2")
_mm256_or_si256 :: #force_inline proc "c" (a, b: __m256i) -> __m256i {
return simd.bit_or(a, b)
}
// Compute the bitwise XOR of 256 bits (representing integer data) in `a` and `b`, and store the result in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_xor_si256)
@(require_results, enable_target_feature="avx2")
_mm256_xor_si256 :: #force_inline proc "c" (a, b: __m256i) -> __m256i {
return simd.bit_xor(a, b)
}
+70
View File
@@ -0,0 +1,70 @@
#+build i386, amd64
package simd_x86
import "core:simd"
// Shift packed 16-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_srlv_epi16)
@(require_results, enable_target_feature="avx512bw,avx512vl")
_mm_srlv_epi16 :: #force_inline proc "c" (a: __m128i, count: __m128i) -> __m128i {
b := simd.lanes_lt(transmute(simd.u16x8)count, simd.u16x8(8 * size_of(u16)))
c := simd.select(b, transmute(simd.u16x8)count, simd.u16x8(0))
return transmute(__m128i)simd.select(b, simd.shr(transmute(simd.u16x8)a, c), simd.u16x8(0))
}
// Shift packed 16-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_srlv_epi16)
@(require_results, enable_target_feature="avx512bw,avx512vl")
_mm256_srlv_epi16 :: #force_inline proc "c" (a: __m256i, count: __m256i) -> __m256i {
b := simd.lanes_lt(transmute(simd.u16x16)count, simd.u16x16(8 * size_of(u16)))
c := simd.select(b, transmute(simd.u16x16)count, simd.u16x16(0))
return transmute(__m256i)simd.select(b, simd.shr(transmute(simd.u16x16)a, c), simd.u16x16(0))
}
// Shift packed 16-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_srlv_epi16)
@(require_results, enable_target_feature="avx512bw,evex512")
_mm512_srlv_epi16 :: #force_inline proc "c" (a: __m512i, count: __m512i) -> __m512i {
b := simd.lanes_lt(transmute(simd.u16x32)count, simd.u16x32(8 * size_of(u16)))
c := simd.select(b, transmute(simd.u16x32)count, simd.u16x32(0))
return transmute(__m512i)simd.select(b, simd.shr(transmute(simd.u16x32)a, c), simd.u16x32(0))
}
// Shift packed 16-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sllv_epi16)
@(require_results, enable_target_feature="avx512bw,avx512vl")
_mm_sllv_epi16 :: #force_inline proc "c" (a: __m128i, count: __m128i) -> __m128i {
b := simd.lanes_lt(transmute(simd.u16x8)count, simd.u16x8(8 * size_of(u16)))
c := simd.select(b, transmute(simd.u16x8)count, simd.u16x8(0))
return transmute(__m128i)simd.select(b, simd.shl(transmute(simd.u16x8)a, c), simd.u16x8(0))
}
// Shift packed 16-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sllv_epi16)
@(require_results, enable_target_feature="avx512bw,avx512vl")
_mm256_sllv_epi16 :: #force_inline proc "c" (a: __m256i, count: __m256i) -> __m256i {
b := simd.lanes_lt(transmute(simd.u16x16)count, simd.u16x16(8 * size_of(u16)))
c := simd.select(b, transmute(simd.u16x16)count, simd.u16x16(0))
return transmute(__m256i)simd.select(b, simd.shl(transmute(simd.u16x16)a, c), simd.u16x16(0))
}
// Shift packed 16-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_sllv_epi16)
@(require_results, enable_target_feature="avx512bw,evex512")
_mm512_sllv_epi16 :: #force_inline proc "c" (a: __m512i, count: __m512i) -> __m512i {
b := simd.lanes_lt(transmute(simd.u16x32)count, simd.u16x32(8 * size_of(u16)))
c := simd.select(b, transmute(simd.u16x32)count, simd.u16x32(0))
return transmute(__m512i)simd.select(b, simd.shl(transmute(simd.u16x32)a, c), simd.u16x32(0))
}
+81
View File
@@ -0,0 +1,81 @@
#+build i386, amd64
package simd_x86
import "core:simd"
// Shift packed 32-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_srlv_epi32)
@(require_results, enable_target_feature="avx512f,evex512")
_mm512_srlv_epi32 :: #force_inline proc "c" (a: __m512i, count: __m512i) -> __m512i {
b := simd.lanes_lt(transmute(simd.u32x16)count, simd.u32x16(8 * size_of(u32)))
c := simd.select(b, transmute(simd.u32x16)count, simd.u32x16(0))
return transmute(__m512i)simd.select(b, simd.shr(transmute(simd.u32x16)a, c), simd.u32x16(0))
}
// Shift packed 64-bit integers in `a` right by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_srlv_epi64)
@(require_results, enable_target_feature="avx512f,evex512")
_mm512_srlv_epi64 :: #force_inline proc "c" (a: __m512i, count: __m512i) -> __m512i {
b := simd.lanes_lt(transmute(simd.u64x8)count, simd.u64x8(8 * size_of(u64)))
c := simd.select(b, transmute(simd.u64x8)count, simd.u64x8(0))
return transmute(__m512i)simd.select(b, simd.shr(transmute(simd.u64x8)a, c), simd.u64x8(0))
}
// Shift packed 32-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_sllv_epi32)
@(require_results, enable_target_feature="avx512f,evex512")
_mm512_sllv_epi32 :: #force_inline proc "c" (a: __m512i, count: __m512i) -> __m512i {
b := simd.lanes_lt(transmute(simd.u32x16)count, simd.u32x16(8 * size_of(u32)))
c := simd.select(b, transmute(simd.u32x16)count, simd.u32x16(0))
return transmute(__m512i)simd.select(b, simd.shl(transmute(simd.u32x16)a, c), simd.u32x16(0))
}
// Shift packed 64-bit integers in `a` left by the amount specified by
// the corresponding element in `count` while shifting in zeros, and store the results in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_sllv_epi64)
@(require_results, enable_target_feature="avx512f,evex512")
_mm512_sllv_epi64 :: #force_inline proc "c" (a: __m512i, count: __m512i) -> __m512i {
b := simd.lanes_lt(transmute(simd.u64x8)count, simd.u64x8(8 * size_of(u64)))
c := simd.select(b, transmute(simd.u64x8)count, simd.u64x8(0))
return transmute(__m512i)simd.select(b, simd.shl(transmute(simd.u64x8)a, c), simd.u64x8(0))
}
// Compute the bitwise AND of 512 bits (representing integer data) in `a` and `b`, and store the result in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_and_si512)
@(require_results, enable_target_feature="avx512f,evex512")
_mm512_and_si512 :: #force_inline proc "c" (a, b: __m512i) -> __m512i {
return simd.bit_and(a, b)
}
// Compute the bitwise NOT of 512 bits (representing integer data) in `a` and then AND with `b`, and store the result in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_andnot_si512)
@(require_results, enable_target_feature="avx512f,evex512")
_mm512_andnot_si512 :: #force_inline proc "c" (a, b: __m512i) -> __m512i {
c := __m512i(-1)
return simd.bit_and(simd.bit_xor(a, c), b)
}
// Compute the bitwise OR of 512 bits (representing integer data) in `a` and `b`, and store the result in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_or_si512)
@(require_results, enable_target_feature="avx512f,evex512")
_mm512_or_si512 :: #force_inline proc "c" (a, b: __m512i) -> __m512i {
return simd.bit_or(a, b)
}
// Compute the bitwise XOR of 512 bits (representing integer data) in `a` and `b`, and store the result in `dst`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm512_xor_si512)
@(require_results, enable_target_feature="avx512f,evex512")
_mm512_xor_si512 :: #force_inline proc "c" (a, b: __m512i) -> __m512i {
return simd.bit_xor(a, b)
}
+7 -2
View File
@@ -482,10 +482,15 @@ _mm_packus_epi16 :: #force_inline proc "c" (a, b: __m128i) -> __m128i {
_mm_extract_epi16 :: #force_inline proc "c" (a: __m128i, $IMM8: u32) -> i32 {
return i32(simd.extract(transmute(u16x8)a, IMM8))
}
// Copy `a` to `dst`, and insert the 16-bit integer `i` into `dst` at the location specified by `imm8`.
//
// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_insert_epi16)
@(require_results, enable_target_feature="sse2")
_mm_insert_epi16 :: #force_inline proc "c" (a: __m128i, i: i32, $IMM8: u32) -> __m128i {
return i32(simd.replace(transmute(u16x8)a, IMM8, i16(i)))
_mm_insert_epi16 :: #force_inline proc "c" (a: __m128i, i: i32, $IMM8: i32) -> __m128i where 0 <= IMM8, IMM8 < 8 {
return transmute(__m128i)simd.replace(transmute(simd.i16x8)a, uint(IMM8), i16(i))
}
@(require_results, enable_target_feature="sse2")
_mm_movemask_epi8 :: #force_inline proc "c" (a: __m128i) -> i32 {
return pmovmskb(transmute(i8x16)a)
+748 -2
View File
@@ -7,6 +7,17 @@ import "base:intrinsics"
_ :: intrinsics
ORD :: intrinsics.type_is_ordered
/*
A generic interface describing a sequence of elements that can be sorted.
It provides the operations the sorting procedures use to inspect and reorder
the elements: `len` reports the number of elements, `less` compares two
elements, and `swap` exchanges two elements. The underlying data lives in
`collection`.
Use `slice_interface` to obtain an `Interface` for a slice, or
`reverse_interface` to wrap an `Interface` so that it is ordered in reverse.
*/
Interface :: struct {
len: proc(it: Interface) -> int,
less: proc(it: Interface, i, j: int) -> bool,
@@ -14,8 +25,30 @@ Interface :: struct {
collection: rawptr,
}
// sort sorts an Interface
// This sort is not guaranteed to be stable
/*
Sorts the elements of an `Interface` in place.
This sort is not guaranteed to be stable.
Inputs:
- it: The `Interface` to sort.
Example:
import "core:fmt"
import "core:sort"
sort_example :: proc() {
data := []int{5, 2, 8, 1, 9}
sort.sort(sort.slice_interface(&data))
fmt.println(data)
}
Output:
[1, 2, 5, 8, 9]
*/
sort :: proc(it: Interface) {
max_depth :: proc(n: int) -> int { // 2*ceil(log2(n+1))
depth: int
@@ -29,6 +62,38 @@ sort :: proc(it: Interface) {
_quick_sort(it, 0, n, max_depth(n))
}
/*
Creates an `Interface` over the given slice of ordered elements, for use with
the sorting procedures.
The elements are compared with the `<` operator, so the resulting sort is in
ascending order.
Inputs:
- s: A pointer to the slice to wrap.
Returns:
- An `Interface` that describes the elements of `s`.
Example:
import "core:fmt"
import "core:sort"
slice_interface_example :: proc() {
data := []int{3, 1, 2}
it := sort.slice_interface(&data)
fmt.println(sort.is_sorted(it))
sort.sort(it)
fmt.println(data)
}
Output:
false
[1, 2, 3]
*/
slice_interface :: proc(s: ^$T/[]$E) -> Interface where ORD(E) {
return Interface{
collection = rawptr(s),
@@ -47,6 +112,33 @@ slice_interface :: proc(s: ^$T/[]$E) -> Interface where ORD(E) {
}
}
/*
Wraps an `Interface` so that the ordering is reversed, making the sorting
procedures sort the elements in descending order.
Inputs:
- it: A pointer to the `Interface` to reverse.
Returns:
- A new `Interface` that reverses the ordering of `it`.
Example:
import "core:fmt"
import "core:sort"
reverse_interface_example :: proc() {
data := []int{5, 2, 8}
s := sort.slice_interface(&data)
sort.sort(sort.reverse_interface(&s))
fmt.println(data)
}
Output:
[8, 5, 2]
*/
reverse_interface :: proc(it: ^Interface) -> Interface {
return Interface{
collection = it,
@@ -66,11 +158,62 @@ reverse_interface :: proc(it: ^Interface) -> Interface {
}
}
/*
Sorts the elements of an `Interface` in descending order, in place.
This sort is not guaranteed to be stable.
Inputs:
- it: The `Interface` to sort.
Example:
import "core:fmt"
import "core:sort"
reverse_sort_example :: proc() {
data := []int{5, 2, 8, 1}
sort.reverse_sort(sort.slice_interface(&data))
fmt.println(data)
}
Output:
[8, 5, 2, 1]
*/
reverse_sort :: proc(it: Interface) {
it := it
sort(reverse_interface(&it))
}
/*
Reports whether the elements of an `Interface` are in ascending order.
Inputs:
- it: The `Interface` to check.
Returns:
- `true` if the elements are sorted in ascending order, `false` otherwise.
Example:
import "core:fmt"
import "core:sort"
is_sorted_example :: proc() {
a := []int{1, 2, 3}
b := []int{3, 1, 2}
fmt.println(sort.is_sorted(sort.slice_interface(&a)))
fmt.println(sort.is_sorted(sort.slice_interface(&b)))
}
Output:
true
false
*/
is_sorted :: proc(it: Interface) -> bool {
n := it->len()
for i := n-1; i > 0; i -= 1 {
@@ -82,12 +225,64 @@ is_sorted :: proc(it: Interface) -> bool {
}
/*
Swaps `n` elements beginning at index `a` with the `n` elements beginning at
index `b`.
Inputs:
- it: The `Interface`.
- a: Start index of the first range to swap.
- b: Start index of the second range to swap.
- n: The number of elements to swap.
Example:
import "core:fmt"
import "core:sort"
swap_range_example :: proc() {
data := []int{1, 2, 3, 4}
sort.swap_range(sort.slice_interface(&data), 0, 2, 2)
fmt.println(data)
}
Output:
[3, 4, 1, 2]
*/
swap_range :: proc(it: Interface, a, b, n: int) {
for i in 0..<n {
it->swap(a+i, b+i)
}
}
/*
Rotates the elements of an `Interface` in the range `[a, b)` so that the
element at index `m` becomes the first element of the range.
Inputs:
- it: The `Interface`.
- a: Start index of the range.
- m: The index whose element becomes first after the rotation.
- b: Exclusive end index of the range.
Example:
import "core:fmt"
import "core:sort"
rotate_example :: proc() {
data := []int{0, 1, 2, 3}
sort.rotate(sort.slice_interface(&data), 0, 2, 4)
fmt.println(data)
}
Output:
[2, 3, 0, 1]
*/
rotate :: proc(it: Interface, a, m, b: int) {
i := m - a
j := b - m
@@ -260,6 +455,33 @@ _insertion_sort :: proc(it: Interface, a, b: int) {
}
}
/*
Sorts a slice in place using bubble sort, ordered by the given comparator.
The comparator `f` is called with two elements and must return a negative
number if the first is less than the second, `0` if they are equal, and a
positive number otherwise.
Inputs:
- array: The slice to sort.
- f: The comparator used to order the elements.
Example:
import "core:fmt"
import "core:sort"
bubble_sort_proc_example :: proc() {
data := []int{5, 3, 8, 1}
sort.bubble_sort_proc(data, sort.compare_ints)
fmt.println(data)
}
Output:
[1, 3, 5, 8]
*/
bubble_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
assert(f != nil)
count := len(array)
@@ -288,6 +510,29 @@ bubble_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
}
}
/*
Sorts a slice of ordered elements in place using bubble sort, in ascending
order.
Inputs:
- array: The slice to sort.
Example:
import "core:fmt"
import "core:sort"
bubble_sort_example :: proc() {
data := []int{5, 3, 8, 1}
sort.bubble_sort(data)
fmt.println(data)
}
Output:
[1, 3, 5, 8]
*/
bubble_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
count := len(array)
@@ -315,6 +560,33 @@ bubble_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
}
}
/*
Sorts a slice in place using quick sort, ordered by the given comparator.
The comparator `f` is called with two elements and must return a negative
number if the first is less than the second, `0` if they are equal, and a
positive number otherwise.
Inputs:
- array: The slice to sort.
- f: The comparator used to order the elements.
Example:
import "core:fmt"
import "core:sort"
quick_sort_proc_example :: proc() {
data := []int{5, 3, 8, 1}
sort.quick_sort_proc(data, sort.compare_ints)
fmt.println(data)
}
Output:
[1, 3, 5, 8]
*/
quick_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
assert(f != nil)
a := array
@@ -343,6 +615,29 @@ quick_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
quick_sort_proc(a[i:n], f)
}
/*
Sorts a slice of ordered elements in place using quick sort, in ascending
order.
Inputs:
- array: The slice to sort.
Example:
import "core:fmt"
import "core:sort"
quick_sort_example :: proc() {
data := []int{5, 3, 8, 1}
sort.quick_sort(data)
fmt.println(data)
}
Output:
[1, 3, 5, 8]
*/
quick_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
a := array
n := len(a)
@@ -378,6 +673,33 @@ _log2 :: proc(x: int) -> int {
return res
}
/*
Sorts a slice in place using merge sort, ordered by the given comparator.
The comparator `f` is called with two elements and must return a negative
number if the first is less than the second, `0` if they are equal, and a
positive number otherwise.
Inputs:
- array: The slice to sort.
- f: The comparator used to order the elements.
Example:
import "core:fmt"
import "core:sort"
merge_sort_proc_example :: proc() {
data := []int{5, 3, 8, 1}
sort.merge_sort_proc(data, sort.compare_ints)
fmt.println(data)
}
Output:
[1, 3, 5, 8]
*/
merge_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
merge :: proc(a: A, start, mid, end: int, f: proc(T, T) -> int) {
s, m := start, mid
@@ -419,6 +741,29 @@ merge_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
internal_sort(array, 0, len(array)-1, f)
}
/*
Sorts a slice of ordered elements in place using merge sort, in ascending
order.
Inputs:
- array: The slice to sort.
Example:
import "core:fmt"
import "core:sort"
merge_sort_example :: proc() {
data := []int{5, 3, 8, 1}
sort.merge_sort(data)
fmt.println(data)
}
Output:
[1, 3, 5, 8]
*/
merge_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
merge :: proc(a: A, start, mid, end: int) {
s, m := start, mid
@@ -460,6 +805,33 @@ merge_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
internal_sort(array, 0, len(array)-1)
}
/*
Sorts a slice in place using heap sort, ordered by the given comparator.
The comparator `f` is called with two elements and must return a negative
number if the first is less than the second, `0` if they are equal, and a
positive number otherwise.
Inputs:
- array: The slice to sort.
- f: The comparator used to order the elements.
Example:
import "core:fmt"
import "core:sort"
heap_sort_proc_example :: proc() {
data := []int{5, 3, 8, 1}
sort.heap_sort_proc(data, sort.compare_ints)
fmt.println(data)
}
Output:
[1, 3, 5, 8]
*/
heap_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
sift_proc :: proc(a: A, pi: int, n: int, f: proc(T, T) -> int) #no_bounds_check {
p := pi
@@ -494,6 +866,29 @@ heap_sort_proc :: proc(array: $A/[]$T, f: proc(T, T) -> int) {
}
}
/*
Sorts a slice of ordered elements in place using heap sort, in ascending
order.
Inputs:
- array: The slice to sort.
Example:
import "core:fmt"
import "core:sort"
heap_sort_example :: proc() {
data := []int{5, 3, 8, 1}
sort.heap_sort(data)
fmt.println(data)
}
Output:
[1, 3, 5, 8]
*/
heap_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
sift :: proc(a: A, pi: int, n: int) #no_bounds_check {
p := pi
@@ -528,6 +923,32 @@ heap_sort :: proc(array: $A/[]$T) where intrinsics.type_is_ordered(T) {
}
}
/*
Compares two booleans for ordering, where `false` is considered less than
`true`.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_bools_example :: proc() {
fmt.println(sort.compare_bools(false, true))
fmt.println(sort.compare_bools(true, true))
fmt.println(sort.compare_bools(true, false))
}
Output:
-1
0
1
*/
compare_bools :: proc(a, b: bool) -> int {
switch {
case !a && b: return -1
@@ -537,6 +958,31 @@ compare_bools :: proc(a, b: bool) -> int {
}
/*
Compares two `int` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_ints_example :: proc() {
fmt.println(sort.compare_ints(1, 2))
fmt.println(sort.compare_ints(2, 2))
fmt.println(sort.compare_ints(3, 2))
}
Output:
-1
0
1
*/
compare_ints :: proc(a, b: int) -> int {
switch delta := a - b; {
case delta < 0: return -1
@@ -545,6 +991,31 @@ compare_ints :: proc(a, b: int) -> int {
return 0
}
/*
Compares two `uint` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_uints_example :: proc() {
fmt.println(sort.compare_uints(1, 2))
fmt.println(sort.compare_uints(2, 2))
fmt.println(sort.compare_uints(3, 2))
}
Output:
-1
0
1
*/
compare_uints :: proc(a, b: uint) -> int {
switch {
case a < b: return -1
@@ -553,6 +1024,31 @@ compare_uints :: proc(a, b: uint) -> int {
return 0
}
/*
Compares two `u8` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_u8s_example :: proc() {
fmt.println(sort.compare_u8s(1, 2))
fmt.println(sort.compare_u8s(2, 2))
fmt.println(sort.compare_u8s(3, 2))
}
Output:
-1
0
1
*/
compare_u8s :: proc(a, b: u8) -> int {
switch {
case a < b: return -1
@@ -561,6 +1057,31 @@ compare_u8s :: proc(a, b: u8) -> int {
return 0
}
/*
Compares two `u16` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_u16s_example :: proc() {
fmt.println(sort.compare_u16s(1, 2))
fmt.println(sort.compare_u16s(2, 2))
fmt.println(sort.compare_u16s(3, 2))
}
Output:
-1
0
1
*/
compare_u16s :: proc(a, b: u16) -> int {
switch {
case a < b: return -1
@@ -569,6 +1090,31 @@ compare_u16s :: proc(a, b: u16) -> int {
return 0
}
/*
Compares two `u32` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_u32s_example :: proc() {
fmt.println(sort.compare_u32s(1, 2))
fmt.println(sort.compare_u32s(2, 2))
fmt.println(sort.compare_u32s(3, 2))
}
Output:
-1
0
1
*/
compare_u32s :: proc(a, b: u32) -> int {
switch {
case a < b: return -1
@@ -577,6 +1123,31 @@ compare_u32s :: proc(a, b: u32) -> int {
return 0
}
/*
Compares two `u64` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_u64s_example :: proc() {
fmt.println(sort.compare_u64s(1, 2))
fmt.println(sort.compare_u64s(2, 2))
fmt.println(sort.compare_u64s(3, 2))
}
Output:
-1
0
1
*/
compare_u64s :: proc(a, b: u64) -> int {
switch {
case a < b: return -1
@@ -585,6 +1156,31 @@ compare_u64s :: proc(a, b: u64) -> int {
return 0
}
/*
Compares two `i8` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_i8s_example :: proc() {
fmt.println(sort.compare_i8s(-1, 2))
fmt.println(sort.compare_i8s(2, 2))
fmt.println(sort.compare_i8s(3, 2))
}
Output:
-1
0
1
*/
compare_i8s :: proc(a, b: i8) -> int {
switch {
case a < b: return -1
@@ -593,6 +1189,31 @@ compare_i8s :: proc(a, b: i8) -> int {
return 0
}
/*
Compares two `i16` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_i16s_example :: proc() {
fmt.println(sort.compare_i16s(-1, 2))
fmt.println(sort.compare_i16s(2, 2))
fmt.println(sort.compare_i16s(3, 2))
}
Output:
-1
0
1
*/
compare_i16s :: proc(a, b: i16) -> int {
switch {
case a < b: return -1
@@ -601,6 +1222,31 @@ compare_i16s :: proc(a, b: i16) -> int {
return 0
}
/*
Compares two `i32` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_i32s_example :: proc() {
fmt.println(sort.compare_i32s(-1, 2))
fmt.println(sort.compare_i32s(2, 2))
fmt.println(sort.compare_i32s(3, 2))
}
Output:
-1
0
1
*/
compare_i32s :: proc(a, b: i32) -> int {
switch {
case a < b: return -1
@@ -609,6 +1255,31 @@ compare_i32s :: proc(a, b: i32) -> int {
return 0
}
/*
Compares two `i64` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_i64s_example :: proc() {
fmt.println(sort.compare_i64s(-1, 2))
fmt.println(sort.compare_i64s(2, 2))
fmt.println(sort.compare_i64s(3, 2))
}
Output:
-1
0
1
*/
compare_i64s :: proc(a, b: i64) -> int {
switch {
case a < b: return -1
@@ -620,6 +1291,31 @@ compare_i64s :: proc(a, b: i64) -> int {
/*
Compares two `f32` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_f32s_example :: proc() {
fmt.println(sort.compare_f32s(1.0, 2.0))
fmt.println(sort.compare_f32s(2.0, 2.0))
fmt.println(sort.compare_f32s(3.0, 2.0))
}
Output:
-1
0
1
*/
compare_f32s :: proc(a, b: f32) -> int {
switch delta := a - b; {
case delta < 0: return -1
@@ -627,6 +1323,31 @@ compare_f32s :: proc(a, b: f32) -> int {
}
return 0
}
/*
Compares two `f64` values for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_f64s_example :: proc() {
fmt.println(sort.compare_f64s(1.0, 2.0))
fmt.println(sort.compare_f64s(2.0, 2.0))
fmt.println(sort.compare_f64s(3.0, 2.0))
}
Output:
-1
0
1
*/
compare_f64s :: proc(a, b: f64) -> int {
switch delta := a - b; {
case delta < 0: return -1
@@ -634,6 +1355,31 @@ compare_f64s :: proc(a, b: f64) -> int {
}
return 0
}
/*
Compares two strings lexicographically (byte-wise) for ordering.
Returns:
- A negative number if `a` is less than `b`, `0` if they are equal, and a
positive number otherwise.
Example:
import "core:fmt"
import "core:sort"
compare_strings_example :: proc() {
fmt.println(sort.compare_strings("apple", "banana"))
fmt.println(sort.compare_strings("apple", "apple"))
fmt.println(sort.compare_strings("banana", "apple"))
}
Output:
-1
0
1
*/
compare_strings :: proc(a, b: string) -> int {
x := transmute(mem.Raw_String)a
y := transmute(mem.Raw_String)b
File diff suppressed because it is too large. Load diff
+242
View File
@@ -0,0 +1,242 @@
package strconv
import "base:intrinsics"
/*
Scans a hexadecimal floating-point number at the start of `s`.
`[+-] 0x hexdigits [. hexdigits] (p|P) [+-] digits`
A `_` between digits is skipped
**Returns**
- mantissa, exp: The value is `mantissa * 2^exp`. If `trunc` is true, the significant hex digits after the first 16 were dropped, and at least one of them was not zero.
- neg: The number has a minus sign.
- nr: The number of bytes in the number.
- ok: `false` if `s` does not start with a hexadecimal float.
*/
scan_hex_float :: proc "contextless" (s: string) -> (mantissa: u64, exp: int, neg, trunc: bool, nr: int, ok: bool) #no_bounds_check {
MAX_HEX_DIGITS :: 16
n := len(s)
if n == 0 {
return
}
neg = s[0] == '-'
i := int(neg || s[0] == '+')
// "0x" is a hex prefix only if another byte follows it.
if !(i+2 < n && s[i] == '0' && lower(s[i+1]) == 'x') {
return
}
i += 2
nd := 0 // number of significant hex digits in the mantissa
saw_digits := false
// Integer part. Leading zeros do not count as significant digits.
for i < n && (s[i] == '0' || s[i] == '_') {
saw_digits ||= s[i] == '0'
i += 1
}
for i+8 <= n && nd+8 <= MAX_HEX_DIGITS {
v := read8_to_u64(s, i)
if !is_eight_hex_digits(v) {
break
}
mantissa = mantissa<<32 | parse_eight_hex_digits(v)
nd += 8
i += 8
saw_digits = true
}
for i < n {
d := hex_digit_table[s[i]]
if d >= 16 {
if s[i] != '_' {
break
}
} else if nd < MAX_HEX_DIGITS {
mantissa = mantissa<<4 | u64(d)
nd += 1
saw_digits = true
} else {
exp += 4 // dropped digit
trunc ||= d != 0
}
i += 1
}
// Fraction part
if i < n && s[i] == '.' {
i += 1
if mantissa == 0 {
// Leading zeros of the fraction change only the exponent
for i < n && (s[i] == '0' || s[i] == '_') {
if s[i] == '0' {
exp -= 4
saw_digits = true
}
i += 1
}
}
for i+8 <= n && nd+8 <= MAX_HEX_DIGITS {
v := read8_to_u64(s, i)
if !is_eight_hex_digits(v) {
break
}
mantissa = mantissa<<32 | parse_eight_hex_digits(v)
nd += 8
exp -= 32
i += 8
saw_digits = true
}
if i+4 <= n && nd+4 <= MAX_HEX_DIGITS {
// Four digits: pad them with "0000" and use the 8-digit code.
v := u64(read4_to_u32(s, i)) | 0x3030_3030 << 32
if is_eight_hex_digits(v) {
mantissa = mantissa<<16 | parse_eight_hex_digits(v) >> 16
nd += 4
exp -= 16
i += 4
saw_digits = true
}
}
for i < n {
d := hex_digit_table[s[i]]
if d >= 16 {
if s[i] != '_' {
break
}
} else if mantissa == 0 && d == 0 {
exp -= 4 // a leading zero of the fraction
saw_digits = true
} else if nd < MAX_HEX_DIGITS {
mantissa = mantissa<<4 | u64(d)
nd += 1
exp -= 4
saw_digits = true
} else {
trunc ||= d != 0 // dropped digit
saw_digits = true
}
i += 1
}
}
if !saw_digits {
return
}
// The binary exponent is required. The first byte after `p` and the sign must be a digit.
if !(i < n && lower(s[i]) == 'p') {
return
}
i += 1
exp_neg := false
if i < n && (s[i] == '+' || s[i] == '-') {
exp_neg = s[i] == '-'
i += 1
}
if i >= n || s[i] - '0' > 9 {
return
}
x := 0
for i < n && (s[i] - '0' <= 9 || s[i] == '_') {
if s[i] != '_' && x < 100_000 { // larger exponents overflow or underflow anyway
x = x*10 + int(s[i] - '0')
}
i += 1
}
exp += -x if exp_neg else x
if mantissa == 0 {
exp = 0
trunc = false
}
nr, ok = i, true
return
}
/*
Converts `mantissa * 2^exp` to the bits of the float type that `info` describes, rounded to
nearest, ties to even. `trunc` means that the exact value is a little larger than
`mantissa * 2^exp` (nonzero digits were dropped).
**Returns**
- float_bits: The bits of the float, with the sign.
- ok: `false` if the value overflows. Then `float_bits` is infinity.
*/
hex_float_bits :: proc "contextless" (mantissa: u64, exp: int, neg, trunc: bool, info: ^Float_Info) -> (float_bits: u64, ok: bool) {
M := int(info.mantbits)
sign := u64(neg) << info.mantbits << info.expbits
if mantissa == 0 {
return sign, true
}
// Normalize: the top bit of m is set, so the value is in [2^(e+63), 2^(e+64)).
lz := intrinsics.count_leading_zeros(mantissa)
m := mantissa << lz
e := exp - int(lz)
biased := e + 63 - info.bias // the biased exponent of a normal result
shift := 63 - M // keep M+1 bits for a normal result
if biased < 1 {
// Subnormal: keep fewer bits.
shift += 1 - biased
biased = 0
}
// Round to nearest, ties to even. `trunc` is a sticky bit below all bits of m.
kept, rest, half: u64
switch {
case shift < 64:
kept = m >> uint(shift)
rest = m & (1<<uint(shift) - 1)
half = 1 << uint(shift - 1)
case shift == 64:
rest = m
half = 1 << 63
case:
return sign, true // less than half of the smallest subnormal
}
if rest > half || (rest == half && (trunc || kept & 1 == 1)) {
kept += 1
}
if biased == 0 {
// Subnormal
return sign | kept, true
}
if kept == 1 << uint(M+1) {
kept >>= 1
biased += 1
}
if biased >= 1<<info.expbits - 1 {
return sign | u64(1<<info.expbits - 1) << info.mantbits, false
}
return sign | u64(biased) << info.mantbits | kept & (1<<info.mantbits - 1), true
}
// NOTE(MatthiasH): direct lookup was always faster in benchmarks
@(rodata)
hex_digit_table := [256]u8{
0..<'0' = 0xff, ':'..<'A' = 0xff, 'G'..<'a' = 0xff, 'g'..=255 = 0xff,
'0' = 0, '1' = 1, '2' = 2, '3' = 3, '4' = 4,
'5' = 5, '6' = 6, '7' = 7, '8' = 8, '9' = 9,
'a' = 10, 'b' = 11, 'c' = 12, 'd' = 13, 'e' = 14, 'f' = 15,
'A' = 10, 'B' = 11, 'C' = 12, 'D' = 13, 'E' = 14, 'F' = 15,
}
is_eight_hex_digits :: #force_inline proc "contextless" (v: u64) -> bool {
ONES :: 0x0101_0101_0101_0101
HIGH :: 0x8080_8080_8080_8080
in_range :: #force_inline proc "contextless" (v: u64, $lo, $hi: u64) -> u64 {
return (v + (0x80 - lo)*ONES) &~ (v + (0x7f - hi)*ONES)
}
digit := in_range(v, '0', '9')
letter := in_range(v | 0x20*ONES, 'a', 'f')
return (digit | letter) &~ v & HIGH == HIGH
}
parse_eight_hex_digits :: #force_inline proc "contextless" (v: u64) -> u64 {
x := (v & 0x0f0f_0f0f_0f0f_0f0f) + ((v >> 6) & 0x0101_0101_0101_0101) * 9
x = ((x << 4) + (x >> 8)) & 0x00ff_00ff_00ff_00ff
x = ((x << 8) + (x >> 16)) & 0x0000_ffff_0000_ffff
return ((x << 16) + (x >> 32)) & 0xffff_ffff
}
+132 -243
View File
@@ -746,9 +746,13 @@ Output:
- ok: `false` if a base 10 float could not be found, or if the input string contained more than just the number.
*/
parse_f32 :: proc(s: string, n: ^int = nil) -> (value: f32, ok: bool) {
v: f64 = ---
v, ok = parse_f64(s, n)
return f32(v), ok
nr: int
value, nr, ok = parse_f32_prefix(s)
if ok && len(s) != nr {
ok = false
}
if n != nil { n^ = nr }
return
}
/*
Parses a 64-bit floating point number from a string
@@ -817,10 +821,7 @@ Output:
- ok: A boolean indicating whether the parsing was successful.
*/
parse_f32_prefix :: proc(str: string) -> (value: f32, nr: int, ok: bool) {
f: f64
f, nr, ok = parse_f64_prefix(str)
value = f32(f)
return
return parse_float_prefix_generic(f32, str)
}
/*
Parses a 64-bit floating point number from a string and returns the parsed number, the length of the parsed substring, and a boolean indicating whether the parsing was successful
@@ -855,6 +856,11 @@ Output:
- ok: `false` if a base 10 float could not be found
*/
parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) {
return parse_float_prefix_generic(f64, str)
}
// Parses directly to `T`, so the result is correctly rounded for both `f32` and `f64`.
parse_float_prefix_generic :: proc($T: typeid, str: string) -> (value: T, nr: int, ok: bool) where T == f32 || T == f64 {
common_prefix_len_ignore_case :: proc "contextless" (s, prefix: string) -> int {
n := len(prefix)
if n > len(s) {
@@ -909,280 +915,163 @@ parse_f64_prefix :: proc(str: string) -> (value: f64, nr: int, ok: bool) {
}
return
}
parse_components :: proc "contextless" (s: string) -> (mantissa: u64, exp: int, neg, trunc, hex: bool, i: int, ok: bool) {
if len(s) == 0 {
return
}
switch s[i] {
case '+': i += 1
case '-': i += 1; neg = true
}
base := u64(10)
MAX_MANT_DIGITS := 19
exp_char := byte('e')
// support stupid 0x1.ABp100 hex floats even if Odin doesn't
if i+2 < len(s) && s[i] == '0' && lower(s[i+1]) == 'x' {
base = 16
MAX_MANT_DIGITS = 16
i += 2
exp_char = 'p'
hex = true
}
underscores := false
saw_dot, saw_digits := false, false
nd := 0
nd_mant := 0
decimal_point := 0
trailing_zeroes_nd := -1
loop: for ; i < len(s); i += 1 {
switch c := s[i]; true {
case c == '_':
underscores = true
continue loop
case c == '.':
if saw_dot {
break loop
}
saw_dot = true
decimal_point = nd
continue loop
case '0' <= c && c <= '9':
saw_digits = true
if c == '0' {
if nd == 0 {
decimal_point -= 1
continue loop
}
if trailing_zeroes_nd == -1 {
trailing_zeroes_nd = nd
}
} else {
trailing_zeroes_nd = -1
}
nd += 1
if nd_mant < MAX_MANT_DIGITS {
mantissa *= base
mantissa += u64(c - '0')
nd_mant += 1
} else if c != '0' {
trunc = true
}
continue loop
case base == 16 && 'a' <= lower(c) && lower(c) <= 'f':
saw_digits = true
trailing_zeroes_nd = -1
nd += 1
if nd_mant < MAX_MANT_DIGITS {
mantissa *= 16
mantissa += u64(lower(c) - 'a' + 10)
nd_mant += 1
} else {
trunc = true
}
continue loop
}
break loop
}
if !saw_digits {
return
}
if !saw_dot {
decimal_point = nd
}
if trailing_zeroes_nd > 0 {
trailing_zeroes_nd = nd_mant - trailing_zeroes_nd
}
for /**/; trailing_zeroes_nd > 0; trailing_zeroes_nd -= 1 {
mantissa /= base
nd_mant -= 1
nd -= 1
}
if base == 16 {
decimal_point *= 4
nd_mant *= 4
}
if i < len(s) && lower(s[i]) == exp_char {
i += 1
if i >= len(s) { return }
exp_sign := 1
switch s[i] {
case '+': i += 1
case '-': i += 1; exp_sign = -1
}
if i >= len(s) || s[i] < '0' || s[i] > '9' {
return
}
e := 0
for ; i < len(s) && ('0' <= s[i] && s[i] <= '9' || s[i] == '_'); i += 1 {
if s[i] == '_' {
underscores = true
continue
}
if e < 1e5 {
e = e*10 + int(s[i]) - '0'
}
}
decimal_point += e * exp_sign
} else if base == 16 {
return
}
if mantissa != 0 {
exp = decimal_point - nd_mant
}
ok = true
return
}
parse_hex :: proc "contextless" (s: string, mantissa: u64, exp: int, neg, trunc: bool) -> (f64, bool) {
info := &_f64_info
mantissa, exp := mantissa, exp
MAX_EXP := 1<<info.expbits + info.bias - 2
MIN_EXP := info.bias + 1
exp += int(info.mantbits)
for mantissa != 0 && mantissa >> (info.mantbits+2) == 0 {
mantissa <<= 1
exp -= 1
}
if trunc {
mantissa |= 1
}
for mantissa >> (info.mantbits+3) != 0 {
mantissa = mantissa>>1 | mantissa&1
exp += 1
}
// denormalize
for mantissa > 1 && exp < MIN_EXP-2 {
mantissa = mantissa>>1 | mantissa&1
exp += 1
}
round := mantissa & 3
mantissa >>= 2
round |= mantissa & 1 // round to even
exp += 2
if round == 3 {
mantissa += 1
if mantissa == 1 << (1 + info.mantbits) {
mantissa >>= 1
exp += 1
}
}
if mantissa>>info.mantbits == 0 {
// zero or denormal
exp = info.bias
}
ok := true
if exp > MAX_EXP {
// infinity or invalid
mantissa = 1<<info.mantbits
exp = MAX_EXP + 1
ok = false
}
bits := mantissa & (1<<info.mantbits - 1)
bits |= u64((exp-info.bias) & (1<<info.expbits - 1)) << info.mantbits
if neg {
bits |= 1 << info.mantbits << info.expbits
}
return transmute(f64)bits, ok
}
if len(str) > 2 && str[0] == '0' && str[1] == 'h' {
nr = 2
// 0h string to float case
@(cold)
parse_0h :: proc "contextless" ($F: typeid, str: string) -> (value: F, nr: int, ok: bool) {
as_int: u64
digits: int
for r in str[2:] {
if r == '_' {
nr += 1
continue
}
v := u64(_digit_value(r))
if v >= 16 {
i := 2
// Read 8 hex digits at a time, then 4 digits at a time (like "0h3c00" or groups
// between `_` separators), then single digits and `_` separators.
for i+8 <= len(str) {
v := read8_to_u64(str, i)
if !is_eight_hex_digits(v) {
break
}
as_int *= 16
as_int += v
digits += 1
as_int = as_int<<32 | parse_eight_hex_digits(v)
digits += 8
i += 8
}
nr += digits
for i < len(str) {
if i+4 <= len(str) {
// Four digits: pad them with "0000" and use the 8-digit code.
v := u64(read4_to_u32(str, i)) | 0x3030_3030 << 32
if is_eight_hex_digits(v) {
as_int = as_int<<16 | parse_eight_hex_digits(v) >> 16
digits += 4
i += 4
continue
}
}
if str[i] != '_' {
v := hex_digit_table[str[i]]
if v >= 16 {
break
}
as_int = as_int<<4 | u64(v)
digits += 1
}
i += 1
}
nr = i
ok = len(str) == nr
switch digits {
case 4:
value = cast(f64)transmute(f16)cast(u16)as_int
value = cast(F)transmute(f16)cast(u16)as_int
case 8:
value = cast(f64)transmute(f32)cast(u32)as_int
value = cast(F)transmute(f32)cast(u32)as_int
case 16:
value = transmute(f64)as_int
value = cast(F)transmute(f64)as_int
case:
ok = false
}
return
}
if value, nr, ok = check_special(str); ok {
return
@(cold)
parse_special :: proc "contextless" ($F: typeid, str: string) -> (value: F, nr: int, ok: bool) {
f: f64
f, nr, ok = check_special(str)
return F(f), nr, ok
}
@(cold)
parse_slow :: proc($F: typeid, str: string, info: ^Float_Info) -> (value: F, ok: bool) {
when F == f64 { Bits :: u64 } else { Bits :: u32 }
d: decimal.Decimal
decimal.set(&d, str)
b, overflow := decimal_to_float_bits(&d, info)
return transmute(F)Bits(b), !overflow
}
if len(str) > 2 && str[0] == '0' && str[1] == 'h' {
return parse_0h(T, str)
}
when T == f64 {
Bits :: u64
info := &_f64_info
} else {
Bits :: u32
info := &_f32_info
}
mantissa: u64
exp: int
neg, trunc, hex: bool
mantissa, exp, neg, trunc, hex, nr = parse_components(str) or_return
if hex {
value, ok = parse_hex(str, mantissa, exp, neg, trunc)
return
neg, trunc: bool
mantissa, exp, neg, trunc, nr, ok = parse_number_string(str)
if !ok {
// Not a decimal number: try a hexadecimal float, then "inf" and "nan".
mantissa, exp, neg, trunc, nr, ok = scan_hex_float(str)
if !ok {
return parse_special(T, str)
}
b, in_range := hex_float_bits(mantissa, exp, neg, trunc, info)
return transmute(T)Bits(b), nr, in_range
}
trunc_block: if !trunc {
// Clinger's fast path algorithm
clinger_fast_path: if !trunc && !(ODIN_ARCH == .i386 && ODIN_OS != .Windows) {
@(static, rodata) pow10 := [?]f64{
1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
1e20, 1e21, 1e22,
}
if mantissa>>_f64_info.mantbits != 0 {
break trunc_block
// Every integer up to 2^53 is an exact f64 value.
if mantissa > 1<<53 {
break clinger_fast_path
}
f := f64(mantissa)
f_abs := f
switch {
case exp == 0:
case exp > 0 && exp <= 15+22:
e := exp
if e > 22 {
f *= pow10[e-22]
e = 22
if f > 1e15 {
break clinger_fast_path
}
}
f *= pow10[e]
case -22 <= exp && exp < 0:
f /= pow10[-exp]
case:
break clinger_fast_path
}
when T == f32 {
// Every f32 midpoint is an f64 value, so rounding to f64 cannot
// move the result past a midpoint. The conversion to f32 is then
// correct, unless the f64 result is exactly a midpoint.
if transmute(u64)f & (1<<29 - 1) == 1<<28 {
break clinger_fast_path
}
}
if neg {
f = -f
}
switch {
case exp == 0:
return f, nr, true
case exp > 0 && exp <= 15+22:
if exp > 22 {
f *= pow10[exp-22]
exp = 22
return T(f), nr, true
}
// Eisel-Lemire's fast float algorithm
when FAST_FLOAT {
fast_float: {
b := fast_float_compute_float(T, exp, mantissa)
if trunc && b != fast_float_compute_float(T, exp, mantissa+1) {
break fast_float
}
if f_abs > 1e15 || f_abs < 1e-15 {
break trunc_block
ok = b >> info.mantbits != 1<<info.expbits - 1 // infinity means overflow
if neg {
b |= 1 << info.mantbits << info.expbits
}
return f * pow10[exp], nr, true
case -22 <= exp && exp < 0:
return f / pow10[-exp], nr, true
return transmute(T)Bits(b), nr, ok
}
}
d: decimal.Decimal
decimal.set(&d, str[:nr])
b, overflow := decimal_to_float_bits(&d, &_f64_info)
value = transmute(f64)b
ok = !overflow
value, ok = parse_slow(T, str[:nr], info)
return
}
/*
@@ -1596,7 +1485,7 @@ Writes a quoted string representation of the input string to a given byte slice
- buf: The byte slice to which the quoted string will be written
- str: The input string to be quoted
!! ISSUE !! NOT EXPECTED -- "\"hello\"" was expected
!! ISSUE !! NOT EXPECTED -- `"\"hello\""` was expected
Example:
+2 -2
View File
@@ -529,7 +529,7 @@ Example:
}
*/
@(require_results)
recv :: proc "contextless" (c: $C/Chan($T)) -> (data: T, ok: bool) where C.D >= .Both {
recv :: proc "contextless" (c: $C/Chan($T, $D)) -> (data: T, ok: bool) where C.D >= .Both {
ok = recv_raw(c, &data)
return
}
@@ -559,7 +559,7 @@ Example:
}
*/
@(require_results)
try_recv :: proc "contextless" (c: $C/Chan($T)) -> (data: T, ok: bool) where C.D >= .Both {
try_recv :: proc "contextless" (c: $C/Chan($T, $D)) -> (data: T, ok: bool) where C.D >= .Both {
ok = try_recv_raw(c, &data)
return
}
+347 -101
View File
@@ -1,31 +1,37 @@
#+build windows
package sys_windows
// Bindings for the various common Win32 dialogs.
// See: https://learn.microsoft.com/en-us/windows/win32/dlgbox/using-common-dialog-boxes
// Corresponds to Commdlg.h
foreign import "system:Comdlg32.lib"
// OpenFile/SaveFile dialogs
LPOFNHOOKPROC :: #type proc "system" (hdlg: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR
OPENFILENAMEW :: struct {
lStructSize: DWORD,
hwndOwner: HWND,
hInstance: HINSTANCE,
lpstrFilter: wstring,
lpstrCustomFilter: wstring,
nMaxCustFilter: DWORD,
nFilterIndex: DWORD,
lpstrFile: wstring,
nMaxFile: DWORD,
lpstrFileTitle: wstring,
nMaxFileTitle: DWORD,
lpstrInitialDir: wstring,
lpstrTitle: wstring,
Flags: DWORD,
nFileOffset: WORD,
nFileExtension: WORD,
lpstrDefExt: wstring,
lCustData: LPARAM,
lpfnHook: LPOFNHOOKPROC,
lpTemplateName: wstring,
lStructSize: DWORD,
hwndOwner: HWND,
hInstance: HINSTANCE,
lpstrFilter: LPCWSTR,
lpstrCustomFilter: LPWSTR,
nMaxCustFilter: DWORD,
nFilterIndex: DWORD,
lpstrFile: LPWSTR,
nMaxFile: DWORD,
lpstrFileTitle: LPWSTR,
nMaxFileTitle: DWORD,
lpstrInitialDir: LPCWSTR,
lpstrTitle: LPCWSTR,
Flags: DWORD,
nFileOffset: WORD,
nFileExtension: WORD,
lpstrDefExt: LPCWSTR,
lCustData: LPARAM,
lpfnHook: LPOFNHOOKPROC,
lpTemplateName: LPCWSTR,
pvReserved: rawptr,
dwReserved: DWORD,
FlagsEx: DWORD,
@@ -35,7 +41,8 @@ OPENFILENAMEW :: struct {
foreign Comdlg32 {
GetOpenFileNameW :: proc(arg1: ^OPENFILENAMEW) -> BOOL ---
GetSaveFileNameW :: proc(arg1: ^OPENFILENAMEW) -> BOOL ---
CommDlgExtendedError :: proc() -> u32 ---
GetFileTitleW :: proc(s: LPCWSTR, Buf: LPWSTR, cchSize: WORD) -> c_short ---
}
OPEN_TITLE :: "Select file to open"
@@ -46,86 +53,6 @@ SAVE_TITLE :: "Select file to save"
SAVE_FLAGS :: u32(OFN_OVERWRITEPROMPT | OFN_EXPLORER)
SAVE_EXT :: "txt"
/*
import "core:strings"
Open_Save_Mode :: enum {
Open = 0,
Save = 1,
}
_open_file_dialog :: proc(title: string, dir: string,
filters: []string, default_filter: u32,
flags: u32, default_ext: string,
mode: Open_Save_Mode, allocator := context.temp_allocator) -> (path: string, ok: bool = true) {
context.allocator = allocator
file_buf := make([]u16, MAX_PATH_WIDE)
defer if !ok {
delete(file_buf)
}
// Filters need to be passed as a pair of strings (title, filter)
filter_len := u32(len(filters))
if filter_len % 2 != 0 {
return "", false
}
filter: string
filter = strings.join(filters, "\u0000", context.temp_allocator)
filter = strings.concatenate({filter, "\u0000"}, context.temp_allocator)
ofn := OPENFILENAMEW{
lStructSize = size_of(OPENFILENAMEW),
lpstrFile = wstring(&file_buf[0]),
nMaxFile = MAX_PATH_WIDE,
lpstrTitle = utf8_to_wstring(title, context.temp_allocator),
lpstrFilter = utf8_to_wstring(filter, context.temp_allocator),
lpstrInitialDir = utf8_to_wstring(dir, context.temp_allocator),
nFilterIndex = u32(clamp(default_filter, 1, filter_len / 2)),
lpstrDefExt = utf8_to_wstring(default_ext, context.temp_allocator),
Flags = u32(flags),
}
switch mode {
case .Open:
ok = bool(GetOpenFileNameW(&ofn))
case .Save:
ok = bool(GetSaveFileNameW(&ofn))
case:
ok = false
}
if !ok {
return
}
file_name, _ := utf16_to_utf8(file_buf[:], allocator)
path = strings.trim_right_null(file_name)
return
}
select_file_to_open :: proc(title := OPEN_TITLE, dir := ".",
filters := []string{"All Files", "*.*"}, default_filter := u32(1),
flags := OPEN_FLAGS, allocator := context.temp_allocator) -> (path: string, ok: bool) {
path, ok = _open_file_dialog(title, dir, filters, default_filter, flags, "", Open_Save_Mode.Open, allocator)
return
}
select_file_to_save :: proc(title := SAVE_TITLE, dir := ".",
filters := []string{"All Files", "*.*"}, default_filter := u32(1),
flags := SAVE_FLAGS, default_ext := SAVE_EXT,
allocator := context.temp_allocator) -> (path: string, ok: bool) {
path, ok = _open_file_dialog(title, dir, filters, default_filter, flags, default_ext, Open_Save_Mode.Save, allocator)
return
}
*/
// TODO: Implement convenience function for select_file_to_open with ALLOW_MULTI_SELECT that takes
// it output of the form "path\u0000\file1u\0000file2" and turns it into []string with the path + file pre-concatenated for you.
OFN_ALLOWMULTISELECT :: 0x00000200 // NOTE(Jeroen): Without OFN_EXPLORER it uses the Win3 dialog.
OFN_CREATEPROMPT :: 0x00002000
OFN_DONTADDTORECENT :: 0x02000000
@@ -153,6 +80,325 @@ OFN_READONLY :: 0x00000001
OFN_SHAREAWARE :: 0x00004000
OFN_SHOWHELP :: 0x00000010
// Choose Color dialog
LPCCHOOKPROC :: #type proc "system" (hwnd: HWND, msg: UINT, wParam: WPARAM, lParam: LPARAM) -> UINT_PTR
CHOOSECOLORW :: struct {
lStructSize: DWORD,
hwndOwner: HWND,
hInstance: HWND,
rgbResult: COLORREF,
lpCustColors: ^COLORREF,
Flags: DWORD,
lCustData: LPARAM,
lpfnHook: LPCCHOOKPROC,
lpTemplateName: LPCWSTR,
}
@(default_calling_convention="system")
foreign Comdlg32 {
ChooseColorW :: proc(lpcc: ^CHOOSECOLORW) -> BOOL ---
}
// Flags for CHOOSECOLORW
CC_RGBINIT :: 0x00000001
CC_FULLOPEN :: 0x00000002
CC_PREVENTFULLOPEN :: 0x00000004
CC_SHOWHELP :: 0x00000008
CC_ENABLEHOOK :: 0x00000010
CC_ENABLETEMPLATE :: 0x00000020
CC_ENABLETEMPLATEHANDLE :: 0x00000040
CC_SOLIDCOLOR :: 0x00000080
CC_ANYCOLOR :: 0x00000100
// Find and replace dialog
LPFRHOOKPROC :: #type proc "system" (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR
FINDREPLACEW :: struct {
lStructSize: DWORD, // size of this struct 0x20
hwndOwner: HWND, // handle to owner's window
hInstance: HINSTANCE, // instance handle of.EXE that contains cust. dlg. template
Flags: DWORD, // one or more of the FR_??
lpstrFindWhat: LPWSTR, // ptr. to search string
lpstrReplaceWith: LPWSTR, // ptr. to replace string
wFindWhatLen: WORD, // size of find buffer
wReplaceWithLen: WORD, // size of replace buffer
lCustData: LPARAM, // data passed to hook fn.
lpfnHook: LPFRHOOKPROC, // ptr. to hook fn. or NULL
lpTemplateName: LPCWSTR, // custom template name
}
// Flags for FINDREPLACEW
FR_DOWN :: 0x00000001
FR_WHOLEWORD :: 0x00000002
FR_MATCHCASE :: 0x00000004
FR_FINDNEXT :: 0x00000008
FR_REPLACE :: 0x00000010
FR_REPLACEALL :: 0x00000020
FR_DIALOGTERM :: 0x00000040
FR_SHOWHELP :: 0x00000080
FR_ENABLEHOOK :: 0x00000100
FR_ENABLETEMPLATE :: 0x00000200
FR_NOUPDOWN :: 0x00000400
FR_NOMATCHCASE :: 0x00000800
FR_NOWHOLEWORD :: 0x00001000
FR_ENABLETEMPLATEHANDLE :: 0x00002000
FR_HIDEUPDOWN :: 0x00004000
FR_HIDEMATCHCASE :: 0x00008000
FR_HIDEWHOLEWORD :: 0x00010000
FR_RAW :: 0x00020000
FR_SHOWWRAPAROUND :: 0x00040000
FR_NOWRAPAROUND :: 0x00080000
FR_WRAPAROUND :: 0x00100000
FR_MATCHDIAC :: 0x20000000
FR_MATCHKASHIDA :: 0x40000000
FR_MATCHALEFHAMZA :: 0x80000000
@(default_calling_convention="system")
foreign Comdlg32 {
FindTextW :: proc(lpcc: ^FINDREPLACEW) -> HWND ---
ReplaceTextW :: proc(lpcc: ^FINDREPLACEW) -> HWND ---
}
FINDMSGSTRINGW :: wstring("commdlg_FindReplace")
// Choose Font dialog
LPCFHOOKPROC :: #type proc "system" (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR
CHOOSEFONTW :: struct {
lStructSize: DWORD,
hwndOwner: HWND, // caller's window handle
hDC: HDC, // printer DC/IC or NULL
lpLogFont: LPLOGFONTW, // ptr. to a LOGFONT struct
iPointSize: INT, // 10 * size in points of selected font
Flags: DWORD, // enum. type flags
rgbColors: COLORREF, // returned text color
lCustData: LPARAM, // data passed to hook fn.
lpfnHook: LPCFHOOKPROC, // ptr. to hook function
lpTemplateName: LPCWSTR, // custom template name
hInstance: HINSTANCE, // instance handle of.EXE that contains cust. dlg. template
lpszStyle: LPWSTR, // return the style field here
// must be LF_FACESIZE or bigger
nFontType: WORD, // same value reported to the EnumFonts call back with the extra FONTTYPE_ bits added
___MISSING_ALIGNMENT__: WORD,
nSizeMin: INT, // minimum pt size allowed &
nSizeMax: INT, // max pt size allowed if CF_LIMITSIZE is used
}
@(default_calling_convention="system")
foreign Comdlg32 {
ChooseFontW :: proc(lpcc: ^CHOOSEFONTW) -> BOOL ---
}
// Flags for CHOOSEFONTW
CF_SCREENFONTS :: 0x00000001
CF_PRINTERFONTS :: 0x00000002
CF_BOTH :: (CF_SCREENFONTS | CF_PRINTERFONTS)
CF_SHOWHELP :: 0x00000004
CF_ENABLEHOOK :: 0x00000008
CF_ENABLETEMPLATE :: 0x00000010
CF_ENABLETEMPLATEHANDLE :: 0x00000020
CF_INITTOLOGFONTSTRUCT :: 0x00000040
CF_USESTYLE :: 0x00000080
CF_EFFECTS :: 0x00000100
CF_APPLY :: 0x00000200
CF_ANSIONLY :: 0x00000400
CF_SCRIPTSONLY :: CF_ANSIONLY
CF_NOVECTORFONTS :: 0x00000800
CF_NOOEMFONTS :: CF_NOVECTORFONTS
CF_NOSIMULATIONS :: 0x00001000
CF_LIMITSIZE :: 0x00002000
CF_FIXEDPITCHONLY :: 0x00004000
CF_WYSIWYG :: 0x00008000 // must also have CF_SCREENFONTS & CF_PRINTERFONTS
CF_FORCEFONTEXIST :: 0x00010000
CF_SCALABLEONLY :: 0x00020000
CF_TTONLY :: 0x00040000
CF_NOFACESEL :: 0x00080000
CF_NOSTYLESEL :: 0x00100000
CF_NOSIZESEL :: 0x00200000
CF_SELECTSCRIPT :: 0x00400000
CF_NOSCRIPTSEL :: 0x00800000
CF_NOVERTFONTS :: 0x01000000
CF_INACTIVEFONTS :: 0x02000000
// Print dialog
LPPRINTHOOKPROC :: #type proc "system" (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR
LPSETUPHOOKPROC :: #type proc "system" (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR
PRINTDLGW :: struct {
lStructSize: DWORD,
hwndOwner: HWND,
hDevMode: HGLOBAL,
hDevNames: HGLOBAL,
hDC: HDC,
Flags: DWORD,
nFromPage: WORD,
nToPage: WORD,
nMinPage: WORD,
nMaxPage: WORD,
nCopies: WORD,
hInstance: HINSTANCE,
lCustData: LPARAM,
lpfnPrintHook: LPPRINTHOOKPROC,
lpfnSetupHook: LPSETUPHOOKPROC,
lpPrintTemplateName: LPCWSTR,
lpSetupTemplateName: LPCWSTR,
hPrintTemplate: HGLOBAL,
hSetupTemplate: HGLOBAL,
}
PRINTPAGERANGE :: struct {
nFromPage: DWORD,
nToPage: DWORD,
}
LPPRINTPAGERANGE :: #type ^PRINTPAGERANGE
HPROPSHEETPAGE :: distinct LPVOID
PRINTDLGEXW :: struct {
lStructSize: DWORD, // size of structure in bytes
hwndOwner: HWND, // caller's window handle
hDevMode: HGLOBAL, // handle to DevMode
hDevNames: HGLOBAL, // handle to DevNames
hDC: HDC, // printer DC/IC or NULL
Flags: DWORD, // PD_ flags
Flags2: DWORD, // reserved
ExclusionFlags: DWORD, // items to exclude from driver pages
nPageRanges: DWORD, // number of page ranges
nMaxPageRanges: DWORD, // max number of page ranges
lpPageRanges: LPPRINTPAGERANGE, // array of page ranges
nMinPage: DWORD, // min page number
nMaxPage: DWORD, // max page number
nCopies: DWORD, // number of copies
hInstance: HINSTANCE, // instance handle
lpPrintTemplateName: LPCWSTR, // template name for app specific area
lpCallback: LPUNKNOWN, // app callback interface
nPropertyPages: DWORD, // number of app property pages in lphPropertyPages
lphPropertyPages: ^HPROPSHEETPAGE, // array of app property page handles
nStartPage: DWORD, // start page id
dwResultAction: DWORD, // result action if S_OK is returned
}
// Device Names structure for PrintDlg and PrintDlgEx.
DEVNAMES :: struct {
wDriverOffset: WORD,
wDeviceOffset: WORD,
wOutputOffset: WORD,
wDefault: WORD,
}
@(default_calling_convention="system")
foreign Comdlg32 {
PrintDlgW :: proc(lpcc: ^PRINTDLGW) -> BOOL ---
PrintDlgExW :: proc(lpcc: ^PRINTDLGEXW) -> HRESULT ---
}
// Flags for PRINTDLGW and PRINTDLGEXW
PD_ALLPAGES :: 0x00000000
PD_SELECTION :: 0x00000001
PD_PAGENUMS :: 0x00000002
PD_NOSELECTION :: 0x00000004
PD_NOPAGENUMS :: 0x00000008
PD_COLLATE :: 0x00000010
PD_PRINTTOFILE :: 0x00000020
PD_PRINTSETUP :: 0x00000040
PD_NOWARNING :: 0x00000080
PD_RETURNDC :: 0x00000100
PD_RETURNIC :: 0x00000200
PD_RETURNDEFAULT :: 0x00000400
PD_SHOWHELP :: 0x00000800
PD_ENABLEPRINTHOOK :: 0x00001000
PD_ENABLESETUPHOOK :: 0x00002000
PD_ENABLEPRINTTEMPLATE :: 0x00004000
PD_ENABLESETUPTEMPLATE :: 0x00008000
PD_ENABLEPRINTTEMPLATEHANDLE :: 0x00010000
PD_ENABLESETUPTEMPLATEHANDLE :: 0x00020000
PD_USEDEVMODECOPIES :: 0x00040000
PD_USEDEVMODECOPIESANDCOLLATE :: 0x00040000
PD_DISABLEPRINTTOFILE :: 0x00080000
PD_HIDEPRINTTOFILE :: 0x00100000
PD_NONETWORKBUTTON :: 0x00200000
PD_CURRENTPAGE :: 0x00400000
PD_NOCURRENTPAGE :: 0x00800000
PD_EXCLUSIONFLAGS :: 0x01000000
PD_USELARGETEMPLATE :: 0x10000000
// Define the start page for the print dialog when using PrintDlgEx.
START_PAGE_GENERAL :: 0xffffffff
// Result action ids for PrintDlgEx.
PD_RESULT_CANCEL :: 0
PD_RESULT_PRINT :: 1
PD_RESULT_APPLY :: 2
// Page Setup dialog
// Window Message IDs for the LPPAGEPAINTHOOK
WM_PSD_PAGESETUPDLG :: (WM_USER )
WM_PSD_FULLPAGERECT :: (WM_USER+1)
WM_PSD_MINMARGINRECT :: (WM_USER+2)
WM_PSD_MARGINRECT :: (WM_USER+3)
WM_PSD_GREEKTEXTRECT :: (WM_USER+4)
WM_PSD_ENVSTAMPRECT :: (WM_USER+5)
WM_PSD_YAFULLPAGERECT :: (WM_USER+6)
LPPAGEPAINTHOOK :: #type proc "system" (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR
LPPAGESETUPHOOK :: #type proc "system" (hwnd: HWND, msg: UINT, wparam: WPARAM, lparam: LPARAM) -> UINT_PTR
PAGESETUPDLGW :: struct {
lStructSize: DWORD,
hwndOwner: HWND,
hDevMode: HGLOBAL,
hDevNames: HGLOBAL,
Flags: DWORD,
ptPaperSize: POINT,
rtMinMargin: RECT,
rtMargin: RECT,
hInstance: HINSTANCE,
lCustData: LPARAM,
lpfnPageSetupHook: LPPAGESETUPHOOK,
lpfnPagePaintHook: LPPAGEPAINTHOOK,
lpPageSetupTemplateName: LPCWSTR,
hPageSetupTemplate: HGLOBAL,
}
@(default_calling_convention="system")
foreign Comdlg32 {
PageSetupDlgW :: proc(lpcc: ^PAGESETUPDLGW) -> BOOL ---
}
PSD_DEFAULTMINMARGINS :: 0x00000000 // default (printer's)
PSD_INWININIINTLMEASURE :: 0x00000000 // 1st of 4 possible
PSD_MINMARGINS :: 0x00000001 // use caller's
PSD_MARGINS :: 0x00000002 // use caller's
PSD_INTHOUSANDTHSOFINCHES :: 0x00000004 // 2nd of 4 possible
PSD_INHUNDREDTHSOFMILLIMETERS :: 0x00000008 // 3rd of 4 possible
PSD_DISABLEMARGINS :: 0x00000010
PSD_DISABLEPRINTER :: 0x00000020
PSD_NOWARNING :: 0x00000080 // must be same as PD_*
PSD_DISABLEORIENTATION :: 0x00000100
PSD_RETURNDEFAULT :: 0x00000400 // must be same as PD_*
PSD_DISABLEPAPER :: 0x00000200
PSD_SHOWHELP :: 0x00000800 // must be same as PD_*
PSD_ENABLEPAGESETUPHOOK :: 0x00002000 // must be same as PD_*
PSD_ENABLEPAGESETUPTEMPLATE :: 0x00008000 // must be same as PD_*
PSD_ENABLEPAGESETUPTEMPLATEHANDLE :: 0x00020000 // must be same as PD_*
PSD_ENABLEPAGEPAINTHOOK :: 0x00040000
PSD_DISABLEPAGEPAINTING :: 0x00080000
PSD_NONETWORKBUTTON :: 0x00200000 // must be same as PD_*
// Common error codes for all comdlg32 dialogs (CommDlgExtendedError)
@(default_calling_convention="system")
foreign Comdlg32 {
CommDlgExtendedError :: proc() -> u32 ---
}
CDERR_DIALOGFAILURE :: 0x0000FFFF
CDERR_GENERALCODES :: 0x00000000
CDERR_STRUCTSIZE :: 0x00000001
+10 -10
View File
@@ -229,20 +229,20 @@ BS_DIBPATTERN8X8 :: 8
BS_MONOPATTERN :: 9
/* Hatch Styles */
HS_HORIZONTAL :: 0 /* ----- */
HS_VERTICAL :: 1 /* ||||| */
HS_FDIAGONAL :: 2 /* \\\\\ */
HS_BDIAGONAL :: 3 /* ///// */
HS_CROSS :: 4 /* +++++ */
HS_DIAGCROSS :: 5 /* xxxxx */
HS_HORIZONTAL :: 0 /* `-----` */
HS_VERTICAL :: 1 /* `|||||` */
HS_FDIAGONAL :: 2 /* `\\\\\` */
HS_BDIAGONAL :: 3 /* `/////` */
HS_CROSS :: 4 /* `+++++` */
HS_DIAGCROSS :: 5 /* `xxxxx` */
HS_API_MAX :: 12
/* Pen Styles */
PS_SOLID :: 0
PS_DASH :: 1 /* ------- */
PS_DOT :: 2 /* ....... */
PS_DASHDOT :: 3 /* _._._._ */
PS_DASHDOTDOT :: 4 /* _.._.._ */
PS_DASH :: 1 /* `-------` */
PS_DOT :: 2 /* `.......` */
PS_DASHDOT :: 3 /* `_._._._` */
PS_DASHDOTDOT :: 4 /* `_.._.._` */
PS_NULL :: 5
PS_INSIDEFRAME :: 6
PS_USERSTYLE :: 7
+2 -2
View File
@@ -213,7 +213,7 @@ VK_OEM_3 :: 0xC0 // '`~' for US
// 0xC1 - 0xDA : reserved
VK_OEM_4 :: 0xDB // '[{' for US
VK_OEM_5 :: 0xDC // '\|' for US
VK_OEM_5 :: 0xDC // `'\|'` for US
VK_OEM_6 :: 0xDD // ']}' for US
VK_OEM_7 :: 0xDE // ''"' for US
VK_OEM_8 :: 0xDF
@@ -222,7 +222,7 @@ VK_OEM_8 :: 0xDF
// Various extended or enhanced keyboards
VK_OEM_AX :: 0xE1 // 'AX' key on Japanese AX kbd
VK_OEM_102 :: 0xE2 // "<>" or "\|" on RT 102-key kbd.
VK_OEM_102 :: 0xE2 // `"<>"` or `"\|"` on RT 102-key kbd.
VK_ICO_HELP :: 0xE3 // Help key on ICO
VK_ICO_00 :: 0xE4 // 00 key on ICO
+5 -6
View File
@@ -1724,6 +1724,8 @@ NM_FONTCHANGED :: NM_OUTOFMEMORY-22
NM_CUSTOMTEXT :: NM_OUTOFMEMORY-23 // uses NMCUSTOMTEXT struct
NM_TVSTATEIMAGECHANGING :: NM_OUTOFMEMORY-23 // uses NMTVSTATEIMAGECHANGING struct, defined after HTREEITEM
// Pointer to a double-null-terminated string.
// Special care must be taken when converting to this type.
PCZZWSTR :: cstring16
SHFILEOPSTRUCTW :: struct {
@@ -2247,7 +2249,7 @@ SEE_MASK_WAITFORINPUTIDLE :: 0x02000000
SEE_MASK_FLAG_LOG_USAGE :: 0x04000000
// When SEE_MASK_FLAG_HINST_IS_SITE is specified SHELLEXECUTEINFO.hInstApp is used as an
// _In_ parameter and specifies a IUnknown* to be used as a site pointer. The site pointer
// `_In_` parameter and specifies a `IUnknown*` to be used as a site pointer. The site pointer
// is used to provide services to shell execute, the handler binding process and the verb handlers
// once they are invoked.
SEE_MASK_FLAG_HINST_IS_SITE :: 0x08000000
@@ -4302,7 +4304,7 @@ SHCONTF_ENABLE_ASYNC :: 0x8000
SHCONTF_INCLUDESUPERHIDDEN :: 0x10000
SHACF_DEFAULT :: 0x00000000 // Currently (SHACF_FILESYSTEM | SHACF_URLALL)
SHACF_FILESYSTEM :: 0x00000001 // This includes the File System as well as the rest of the shell (Desktop\My Computer\Control Panel\)
SHACF_FILESYSTEM :: 0x00000001 // This includes the File System as well as the rest of the shell (`Desktop\My Computer\Control Panel\`)
SHACF_URLALL :: (SHACF_URLHISTORY | SHACF_URLMRU)
SHACF_URLHISTORY :: 0x00000002 // URLs in the User's History
SHACF_URLMRU :: 0x00000004 // URLs in the User's Recently Used list.
@@ -5479,10 +5481,9 @@ CRYPT_DIGEST_BLOB :: distinct CRYPTOAPI_BLOB
CRYPT_DER_BLOB :: distinct CRYPTOAPI_BLOB
CRYPT_ATTR_BLOB :: distinct CRYPTOAPI_BLOB
//+-------------------------------------------------------------------------
// In a CRYPT_BIT_BLOB the last byte may contain 0-7 unused bits. Therefore, the
// overall bit length is cbData * 8 - cUnusedBits.
//--------------------------------------------------------------------------
//
// certenrolls_begin -- CERT_CONTEXT
CRYPT_BIT_BLOB :: struct {
cbData: DWORD,
@@ -5490,12 +5491,10 @@ CRYPT_BIT_BLOB :: struct {
cUnusedBits: DWORD,
}
//+-------------------------------------------------------------------------
// Type used for any algorithm
//
// Where the Parameters CRYPT_OBJID_BLOB is in its encoded representation. For most
// algorithm types, the Parameters CRYPT_OBJID_BLOB is NULL (Parameters.cbData = 0).
//--------------------------------------------------------------------------
CRYPT_ALGORITHM_IDENTIFIER :: struct {
pszObjId: LPSTR,
Parameters: CRYPT_OBJID_BLOB,
+2
View File
@@ -205,6 +205,7 @@ foreign user32 {
ClipCursor :: proc(lpRect: LPRECT) -> BOOL ---
GetCursorPos :: proc(lpPoint: LPPOINT) -> BOOL ---
SetCursorPos :: proc(X, Y: INT) -> BOOL ---
GetCursor :: proc() -> HCURSOR ---
SetCursor :: proc(hCursor: HCURSOR) -> HCURSOR ---
when !intrinsics.is_package_imported("raylib") {
ShowCursor :: proc(bShow: BOOL) -> INT ---
@@ -229,6 +230,7 @@ foreign user32 {
GetThreadDpiAwarenessContext :: proc() -> DPI_AWARENESS_CONTEXT ---
GetWindowDpiAwarenessContext :: proc(hwnd: HWND) -> DPI_AWARENESS_CONTEXT ---
GetDpiFromDpiAwarenessContext :: proc(value: DPI_AWARENESS_CONTEXT) -> UINT ---
GetDpiForSystem :: proc() -> UINT ---
GetDpiForWindow :: proc(hwnd: HWND) -> UINT ---
SetProcessDpiAwarenessContext :: proc(value: DPI_AWARENESS_CONTEXT) -> BOOL ---
+35 -2
View File
@@ -236,8 +236,25 @@ utf8_to_wstring_buf :: proc(buf: []u16, s: string) -> wstring {
// An empty string is valid, and results in a value distinct from `nil`.
utf8_to_wstring :: proc{utf8_to_wstring_alloc, utf8_to_wstring_buf}
/*
Converts a UTF-16 `wstring` into a regular UTF-8 `string` and allocates the result.
The procedure can either assume a null-terminated input string, or convert
a fixed number of characters.
*Allocates Using Provided Allocator*
Inputs:
- s: The string to be converted
- N: The number of characters in `s` that should be converted. A value of `-1` indicates that the
procedure should keep going until it finds a terminating null character in `s`.
- allocator: (default: context.temp_allocator)
Returns:
- res: A cloned and converted string
- err: An optional allocator error if one occured, `nil` otherwise
*/
@(require_results)
wstring_to_utf8_alloc :: proc(s: wstring, N: int, allocator := context.temp_allocator) -> (res: string, err: runtime.Allocator_Error) {
wstring_to_utf8_alloc :: proc(s: wstring, N := -1, allocator := context.temp_allocator) -> (res: string, err: runtime.Allocator_Error) {
context.allocator = allocator
if N == 0 {
@@ -271,6 +288,22 @@ wstring_to_utf8_alloc :: proc(s: wstring, N: int, allocator := context.temp_allo
return string(text[:n]), nil
}
/*
Converts a UTF-16 `wstring` into a regular UTF-8 `string`, using `buf` as its backing buffer.
The procedure can either assume a null-terminated input string, or convert
a fixed number of characters.
*Uses `buf` for backing*
Inputs:
- buf: Backing buffer for result string
- s: The string to be converted
- N: The number of characters in `s` that should be converted. A value of `-1` indicates that the
procedure should keep going until it finds a terminating null character in `s`.
Returns:
- res: A cloned and converted string
*/
@(require_results)
wstring_to_utf8_buf :: proc(buf: []u8, s: wstring, N := -1) -> (res: string) {
n := WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, s, c_int(N), nil, 0, nil, nil)
@@ -307,7 +340,7 @@ to it will be converted.
Inputs:
- s: The string to be converted
- allocator: (default: context.allocator)
- allocator: (default: context.temp_allocator)
Returns:
- res: A cloned and converted string
-7
View File
@@ -376,7 +376,6 @@ DDM_SETFMT :: 0x0400
DM_GETDEFID :: 0x0400
NIN_SELECT :: 0x0400
TBM_GETPOS :: 0x0400
WM_PSD_PAGESETUPDLG :: 0x0400
WM_USER :: 0x0400
CBEM_INSERTITEMA :: 0x0401
DDM_DRAW :: 0x0401
@@ -389,7 +388,6 @@ TB_ENABLEBUTTON :: 0x0401
TBM_GETRANGEMIN :: 0x0401
TTM_ACTIVATE :: 0x0401
WM_CHOOSEFONT_GETLOGFONT :: 0x0401
WM_PSD_FULLPAGERECT :: 0x0401
CBEM_SETIMAGELIST :: 0x0402
DDM_CLOSE :: 0x0402
DM_REPOSITION :: 0x0402
@@ -399,7 +397,6 @@ RB_DELETEBAND :: 0x0402
SB_GETTEXTA :: 0x0402
TB_CHECKBUTTON :: 0x0402
TBM_GETRANGEMAX :: 0x0402
WM_PSD_MINMARGINRECT :: 0x0402
CBEM_GETIMAGELIST :: 0x0403
DDM_BEGIN :: 0x0403
HKM_SETRULES :: 0x0403
@@ -409,7 +406,6 @@ SB_GETTEXTLENGTHA :: 0x0403
TBM_GETTIC :: 0x0403
TB_PRESSBUTTON :: 0x0403
TTM_SETDELAYTIME :: 0x0403
WM_PSD_MARGINRECT :: 0x0403
CBEM_GETITEMA :: 0x0404
DDM_END :: 0x0404
PBM_SETSTEP :: 0x0404
@@ -418,13 +414,11 @@ SB_SETPARTS :: 0x0404
TB_HIDEBUTTON :: 0x0404
TBM_SETTIC :: 0x0404
TTM_ADDTOOLA :: 0x0404
WM_PSD_GREEKTEXTRECT :: 0x0404
CBEM_SETITEMA :: 0x0405
PBM_STEPIT :: 0x0405
TB_INDETERMINATE :: 0x0405
TBM_SETPOS :: 0x0405
TTM_DELTOOLA :: 0x0405
WM_PSD_ENVSTAMPRECT :: 0x0405
CBEM_GETCOMBOCONTROL :: 0x0406
PBM_SETRANGE32 :: 0x0406
RB_SETBANDINFOA :: 0x0406
@@ -432,7 +426,6 @@ SB_GETPARTS :: 0x0406
TB_MARKBUTTON :: 0x0406
TBM_SETRANGE :: 0x0406
TTM_NEWTOOLRECTA :: 0x0406
WM_PSD_YAFULLPAGERECT :: 0x0406
CBEM_GETEDITCONTROL :: 0x0407
PBM_GETRANGE :: 0x0407
RB_SETPARENT :: 0x0407
+2 -4
View File
@@ -187,8 +187,7 @@ datetime_to_utc :: proc(dt: datetime.DateTime) -> (out: datetime.DateTime, succe
tm := time.datetime_to_time(dt) or_return
record := region_get_nearest(dt.tz, tm) or_return
secs := time.time_to_unix(tm)
adj_time := time.unix(secs - record.utc_offset, 0)
adj_time := time.time_add(tm, -time.Duration(record.utc_offset) * time.Second)
adj_dt := time.time_to_datetime(adj_time) or_return
return adj_dt, true
}
@@ -220,8 +219,7 @@ datetime_to_tz :: proc(dt: datetime.DateTime, tz: ^datetime.TZ_Region) -> (out:
tm := time.datetime_to_time(dt) or_return
record := region_get_nearest(tz, tm) or_return
secs := time.time_to_unix(tm)
adj_time := time.unix(secs + record.utc_offset, i64(dt.nano))
adj_time := time.time_add(tm, time.Duration(record.utc_offset) * time.Second)
adj_dt := time.time_to_datetime(adj_time) or_return
adj_dt.tz = tz
+1
View File
@@ -57,6 +57,7 @@ package all
@(require) import "core:crypto/tuplehash"
@(require) import "core:crypto/x25519"
@(require) import "core:crypto/x448"
@(require) import "core:crypto/x509"
@(require) import "core:debug/pe"
@(require) import "core:debug/trace"
+1
View File
@@ -62,6 +62,7 @@ package all
@(require) import "core:crypto/tuplehash"
@(require) import "core:crypto/x25519"
@(require) import "core:crypto/x448"
@(require) import "core:crypto/x509"
@(require) import "core:debug/pe"
@(require) import "core:debug/trace"
+13
View File
@@ -94,6 +94,19 @@ gb_internal Slice<T> slice_make(gbAllocator const &allocator, isize count) {
return s;
}
template <typename T>
gb_internal Slice<T> slice_make_aligned(gbAllocator const &allocator, isize count, isize alignment) {
GB_ASSERT(count >= 0);
Slice<T> s = {};
s.data = cast(T *)gb_alloc_align(allocator, count*gb_size_of(T), alignment);
if (count > 0) {
GB_ASSERT(s.data != nullptr);
}
s.count = count;
return s;
}
template <typename T>
gb_internal void slice_init(Slice<T> *s, gbAllocator const &allocator, isize count) {
GB_ASSERT(count >= 0);
+10 -24
View File
@@ -100,20 +100,15 @@ gb_internal void big_int_rem_eq(BigInt *dst, BigInt const *x);
gb_internal bool big_int_is_neg(BigInt const *x);
gb_internal void big_int_neg(BigInt *dst, BigInt const *x);
// NOTE: libtommath allows the output to alias an input, so `dst` is not copied first
gb_internal void big_int_add_eq(BigInt *dst, BigInt const *x) {
BigInt res = {};
big_int_init(&res, dst);
big_int_add(dst, &res, x);
big_int_add(dst, dst, x);
}
gb_internal void big_int_sub_eq(BigInt *dst, BigInt const *x) {
BigInt res = {};
big_int_init(&res, dst);
big_int_sub(dst, &res, x);
big_int_sub(dst, dst, x);
}
gb_internal void big_int_shl_eq(BigInt *dst, BigInt const *x) {
BigInt res = {};
big_int_init(&res, dst);
big_int_shl(dst, &res, x);
big_int_shl(dst, dst, x);
}
gb_internal void big_int_shr_eq(BigInt *dst, BigInt const *x) {
BigInt res = {};
@@ -121,9 +116,7 @@ gb_internal void big_int_shr_eq(BigInt *dst, BigInt const *x) {
big_int_shr(dst, &res, x);
}
gb_internal void big_int_mul_eq(BigInt *dst, BigInt const *x) {
BigInt res = {};
big_int_init(&res, dst);
big_int_mul(dst, &res, x);
big_int_mul(dst, dst, x);
}
gb_internal void big_int_quo_eq(BigInt *dst, BigInt const *x) {
BigInt res = {};
@@ -214,9 +207,6 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success
mp_zero(dst);
BigInt digit = {};
defer (big_int_dealloc(&digit));
isize i = 0;
isize digit_count = 0;
for (; i < len; i++) {
@@ -246,9 +236,8 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success
digit_count += 1;
}
big_int_from_u64(&digit, v);
big_int_mul_eq(dst, &b);
big_int_add_eq(dst, &digit);
mp_mul_d(dst, cast(mp_digit)base, dst);
mp_add_d(dst, cast(mp_digit)v, dst);
}
if (digit_count == 0) {
// a base prefix with only digit separators after it, `0x_`, has no digits at all
@@ -289,7 +278,7 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success
v = u64_digit_value(r);
} else {
*success = false;
break;
return;
}
exp *= 10;
exp += v;
@@ -300,11 +289,8 @@ gb_internal void big_int_from_string(BigInt *dst, String const &s, bool *success
return;
}
// NOTE(Jeroen): A valid integer can never have an exponent larger than 308 (per `max(f64)`).
// As an integer, not even larger than `max(u128)` which has a base 10 exponent of 38.
// But we also use this path to parse float literals like those in `core:math.pow10_f64`,
// so we have to stick with 1e308.
if (exp > 308) {
// NOTE(bill): Just limit the maximum exponent to bigger than the actual maximum to allow for keeping overflows
if (exp > 512) {
*success = false;
return;
}
+228
View File
@@ -0,0 +1,228 @@
struct BigRat {
mp_int num; // signed
mp_int den; // > 0
};
gb_global i64 const BIG_RAT_MAX_DECIMAL_EXP = 65536;
gb_global i32 const BIG_RAT_MAX_COMPONENT_BITS = 65536;
// True if either component's magnitude exceeds BIG_RAT_MAX_COMPONENT_BITS (call after normalizing).
gb_internal bool big_rat_components_too_large(mp_int const *num, mp_int const *den) {
return mp_count_bits(num) > BIG_RAT_MAX_COMPONENT_BITS ||
mp_count_bits(den) > BIG_RAT_MAX_COMPONENT_BITS;
}
// Reduce num/den to lowest terms with den > 0 (0 becomes 0/1).
gb_internal void big_rat_normalize(mp_int *num, mp_int *den) {
if (mp_iszero(num)) {
mp_set_u64(den, 1);
return;
}
if (big_int_is_neg(den)) {
mp_neg(num, num);
mp_neg(den, den);
}
mp_int g;
mp_int one;
mp_init(&g); defer (mp_clear(&g));
mp_init(&one); defer (mp_clear(&one));
mp_set_u64(&one, 1);
mp_gcd(num, den, &g);
if (!mp_iszero(&g) && mp_cmp(&g, &one) != MP_EQ) {
mp_int q, r;
mp_init(&q); defer (mp_clear(&q));
mp_init(&r); defer (mp_clear(&r));
mp_div(num, &g, &q, &r);
mp_copy(&q, num);
mp_div(den, &g, &q, &r);
mp_copy(&q, den);
}
}
gb_internal bool big_rat_from_decimal_string(String const &s, mp_int *num, mp_int *den) {
TEMPORARY_ALLOCATOR_GUARD();
char *digits = gb_alloc_array(temporary_allocator(), char, s.len + 2);
isize dlen = 0;
isize i = 0;
bool neg = false;
if (i < s.len && (s[i] == '+' || s[i] == '-')) {
neg = s[i] == '-';
i += 1;
}
i64 frac_digits = 0;
bool seen_dot = false;
for (; i < s.len; i++) {
u8 c = s[i];
if (c == '_') {
continue;
}
if (c == '.') {
if (seen_dot) {
return false;
}
seen_dot = true;
continue;
}
if (c == 'e' || c == 'E') {
break;
}
if (!gb_char_is_digit(cast(char)c)) {
return false;
}
digits[dlen++] = cast(char)c;
if (seen_dot) {
frac_digits += 1;
}
}
if (dlen == 0) {
digits[dlen++] = '0';
}
digits[dlen] = 0;
i64 exp = 0;
bool exp_neg = false;
if (i < s.len && (s[i] == 'e' || s[i] == 'E')) {
i += 1;
if (i < s.len && (s[i] == '+' || s[i] == '-')) {
exp_neg = s[i] == '-';
i += 1;
}
isize exp_digits = 0;
for (; i < s.len; i++) {
u8 c = s[i];
if (c == '_') {
continue;
}
if (!gb_char_is_digit(cast(char)c)) {
return false;
}
if (exp <= BIG_RAT_MAX_DECIMAL_EXP) { // clamp so it cannot overflow; rejected below
exp = exp*10 + cast(i64)(c - '0');
}
exp_digits += 1;
}
if (exp_digits == 0) return false;
}
i64 signed_exp = exp_neg ? -exp : exp;
i64 net = signed_exp - frac_digits; // value = mantissa * 10^net
if (net > BIG_RAT_MAX_DECIMAL_EXP || net < -BIG_RAT_MAX_DECIMAL_EXP) {
return false;
}
mp_init(num);
mp_init(den);
mp_read_radix(num, digits, 10);
mp_set_u64(den, 1);
if (net != 0) {
mp_int ten; mp_init(&ten); defer (mp_clear(&ten)); mp_set_u64(&ten, 10);
mp_int p; mp_init(&p); defer (mp_clear(&p));
mp_expt_n(&ten, cast(int)(net < 0 ? -net : net), &p);
if (net > 0) {
mp_mul(num, &p, num);
} else {
mp_copy(&p, den);
}
}
if (neg) {
mp_neg(num, num);
}
return true;
}
// Convert the exact rational `a/b` (b != 0) to the nearest value of a target IEEE-754 binary float,
// with round-to-nearest, ties-to-even. `mantissa_bits`/`ebias` select the target format:
// f16: 10 / 15, f32: 23 / 127, f64: 52 / 1023.
// The result is returned as an f64 that exactly equals that target value (target subnormals and
// overflow-to-infinity included), so it can be stored in an f64 and re-emitted losslessly.
// NOTE(bill): Ported from core:math/big `internal_rat_to_float`.
gb_internal f64 big_rat_to_float(mp_int const *a_in, mp_int const *b_in, int mantissa_bits, int ebias) {
// NOTE: lowercase locals on purpose: `MSIZE` is a system macro on some platforms (arm/param.h).
int const msize = mantissa_bits; // explicit mantissa bits
int const msize1 = msize + 1; // incl. the implicit bit
int const msize2 = msize + 2; // one guard bit
int const emin = 1 - ebias;
int alen = mp_count_bits(a_in);
if (alen == 0) {
return big_int_is_neg(a_in) ? -0.0 : 0.0;
}
bool has_sign = big_int_is_neg(a_in) != big_int_is_neg(b_in);
int exp = alen - mp_count_bits(b_in);
mp_int a2, b2, q, r;
mp_init(&a2); defer (mp_clear(&a2));
mp_init(&b2); defer (mp_clear(&b2));
mp_init(&q); defer (mp_clear(&q));
mp_init(&r); defer (mp_clear(&r));
mp_abs(a_in, &a2);
mp_abs(b_in, &b2);
int shift = msize2 - exp;
if (shift > 0) {
mp_mul_2d(&a2, shift, &a2);
} else if (shift < 0) {
mp_mul_2d(&b2, -shift, &b2);
}
mp_div(&a2, &b2, &q, &r);
bool has_rem = !mp_iszero(&r);
u64 mantissa = mp_get_mag_u64(&q);
if ((mantissa >> msize2) == 1) {
if (mantissa & 1) {
has_rem = true;
}
mantissa >>= 1;
exp += 1;
}
// mantissa is now in [2^msize1, 2^msize2): msize1 significant bits plus one guard bit.
if (emin - msize <= exp && exp <= emin) {
// Denormalise: fold the bits that fall below the subnormal grid into the guard/sticky.
unsigned sh = cast(unsigned)(emin - (exp - 1));
u64 lost = mantissa & ((cast(u64)1 << sh) - 1);
has_rem = has_rem || (lost != 0);
mantissa >>= sh;
exp = 2 - ebias;
}
if (mantissa & 1) {
if (has_rem || (mantissa & 2)) { // round half to even
mantissa += 1;
if (mantissa >= (cast(u64)1 << msize2)) {
mantissa >>= 1;
exp += 1;
}
}
}
mantissa >>= 1; // drop the guard bit
f64 f = ldexp(cast(f64)mantissa, exp - msize1);
// Materialise the target format's overflow-to-infinity (exact otherwise: `f` already has the
// target's mantissa width and exponent, so the narrowing cast does not round).
if (msize == 23) {
f = cast(f64)cast(f32)f;
} else if (msize == 10) {
f = cast(f64)f16_to_f32(f32_to_f16(cast(f32)f));
}
if (has_sign) {
f = -f;
}
return f;
}
// Convert the exact rational `a/b` (b != 0) to the nearest f64 (round-to-nearest, ties-to-even).
gb_internal f64 big_rat_to_f64(mp_int const *a_in, mp_int const *b_in) {
return big_rat_to_float(a_in, b_in, 52, 1023);
}
+19 -10
View File
@@ -317,10 +317,11 @@ enum VetFlags : u64 {
VetFlag_Tabs = 1u<<9,
VetFlag_UnusedProcedures = 1u<<10,
VetFlag_ExplicitAllocators = 1u<<11,
VetFlag_WhenShadowing = 1u<<12,
VetFlag_Unused = VetFlag_UnusedVariables|VetFlag_UnusedImports,
VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated|VetFlag_Cast,
VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated|VetFlag_Cast|VetFlag_WhenShadowing,
VetFlag_Using = VetFlag_UsingStmt|VetFlag_UsingParam,
};
@@ -352,6 +353,8 @@ u64 get_vet_flag_from_name(String const &name) {
return VetFlag_UnusedProcedures;
} else if (name == "explicit-allocators") {
return VetFlag_ExplicitAllocators;
} else if (name == "when-shadowing") {
return VetFlag_WhenShadowing;
}
return VetFlag_NONE;
}
@@ -435,14 +438,23 @@ enum LTOKind : i32 {
enum LinkerChoice : i32 {
Linker_Invalid = -1,
Linker_Default = 0,
Linker_Default = 0, // radlink on Windows
Linker_lld,
Linker_msvc,
Linker_radlink,
Linker_mold,
Linker_COUNT,
};
String linker_choices[Linker_COUNT] = {
str_lit("default"),
str_lit("lld"),
str_lit("msvc"),
str_lit("radlink"),
str_lit("mold"),
};
enum SourceCodeLocationInfo : u8 {
SourceCodeLocationInfo_Normal = 0,
SourceCodeLocationInfo_Obfuscated = 1,
@@ -450,13 +462,6 @@ enum SourceCodeLocationInfo : u8 {
SourceCodeLocationInfo_None = 3,
};
String linker_choices[Linker_COUNT] = {
str_lit("default"),
str_lit("lld"),
str_lit("radlink"),
str_lit("mold"),
};
enum IntegerDivisionByZeroKind : u8 {
IntegerDivisionByZero_Trap,
IntegerDivisionByZero_Zero,
@@ -546,6 +551,7 @@ struct BuildContext {
bool ignore_unknown_attributes;
bool no_bounds_check;
bool no_type_assert;
bool lifetime_markers; // Opt-in to llvm.lifetime.* markers on scoped locals.
bool dynamic_literals; // Opt-in to `#+feature dynamic-literals` project-wide.
bool no_output_files;
bool no_crt;
@@ -597,6 +603,9 @@ struct BuildContext {
bool internal_weak_monomorphization;
bool internal_ignore_llvm_verification;
bool internal_llvm_no_sroa;
bool internal_global_entity_graph;
u64 internal_shuffle_global_entities; // seed, 0 = no shuffle
bool internal_check_global_edges;
bool enable_rvo;
@@ -2339,7 +2348,7 @@ gb_internal bool init_build_paths(String init_filename) {
return false;
}
if (build_context.linker_choice == Linker_Default && find_result.vs_exe_path.len == 0) {
if (build_context.linker_choice == Linker_msvc && find_result.vs_exe_path.len == 0) {
gb_printf_err("link.exe not found.\n");
return false;
}
+1 -1
View File
@@ -217,7 +217,7 @@ enum AsmMismatch : u8 {
// Accepts either a signed or an unsigned interpretation of the bit pattern, which
// matches how the assembler treats imm fields (e.g. both 200 and -56 fit imm8).
gb_internal bool check_asm_immediate_value_fits(ExactValue ev, i32 bits, i32 *needed_, AsmMismatch *mismatch_) {
if (ev.kind == ExactValue_Float) {
if (ev.kind == ExactValue_Float || ev.kind == ExactValue_Rational) {
// Try to convert it if possible to an integer
ev = exact_value_to_integer(ev);
}
+209 -123
View File
@@ -686,6 +686,14 @@ gb_internal bool check_builtin_objc_procedure(CheckerContext *c, Operand *operan
} else {
try_to_add_package_dependency(c, "runtime", "_NSConcreteStackBlock");
}
for (isize i = 0; i < capture_arg_count; i++) {
Type *t = param_operands[i].type;
if (is_type_pointer(t) && is_type_objc_object(t)) {
try_to_add_package_dependency(c, "runtime", "_Block_object_assign");
try_to_add_package_dependency(c, "runtime", "_Block_object_dispose");
break;
}
}
*operand = poly_op;
operand->type = alloc_type_pointer(operand->type);
@@ -2029,7 +2037,61 @@ gb_internal bool check_builtin_simd_operation(CheckerContext *c, Operand *operan
return false;
}
gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &original_string, bool err_on_not_found, LoadFileCache **cache_, LoadFileTier tier, bool use_mutex=true) {
// NOTE(bill, 2026-10-02) The cache entry of `path` loaded to at least `tier`.
// The map is only locked to find or add the entry, and the file is loaded under the entry's own mutex, so different files load at once.
gb_internal LoadFileCache *load_file_cache_entry(CheckerInfo *info, String const &path, LoadFileTier tier) {
LoadFileCache *cache = nullptr;
mutex_lock(&info->load_file_mutex);
LoadFileCache **cache_ptr = string_map_get(&info->load_file_cache, path);
if (cache_ptr != nullptr) {
cache = *cache_ptr;
} else {
cache = permanent_alloc_item<LoadFileCache>();
cache->path = path;
string_map_init(&cache->hashes, 32);
string_map_set(&info->load_file_cache, path, cache);
}
mutex_unlock(&info->load_file_mutex);
MUTEX_GUARD(&cache->mutex);
if (tier > cache->tier) {
cache->tier = tier;
TEMPORARY_ALLOCATOR_GUARD();
char *c_str = alloc_cstring(temporary_allocator(), path);
gbFile f = {};
cache->file_error = gb_file_open(&f, c_str);
defer (gb_file_close(&f));
if (cache->file_error == gbFileError_None) {
cache->exists = true;
switch(tier) {
case LoadFileTier_Exists:
// Nothing to do.
break;
case LoadFileTier_Contents: {
isize file_size = cast(isize)gb_file_size(&f);
if (file_size > 0) {
u8 *ptr = permanent_alloc_array<u8>(file_size+1);
gb_file_read_at(&f, ptr, file_size, 0);
ptr[file_size] = '\0';
cache->data.text = ptr;
cache->data.len = file_size;
}
break;
}
default:
GB_PANIC("Unhandled LoadFileTier");
break;
};
}
}
return cache;
}
gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String const &original_string, bool err_on_not_found, LoadFileCache **cache_, LoadFileTier tier) {
ast_node(ce, CallExpr, call);
ast_node(bd, BasicDirective, ce->proc);
String builtin_name = bd->name.string;
@@ -2051,75 +2113,12 @@ gb_internal bool cache_load_file_directive(CheckerContext *c, Ast *call, String
}
}
if (use_mutex) mutex_lock(&c->info->load_file_mutex);
defer (if (use_mutex) mutex_unlock(&c->info->load_file_mutex));
LoadFileCache *cache = load_file_cache_entry(c->info, path, tier);
if (cache_) *cache_ = cache;
gbFileError file_error = gbFileError_None;
String data = {};
bool exists = false;
LoadFileTier cache_tier = LoadFileTier_Invalid;
LoadFileCache **cache_ptr = string_map_get(&c->info->load_file_cache, path);
LoadFileCache *cache = cache_ptr ? *cache_ptr : nullptr;
if (cache) {
file_error = cache->file_error;
data = cache->data;
exists = cache->exists;
cache_tier = cache->tier;
}
defer ({
if (cache == nullptr) {
LoadFileCache *new_cache = permanent_alloc_item<LoadFileCache>();
new_cache->path = path;
new_cache->data = data;
new_cache->file_error = file_error;
new_cache->exists = exists;
new_cache->tier = cache_tier;
string_map_init(&new_cache->hashes, 32);
string_map_set(&c->info->load_file_cache, path, new_cache);
if (cache_) *cache_ = new_cache;
} else {
cache->data = data;
cache->file_error = file_error;
cache->exists = exists;
cache->tier = cache_tier;
if (cache_) *cache_ = cache;
}
});
if (tier > cache_tier) {
cache_tier = tier;
TEMPORARY_ALLOCATOR_GUARD();
char *c_str = alloc_cstring(temporary_allocator(), path);
gbFile f = {};
file_error = gb_file_open(&f, c_str);
defer (gb_file_close(&f));
if (file_error == gbFileError_None) {
exists = true;
switch(tier) {
case LoadFileTier_Exists:
// Nothing to do.
break;
case LoadFileTier_Contents: {
isize file_size = cast(isize)gb_file_size(&f);
if (file_size > 0) {
u8 *ptr = permanent_alloc_array<u8>(file_size+1);
gb_file_read_at(&f, ptr, file_size, 0);
ptr[file_size] = '\0';
data.text = ptr;
data.len = file_size;
}
break;
}
default:
GB_PANIC("Unhandled LoadFileTier");
};
}
}
mutex_lock(&cache->mutex);
gbFileError file_error = cache->file_error;
mutex_unlock(&cache->mutex);
switch (file_error) {
default:
@@ -2253,6 +2252,62 @@ gb_internal int file_cache_sort_cmp(void const *x, void const *y) {
return string_compare(a->path, b->path);
}
// NOTE(bill): a directory may hold thousands of files, which are read one at a time otherwise.
// This thread and a few helper tasks take them in turn and this thread only waits for the ones a running helper has taken,
// and the job is freed by whichever of them finishes with it last.
struct LoadDirectoryPrefetch {
CheckerInfo * info;
Array<String> paths;
std::atomic<isize> next;
std::atomic<isize> done;
std::atomic<i32> refs;
};
gb_internal void load_directory_prefetch_run(LoadDirectoryPrefetch *job) {
for (isize i = job->next.fetch_add(1); i < job->paths.count; i = job->next.fetch_add(1)) {
load_file_cache_entry(job->info, job->paths[i], LoadFileTier_Contents);
job->done.fetch_add(1);
}
if (job->refs.fetch_sub(1) == 1) {
array_free(&job->paths);
gb_free(heap_allocator(), job);
}
}
gb_internal WORKER_TASK_PROC(load_directory_prefetch_worker) {
load_directory_prefetch_run(cast(LoadDirectoryPrefetch *)data);
return 0;
}
gb_internal void load_directory_prefetch(CheckerInfo *info, Array<FileInfo> const &list) {
isize const FILES_PER_HELPER = 64;
LoadDirectoryPrefetch *job = gb_alloc_item(heap_allocator(), LoadDirectoryPrefetch);
job->info = info;
array_init(&job->paths, heap_allocator(), 0, list.count);
for (FileInfo const &fi : list) {
if (!fi.is_dir) {
array_add(&job->paths, fi.fullpath);
}
}
isize count = job->paths.count;
isize helpers = gb_min(global_thread_pool.threads.count - 1, count/FILES_PER_HELPER);
job->refs.store(cast(i32)(helpers + 1));
for (isize i = 0; i < helpers; i++) {
thread_pool_add_task(load_directory_prefetch_worker, job);
}
job->refs.fetch_add(1); // NOTE(bill): kept until every file is done
load_directory_prefetch_run(job);
while (job->done.load() < count) {
yield_thread();
}
if (job->refs.fetch_sub(1) == 1) {
array_free(&job->paths);
gb_free(heap_allocator(), job);
}
}
gb_internal LoadDirectiveResult check_load_directory_directive(CheckerContext *c, Operand *operand, Ast *call, Type *type_hint, bool err_on_not_found) {
ast_node(ce, CallExpr, call);
ast_node(bd, BasicDirective, ce->proc);
@@ -2301,39 +2356,26 @@ gb_internal LoadDirectiveResult check_load_directory_directive(CheckerContext *c
bool ok = determine_path_from_string(ignore_mutex, call, base_dir, original_string, &path);
gb_unused(ok);
}
MUTEX_GUARD(&c->info->load_directory_mutex);
gbFileError file_error = gbFileError_None;
Array<LoadFileCache *> file_caches = {};
// NOTE(bill): the map is only locked to find or add the directory's entry which is loaded under its own mutex
LoadDirectoryCache *cache = nullptr;
mutex_lock(&c->info->load_directory_mutex);
LoadDirectoryCache **cache_ptr = string_map_get(&c->info->load_directory_cache, path);
LoadDirectoryCache *cache = cache_ptr ? *cache_ptr : nullptr;
if (cache) {
file_error = cache->file_error;
if (cache_ptr != nullptr) {
cache = *cache_ptr;
} else {
cache = permanent_alloc_item<LoadDirectoryCache>();
cache->path = path;
string_map_set(&c->info->load_directory_cache, path, cache);
}
defer ({
if (cache == nullptr) {
LoadDirectoryCache *new_cache = permanent_alloc_item<LoadDirectoryCache>();
new_cache->path = path;
new_cache->files = file_caches;
new_cache->file_error = file_error;
string_map_set(&c->info->load_directory_cache, path, new_cache);
map_set(&c->info->load_directory_map, call, new_cache);
} else {
cache->file_error = file_error;
map_set(&c->info->load_directory_map, call, cache);
}
});
map_set(&c->info->load_directory_map, call, cache);
mutex_unlock(&c->info->load_directory_mutex);
MUTEX_GUARD(&cache->mutex);
LoadDirectiveResult result = LoadDirective_Success;
if (cache == nullptr) {
if (!cache->loaded) {
cache->loaded = true;
Array<FileInfo> list = {};
ReadDirectoryError rd_err = read_directory(path, &list);
defer (array_free(&list));
@@ -2364,27 +2406,26 @@ gb_internal LoadDirectiveResult check_load_directory_directive(CheckerContext *c
return LoadDirective_Error;
}
load_directory_prefetch(c->info, list);
isize files_to_reserve = list.count+1; // always reserve 1
file_caches = array_make<LoadFileCache *>(heap_allocator(), 0, files_to_reserve);
mutex_lock(&c->info->load_file_mutex);
defer (mutex_unlock(&c->info->load_file_mutex));
cache->files = array_make<LoadFileCache *>(heap_allocator(), 0, files_to_reserve);
for (FileInfo fi : list) {
LoadFileCache *cache = nullptr;
LoadFileCache *file_cache = nullptr;
if (fi.is_dir) {
continue;
}
if (cache_load_file_directive(c, call, fi.fullpath, err_on_not_found, &cache, LoadFileTier_Contents, /*use_mutex*/false)) {
array_add(&file_caches, cache);
if (cache_load_file_directive(c, call, fi.fullpath, err_on_not_found, &file_cache, LoadFileTier_Contents)) {
array_add(&cache->files, file_cache);
} else {
result = LoadDirective_Error;
}
}
array_sort(file_caches, file_cache_sort_cmp);
array_sort(cache->files, file_cache_sort_cmp);
}
@@ -2574,7 +2615,7 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o
LoadFileCache *cache = nullptr;
if (cache_load_file_directive(c, call, original_string, true, &cache, LoadFileTier_Contents)) {
MUTEX_GUARD(&c->info->load_file_mutex);
MUTEX_GUARD(&cache->mutex);
// TODO(bill): make these procedures fast :P
u64 hash_value = 0;
u64 *hash_value_ptr = string_map_get(&cache->hashes, hash_kind);
@@ -3951,10 +3992,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
if (is_type_complex(t)) {
if (x->mode == Addressing_Constant) {
// Keep the conjugate exact: negate the imaginary component(s) as ExactValues.
ExactValue v = exact_value_to_complex(x->value);
f64 r = v.value_complex->real;
f64 i = -v.value_complex->imag;
x->value = exact_value_complex(r, i);
ExactValue r = v.value_complex->real;
ExactValue i = exact_unary_operator_value(Token_Sub, v.value_complex->imag, 0, false);
x->value = exact_value_complex_ev(r, i);
x->mode = Addressing_Constant;
} else {
x->mode = Addressing_Value;
@@ -3962,11 +4004,11 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
} else if (is_type_quaternion(t)) {
if (x->mode == Addressing_Constant) {
ExactValue v = exact_value_to_quaternion(x->value);
f64 r = +v.value_quaternion->real;
f64 i = -v.value_quaternion->imag;
f64 j = -v.value_quaternion->jmag;
f64 k = -v.value_quaternion->kmag;
x->value = exact_value_quaternion(r, i, j, k);
ExactValue r = v.value_quaternion->real;
ExactValue i = exact_unary_operator_value(Token_Sub, v.value_quaternion->imag, 0, false);
ExactValue j = exact_unary_operator_value(Token_Sub, v.value_quaternion->jmag, 0, false);
ExactValue k = exact_unary_operator_value(Token_Sub, v.value_quaternion->kmag, 0, false);
x->value = exact_value_quaternion_ev(r, i, j, k);
x->mode = Addressing_Constant;
} else {
x->mode = Addressing_Value;
@@ -4594,17 +4636,24 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
operand->value.value_float = bit_cast<f64>(abs);
break;
}
case ExactValue_Rational: {
mp_int n; mp_init(&n);
defer (mp_clear(&n));
mp_abs(&operand->value.value_rational->num, &n);
operand->value = exact_value_rational_from_ints(&n, &operand->value.value_rational->den);
break;
}
case ExactValue_Complex: {
f64 r = operand->value.value_complex->real;
f64 i = operand->value.value_complex->imag;
f64 r = exact_value_to_f64(operand->value.value_complex->real);
f64 i = exact_value_to_f64(operand->value.value_complex->imag);
operand->value = exact_value_float(gb_sqrt(r*r + i*i));
break;
}
case ExactValue_Quaternion: {
f64 r = operand->value.value_quaternion->real;
f64 i = operand->value.value_quaternion->imag;
f64 j = operand->value.value_quaternion->jmag;
f64 k = operand->value.value_quaternion->kmag;
f64 r = exact_value_to_f64(operand->value.value_quaternion->real);
f64 i = exact_value_to_f64(operand->value.value_quaternion->imag);
f64 j = exact_value_to_f64(operand->value.value_quaternion->jmag);
f64 k = exact_value_to_f64(operand->value.value_quaternion->kmag);
operand->value = exact_value_float(gb_sqrt(r*r + i*i + j*j + k*k));
break;
}
@@ -5202,6 +5251,9 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
operand->type = o.type;
ExactValue value = o.value;
if (value.kind == ExactValue_Rational) {
value = exact_value_to_float(value); // constant floor/ceil/round operate on the f64
}
if (value.kind == ExactValue_Integer) {
// do nothing
} else if (value.kind == ExactValue_Float) {
@@ -5507,17 +5559,42 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
ExactValue value = arg->tav.value;
GB_ASSERT(value.kind == ExactValue_Compound);
ast_node(cl, CompoundLit, value.value_compound);
count_needed += cl->elems.count;
count_needed += is_type_array(arg->tav.type)
? cast(isize)get_array_type_count(arg->tav.type)
: cl->elems.count;
}
Array<Ast *> new_elems = {};
array_init(&new_elems, permanent_allocator(), 0, count_needed);
CheckerContext zero_context = *c;
zero_context.type_hint_expr = nullptr;
for (Ast *arg : ce->args) {
ExactValue value = arg->tav.value;
GB_ASSERT(value.kind == ExactValue_Compound);
ast_node(cl, CompoundLit, value.value_compound);
array_add_elems(&new_elems, cl->elems.data, cl->elems.count);
if (is_type_array(arg->tav.type)) {
isize count = cast(isize)get_array_type_count(arg->tav.type);
GB_ASSERT(cl->elems.count <= count);
for (isize i = cl->elems.count; i < count; i++) {
Ast *zero = ast_compound_lit(arg->file(), nullptr, {}, cl->open, cl->close);
if (is_type_constant_type(elem_type)) {
Operand z = {};
check_expr_with_type_hint(&zero_context, &z, zero, elem_type);
if (z.mode == Addressing_Invalid) {
return false;
}
GB_ASSERT(z.mode == Addressing_Constant);
GB_ASSERT(are_types_identical(z.type, elem_type));
} else {
add_type_and_value(c, zero, Addressing_Constant, elem_type, exact_value_compound(zero));
}
array_add(&new_elems, zero);
}
}
}
Ast *new_compound_lit = ast_compound_lit(lhs.expr->file(), nullptr, new_elems, ast_token(lhs.expr), ast_end_token(ce->args[ce->args.count-1]));
@@ -6993,6 +7070,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
variants[i] = alloc_type_pointer(bt->Union.variants[i]);
}
new_type->Union.variants = variants;
wait_signal_set(&new_type->Union.variants_wait_signal); // built directly, not via check_union_type
// NOTE(bill): Is this even correct?
new_type->Union.node = operand->expr;
@@ -7170,6 +7248,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
}
merged_union->Union.variants = slice_from_array(variants);
wait_signal_set(&merged_union->Union.variants_wait_signal); // built directly, not via check_union_type
operand->mode = Addressing_Type;
operand->type = merged_union;
@@ -7483,7 +7562,7 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
operand->type = t_untyped_bool;
bool is_specialization = false;
if (!are_types_identical(s, t)) {
is_specialization = check_type_specialization_to(c, s, t, false, false);
is_specialization = subst_check_specialization(c, s, t, /*modify_type*/false);
}
operand->value = exact_value_bool(is_specialization);
@@ -8383,6 +8462,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
add_comparison_procedures_for_fields(c, type);
operand->mode = Addressing_Value;
operand->type = t_equal_proc;
break;
@@ -8431,7 +8512,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
return false;
}
add_map_key_type_dependencies(c, type);
add_map_key_type_dependencies(c, type->Map.key);
add_comparison_procedures_for_fields(c, type->Map.key);
operand->mode = Addressing_Value;
operand->type = t_map_info_ptr;
@@ -8472,8 +8554,12 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As
{
Ast *call_expr = unparen_expr(ce->args[0]);
Operand op = {};
bool prev_in_procedure_of = c->in_procedure_of;
c->in_procedure_of = true;
check_expr_base(c, &op, ce->args[0], nullptr);
if (op.mode != Addressing_Value || call_expr == nullptr || call_expr->kind != Ast_CallExpr) {
c->in_procedure_of = prev_in_procedure_of;
bool is_call_mode = op.mode == Addressing_Value || op.mode == Addressing_NoValue || op.mode == Addressing_OptionalOk;
if (!is_call_mode || call_expr == nullptr || call_expr->kind != Ast_CallExpr) {
error(ce->args[0], "Expected a call expression for '%.*s'", LIT(builtin_name));
return false;
}
+177 -89
View File
@@ -170,7 +170,7 @@ gb_internal void override_entity_in_scope(Entity *original_entity, Entity *new_e
// has been "evaluated" and the variant data can be copied across
rw_mutex_lock(&found_scope->mutex);
scope_map_insert(&found_scope->elements, original_intern, hash, new_entity);
scope_map_replace(&found_scope->elements, original_intern, hash, new_entity);
rw_mutex_unlock(&found_scope->mutex);
original_entity->flags |= EntityFlag_Overridden;
@@ -996,6 +996,9 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e)
} else {
String name = ident->Ident.token.string;
Entity *found = scope_lookup(ctx->scope, ident->Ident.interned, ident->Ident.hash);
if (found != nullptr) {
found = resolve_alias_entity(ctx, found, nullptr);
}
if (found == nullptr) {
if (is_blank_ident(name)) {
@@ -1254,41 +1257,95 @@ gb_internal void check_target_feature_attributes(AttributeContext &ac, Entity *e
}
}
gb_internal void check_foreign_procedure(CheckerContext *ctx, Entity *e, DeclInfo *d) {
GB_ASSERT(e != nullptr);
GB_ASSERT(e->kind == Entity_Procedure);
String name = e->Procedure.link_name;
gb_internal void add_link_name_use(CheckerInfo *info, String name, Entity *e, DeclInfo *d, LinkNameUseKind kind) {
mutex_lock(&info->foreign_mutex);
array_add(&info->link_names, LinkNameUse{name, e, d, kind});
mutex_unlock(&info->foreign_mutex);
}
mutex_lock(&ctx->info->foreign_mutex);
gb_internal GB_COMPARE_PROC(link_name_use_cmp) {
LinkNameUse const *x = cast(LinkNameUse const *)a;
LinkNameUse const *y = cast(LinkNameUse const *)b;
i32 cmp = string_compare(x->name, y->name);
if (cmp != 0) {
return cmp;
}
if (x->entity != y->entity) {
return entity_source_order_cmp(x->entity, y->entity);
}
return i32_cmp(x->kind, y->kind);
}
gb_internal void check_link_name_uses(Checker *c) {
auto &uses = c->info.link_names;
array_sort(uses, link_name_use_cmp);
LinkNameUse *first = nullptr;
for (isize i = 0; i < uses.count; i++) {
LinkNameUse *u = &uses[i];
if (i > 0 && uses[i-1].name != u->name) {
first = nullptr;
} else if (i > 0 && uses[i-1].entity == u->entity) {
continue;
}
String name = u->name;
if (name == "main" && u->kind != LinkNameUse_Variable) {
if (u->kind == LinkNameUse_ForeignProcedure || u->entity->pkg->kind != Package_Runtime) {
error(u->decl->proc_lit, "The link name 'main' is reserved for internal use");
}
continue;
}
if (first == nullptr) {
first = u;
continue;
}
Entity *e = u->entity;
Entity *f = first->entity;
auto *fp = &ctx->info->foreigns;
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(fp, key);
if (found && e != *found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
Type *this_type = base_type(e->type);
Type *other_type = base_type(f->type);
if (is_type_proc(this_type) && is_type_proc(other_type)) {
if (!are_signatures_similar_enough(this_type, other_type)) {
error(d->proc_lit,
"Redeclaration of foreign procedure '%.*s' with different type signatures\n"
switch (u->kind) {
case LinkNameUse_ForeignProcedure:
if (is_type_proc(this_type) && is_type_proc(other_type)) {
if (!are_signatures_similar_enough(this_type, other_type)) {
error(u->decl->proc_lit,
"Redeclaration of foreign procedure '%.*s' with different type signatures\n"
"\tat %s",
LIT(name), token_pos_to_string(pos));
}
} else if (!signature_parameter_similar_enough(this_type, other_type)) {
error(u->decl->proc_lit,
"Foreign entity '%.*s' previously declared elsewhere with a different type\n"
"\tat %s",
LIT(name), token_pos_to_string(pos));
}
} else if (!signature_parameter_similar_enough(this_type, other_type)) {
error(d->proc_lit,
"Foreign entity '%.*s' previously declared elsewhere with a different type\n"
"\tat %s",
break;
case LinkNameUse_Procedure:
// TODO(bill): Better error message?
error(u->decl->proc_lit,
"Non-unique linking name for procedure '%.*s'\n"
"\tother at %s",
LIT(name), token_pos_to_string(pos));
break;
case LinkNameUse_Variable:
if (e->type == nullptr || f->type == nullptr || !signature_parameter_similar_enough(this_type, other_type)) {
error(e->token,
"Foreign entity '%.*s' previously declared elsewhere with a different type\n"
"\tat %s",
LIT(name), token_pos_to_string(pos));
}
break;
}
} else if (name == "main") {
error(d->proc_lit, "The link name 'main' is reserved for internal use");
} else {
string_map_set(fp, key, e);
}
}
mutex_unlock(&ctx->info->foreign_mutex);
gb_internal void check_foreign_procedure(CheckerContext *ctx, Entity *e, DeclInfo *d) {
GB_ASSERT(e != nullptr);
GB_ASSERT(e->kind == Entity_Procedure);
add_link_name_use(ctx->info, e->Procedure.link_name, e, d, LinkNameUse_ForeignProcedure);
}
gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
@@ -1559,14 +1616,17 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
}
if (e->pkg->kind == Package_Init) {
if (ctx->info->entry_point != nullptr) {
mutex_lock(&ctx->info->entry_point_mutex);
Entity *prev_entry_point = ctx->info->entry_point;
if (prev_entry_point == nullptr) {
ctx->info->entry_point = e;
}
mutex_unlock(&ctx->info->entry_point_mutex);
if (prev_entry_point != nullptr) {
begin_error_block();
error(e->token, "Redeclaration of the entry point procedure 'main'");
error_line("\tSuggestion: Is this a single-file package? If so, try compiling using the `-file` flag.\n");
end_error_block();
} else {
ctx->info->entry_point = e;
}
}
}
@@ -1657,28 +1717,7 @@ gb_internal void check_proc_decl(CheckerContext *ctx, Entity *e, DeclInfo *d) {
name = e->Procedure.link_name;
}
if (e->Procedure.link_name.len > 0 || is_export) {
mutex_lock(&ctx->info->foreign_mutex);
auto *fp = &ctx->info->foreigns;
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(fp, key);
if (found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
// TODO(bill): Better error message?
error(d->proc_lit,
"Non unique linking name for procedure '%.*s'\n"
"\tother at %s",
LIT(name), token_pos_to_string(pos));
} else if (name == "main") {
if (d->entity.load()->pkg->kind != Package_Runtime) {
error(d->proc_lit, "The link name 'main' is reserved for internal use");
}
} else {
string_map_set(fp, key, e);
}
mutex_unlock(&ctx->info->foreign_mutex);
add_link_name_use(ctx->info, name, e, d, LinkNameUse_Procedure);
}
}
@@ -1774,24 +1813,7 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *e, Ast
name = e->Variable.link_name;
}
auto *fp = &ctx->info->foreigns;
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(fp, key);
if (found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
Type *this_type = base_type(e->type);
Type *other_type = base_type(f->type);
bool type_is_null = (e->type == nullptr || f->type == nullptr);
if (type_is_null || !signature_parameter_similar_enough(this_type, other_type)) {
error(e->token,
"Foreign entity '%.*s' previously declared elsewhere with a different type\n"
"\tat %s",
LIT(name), token_pos_to_string(pos));
}
} else {
string_map_set(fp, key, e);
}
add_link_name_use(ctx->info, name, e, decl, LinkNameUse_Variable);
}
if (e->Variable.link_name.len > 0) {
@@ -1907,9 +1929,15 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, D
ptr_set_destroy(&entity_set);
// NOTE(bill, 2026-10-01): an invalid overload is dropped from this group only, as others may be using that procedure
auto invalid = array_make<bool>(temporary_allocator(), pge->entities.count);
for (isize j = 0; j < pge->entities.count; j++) {
invalid[j] = false;
}
for (isize j = 0; j < pge->entities.count; j++) {
Entity *p = pge->entities[j];
if (p->type == t_invalid) {
if (p->type == t_invalid || invalid[j]) {
// NOTE(bill): This invalid overload has already been handled
continue;
}
@@ -1925,16 +1953,14 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, D
GB_ASSERT(p != q);
bool is_invalid = false;
bool different_results = false;
TokenPos pos = q->token.pos;
if (q->type == nullptr || q->type == t_invalid) {
if (q->type == nullptr || q->type == t_invalid || invalid[k]) {
continue;
}
ERROR_BLOCK();
if (q->flags & EntityFlag_Disabled) {
continue;
}
@@ -1956,21 +1982,18 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, D
if (!both_have_where_clauses) switch (kind) {
case ProcOverload_Identical:
error(p->token, "Overloaded procedure '%.*s' has the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
is_invalid = true;
break;
// case ProcOverload_CallingConvention:
// error(p->token, "Overloaded procedure '%.*s' has the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
// is_invalid = true;
// break;
case ProcOverload_ParamVariadic:
error(p->token, "Overloaded procedure '%.*s' has the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
is_invalid = true;
break;
case ProcOverload_ResultCount:
case ProcOverload_ResultTypes:
error(p->token, "Overloaded procedure '%.*s' has the same parameters but different results in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
is_invalid = true;
different_results = true;
break;
case ProcOverload_Polymorphic:
break;
@@ -1983,11 +2006,25 @@ gb_internal void check_proc_group_decl(CheckerContext *ctx, Entity *pg_entity, D
}
if (is_invalid) {
// NOTE(bill): only now, as the error block is shared by every thread
ERROR_BLOCK();
if (different_results) {
error(p->token, "Overloaded procedure '%.*s' has the same parameters but different results in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
} else {
error(p->token, "Overloaded procedure '%.*s' has the same type as another procedure in the procedure group '%.*s'", LIT(name), LIT(proc_group_name));
}
error_line("\tprevious procedure at %s\n", token_pos_to_string(pos));
q->type = t_invalid;
invalid[k] = true;
}
}
}
isize valid_count = 0;
for (isize j = 0; j < pge->entities.count; j++) {
if (!invalid[j]) {
pge->entities[valid_count++] = pge->entities[j];
}
}
pge->entities.count = valid_count;
AttributeContext ac = {};
check_decl_attributes(ctx, d->attributes, proc_group_attribute, &ac);
@@ -2137,9 +2174,31 @@ gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d,
if (e->state == EntityState_Resolved) {
return;
}
if (e->flags & EntityFlag_Lazy) {
mutex_lock(&ctx->info->lazy_mutex);
GlobalWhenTrialEntityScope trial_scope = {};
if (global_when_trial != nullptr && !global_when_trial_begin_entity(e, &trial_scope)) {
return;
}
defer (global_when_trial_end_entity(&trial_scope));
// NOTE(bill): checked by whichever thread claims it first; any other that needs it meanwhile waits for it
i32 owner = 0;
if (!e->checking_thread.compare_exchange_strong(owner, cast(i32)current_thread_index() + 1)) {
if (thread_wait_for_owner(&e->checking_thread, owner, owner)) {
return;
}
// NOTE: this thread is checking it already, or the thread checking it waits for this one
error(e->token, "Illegal declaration cycle of `%.*s`", LIT(e->token.string));
return;
}
if (e->state == EntityState_Resolved) {
// NOTE: another thread finished it before this one claimed it
e->checking_thread.store(0);
futex_broadcast(&e->checking_thread);
return;
}
bool is_lazy = (e->flags & EntityFlag_Lazy) != 0;
GlobalEntityTimingFrame timing_frame = global_entity_timing_begin(e);
String name = e->token.string;
@@ -2159,20 +2218,37 @@ gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d,
}
CheckerContext c = *ctx;
if (d->scope->flags & ScopeFlag_File) {
// NOTE(bill): a global is checked in a context of its own file, never in that of whatever needed it first,
// which may be in another file or package, or a procedure body.
// Only the cycle detection carries over.
CheckerTypePath *type_path = c.type_path;
UntypedExprInfoMap *untyped = c.untyped;
gb_zero_size(&c.pkg, gb_size_of(CheckerContext) - gb_offset_of(CheckerContext, pkg));
add_curr_ast_file(&c, d->scope->file);
c.type_path = type_path;
c.untyped = untyped;
}
c.scope = d->scope;
c.decl = d;
c.type_level = 0;
c.curr_proc_calling_convention = ProcCC_Contextless;
// NOTE: a file scope's is set from its own file and shared by every thread, see `create_scope_from_file`
bool set_context = (c.scope->flags & ScopeFlag_File) == 0;
auto prev_flags = c.scope->flags;
defer (c.scope->flags = prev_flags);
if (check_feature_flags(ctx, d->decl_node) & OptInFeatureFlag_GlobalContext) {
c.scope->flags |= ScopeFlag_ContextDefined;
} else {
c.scope->flags &= ~ScopeFlag_ContextDefined;
defer (if (set_context) {
c.scope->flags = prev_flags;
});
if (set_context) {
if (check_feature_flags(ctx, d->decl_node) & OptInFeatureFlag_GlobalContext) {
c.scope->flags |= ScopeFlag_ContextDefined;
} else {
c.scope->flags &= ~ScopeFlag_ContextDefined;
}
}
global_group_check_edge(ctx, e);
e->parent_proc_decl = c.curr_proc_decl;
e->state = EntityState_InProgress;
@@ -2222,18 +2298,30 @@ gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d,
}
end:;
global_entity_timing_end(timing_frame, e);
// NOTE(bill): Add it to the list of checked entities
if (e->flags & EntityFlag_Lazy) {
if (is_lazy) {
mutex_lock(&ctx->info->lazy_mutex);
array_add(&ctx->info->entities, e);
mutex_unlock(&ctx->info->lazy_mutex);
}
e->checking_thread.store(0);
futex_broadcast(&e->checking_thread);
}
// An entity in progress on another thread is waited for, unless that thread waits for this one
gb_internal void wait_for_entity(Entity *e) {
i32 owner = e->checking_thread.load();
if (owner != 0) {
thread_wait_for_owner(&e->checking_thread, owner, owner);
}
}
gb_internal void add_deps_from_child_to_parent(DeclInfo *decl) {
if (decl && decl->parent) {
Scope *ps = decl->parent->scope;
if (ps->flags & (ScopeFlag_File & ScopeFlag_Pkg & ScopeFlag_Global)) {
if (ps->flags & (ScopeFlag_Pkg | ScopeFlag_Global)) {
return;
} else {
// NOTE(bill): Add the dependencies from the procedure literal (lambda)
@@ -2337,7 +2425,7 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de
break;
}
bool is_value = (e->flags & EntityFlag_Value) != 0 && !is_type_pointer(e->type);
bool is_value = (e->flags & EntityFlag_Value) != 0 && !is_type_pointer(e->type) && !is_type_soa_pointer(e->type);
String name = e->token.string;
Type *t = base_type(type_deref(e->type));
if (t->kind == Type_Struct) {
+1242 -628
View File
File diff suppressed because it is too large. Load diff
+10 -20
View File
@@ -846,10 +846,10 @@ gb_internal bool check_using_stmt_entity(CheckerContext *ctx, AstUsingStmt *us,
}
case Entity_Variable: {
bool is_ptr = is_type_pointer(e->type);
bool is_ptr = is_type_pointer(e->type) || is_type_soa_pointer(e->type);
Type *t = base_type(type_deref(e->type));
if (t->kind == Type_Struct) {
wait_signal_until_available(&t->Struct.fields_wait_signal);
wait_for_record_signal(&t->Struct.fields_wait_signal, &t->Struct.checking_thread);
Scope *found = t->Struct.scope;
GB_ASSERT(found != nullptr);
@@ -1187,7 +1187,7 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags
}
} else {
x.mode = Addressing_Constant;
x.type = t_bool;
x.type = t_untyped_bool;
x.value = exact_value_bool(true);
Token token = {};
@@ -1315,6 +1315,9 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags
} else {
check_expr_with_type_hint(ctx, &y, expr, x.type);
}
if (expr->viral_state_flags & ViralStateFlag_ContainsDeferredProcedure) {
error(expr, "Procedure calls that have an associated deferred procedure are not allowed within case clauses");
}
if (x.mode == Addressing_Invalid ||
y.mode == Addressing_Invalid) {
@@ -1536,6 +1539,9 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_
bool saw_nil = false;
// TODO(bill): Make robust
Type *bt = base_type(type_deref(x.type));
if (bt->kind == Type_Union) {
wait_for_record_signal(&bt->Union.variants_wait_signal, &bt->Union.checking_thread);
}
Type *case_type = nullptr;
for (Ast *type_expr : cc->list) {
@@ -2349,23 +2355,7 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f
}
init_entity_foreign_library(ctx, e);
auto *fp = &ctx->checker->info.foreigns;
StringHashKey key = string_hash_string(name);
Entity **found = string_map_get(fp, key);
if (found) {
Entity *f = *found;
TokenPos pos = f->token.pos;
Type *this_type = base_type(e->type);
Type *other_type = base_type(f->type);
if (!signature_parameter_similar_enough(this_type, other_type)) {
error(e->token,
"Foreign entity '%.*s' previously declared elsewhere with a different type\n"
"\tat %s",
LIT(name), token_pos_to_string(pos));
}
} else {
string_map_set(fp, key, e);
}
add_link_name_use(ctx->info, name, e, ctx->decl, LinkNameUse_Variable);
} else if (e->flags & EntityFlag_Static) {
if (vd->values.count > 0) {
if (entity_count != vd->values.count) {
+1350 -194
View File
File diff suppressed because it is too large. Load diff
+624 -714
View File
File diff suppressed because it is too large. Load diff
+75 -7
View File
@@ -85,6 +85,7 @@ struct Operand {
Ast * expr;
BuiltinProcId builtin_id;
Entity * proc_group;
bool deferred_untyped_arg; // untyped arg (`{...}`, `.Member`) whose type is resolved from a poly param later
};
@@ -206,10 +207,12 @@ struct VariadicReuseData {
struct DeclInfo {
DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment
BlockingMutex next_mutex;
BlockingMutex next_mutex; // also used for `nested_to_check`
DeclInfo * next_child;
DeclInfo * next_sibling;
Array<struct ProcInfo *> nested_to_check; // nested procedures to check once this body is checked
Scope * scope;
std::atomic<Entity *> entity;
@@ -222,6 +225,7 @@ struct DeclInfo {
Type * gen_proc_type; // Precalculated
Entity * para_poly_original;
std::atomic<struct ProcInfo *> gen_proc_info; // a specialization's body, queued for checking when it is first used
bool is_using;
bool foreign_require_results;
@@ -268,6 +272,20 @@ struct ProcInfo {
};
enum LinkNameUseKind : u8 {
LinkNameUse_ForeignProcedure,
LinkNameUse_Procedure, // exported or with a link name
LinkNameUse_Variable, // foreign or exported
};
struct LinkNameUse {
String name;
Entity * entity;
DeclInfo * decl;
LinkNameUseKind kind;
};
enum { DEFAULT_SCOPE_CAPACITY = 32 };
@@ -460,6 +478,19 @@ gb_internal Entity *scope_map_get(ScopeMap *m, InternedString key, u32 hash) {
}
}
// NOTE: the key must be present; never grows, so lookups that do not lock see either value
gb_internal void scope_map_replace(ScopeMap *m, InternedString key, u32 hash, Entity *value) {
u32 mask = m->cap-1;
for (u32 pos = hash & mask;; pos = (pos + 1) & mask) {
ScopeMapSlot *s = &m->slots[pos];
GB_ASSERT(s->hash != 0);
if (s->hash == hash && m->keys[pos] == key) {
s->value = value;
return;
}
}
}
gb_internal void scope_map_clear(ScopeMap *m) {
gb_memset(m->slots, 0, gb_size_of(*m->slots) * m->cap);
m->count = 0;
@@ -547,6 +578,7 @@ enum ScopeFlag : i32 {
ScopeFlag_Type = 1<<7,
ScopeFlag_HasBeenImported = 1<<10, // This is only applicable to file scopes
ScopeFlag_ReadOnly = 1<<11, // file, package and universe scopes once every global is declared: read without locking
ScopeFlag_ContextDefined = 1<<16,
};
@@ -563,6 +595,7 @@ struct Scope {
RwMutex mutex;
ScopeMap elements;
PtrSet<Scope *> imported;
PtrMap<u64, struct GlobalDeclSource *> *placeholders; // multi-map; names a global 'when' or 'foreign' block may declare, until all are resolved
DeclInfo *decl_info;
@@ -663,6 +696,8 @@ enum LoadFileTier {
struct LoadFileCache {
LoadFileTier tier;
bool exists;
BlockingMutex mutex; // for everything below
String path;
gbFileError file_error;
String data;
@@ -676,6 +711,9 @@ struct LoadDirectoryFile {
};
struct LoadDirectoryCache {
bool loaded;
BlockingMutex mutex; // for everything below
String path;
gbFileError file_error;
Array<LoadFileCache *> files;
@@ -684,6 +722,7 @@ struct LoadDirectoryCache {
struct GenProcsData {
Array<Entity *> procs;
Array<u64> hashes; // `proc_type_identity_hash` of each of `procs`
RwMutex mutex;
};
@@ -750,7 +789,7 @@ struct CheckerInfo {
BlockingMutex type_and_value_mutex;
RecursiveMutex lazy_mutex; // Mutex required for lazy type checking of specific files
RecursiveMutex lazy_mutex; // for adding checked lazy entities to `entities`
// BlockingMutex type_info_mutex; // NOT recursive
@@ -759,10 +798,13 @@ struct CheckerInfo {
// TypeSet type_info_set;
BlockingMutex foreign_mutex; // NOT recursive
StringMap<Entity *> foreigns;
Array<struct LinkNameUse> link_names; // checked for clashes once everything is checked, see `check_link_name_uses`
MPSCQueue<Entity *> definition_queue;
MPSCQueue<Entity *> entity_queue;
BlockingMutex entry_point_mutex;
PerThreadArray<Entity *> definition_queue;
PerThreadArray<Entity *> entity_queue;
std::atomic<u64> entities_without_file; // for their `order_in_src`
MPSCQueue<Entity *> required_global_variable_queue;
MPSCQueue<Entity *> required_foreign_imports_through_force_queue;
MPSCQueue<Entity *> foreign_imports_to_check_fullpaths;
@@ -837,7 +879,7 @@ struct CheckerContext {
u32 stmt_flags;
bool in_enum_type;
bool in_proc_group;
bool collect_delayed_decls;
bool in_procedure_of;
bool allow_polymorphic_types;
bool disallow_polymorphic_return_types; // NOTE(zen3ger): no poly type decl in return types
bool no_polymorphic_errors;
@@ -845,9 +887,12 @@ struct CheckerContext {
bool in_polymorphic_specialization;
bool allow_arrow_right_selector_expr;
bool allow_c_vararg_param;
bool allow_in_progress_type_operand; // a bare type name may still be being checked (polymorphic record arguments)
u8 bit_field_bit_size;
Scope * polymorphic_scope;
Array<Entity *> *trial_entities; // global declarations are collected here only, for a global 'when' trial
Ast *assignment_lhs_hint;
Ast *asm_template_hint;
};
@@ -864,13 +909,14 @@ struct Checker {
MPSCQueue<Entity *> procs_with_deferred_to_check;
MPSCQueue<Entity *> procs_with_objc_context_provider_to_check;
BlockingMutex procs_to_check_mutex;
Array<ProcInfo *> procs_to_check;
BlockingMutex nested_proc_lits_mutex;
Array<DeclInfo *> nested_proc_lits;
MPSCQueue<UntypedExprInfo> global_untyped_queue;
PerThreadArray<UntypedExprInfo> global_untyped_queue;
MPSCQueue<Type *> soa_types_to_complete;
};
@@ -915,6 +961,28 @@ gb_internal void check_add_foreign_import_decl(CheckerContext *c, Ast *decl);
gb_internal void check_entity_decl(CheckerContext *c, Entity *e, DeclInfo *d, Type *named_type);
gb_internal void global_group_check_edge(CheckerContext *ctx, Entity *e);
// While a group of global entities is checked: its incomplete '#soa' types, completed by the same thread
gb_thread_local Array<Type *> *global_group_soa_types;
struct GlobalWhenTrialEntityScope {
struct GlobalWhenTrial *trial;
i32 mute_depth;
};
gb_internal bool global_when_trial_begin_entity(Entity *e, GlobalWhenTrialEntityScope *scope);
gb_internal void global_when_trial_end_entity(GlobalWhenTrialEntityScope *scope);
// -internal-global-entity-graph
struct GlobalEntityTimingFrame {
u64 start;
u64 saved_child_ticks;
bool active;
};
gb_internal GlobalEntityTimingFrame global_entity_timing_begin(Entity *e);
gb_internal void global_entity_timing_end(GlobalEntityTimingFrame const &f, Entity *e);
gb_internal void wait_for_entity(Entity *e);
gb_internal Ast *remove_type_alias_clutter(Ast *node);
gb_internal void check_const_decl(CheckerContext *c, Entity *e, Ast *type_expr, Ast *init_expr, Type *named_type);
gb_internal void check_type_decl(CheckerContext *c, Entity *e, Ast *type_expr, Type *def);
File diff suppressed because it is too large. Load diff
+9 -9
View File
@@ -392,12 +392,14 @@ ArenaTemp arena_temp_begin(Arena *arena) {
GB_ASSERT(arena);
GB_ASSERT(arena->parent_thread == get_current_thread());
if (arena->curr_block == nullptr) {
arena_alloc(arena, 0, 1);
}
ArenaTemp temp = {};
temp.arena = arena;
temp.block = arena->curr_block;
if (arena->curr_block != nullptr) {
temp.used = arena->curr_block->used;
}
temp.used = arena->curr_block->used;
arena->temp_count += 1;
return temp;
}
@@ -428,8 +430,8 @@ void arena_temp_end(ArenaTemp const &temp) {
MemoryBlock *block = arena->curr_block;
if (block) {
GB_ASSERT_MSG(block->used >= temp.used, "out of order use of arena_temp_end");
isize amount_to_zero = gb_min(block->used - temp.used, block->size - block->used);
gb_zero_size(block->base + temp.used, amount_to_zero);
// `arena_alloc` expects the memory to be zeroed already
gb_zero_size(block->base + temp.used, block->used - temp.used);
block->used = temp.used;
}
}
@@ -605,16 +607,14 @@ gb_internal gbAllocator permanent_allocator() {
}
gb_internal gbAllocator temporary_allocator() {
// return {thread_arena_allocator_proc, cast(void *)cast(uintptr)ThreadArena_Temporary};
return permanent_allocator();
return {thread_arena_allocator_proc, cast(void *)cast(uintptr)ThreadArena_Temporary};
}
#define TEMP_ARENA_GUARD(arena) ArenaTempGuard GB_DEFER_3(_arena_guard_){arena}
// #define TEMPORARY_ALLOCATOR_GUARD() TEMP_ARENA_GUARD(get_arena(ThreadArena_Temporary))
#define TEMPORARY_ALLOCATOR_GUARD()
#define TEMPORARY_ALLOCATOR_GUARD() TEMP_ARENA_GUARD(get_arena(ThreadArena_Temporary))
#define PERMANENT_ALLOCATOR_GUARD()
+7 -1
View File
@@ -76,7 +76,8 @@ enum EntityFlag : u64 {
EntityFlag_Init = 1ull<<31,
EntityFlag_Subtype = 1ull<<32,
EntityFlag_Fini = 1ull<<33,
EntityFlag_PolyConstArg = 1ull<<34, // passed to a `$` parameter, so a local procedure may be called outside its parent
EntityFlag_CustomLinkName = 1ull<<40,
EntityFlag_CustomLinkage_Internal = 1ull<<41,
EntityFlag_CustomLinkage_Strong = 1ull<<42,
@@ -142,6 +143,10 @@ enum ProcedureOptimizationMode : u8 {
BlockingMutex global_type_name_objc_metadata_mutex;
struct TypeNameObjCMetadata;
gb_internal TypeNameObjCMetadata *entity_objc_metadata(struct Entity *e);
struct TypeNameObjCMetadataEntry {
InternedString interned;
Entity *entity;
@@ -206,6 +211,7 @@ struct Entity {
u64 id;
std::atomic<u64> flags;
std::atomic<EntityState> state;
Futex checking_thread; // 1 + the index of the thread in `check_entity_decl` for it, else 0
std::atomic<i32> min_dep_count;
Token token;
Scope * scope;
+180 -4
View File
@@ -27,6 +27,61 @@ struct ErrorCollector {
gb_global ErrorCollector global_error_collector;
// Scoped, per-thread error muting. While muted, error/warning emission is suppressed but still
// *counted*, so a caller can trial-check something (e.g. one branch of a procedure group) and learn
// whether it would have failed without printing anything. Muting nests.
gb_thread_local i32 global_error_mute_depth = 0;
gb_thread_local i64 global_error_mute_count = 0;
gb_internal void begin_error_mute(void) {
global_error_mute_depth += 1;
}
gb_internal void end_error_mute(void) {
GB_ASSERT(global_error_mute_depth > 0);
global_error_mute_depth -= 1;
}
gb_internal i64 error_mute_count(void) {
return global_error_mute_count;
}
gb_internal bool is_error_muted(void) {
return global_error_mute_depth > 0;
}
// Optional annotations for the next errored source line.
// All per-thread, so nothing leaks between concurrently-checked files.
// `show_error_on_line` snapshots and clears them.
//
// primary label, inline: primary label, vertical: secondary span (always vertical):
// append(&x, true) append(x, {1,2,3}) append(&x, true)
// ^~~^ expected '…', found '…' ^ ^^ ^~~^ expected '…', found '…'
// | |
// expected '^…', pass '&x' '[dynamic][3]int', elements are '[3]int'
gb_thread_local char global_caret_label_buf[512]; // primary label text
gb_thread_local bool global_caret_label_vertical; // render primary label as | + text below, not inline
gb_thread_local bool global_caret_sec_present; // a secondary span (to the left) is set
gb_thread_local TokenPos global_caret_sec_pos;
gb_thread_local TokenPos global_caret_sec_end;
gb_thread_local char global_caret_sec_label[512];
gb_internal void set_caret_label(char const *text) {
global_caret_label_vertical = false;
if (text == nullptr) {
global_caret_label_buf[0] = 0;
} else {
gb_snprintf(global_caret_label_buf, gb_size_of(global_caret_label_buf), "%s", text);
}
}
gb_internal void set_caret_label_vertical(char const *text) {
set_caret_label(text);
global_caret_label_vertical = true;
}
gb_internal void set_caret_secondary(TokenPos pos, TokenPos end, char const *text) {
global_caret_sec_present = text != nullptr;
global_caret_sec_pos = pos;
global_caret_sec_end = end;
gb_snprintf(global_caret_sec_label, gb_size_of(global_caret_sec_label), "%s", text ? text : "");
}
gb_internal void push_error_value(TokenPos const &pos, ErrorValueKind kind = ErrorValue_Error) {
GB_ASSERT_MSG(global_error_collector.curr_error_value_set.load() == false, "Possible race condition in error handling system, please report this with an issue");
@@ -196,6 +251,10 @@ gb_internal void print_all_errors(void);
typedef ERROR_OUT_PROC(ErrorOutProc);
gb_internal ERROR_OUT_PROC(default_error_out_va) {
if (global_error_mute_depth > 0) {
// NOTE(bill): the error this would continue was muted, so there is no current error value
return;
}
char buf[4096] = {};
isize len = gb_snprintf_va(buf, gb_size_of(buf), fmt, va);
isize n = len-1;
@@ -288,6 +347,22 @@ gb_internal void terminal_reset_colours(void) {
gb_internal isize show_error_on_line(TokenPos const &pos, TokenPos end) {
get_error_value()->end = end;
// Consume the caret annotations now, so they are cleared even on an early return and can never leak
// onto a later error's line.
char caret_label[512];
gb_snprintf(caret_label, gb_size_of(caret_label), "%s", global_caret_label_buf);
bool caret_label_vertical = global_caret_label_vertical;
bool sec_present = global_caret_sec_present;
TokenPos sec_pos = global_caret_sec_pos;
TokenPos sec_end = global_caret_sec_end;
char sec_label[512];
gb_snprintf(sec_label, gb_size_of(sec_label), "%s", global_caret_sec_label);
global_caret_label_buf[0] = 0;
global_caret_label_vertical = false;
global_caret_sec_present = false;
global_caret_sec_label[0] = 0;
if (!show_error_line()) {
return -1;
}
@@ -492,13 +567,57 @@ gb_internal isize show_error_on_line(TokenPos const &pos, TokenPos end) {
error_out(" ...");
}
error_out("\n\t");
for (i32 i = squiggle_padding; i > 0; i -= 1) {
error_out(" ");
// Secondary span (drawn to the left of the primary on the same line): compute its padding/width the
// same way as the primary's, and only draw it if it sits fully to the left within the window.
i32 sec_pad = 0;
i32 sec_len = 0;
bool draw_sec = sec_present && sec_pos.line == pos.line && sec_end.line == pos.line;
if (draw_sec) {
i32 sec_start_byte = error_start_index_bytes + (sec_pos.column - pos.column);
i32 sec_end_byte = error_start_index_bytes + (sec_end.column - pos.column);
if (window_open_bytes > 0) {
sec_pad += 4;
}
for (i32 i = 0; i < line_length_graphemes; i += 1) {
if (graphemes[i].byte_index < window_open_bytes) continue;
if (graphemes[i].byte_index >= sec_start_byte) break;
sec_pad += graphemes[i].width;
}
for (i32 i = 0; i < line_length_graphemes; i += 1) {
if (graphemes[i].byte_index < sec_start_byte) continue;
if (graphemes[i].byte_index >= sec_end_byte) break;
sec_len += graphemes[i].width;
}
if (sec_len < 1) {
sec_len = 1;
}
if (sec_start_byte >= error_start_index_bytes || sec_pad + sec_len > squiggle_padding) {
draw_sec = false; // overlaps or is not to the left; skip rather than misalign
}
}
error_out("\n\t");
i32 printed = 0;
terminal_set_colours(TerminalStyle_Bold, TerminalColour_Green);
if (draw_sec) {
for (i32 i = sec_pad - printed; i > 0; i -= 1) {
error_out(" ");
}
printed = sec_pad;
error_out("^");
for (i32 k = sec_len - 2; k > 0; k -= 1) {
error_out("~");
}
if (sec_len >= 2) {
error_out("^");
}
printed += sec_len;
}
for (i32 i = squiggle_padding - printed; i > 0; i -= 1) {
error_out(" ");
}
if (squiggle_length > 0) {
error_out("^");
@@ -515,12 +634,46 @@ gb_internal isize show_error_on_line(TokenPos const &pos, TokenPos end) {
}
}
if (caret_label[0] != 0 && !caret_label_vertical) {
terminal_set_colours(TerminalStyle_Normal, TerminalColour_Grey);
error_out(" %s", caret_label);
}
// NOTE(Feoramund): Specifically print a newline, then reset colours,
// instead of the other way around. Otherwise the printing mechanism
// will collapse the newline for reasons currently beyond my ken.
error_out("\n");
terminal_reset_colours();
// A vertical label hangs under its span: `|` then the text, aligned to the span's column. The
// secondary span takes priority (its label explains the primary); otherwise a vertical primary label.
i32 vpad = -1;
char const *vtext = nullptr;
if (draw_sec && sec_label[0] != 0) {
vpad = sec_pad;
vtext = sec_label;
} else if (caret_label_vertical && caret_label[0] != 0) {
vpad = squiggle_padding;
vtext = caret_label;
}
if (vpad >= 0 && vtext != nullptr && vtext[0] != 0) {
error_out("\t");
for (i32 i = vpad; i > 0; i -= 1) {
error_out(" ");
}
terminal_set_colours(TerminalStyle_Bold, TerminalColour_Green);
error_out("|\n");
terminal_reset_colours();
error_out("\t");
for (i32 i = vpad; i > 0; i -= 1) {
error_out(" ");
}
terminal_set_colours(TerminalStyle_Normal, TerminalColour_Grey);
error_out("%s\n", vtext);
terminal_reset_colours();
}
return squiggle_padding;
}
@@ -542,6 +695,10 @@ gb_internal void error_out_coloured(char const *str, TerminalStyle style, Termin
gb_internal void error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
if (global_error_mute_depth > 0) {
global_error_mute_count += 1;
return;
}
global_error_collector.count.fetch_add(1);
mutex_lock(&global_error_collector.mutex);
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) {
@@ -579,6 +736,10 @@ gb_internal void warning_va(TokenPos const &pos, TokenPos end, char const *fmt,
if (global_ignore_warnings()) {
return;
}
if (global_error_mute_depth > 0) {
global_error_mute_count += 1;
return;
}
global_error_collector.warning_count.fetch_add(1);
mutex_lock(&global_error_collector.mutex);
@@ -608,10 +769,17 @@ gb_internal void warning_va(TokenPos const &pos, TokenPos end, char const *fmt,
gb_internal void error_line_va(char const *fmt, va_list va) {
if (global_error_mute_depth > 0) {
return;
}
error_out_va(fmt, va);
}
gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_list va) {
if (global_error_mute_depth > 0) {
global_error_mute_count += 1;
return;
}
global_error_collector.count.fetch_add(1);
mutex_lock(&global_error_collector.mutex);
if (global_error_collector.count.load() > MAX_ERROR_COLLECTOR_COUNT()) {
@@ -644,6 +812,10 @@ gb_internal void error_no_newline_va(TokenPos const &pos, char const *fmt, va_li
gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
if (global_error_mute_depth > 0) {
global_error_mute_count += 1;
return;
}
global_error_collector.count.fetch_add(1);
mutex_lock(&global_error_collector.mutex);
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) {
@@ -676,6 +848,10 @@ gb_internal void syntax_error_va(TokenPos const &pos, TokenPos end, char const *
}
gb_internal void syntax_error_with_verbose_va(TokenPos const &pos, TokenPos end, char const *fmt, va_list va) {
if (global_error_mute_depth > 0) {
global_error_mute_count += 1;
return;
}
global_error_collector.count.fetch_add(1);
mutex_lock(&global_error_collector.mutex);
if (global_error_collector.count > MAX_ERROR_COLLECTOR_COUNT()) {
+360 -143
View File
@@ -7,12 +7,10 @@ struct Type;
struct Entity;
gb_internal bool are_types_identical(Type *x, Type *y);
struct Complex128 {
f64 real, imag;
};
struct Quaternion256 {
f64 imag, jmag, kmag, real;
};
// NOTE(bill): Defined after ExactValue below, since their components are now exact values
// (each a Float=f64 or Rational=big_rat) so complex/quaternion constant folding stays exact.
struct ExactComplex;
struct ExactQuaternion;
enum ExactValueKind {
ExactValue_Invalid = 0,
@@ -30,6 +28,7 @@ enum ExactValueKind {
ExactValue_String16 = 11,
ExactValue_AsmTemplate = 12,
ExactValue_Variant = 13,
ExactValue_Rational = 14, // exact num/den for untyped float constants
ExactValue_Count,
};
@@ -50,28 +49,39 @@ gb_global char const *exact_value_kind_string[ExactValue_Count] = {
"String16",
"AsmTemplate",
"Variant",
"Rational",
};
struct ExactValue {
ExactValueKind kind;
union {
bool value_bool;
String value_string;
BigInt value_integer;
f64 value_float;
i64 value_pointer; // NOTE(bill): This must be an integer and not a pointer
Complex128 *value_complex;
Quaternion256 *value_quaternion;
Ast * value_compound;
Ast * value_procedure;
Type * value_typeid;
String16 value_string16;
Ast * value_asm_template;
Ast * value_variant;
bool value_bool;
String value_string;
BigInt value_integer;
f64 value_float;
BigRat * value_rational;
i64 value_pointer; // NOTE(bill): This must be an integer and not a pointer
ExactComplex *value_complex;
ExactQuaternion *value_quaternion;
Ast * value_compound;
Ast * value_procedure;
Type * value_typeid;
String16 value_string16;
Ast * value_asm_template;
Ast * value_variant;
};
Type *variant_type;
};
// Complex/quaternion components are exact numeric values (Integer/Rational/Float), so their constant
// arithmetic keeps full precision until the value is rounded to a concrete type.
struct ExactComplex {
ExactValue real, imag;
};
struct ExactQuaternion {
ExactValue imag, jmag, kmag, real;
};
gb_global ExactValue const empty_exact_value = {};
gb_internal uintptr hash_exact_value(ExactValue v) {
@@ -99,14 +109,27 @@ gb_internal uintptr hash_exact_value(ExactValue v) {
case ExactValue_Float:
res = gb_fnv32a(&v.value_float, gb_size_of(v.value_float));
break;
case ExactValue_Rational:
{
BigInt const &n = v.value_rational->num;
BigInt const &d = v.value_rational->den;
u32 kn = gb_fnv32a(n.dp, gb_size_of(*n.dp) * n.used);
u32 kd = gb_fnv32a(d.dp, gb_size_of(*d.dp) * d.used);
res = ((kn ^ (u8)n.sign) * 0x01000193) ^ kd;
break;
}
case ExactValue_Pointer:
res = ptr_map_hash_key(v.value_pointer);
break;
case ExactValue_Complex:
res = gb_fnv32a(v.value_complex, gb_size_of(Complex128));
res = hash_exact_value(v.value_complex->real) ^
(hash_exact_value(v.value_complex->imag) * 0x01000193);
break;
case ExactValue_Quaternion:
res = gb_fnv32a(v.value_quaternion, gb_size_of(Quaternion256));
res = hash_exact_value(v.value_quaternion->real) ^
(hash_exact_value(v.value_quaternion->imag) * 0x01000193) ^
(hash_exact_value(v.value_quaternion->jmag) * 0x01000193) ^
(hash_exact_value(v.value_quaternion->kmag) * 0x01000193);
break;
case ExactValue_Compound:
res = ptr_map_hash_key(v.value_compound);
@@ -173,17 +196,51 @@ gb_internal ExactValue exact_value_float(f64 f) {
return result;
}
gb_internal ExactValue exact_value_complex(f64 real, f64 imag) {
// Make an exact-rational value from num/den (copied and reduced to lowest terms, den > 0).
gb_internal ExactValue exact_value_rational_from_ints(mp_int const *num, mp_int const *den) {
BigRat *br = permanent_alloc_item<BigRat>();
mp_init(&br->num);
mp_init(&br->den);
mp_copy(num, &br->num);
mp_copy(den, &br->den);
big_rat_normalize(&br->num, &br->den);
ExactValue result = {ExactValue_Rational};
result.value_rational = br;
return result;
}
gb_internal ExactValue exact_value_rational_from_integer(BigInt const *i) {
mp_int one; mp_init(&one); defer (mp_clear(&one)); mp_set_u64(&one, 1);
return exact_value_rational_from_ints(i, &one);
}
gb_internal ExactValue exact_value_rational_arith_result(mp_int const *num, mp_int const *den) {
ExactValue r = exact_value_rational_from_ints(num, den); // normalizes (GCD reduce)
if (big_rat_components_too_large(&r.value_rational->num, &r.value_rational->den)) {
return exact_value_float(big_rat_to_f64(&r.value_rational->num, &r.value_rational->den));
}
return r;
}
gb_internal ExactValue exact_value_as_rational_if_integer(ExactValue v) {
if (v.kind == ExactValue_Integer) {
return exact_value_rational_from_integer(&v.value_integer);
}
return v;
}
// Exact-component constructors: each component is a numeric ExactValue (Integer/Rational/Float).
gb_internal ExactValue exact_value_complex_ev(ExactValue real, ExactValue imag) {
ExactValue result = {ExactValue_Complex};
result.value_complex = permanent_alloc_item<Complex128>();
result.value_complex = permanent_alloc_item<ExactComplex>();
result.value_complex->real = real;
result.value_complex->imag = imag;
return result;
}
gb_internal ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
gb_internal ExactValue exact_value_quaternion_ev(ExactValue real, ExactValue imag, ExactValue jmag, ExactValue kmag) {
ExactValue result = {ExactValue_Quaternion};
result.value_quaternion = permanent_alloc_item<Quaternion256>();
result.value_quaternion = permanent_alloc_item<ExactQuaternion>();
result.value_quaternion->real = real;
result.value_quaternion->imag = imag;
result.value_quaternion->jmag = jmag;
@@ -191,6 +248,14 @@ gb_internal ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64
return result;
}
gb_internal ExactValue exact_value_complex(f64 real, f64 imag) {
return exact_value_complex_ev(exact_value_float(real), exact_value_float(imag));
}
gb_internal ExactValue exact_value_quaternion(f64 real, f64 imag, f64 jmag, f64 kmag) {
return exact_value_quaternion_ev(exact_value_float(real), exact_value_float(imag), exact_value_float(jmag), exact_value_float(kmag));
}
gb_internal ExactValue exact_value_pointer(i64 ptr) {
ExactValue result = {ExactValue_Pointer};
result.value_pointer = ptr;
@@ -383,12 +448,28 @@ gb_internal ExactValue exact_value_float_from_string(String string) {
return exact_value_integer_from_string(string);
}
bool success;
f64 f = float_from_string(string, &success);
if (!success) {
return {ExactValue_Invalid};
// A finite base-10 floating-point literal is kept as an EXACT rational so that constant folding is
// exact and only rounds once, when the constant is finally given a concrete type (see
// `exact_value_to_float` and `check_representable_as_constant`). This mirrors Go's `go/constant`,
// where small values are held as `big.Rat`. The `0h...` hexadecimal-float path above keeps its
// exact bit pattern as an `f64`; that is also the side channel for the +/-Inf and NaN values that a
// rational cannot represent.
mp_int num, den;
if (big_rat_from_decimal_string(string, &num, &den)) {
// A zero-valued literal stays an f64 so that signed zero survives: a rational 0/1 has no sign,
// but `-0.0` (unary minus applied to this `0.0`) must keep its sign bit.
bool is_zero = mp_iszero(&num);
if (is_zero) {
mp_clear(&num);
mp_clear(&den);
return exact_value_float(0.0);
}
ExactValue r = exact_value_rational_from_ints(&num, &den);
mp_clear(&num);
mp_clear(&den);
return r;
}
return exact_value_float(f);
return {ExactValue_Invalid};
}
@@ -401,12 +482,15 @@ gb_internal ExactValue exact_value_from_basic_literal(TokenKind kind, String con
String str = string;
Rune last_rune = cast(Rune)str[str.len-1];
str.len--; // Ignore the 'i|j|k'
f64 imag = float_from_string(str);
// Parse the magnitude with the same exact (rational) path as an ordinary float literal so the
// imaginary component keeps full precision rather than being pre-rounded to f64.
ExactValue imag = exact_value_float_from_string(str);
ExactValue zero = exact_value_i64(0);
switch (last_rune) {
case 'i': return exact_value_complex(0, imag);
case 'j': return exact_value_quaternion(0, 0, imag, 0);
case 'k': return exact_value_quaternion(0, 0, 0, imag);
case 'i': return exact_value_complex_ev(zero, imag);
case 'j': return exact_value_quaternion_ev(zero, zero, imag, zero);
case 'k': return exact_value_quaternion_ev(zero, zero, zero, imag);
default: GB_PANIC("Invalid imaginary basic literal");
}
}
@@ -453,6 +537,17 @@ gb_internal ExactValue exact_value_to_integer(ExactValue v) {
case ExactValue_Pointer:
return exact_value_i64(cast(i64)cast(intptr)v.value_pointer);
case ExactValue_Rational:
// NOTE(bill): Only an exact integer (den == 1 after reduction) converts to an integer
if (mp_cmp_d(&v.value_rational->den, 1) == MP_EQ) {
ExactValue r = {ExactValue_Integer};
r.value_integer = {0};
mp_init(&r.value_integer);
mp_copy(&v.value_rational->num, &r.value_integer);
return r;
}
break;
}
ExactValue r = {ExactValue_Invalid};
return r;
@@ -464,6 +559,8 @@ gb_internal ExactValue exact_value_to_float(ExactValue v) {
return exact_value_float(big_int_to_f64(&v.value_integer));
case ExactValue_Float:
return v;
case ExactValue_Rational:
return exact_value_float(big_rat_to_f64(&v.value_rational->num, &v.value_rational->den));
}
ExactValue r = {ExactValue_Invalid};
return r;
@@ -472,31 +569,27 @@ gb_internal ExactValue exact_value_to_float(ExactValue v) {
gb_internal ExactValue exact_value_to_complex(ExactValue v) {
switch (v.kind) {
case ExactValue_Integer:
return exact_value_complex(big_int_to_f64(&v.value_integer), 0);
case ExactValue_Float:
return exact_value_complex(v.value_float, 0);
case ExactValue_Rational:
return exact_value_complex_ev(v, exact_value_i64(0)); // keep the real component exact
case ExactValue_Complex:
return v;
// case ExactValue_Quaternion:
// return exact_value_complex(v.value_quaternion.real, v.value_quaternion.imag);
}
ExactValue r = {ExactValue_Invalid};
v.value_complex = permanent_alloc_item<Complex128>();
return r;
}
gb_internal ExactValue exact_value_to_quaternion(ExactValue v) {
switch (v.kind) {
case ExactValue_Integer:
return exact_value_quaternion(big_int_to_f64(&v.value_integer), 0, 0, 0);
case ExactValue_Float:
return exact_value_quaternion(v.value_float, 0, 0, 0);
case ExactValue_Rational:
return exact_value_quaternion_ev(v, exact_value_i64(0), exact_value_i64(0), exact_value_i64(0));
case ExactValue_Complex:
return exact_value_quaternion(v.value_complex->real, v.value_complex->imag, 0, 0);
return exact_value_quaternion_ev(v.value_complex->real, v.value_complex->imag, exact_value_i64(0), exact_value_i64(0));
case ExactValue_Quaternion:
return v;
}
ExactValue r = {ExactValue_Invalid};
v.value_quaternion = permanent_alloc_item<Quaternion256>();
return r;
}
@@ -504,11 +597,12 @@ gb_internal ExactValue exact_value_real(ExactValue v) {
switch (v.kind) {
case ExactValue_Integer:
case ExactValue_Float:
case ExactValue_Rational:
return v;
case ExactValue_Complex:
return exact_value_float(v.value_complex->real);
return v.value_complex->real;
case ExactValue_Quaternion:
return exact_value_float(v.value_quaternion->real);
return v.value_quaternion->real;
}
ExactValue r = {ExactValue_Invalid};
return r;
@@ -518,11 +612,12 @@ gb_internal ExactValue exact_value_imag(ExactValue v) {
switch (v.kind) {
case ExactValue_Integer:
case ExactValue_Float:
case ExactValue_Rational:
return exact_value_i64(0);
case ExactValue_Complex:
return exact_value_float(v.value_complex->imag);
return v.value_complex->imag;
case ExactValue_Quaternion:
return exact_value_float(v.value_quaternion->imag);
return v.value_quaternion->imag;
}
ExactValue r = {ExactValue_Invalid};
return r;
@@ -532,10 +627,11 @@ gb_internal ExactValue exact_value_jmag(ExactValue v) {
switch (v.kind) {
case ExactValue_Integer:
case ExactValue_Float:
case ExactValue_Rational:
case ExactValue_Complex:
return exact_value_i64(0);
case ExactValue_Quaternion:
return exact_value_float(v.value_quaternion->jmag);
return v.value_quaternion->jmag;
}
ExactValue r = {ExactValue_Invalid};
return r;
@@ -545,10 +641,11 @@ gb_internal ExactValue exact_value_kmag(ExactValue v) {
switch (v.kind) {
case ExactValue_Integer:
case ExactValue_Float:
case ExactValue_Rational:
case ExactValue_Complex:
return exact_value_i64(0);
case ExactValue_Quaternion:
return exact_value_float(v.value_quaternion->kmag);
return v.value_quaternion->kmag;
}
ExactValue r = {ExactValue_Invalid};
return r;
@@ -626,6 +723,7 @@ gb_internal ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i3
switch (v.kind) {
case ExactValue_Invalid:
case ExactValue_Integer:
case ExactValue_Rational:
case ExactValue_Float:
case ExactValue_Complex:
case ExactValue_Quaternion:
@@ -649,17 +747,22 @@ gb_internal ExactValue exact_unary_operator_value(TokenKind op, ExactValue v, i3
i.value_float = -i.value_float;
return i;
}
case ExactValue_Rational: {
mp_int n; mp_init(&n); defer (mp_clear(&n));
big_int_neg(&n, &v.value_rational->num);
return exact_value_rational_from_ints(&n, &v.value_rational->den);
}
case ExactValue_Complex: {
f64 real = v.value_complex->real;
f64 imag = v.value_complex->imag;
return exact_value_complex(-real, -imag);
ExactValue re = exact_unary_operator_value(Token_Sub, v.value_complex->real, precision, is_unsigned);
ExactValue im = exact_unary_operator_value(Token_Sub, v.value_complex->imag, precision, is_unsigned);
return exact_value_complex_ev(re, im);
}
case ExactValue_Quaternion: {
f64 real = v.value_quaternion->real;
f64 imag = v.value_quaternion->imag;
f64 jmag = v.value_quaternion->jmag;
f64 kmag = v.value_quaternion->kmag;
return exact_value_quaternion(-real, -imag, -jmag, -kmag);
ExactValue re = exact_unary_operator_value(Token_Sub, v.value_quaternion->real, precision, is_unsigned);
ExactValue im = exact_unary_operator_value(Token_Sub, v.value_quaternion->imag, precision, is_unsigned);
ExactValue jm = exact_unary_operator_value(Token_Sub, v.value_quaternion->jmag, precision, is_unsigned);
ExactValue km = exact_unary_operator_value(Token_Sub, v.value_quaternion->kmag, precision, is_unsigned);
return exact_value_quaternion_ev(re, im, jm, km);
}
}
break;
@@ -709,16 +812,19 @@ gb_internal i32 exact_value_order(ExactValue const &v) {
return 1;
case ExactValue_Integer:
return 2;
case ExactValue_Float:
case ExactValue_Rational: // exact; between integer and (lossy) float
return 3;
case ExactValue_Complex:
case ExactValue_Float:
return 4;
case ExactValue_Quaternion:
case ExactValue_Complex:
return 5;
case ExactValue_Pointer:
case ExactValue_Quaternion:
return 6;
case ExactValue_Procedure:
case ExactValue_Pointer:
return 7;
case ExactValue_Procedure:
case ExactValue_Typeid:
return 8;
default:
GB_PANIC("How'd you get here? Invalid Value.kind %d", v.kind);
@@ -753,15 +859,35 @@ gb_internal void match_exact_values(ExactValue *x, ExactValue *y) {
switch (y->kind) {
case ExactValue_Integer:
return;
case ExactValue_Rational:
// Promote the integer to an exact rational so folding stays exact.
*x = exact_value_rational_from_integer(&x->value_integer);
return;
case ExactValue_Float:
// TODO(bill): Is this good enough?
*x = exact_value_float(big_int_to_f64(&x->value_integer));
return;
case ExactValue_Complex:
*x = exact_value_complex(big_int_to_f64(&x->value_integer), 0);
*x = exact_value_to_complex(*x); // keep the integer component exact
return;
case ExactValue_Quaternion:
*x = exact_value_quaternion(big_int_to_f64(&x->value_integer), 0, 0, 0);
*x = exact_value_to_quaternion(*x); // keep the integer component exact
return;
}
break;
case ExactValue_Rational:
switch (y->kind) {
case ExactValue_Rational:
return;
case ExactValue_Float:
*x = exact_value_to_float(*x);
return;
case ExactValue_Complex:
*x = exact_value_to_complex(*x);
return;
case ExactValue_Quaternion:
*x = exact_value_to_quaternion(*x);
return;
}
break;
@@ -841,6 +967,27 @@ gb_internal ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, E
return res;
}
case ExactValue_Rational: {
// Exact rational arithmetic: a/b (op) c/d, result reduced to lowest terms.
mp_int const *an = &x.value_rational->num, *ad = &x.value_rational->den;
mp_int const *bn = &y.value_rational->num, *bd = &y.value_rational->den;
mp_int nn, nd, t1, t2;
mp_init(&nn); mp_init(&nd); mp_init(&t1); mp_init(&t2);
defer (mp_clear(&nn)); defer (mp_clear(&nd)); defer (mp_clear(&t1)); defer (mp_clear(&t2));
switch (op) {
case Token_Add: // (an*bd + bn*ad) / (ad*bd)
big_int_mul(&t1, an, bd); big_int_mul(&t2, bn, ad); big_int_add(&nn, &t1, &t2); big_int_mul(&nd, ad, bd); break;
case Token_Sub:
big_int_mul(&t1, an, bd); big_int_mul(&t2, bn, ad); big_int_sub(&nn, &t1, &t2); big_int_mul(&nd, ad, bd); break;
case Token_Mul:
big_int_mul(&nn, an, bn); big_int_mul(&nd, ad, bd); break;
case Token_Quo: // (an/ad) / (bn/bd) = (an*bd) / (ad*bn)
big_int_mul(&nn, an, bd); big_int_mul(&nd, ad, bn); break;
default: goto error;
}
return exact_value_rational_arith_result(&nn, &nd);
}
case ExactValue_Float: {
f64 a = x.value_float;
f64 b = y.value_float;
@@ -855,86 +1002,103 @@ gb_internal ExactValue exact_binary_operator_value(TokenKind op, ExactValue x, E
}
case ExactValue_Complex: {
// Exact per-component arithmetic (each component is an Integer/Rational/Float ExactValue).
#define EV_MUL(p, q) exact_binary_operator_value(Token_Mul, (p), (q))
#define EV_ADD(p, q) exact_binary_operator_value(Token_Add, (p), (q))
#define EV_SUB(p, q) exact_binary_operator_value(Token_Sub, (p), (q))
#define EV_QUO(p, q) exact_binary_operator_value(Token_Quo, exact_value_as_rational_if_integer(p), exact_value_as_rational_if_integer(q))
y = exact_value_to_complex(y);
f64 a = x.value_complex->real;
f64 b = x.value_complex->imag;
f64 c = y.value_complex->real;
f64 d = y.value_complex->imag;
f64 real = 0;
f64 imag = 0;
ExactValue a = x.value_complex->real;
ExactValue b = x.value_complex->imag;
ExactValue c = y.value_complex->real;
ExactValue d = y.value_complex->imag;
ExactValue real = {};
ExactValue imag = {};
switch (op) {
case Token_Add:
real = a + c;
imag = b + d;
real = EV_ADD(a, c);
imag = EV_ADD(b, d);
break;
case Token_Sub:
real = a - c;
imag = b - d;
real = EV_SUB(a, c);
imag = EV_SUB(b, d);
break;
case Token_Mul:
real = (a*c - b*d);
imag = (b*c + a*d);
real = EV_SUB(EV_MUL(a, c), EV_MUL(b, d)); // a*c - b*d
imag = EV_ADD(EV_MUL(b, c), EV_MUL(a, d)); // b*c + a*d
break;
case Token_Quo: {
f64 s = c*c + d*d;
real = (a*c + b*d)/s;
imag = (b*c - a*d)/s;
ExactValue s = EV_ADD(EV_MUL(c, c), EV_MUL(d, d)); // c*c + d*d
real = EV_QUO(EV_ADD(EV_MUL(a, c), EV_MUL(b, d)), s); // (a*c + b*d)/s
imag = EV_QUO(EV_SUB(EV_MUL(b, c), EV_MUL(a, d)), s); // (b*c - a*d)/s
break;
}
default: goto error;
}
return exact_value_complex(real, imag);
break;
return exact_value_complex_ev(real, imag);
#undef EV_MUL
#undef EV_ADD
#undef EV_SUB
#undef EV_QUO
}
case ExactValue_Quaternion: {
#define EV_MUL(p, q) exact_binary_operator_value(Token_Mul, (p), (q))
#define EV_ADD(p, q) exact_binary_operator_value(Token_Add, (p), (q))
#define EV_SUB(p, q) exact_binary_operator_value(Token_Sub, (p), (q))
#define EV_QUO(p, q) exact_binary_operator_value(Token_Quo, exact_value_as_rational_if_integer(p), exact_value_as_rational_if_integer(q))
#define EV_NEG(p) exact_unary_operator_value(Token_Sub, (p), 0, false)
y = exact_value_to_quaternion(y);
f64 xr = x.value_quaternion->real;
f64 xi = x.value_quaternion->imag;
f64 xj = x.value_quaternion->jmag;
f64 xk = x.value_quaternion->kmag;
f64 yr = y.value_quaternion->real;
f64 yi = y.value_quaternion->imag;
f64 yj = y.value_quaternion->jmag;
f64 yk = y.value_quaternion->kmag;
ExactValue xr = x.value_quaternion->real;
ExactValue xi = x.value_quaternion->imag;
ExactValue xj = x.value_quaternion->jmag;
ExactValue xk = x.value_quaternion->kmag;
ExactValue yr = y.value_quaternion->real;
ExactValue yi = y.value_quaternion->imag;
ExactValue yj = y.value_quaternion->jmag;
ExactValue yk = y.value_quaternion->kmag;
f64 real = 0;
f64 imag = 0;
f64 jmag = 0;
f64 kmag = 0;
ExactValue real = {};
ExactValue imag = {};
ExactValue jmag = {};
ExactValue kmag = {};
switch (op) {
case Token_Add:
real = xr + yr;
imag = xi + yi;
jmag = xj + yj;
kmag = xk + yk;
real = EV_ADD(xr, yr); imag = EV_ADD(xi, yi); jmag = EV_ADD(xj, yj); kmag = EV_ADD(xk, yk);
break;
case Token_Sub:
real = xr - yr;
imag = xi - yi;
jmag = xj - yj;
kmag = xk - yk;
real = EV_SUB(xr, yr); imag = EV_SUB(xi, yi); jmag = EV_SUB(xj, yj); kmag = EV_SUB(xk, yk);
break;
case Token_Mul:
imag = xr * yi + xi * yr + xj * yk - xk * yj;
jmag = xr * yj - xi * yk + xj * yr + xk * yi;
kmag = xr * yk + xi * yj - xj * yi + xk * yr;
real = xr * yr - xi * yi - xj * yj - xk * yk;
// Hamilton product (matches the previous f64 formulas term-for-term).
imag = EV_SUB(EV_ADD(EV_ADD(EV_MUL(xr, yi), EV_MUL(xi, yr)), EV_MUL(xj, yk)), EV_MUL(xk, yj));
jmag = EV_ADD(EV_ADD(EV_SUB(EV_MUL(xr, yj), EV_MUL(xi, yk)), EV_MUL(xj, yr)), EV_MUL(xk, yi));
kmag = EV_ADD(EV_SUB(EV_ADD(EV_MUL(xr, yk), EV_MUL(xi, yj)), EV_MUL(xj, yi)), EV_MUL(xk, yr));
real = EV_SUB(EV_SUB(EV_SUB(EV_MUL(xr, yr), EV_MUL(xi, yi)), EV_MUL(xj, yj)), EV_MUL(xk, yk));
break;
case Token_Quo: {
f64 invmag2 = 1.0 / (yr*yr + yi*yi + yj*yj + yk*yk);
imag = (xr * -yi + xi * +yr + xj * -yk - xk * -yj) * invmag2;
jmag = (xr * -yj - xi * -yk + xj * +yr + xk * -yi) * invmag2;
kmag = (xr * -yk + xi * -yj - xj * -yi + xk * +yr) * invmag2;
real = (xr * +yr - xi * -yi - xj * -yj - xk * -yk) * invmag2;
// q1 / q2 = q1 * conj(q2) / |q2|^2
ExactValue nyi = EV_NEG(yi), nyj = EV_NEG(yj), nyk = EV_NEG(yk);
ExactValue mag2 = EV_ADD(EV_ADD(EV_ADD(EV_MUL(yr, yr), EV_MUL(yi, yi)), EV_MUL(yj, yj)), EV_MUL(yk, yk));
imag = EV_SUB(EV_ADD(EV_ADD(EV_MUL(xr, nyi), EV_MUL(xi, yr)), EV_MUL(xj, nyk)), EV_MUL(xk, nyj));
jmag = EV_ADD(EV_ADD(EV_SUB(EV_MUL(xr, nyj), EV_MUL(xi, nyk)), EV_MUL(xj, yr)), EV_MUL(xk, nyi));
kmag = EV_ADD(EV_SUB(EV_ADD(EV_MUL(xr, nyk), EV_MUL(xi, nyj)), EV_MUL(xj, nyi)), EV_MUL(xk, yr));
real = EV_SUB(EV_SUB(EV_SUB(EV_MUL(xr, yr), EV_MUL(xi, nyi)), EV_MUL(xj, nyj)), EV_MUL(xk, nyk));
imag = EV_QUO(imag, mag2);
jmag = EV_QUO(jmag, mag2);
kmag = EV_QUO(kmag, mag2);
real = EV_QUO(real, mag2);
break;
}
default: goto error;
}
return exact_value_quaternion(real, imag, jmag, kmag);
break;
return exact_value_quaternion_ev(real, imag, jmag, kmag);
#undef EV_MUL
#undef EV_ADD
#undef EV_SUB
#undef EV_QUO
#undef EV_NEG
}
case ExactValue_String: {
@@ -1022,6 +1186,23 @@ gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y)
break;
}
case ExactValue_Rational: {
// a/b (op) c/d with b,d > 0 <=> a*d (op) c*b
mp_int lhs, rhs; mp_init(&lhs); mp_init(&rhs); defer (mp_clear(&lhs)); defer (mp_clear(&rhs));
big_int_mul(&lhs, &x.value_rational->num, &y.value_rational->den);
big_int_mul(&rhs, &y.value_rational->num, &x.value_rational->den);
i32 cmp = big_int_cmp(&lhs, &rhs);
switch (op) {
case Token_CmpEq: return cmp == 0;
case Token_NotEq: return cmp != 0;
case Token_Lt: return cmp < 0;
case Token_LtEq: return cmp <= 0;
case Token_Gt: return cmp > 0;
case Token_GtEq: return cmp >= 0;
}
break;
}
case ExactValue_Float: {
f64 a = x.value_float;
f64 b = y.value_float;
@@ -1041,40 +1222,28 @@ gb_internal bool compare_exact_values(TokenKind op, ExactValue x, ExactValue y)
}
case ExactValue_Complex: {
f64 a = x.value_complex->real;
f64 b = x.value_complex->imag;
f64 c = y.value_complex->real;
f64 d = y.value_complex->imag;
if (isnan(a) || isnan(b) || isnan(c) || isnan(d)) {
return op == Token_NotEq;
}
// Compare component-wise using exact comparisons (each component is a numeric ExactValue).
ExactComplex a = *x.value_complex;
ExactComplex b = *y.value_complex;
bool real_eq = compare_exact_values(Token_CmpEq, a.real, b.real);
bool imag_eq = compare_exact_values(Token_CmpEq, a.imag, b.imag);
switch (op) {
case Token_CmpEq: return cmp_f64(a, c) == 0 && cmp_f64(b, d) == 0;
case Token_NotEq: return cmp_f64(a, c) != 0 || cmp_f64(b, d) != 0;
case Token_CmpEq: return real_eq && imag_eq;
case Token_NotEq: return !real_eq || !imag_eq;
}
break;
}
case ExactValue_Quaternion: {
Quaternion256 a = *x.value_quaternion;
Quaternion256 b = *y.value_quaternion;
if (isnan(a.real) || isnan(a.imag) || isnan(a.jmag) || isnan(a.kmag) ||
isnan(b.real) || isnan(b.imag) || isnan(b.jmag) || isnan(b.kmag)) {
return op == Token_NotEq;
}
ExactQuaternion a = *x.value_quaternion;
ExactQuaternion b = *y.value_quaternion;
bool real_eq = compare_exact_values(Token_CmpEq, a.real, b.real);
bool imag_eq = compare_exact_values(Token_CmpEq, a.imag, b.imag);
bool jmag_eq = compare_exact_values(Token_CmpEq, a.jmag, b.jmag);
bool kmag_eq = compare_exact_values(Token_CmpEq, a.kmag, b.kmag);
switch (op) {
case Token_CmpEq:
return cmp_f64(a.real, b.real) == 0 &&
cmp_f64(a.imag, b.imag) == 0 &&
cmp_f64(a.jmag, b.jmag) == 0 &&
cmp_f64(a.kmag, b.kmag) == 0;
case Token_NotEq:
return cmp_f64(a.real, b.real) != 0 ||
cmp_f64(a.imag, b.imag) != 0 ||
cmp_f64(a.jmag, b.jmag) != 0 ||
cmp_f64(a.kmag, b.kmag) != 0;
case Token_CmpEq: return real_eq && imag_eq && jmag_eq && kmag_eq;
case Token_NotEq: return !real_eq || !imag_eq || !jmag_eq || !kmag_eq;
}
break;
}
@@ -1161,6 +1330,22 @@ gb_internal Entity *strip_entity_wrapping(Entity *e);
gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthand);
gb_internal gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit);
gb_internal gbString write_exact_complex_component_to_string(gbString str, ExactValue comp, isize string_limit) {
f64 f = exact_value_to_f64(comp);
// The float formatter cannot render a magnitude at or beyond 2**63 (it prints 2**63's digits on a
// loop), and that also catches Inf/NaN since the range test below is false for them. For an exact
// integer/rational component that large, print its exact form (digits, or `num.0/den`) instead.
static f64 const LIMIT = 9223372036854775808.0; // 2**63
bool formatter_safe = (f >= -LIMIT) && (f <= LIMIT);
if (!formatter_safe && (comp.kind == ExactValue_Integer || comp.kind == ExactValue_Rational)) {
return write_exact_value_to_string(str, comp, string_limit);
}
return gb_string_append_fmt(str, "%.17g", f);
}
gb_internal gbString write_exact_value_to_string(gbString str, ExactValue const &v, isize string_limit=36) {
switch (v.kind) {
case ExactValue_Invalid:
@@ -1204,10 +1389,42 @@ gb_internal gbString write_exact_value_to_string(gbString str, ExactValue const
// NOTE(tf2spi): %.17g is specific enough to canonically serialize f64
case ExactValue_Float:
return gb_string_append_fmt(str, "%.17g", v.value_float);
case ExactValue_Rational:
// Integer-valued (den == 1, e.g. an overflowing literal like `1.0e400`) prints its exact decimal,
// so a diagnostic shows the real magnitude rather than an f64 that has rounded to +Inf.
if (mp_cmp_d(&v.value_rational->den, 1) == MP_EQ) {
String s = big_int_to_string(heap_allocator(), &v.value_rational->num);
str = gb_string_append_length(str, s.text, s.len);
gb_free(heap_allocator(), s.text);
return str;
}
// Non-integer: print the exact fraction as `<num>.0/<den>` (e.g. `1.0/3`). The `.0` on the
// numerator marks it as a decimal division, so it reads as the float `1.0/3` rather than the
// integer division `1/3` (which would be 0), and it round-trips as valid Odin source.
{
String ns = big_int_to_string(heap_allocator(), &v.value_rational->num);
String ds = big_int_to_string(heap_allocator(), &v.value_rational->den);
str = gb_string_append_length(str, ns.text, ns.len);
str = gb_string_append_fmt(str, ".0/");
str = gb_string_append_length(str, ds.text, ds.len);
gb_free(heap_allocator(), ns.text);
gb_free(heap_allocator(), ds.text);
return str;
}
case ExactValue_Complex:
return gb_string_append_fmt(str, "%.17g+%.17gi", v.value_complex->real, v.value_complex->imag);
str = write_exact_complex_component_to_string(str, v.value_complex->real, string_limit);
str = gb_string_append_fmt(str, "+");
str = write_exact_complex_component_to_string(str, v.value_complex->imag, string_limit);
return gb_string_append_fmt(str, "i");
case ExactValue_Quaternion:
return gb_string_append_fmt(str, "%.17g+%.17gi+%.17gj+%.17gk", v.value_quaternion->real, v.value_quaternion->imag, v.value_quaternion->jmag, v.value_quaternion->kmag);
str = write_exact_complex_component_to_string(str, v.value_quaternion->real, string_limit);
str = gb_string_append_fmt(str, "+");
str = write_exact_complex_component_to_string(str, v.value_quaternion->imag, string_limit);
str = gb_string_append_fmt(str, "i+");
str = write_exact_complex_component_to_string(str, v.value_quaternion->jmag, string_limit);
str = gb_string_append_fmt(str, "j+");
str = write_exact_complex_component_to_string(str, v.value_quaternion->kmag, string_limit);
return gb_string_append_fmt(str, "k");
case ExactValue_Pointer:
return str;
+4
View File
@@ -1,3 +1,7 @@
// NOTE: the default is 32 digits (256 bytes), but nearly every constant fits in 64 bits and digits
// grow when needed. 4 is the minimum of 3 digits rounded up to MP_CALLOC's 16-byte alignment.
#define MP_DEFAULT_DIGIT_COUNT 4
#include "libtommath/mp_2expt.c"
#include "libtommath/mp_abs.c"
#include "libtommath/mp_add.c"
+164 -7
View File
@@ -13,6 +13,85 @@ struct LinkerData {
gb_internal i32 system_exec_command_line_app(char const *name, char const *fmt, ...);
gb_internal bool system_exec_command_line_app_output(char const *command, gbString *output);
gb_internal i32 system_exec_msvc_linker_app(char const *name, char const *fmt, ...) {
isize const cmd_cap = 64<<20;
char *cmd = gb_alloc_array(heap_allocator(), char, cmd_cap);
defer (gb_free(heap_allocator(), cmd));
va_list va;
va_start(va, fmt);
isize cmd_len = gb_snprintf_va(cmd, cmd_cap-1, fmt, va) - 1;
va_end(va);
#if defined(GB_SYSTEM_WINDOWS)
// NOTE(bill, 2026-10-03): CreateProcessW limits the command line to 32767 UTF-16 code units so we need to pass the arguments into a response file
if (cmd_len >= 32767 && !build_context.print_linker_flags) {
char const *exe_end = cmd[0] == '"' ? gb_char_first_occurence(cmd+1, '"') : nullptr;
GB_ASSERT(exe_end != nullptr);
isize exe_len = exe_end+1 - cmd;
gbString rsp = gb_string_make_reserve(heap_allocator(), cmd_len);
defer (gb_string_free(rsp));
// NOTE(bill): link.exe rejects response file lines of 128 KiB or more
bool in_quotes = false;
bool separate = false;
isize backslashes = 0;
for (char const *c = cmd+exe_len; *c; c++) {
if (!in_quotes && (*c == ' ' || *c == '\t')) {
separate = gb_string_length(rsp) > 0;
continue;
}
if (separate) {
rsp = gb_string_appendc(rsp, "\n");
separate = false;
}
if (*c == '"' && (backslashes & 1) == 0) {
in_quotes = !in_quotes;
}
backslashes = *c == '\\' ? backslashes+1 : 0;
rsp = gb_string_append_length(rsp, c, 1);
}
String dir = temporary_directory(temporary_allocator());
if (dir.len == 0) {
dir = build_context.build_paths[BuildPath_Output].basename;
}
gbString rsp_path = gb_string_make(heap_allocator(), "");
defer (gb_string_free(rsp_path));
rsp_path = gb_string_append_fmt(rsp_path, "%.*s/%.*s-%u.rsp", LIT(dir), LIT(build_context.build_paths[BuildPath_Output].name), GetCurrentProcessId());
{
gbFile f = {};
if (gb_file_create(&f, rsp_path) != gbFileError_None) {
gb_printf_err("Failed to create linker response file: %s\n", rsp_path);
return -1;
}
if (build_context.linker_choice != Linker_Default && build_context.linker_choice != Linker_radlink) {
// NOTE(bill): link.exe reads a response file without a BOM in the ANSI code page but radlink does not skip a BOM
gb_file_write(&f, "\xef\xbb\xbf", 3);
}
gb_file_write(&f, rsp, gb_string_length(rsp));
gb_file_close(&f);
}
if (build_context.show_system_calls) {
gb_printf_err("[RESPONSE FILE] %s\n%s\n\n", rsp_path, rsp);
}
i32 result = system_exec_command_line_app(name, "%.*s @\"%s\"", cast(int)exe_len, cmd, rsp_path);
if (!build_context.keep_temp_files) {
gb_file_remove(rsp_path);
}
return result;
}
#endif
return system_exec_command_line_app(name, "%.*s", cast(int)cmd_len, cmd);
}
// No longer required not that LLVM 14 is removed(?)
gb_internal void linker_enable_system_library_linking(LinkerData *ld) {
ld->needs_system_library_linked = true;
@@ -161,7 +240,7 @@ gb_internal i32 linker_stage(LinkerData *gen) {
try_cross_linking:;
#if defined(GB_SYSTEM_WINDOWS)
String section_name = str_lit("msvc-link");
String section_name = str_lit("rad-link");
bool is_windows = build_context.metrics.os == TargetOs_windows;
#else
String section_name = str_lit("ld-link");
@@ -174,12 +253,13 @@ try_cross_linking:;
switch (build_context.linker_choice) {
case Linker_Default: break;
case Linker_lld: section_name = str_lit("lld-link"); break;
#if defined(GB_SYSTEM_WINDOWS)
case Linker_radlink: break;
#endif
#if defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_NETBSD)
case Linker_mold: section_name = str_lit("mold-link"); break;
#endif
#if defined(GB_SYSTEM_WINDOWS)
case Linker_radlink: section_name = str_lit("rad-link"); break;
#endif
case Linker_msvc: section_name = str_lit("msvc-link"); break;
default:
gb_printf_err("'%.*s' linker is not supported on this platform\n", LIT(linker_choices[build_context.linker_choice]));
return 1;
@@ -209,7 +289,6 @@ try_cross_linking:;
add_path(build_context.build_paths[BuildPath_VS_LIB].basename);
}
StringSet min_libs_set = {};
string_set_init(&min_libs_set, 64);
defer (string_set_destroy(&min_libs_set));
@@ -367,6 +446,10 @@ try_cross_linking:;
if (build_context.ODIN_DEBUG) {
link_settings = gb_string_append_fmt(link_settings, " /DEBUG");
if (build_context.build_mode != BuildMode_StaticLibrary) {
// NOTE(bill): `/opt:ref` would also fold identical functions, which is slow and confuses the debugger
link_settings = gb_string_append_fmt(link_settings, " /OPT:NOICF");
}
}
gbString object_files = gb_string_make(heap_allocator(), "");
@@ -387,8 +470,36 @@ try_cross_linking:;
lld_lto_flags = gb_string_append_fmt(lld_lto_flags, "/opt:lldltojobs=%d ", build_context.thread_count);
}
String res_path = {};
String rc_path = {};
defer (gb_free(heap_allocator(), res_path.text));
defer (gb_free(heap_allocator(), rc_path.text));
if (build_context.has_resource) {
res_path = quote_path(heap_allocator(), build_context.build_paths[BuildPath_RES]);
rc_path = quote_path(heap_allocator(), build_context.build_paths[BuildPath_RC]);
if (build_context.build_paths[BuildPath_RC].basename == "") {
debugf("Using precompiled resource %.*s\n", LIT(res_path));
} else {
debugf("Compiling resource %.*s\n", LIT(res_path));
result = system_exec_command_line_app("resource compiler",
"\"%.*src.exe\" /nologo /fo %.*s %.*s",
LIT(windows_sdk_bin_path),
LIT(res_path),
LIT(rc_path)
);
if (result) {
return result;
}
}
}
switch (build_context.linker_choice) {
case Linker_lld:
<<<<<<< HEAD
{
#if defined(GB_SYSTEM_WINDOWS)
char linker_path[4096] = {0};
@@ -420,12 +531,31 @@ try_cross_linking:;
lib_str,
lld_lto_flags
);
=======
result = system_exec_msvc_linker_app("msvc-lld-link",
"\"%.*s\\bin\\lld-link\" %s %.*s -OUT:\"%.*s\" %s "
"/nologo /incremental:no /opt:ref /subsystem:%.*s "
"%.*s "
"%.*s "
"%s "
"%s "
"",
LIT(build_context.ODIN_ROOT), object_files, LIT(res_path), LIT(output_filename),
link_settings,
LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]),
LIT(build_context.link_flags),
LIT(build_context.extra_linker_flags),
lib_str,
lld_lto_flags
);
>>>>>>> upstream/master
if (result) {
return result;
}
break;
}
<<<<<<< HEAD
case Linker_radlink:
result = system_exec_command_line_app("msvc-rad-link",
"\"%.*s\\bin\\radlink\" %s -OUT:\"%.*s\" %s "
@@ -472,7 +602,11 @@ try_cross_linking:;
} else {
res_path = {};
}
=======
break;
>>>>>>> upstream/master
case Linker_msvc: {
String linker_name = str_lit("link.exe");
switch (build_context.build_mode) {
case BuildMode_Executable:
@@ -489,8 +623,7 @@ try_cross_linking:;
break;
}
result = system_exec_command_line_app("msvc-link",
result = system_exec_msvc_linker_app("msvc-link",
"\"%.*s%.*s\" %s %.*s -OUT:\"%.*s\" %s "
"/nologo /subsystem:%.*s "
"%.*s "
@@ -504,11 +637,35 @@ try_cross_linking:;
LIT(build_context.extra_linker_flags),
lib_str
);
if (result) {
return result;
}
break;
}
default: { // radlink
result = system_exec_msvc_linker_app("msvc-rad-link",
"\"%.*s\\bin\\radlink\" %s %.*s -OUT:\"%.*s\" %s "
"/nologo /incremental:no /opt:ref /subsystem:%.*s "
"%.*s "
"%.*s "
"%s "
"",
LIT(build_context.ODIN_ROOT), object_files, LIT(res_path), LIT(output_filename),
link_settings,
LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]),
LIT(build_context.link_flags),
LIT(build_context.extra_linker_flags),
lib_str
);
if (result) {
return result;
}
break;
}
}
} else {
+59 -56
View File
@@ -150,6 +150,23 @@ gb_internal LLVMTypeRef lb_function_type_to_llvm_raw(lbFunctionType *ft, bool is
// return LLVMPointerType(func_type, 0);
// }
gb_internal lbCallingConventionKind lb_calling_convention_kind(ProcCallingConvention cc) {
if (selected_subtarget == Subtarget_Playdate) {
return lbCallingConvention_ARM_AAPCS_VFP;
}
if (is_arch_wasm()) {
return lbCallingConvention_C;
}
return lb_calling_convention_map[cc];
}
gb_internal LLVMAttributeRef lb_create_nocapture_attribute(LLVMContextRef c) {
#if LLVM_VERSION_MAJOR >= 21
return lb_create_enum_attribute(c, "captures", 0); // 0 == CaptureInfo::none()
#else
return lb_create_enum_attribute(c, "nocapture");
#endif
}
gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType *ft, ProcCallingConvention calling_convention) {
if (ft == nullptr) {
@@ -164,11 +181,7 @@ gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType
LLVMContextRef c = ft->ctx;
LLVMAttributeRef noalias_attr = lb_create_enum_attribute(c, "noalias");
LLVMAttributeRef nonnull_attr = lb_create_enum_attribute(c, "nonnull");
#if LLVM_VERSION_MAJOR >= 21
LLVMAttributeRef nocapture_attr = lb_create_string_attribute(c, make_string_c("captures"), make_string_c("none"));
#else
LLVMAttributeRef nocapture_attr = lb_create_enum_attribute(c, "nocapture");
#endif
LLVMAttributeRef nocapture_attr = lb_create_nocapture_attribute(c);
unsigned arg_index = offset;
for (unsigned i = 0; i < arg_count; i++) {
@@ -204,13 +217,7 @@ gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType
LLVMAddAttributeAtIndex(fn, offset, noalias_attr);
}
lbCallingConventionKind cc_kind = lbCallingConvention_C;
// TODO(bill): Clean up this logic
if (selected_subtarget == Subtarget_Playdate) {
cc_kind = lbCallingConvention_ARM_AAPCS_VFP;
} else if (!is_arch_wasm()) {
cc_kind = lb_calling_convention_map[calling_convention];
}
lbCallingConventionKind cc_kind = lb_calling_convention_kind(calling_convention);
// if (build_context.metrics.arch == TargetArch_amd64) {
// if (build_context.metrics.os == TargetOs_windows) {
// if (cc_kind == lbCallingConvention_C) {
@@ -233,6 +240,44 @@ gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType
}
struct lbTypeLayout {
i64 size;
i64 align;
};
gb_thread_local PtrMap<LLVMTypeRef, lbTypeLayout> lb_aggregate_layouts;
gb_internal lbTypeLayout lb_aggregate_layout(LLVMTypeRef type) {
if (lbTypeLayout *found = map_get(&lb_aggregate_layouts, type)) {
return *found;
}
lbTypeLayout layout = {0, 1};
if (LLVMGetTypeKind(type) == LLVMArrayTypeKind) {
LLVMTypeRef elem = OdinLLVMGetArrayElementType(type);
layout.size = cast(i64)LLVMGetArrayLength(type) * lb_sizeof(elem);
layout.align = lb_alignof(elem);
} else {
GB_ASSERT(LLVMGetTypeKind(type) == LLVMStructTypeKind);
if (LLVMIsOpaqueStruct(type)) {
return layout;
}
bool is_packed = LLVMIsPackedStruct(type);
unsigned field_count = LLVMCountStructElementTypes(type);
for (unsigned i = 0; i < field_count; i++) {
LLVMTypeRef field = LLVMStructGetTypeAtIndex(type, i);
if (!is_packed) {
i64 field_align = lb_alignof(field);
layout.size = llvm_align_formula(layout.size, field_align);
layout.align = gb_max(layout.align, field_align);
}
layout.size += lb_sizeof(field);
}
layout.size = llvm_align_formula(layout.size, layout.align);
}
map_set(&lb_aggregate_layouts, type, layout);
return layout;
}
gb_internal i64 lb_sizeof(LLVMTypeRef type) {
LLVMTypeKind kind = LLVMGetTypeKind(type);
switch (kind) {
@@ -252,35 +297,8 @@ gb_internal i64 lb_sizeof(LLVMTypeRef type) {
case LLVMPointerTypeKind:
return build_context.ptr_size;
case LLVMStructTypeKind:
{
unsigned field_count = LLVMCountStructElementTypes(type);
i64 offset = 0;
if (LLVMIsPackedStruct(type)) {
for (unsigned i = 0; i < field_count; i++) {
LLVMTypeRef field = LLVMStructGetTypeAtIndex(type, i);
offset += lb_sizeof(field);
}
} else {
for (unsigned i = 0; i < field_count; i++) {
LLVMTypeRef field = LLVMStructGetTypeAtIndex(type, i);
i64 align = lb_alignof(field);
offset = llvm_align_formula(offset, align);
offset += lb_sizeof(field);
}
offset = llvm_align_formula(offset, lb_alignof(type));
}
return offset;
}
break;
case LLVMArrayTypeKind:
{
LLVMTypeRef elem = OdinLLVMGetArrayElementType(type);
i64 elem_size = lb_sizeof(elem);
i64 count = LLVMGetArrayLength(type);
i64 size = count * elem_size;
return size;
}
break;
return lb_aggregate_layout(type).size;
#if LLVM_VERSION_MAJOR < 20
case LLVMX86_MMXTypeKind:
@@ -320,23 +338,8 @@ gb_internal i64 lb_alignof(LLVMTypeRef type) {
case LLVMPointerTypeKind:
return build_context.ptr_size;
case LLVMStructTypeKind:
{
if (LLVMIsPackedStruct(type)) {
return 1;
} else {
unsigned field_count = LLVMCountStructElementTypes(type);
i64 max_align = 1;
for (unsigned i = 0; i < field_count; i++) {
LLVMTypeRef field = LLVMStructGetTypeAtIndex(type, i);
i64 field_align = lb_alignof(field);
max_align = gb_max(max_align, field_align);
}
return max_align;
}
}
break;
case LLVMArrayTypeKind:
return lb_alignof(OdinLLVMGetArrayElementType(type));
return lb_aggregate_layout(type).align;
#if LLVM_VERSION_MAJOR < 20
case LLVMX86_MMXTypeKind:
+606 -327
View File
File diff suppressed because it is too large. Load diff
+43 -6
View File
@@ -24,6 +24,7 @@
#endif
struct lbProcedure;
struct lbGlobalVariable;
struct lbValue {
LLVMValueRef value;
@@ -108,6 +109,11 @@ struct lbPadType {
LLVMTypeRef type;
};
struct NamedMetaDataKind {
String name;
unsigned kind;
};
struct lbModule {
LLVMModuleRef mod;
LLVMContextRef ctx;
@@ -120,9 +126,15 @@ struct lbModule {
lbModule *polymorphic_module;
CheckerInfo *info;
AstPackage *pkg; // possibly associated
AstFile *file; // possibly associated
char const *module_name;
AstPackage * pkg; // possibly associated
AstFile * file; // possibly associated
char const * module_name;
NamedMetaDataKind metadata_kinds[4];
isize metadata_kind_count;
i64 estimated_cost;
i32 split_part;
PtrMap<u64/*type hash*/, LLVMTypeRef> types; // mutex: types_mutex
PtrMap<void *, lbStructFieldRemapping> struct_field_remapping; // Key: LLVMTypeRef or Type *, mutex: types_mutex
@@ -141,8 +153,6 @@ struct lbModule {
StringMap<lbProcedure *> procedures;
PtrMap<LLVMValueRef, Entity *> procedure_values;
MPSCQueue<lbProcedure *> missing_procedures_to_check;
StringMap<LLVMValueRef> const_strings;
String16Map<LLVMValueRef> const_string16s;
@@ -153,6 +163,7 @@ struct lbModule {
MPSCQueue<lbProcedure *> procedures_to_generate;
Array<Entity *> global_procedures_to_create;
Array<Entity *> global_types_to_create;
Array<lbGlobalVariable *> global_variables;
BlockingMutex generated_procedures_mutex;
Array<lbProcedure *> generated_procedures;
@@ -203,16 +214,21 @@ struct lbGenerator : LinkerData {
PtrMap<void *, lbModule *> modules; // key is `AstPackage *` (`void *` is used for future use)
PtrMap<LLVMContextRef, lbModule *> modules_through_ctx;
PtrMap<AstFile *, lbModule *> file_modules;
lbModule default_module;
lbModule *equal_module;
isize used_module_count;
bool modules_in_parallel;
lbProcedure *startup_runtime;
lbProcedure *cleanup_runtime;
lbProcedure *objc_names;
Array<lbProcedure *> global_init_procedures;
MPSCQueue<lbEntityCorrection> entities_to_correct_linkage;
MPSCQueue<lbObjCGlobal> objc_selectors;
MPSCQueue<lbObjCGlobal> objc_classes;
@@ -279,6 +295,12 @@ struct lbDefer {
};
};
struct lbLifetimeLocal {
LLVMValueRef ptr;
i64 size;
isize scope_index;
};
struct lbTargetList {
lbTargetList *prev;
bool is_block;
@@ -375,8 +397,13 @@ struct lbProcedure {
Array<lbValue> asan_stack_locals;
Array<lbLifetimeLocal> lifetime_locals;
// matches scope_stack (count == scope_index);
// whether that scope's named locals may be lifetime marked
Array<bool> lifetime_scopes;
void (*generate_body)(lbModule *m, lbProcedure *p);
Array<lbGlobalVariable> *global_variables;
Array<lbGlobalVariable *> global_variables;
lbProcedure *objc_names;
Type *internal_gen_type; // map_set, map_get, etc.
@@ -487,6 +514,10 @@ gb_internal lbAddr lb_add_global_generated_from_procedure(lbProcedure *p, Type *
gb_internal lbAddr lb_add_global_generated_with_name(lbModule *m, Type *type, lbValue value, String name, Entity **entity_=nullptr);
gb_internal lbAddr lb_add_local(lbProcedure *p, Type *type, Entity *e=nullptr, bool zero_init=true, bool force_no_init=false);
gb_internal bool lb_lifetime_markers_enabled(void);
gb_internal void lb_add_lifetime_local(lbProcedure *p, LLVMValueRef ptr, Type *type);
gb_internal void lb_emit_lifetime_ends(lbProcedure *p, lbDeferExitKind kind, lbBlock *block);
gb_internal void lb_add_foreign_library_path(lbModule *m, Entity *e);
gb_internal lbValue lb_typeid(lbModule *m, Type *type);
@@ -599,6 +630,9 @@ 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 LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, usize len, unsigned alignment, bool is_volatile);
gb_internal bool lb_const_has_misaligned_pointer(LLVMTargetDataRef td, LLVMValueRef c, u64 offset, u64 base_align);
gb_internal void lb_add_attribute_to_proc(lbModule *m, LLVMValueRef proc_value, char const *name, u64 value=0);
gb_internal gb_inline i64 lb_max_zero_init_size(void) {
if (build_context.metrics.os == TargetOs_darwin && build_context.metrics.arch == TargetArch_arm64) {
// https://github.com/odin-lang/Odin/issues/6347
@@ -632,6 +666,7 @@ gb_internal lbValue lb_make_string_value(lbProcedure *p, Type *string_type, lbVa
gb_internal String lb_internal_gen_name_from_type(char const *prefix, Type *type);
gb_internal unsigned lb_metadata_kind(lbModule *m, String const &name);
gb_internal void lb_set_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name, u64 value);
gb_internal u64 lb_get_metadata_custom_u64(lbModule *m, LLVMValueRef v_ref, String name);
@@ -718,6 +753,8 @@ lbCallingConventionKind const lb_calling_convention_map[ProcCC_MAX] = {
};
gb_internal lbCallingConventionKind lb_calling_convention_kind(ProcCallingConvention cc);
enum : LLVMDWARFTypeEncoding {
LLVMDWARFTypeEncoding_Address = 1,
LLVMDWARFTypeEncoding_Boolean = 2,
+183 -54
View File
@@ -239,6 +239,60 @@ gb_internal LLVMValueRef llvm_const_array(lbModule *m, LLVMTypeRef elem_type, LL
return LLVMConstArray(elem_type, values, value_count);
}
// Each constant `insertvalue` rebuilds and uniques the whole aggregate,
// so the nested fields of a compound literal are collected and built once.
struct lbConstAggregate {
LLVMValueRef value;
lbConstAggregate *elems;
unsigned elem_count;
};
gb_internal void lb_const_aggregate_insert(lbModule *m, lbConstAggregate *agg, LLVMValueRef base, LLVMValueRef val, unsigned *indices, isize count) {
if (agg->elems == nullptr) {
agg->value = base;
}
for (isize i = 0; i < count; i++) {
if (agg->elems == nullptr) {
LLVMTypeRef type = LLVMTypeOf(agg->value);
if (LLVMGetTypeKind(type) == LLVMArrayTypeKind) {
agg->elem_count = cast(unsigned)LLVMGetArrayLength(type);
} else {
agg->elem_count = LLVMCountStructElementTypes(type);
}
agg->elems = gb_alloc_array(temporary_allocator(), lbConstAggregate, agg->elem_count);
for (unsigned j = 0; j < agg->elem_count; j++) {
agg->elems[j].value = llvm_const_extract_value(m, agg->value, j);
}
}
agg = &agg->elems[indices[i]];
}
agg->value = val;
agg->elems = nullptr;
}
gb_internal LLVMValueRef lb_const_aggregate_build(lbModule *m, lbConstAggregate *agg) {
if (agg->elems == nullptr) {
return agg->value;
}
LLVMTypeRef type = LLVMTypeOf(agg->value);
LLVMValueRef *values = gb_alloc_array(temporary_allocator(), LLVMValueRef, agg->elem_count);
for (unsigned i = 0; i < agg->elem_count; i++) {
values[i] = lb_const_aggregate_build(m, &agg->elems[i]);
}
if (LLVMGetTypeKind(type) == LLVMArrayTypeKind) {
return llvm_const_array(m, OdinLLVMGetArrayElementType(type), values, agg->elem_count);
}
return llvm_const_named_struct_internal(m, type, values, agg->elem_count);
}
gb_internal LLVMValueRef lb_const_aggregate_take(lbModule *m, lbConstAggregate *agg, LLVMValueRef value) {
if (agg->elems != nullptr) {
value = lb_const_aggregate_build(m, agg);
}
*agg = {};
return value;
}
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);
@@ -427,25 +481,35 @@ gb_internal String lb_source_code_location_gen_name(lbProcedure *p, Ast *node) {
gb_internal lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, String const &procedure, TokenPos const &pos) {
lbValue loc = lb_emit_source_code_location_const(p, procedure, pos);
lbAddr addr = lb_add_global_generated_with_name(p->module, loc.type, loc, lb_source_code_location_gen_name(procedure, pos));
gb_internal lbValue lb_source_code_location_global_ptr(lbModule *m, lbValue loc, String const &name) {
// NOTE(bill): every polymorphic instance of a procedure produces the same location under the same name.
// Reuse it rather than letting LLVM rename the duplicate, as which instance got the new name depended
// on the order the instances were generated in.
LLVMValueRef found = LLVMGetNamedGlobal(m->mod, alloc_cstring(temporary_allocator(), name));
if (found != nullptr && LLVMGetInitializer(found) == loc.value) {
lbValue g = {};
g.type = alloc_type_pointer(default_type(loc.type));
g.value = LLVMConstPointerCast(found, lb_type(m, g.type));
return g;
}
lbAddr addr = lb_add_global_generated_with_name(m, loc.type, loc, name);
lb_make_global_private_const(addr);
return addr.addr;
}
gb_internal lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, String const &procedure, TokenPos const &pos) {
lbValue loc = lb_emit_source_code_location_const(p, procedure, pos);
return lb_source_code_location_global_ptr(p->module, loc, lb_source_code_location_gen_name(procedure, pos));
}
gb_internal lbValue lb_const_source_code_location_as_global_ptr(lbModule *m, String const &procedure, TokenPos const &pos) {
lbValue loc = lb_const_source_code_location_const(m, procedure, pos);
lbAddr addr = lb_add_global_generated_with_name(m, loc.type, loc, lb_source_code_location_gen_name(procedure, pos));
lb_make_global_private_const(addr);
return addr.addr;
return lb_source_code_location_global_ptr(m, loc, lb_source_code_location_gen_name(procedure, pos));
}
gb_internal lbValue lb_emit_source_code_location_as_global_ptr(lbProcedure *p, Ast *node) {
lbValue loc = lb_emit_source_code_location_const(p, node);
lbAddr addr = lb_add_global_generated_with_name(p->module, loc.type, loc, lb_source_code_location_gen_name(p, node));
lb_make_global_private_const(addr);
return addr.addr;
return lb_source_code_location_global_ptr(p->module, loc, lb_source_code_location_gen_name(p, node));
}
@@ -460,6 +524,21 @@ gb_internal lbValue lb_emit_source_code_location_as_global(lbProcedure *p, Ast *
// NOTE(bill): Constants which cannot be an LLVM constant were built in a local of their own
// which was copied from rather than loaded and stored as a first class aggregate
gb_internal void lb_store_local_constant(lbProcedure *p, LLVMValueRef dst, LLVMValueRef value) {
if (!LLVMIsALoadInst(value) || !LLVMIsAAllocaInst(LLVMGetOperand(value, 0))) {
LLVMBuildStore(p->builder, value, dst);
return;
}
LLVMValueRef src = LLVMGetOperand(value, 0);
LLVMTypeRef type = LLVMTypeOf(value);
LLVMValueRef size = LLVMConstInt(lb_type(p->module, t_int), lb_sizeof(type), false);
unsigned dst_alignment = LLVMABIAlignmentOfType(LLVMGetModuleDataLayout(p->module->mod), type);
LLVMBuildMemCpy(p->builder, dst, dst_alignment, src, lb_try_get_alignment(src, 1), size);
}
gb_internal LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type, Type *elem_type, isize count, LLVMValueRef *values, lbConstContext cc) {
if (cc.allow_local) {
cc.is_rodata = false;
@@ -488,7 +567,7 @@ gb_internal LLVMValueRef lb_build_constant_array_values(lbModule *m, Type *type,
if (is_type_proc(elem_type)) {
values[i] = LLVMConstPointerCast(values[i], llvm_elem_type);
}
LLVMBuildStore(p->builder, values[i], elem.value);
lb_store_local_constant(p, elem.value, values[i]);
}
return lb_addr_load(p, v).value;
}
@@ -500,7 +579,45 @@ gb_internal LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, Bi
if (big_int_is_zero(a)) {
return LLVMConstNull(lb_type(m, original_type));
}
// NOTE(bill): a bit_set backed by an array of integers (e.g. `bit_set[E; [4]u64]`) is represented as an LLVM array.
// There for its constant value is the same bit mask as an integer-backed bit_set, split into element-sized
// little-endian chunks (element `i` holds bits `[i*elem_bits, (i+1)*elem_bits)`), which matches how membership
// and literals index into the array.
if (is_type_bit_set(original_type)) {
Type *backing = bit_set_to_int(original_type);
if (is_type_array(backing)) {
Type *elem = backing->Array.elem;
i64 n = backing->Array.count;
i64 elem_bits = 8*type_size_of(elem);
BigInt v = {};
big_int_init(&v, a);
defer (big_int_dealloc(&v));
BigInt shift = {};
big_int_from_u64(&shift, cast(u64)elem_bits);
defer (big_int_dealloc(&shift));
BigInt mask = {}; // (1 << elem_bits) - 1
big_int_from_u64(&mask, 1);
big_int_shl(&mask, &mask, &shift);
mp_decr(&mask);
defer (big_int_dealloc(&mask));
LLVMTypeRef elem_llvm = lb_type(m, elem);
LLVMValueRef *elems = gb_alloc_array(temporary_allocator(), LLVMValueRef, cast(isize)n);
for (i64 i = 0; i < n; i++) {
BigInt chunk = {};
big_int_and(&chunk, &v, &mask);
elems[i] = lb_big_int_to_llvm(m, elem, &chunk);
big_int_dealloc(&chunk);
big_int_shr_eq(&v, &shift);
}
return LLVMConstArray(elem_llvm, elems, cast(unsigned)n);
}
}
BigInt val = {};
big_int_init(&val, a);
@@ -753,14 +870,14 @@ gb_internal lbValue lb_const_value_bit_field(lbModule *m, Type *type, Ast *value
GB_ASSERT(mask_width > 0);
bits_to_set -= mask_width;
LLVMValueRef mask = lb_const_low_bits_mask(vt, mask_width);
LLVMValueRef mask = lb_const_low_bits_mask(lit, mask_width);
LLVMValueRef to_set = LLVMBuildAnd(m->const_dummy_builder, val, mask, "");
LLVMValueRef to_set = LLVMBuildIntCast2(m->const_dummy_builder, val, lit, false, "");
to_set = LLVMBuildAnd(m->const_dummy_builder, to_set, mask, "");
if (elem_bit_offset != 0) {
to_set = LLVMBuildShl(m->const_dummy_builder, to_set, LLVMConstInt(vt, elem_bit_offset, false), "");
to_set = LLVMBuildShl(m->const_dummy_builder, to_set, LLVMConstInt(lit, elem_bit_offset, false), "");
}
to_set = LLVMBuildTrunc(m->const_dummy_builder, to_set, lit, "");
if (LLVMIsNull(elems[elem_idx])) {
elems[elem_idx] = to_set; // don't even bother doing `0 | to_set`
@@ -830,7 +947,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
bool is_local = cc.allow_local && m->curr_procedure != nullptr;
if (is_type_union(type) && is_type_union_constantable(type)) {
// A union constant needs a payload this backend can build, and the checker pins
// `variant_type` even for variants it cannot (`any` needs a backing global and a typeid),
// so ask the same question the aggregate constant paths ask.
if (is_type_union(type) && (is_type_union_constantable(type) ||
(value.variant_type != nullptr && elem_type_can_be_constant(value.variant_type)))) {
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_Union);
if (bt->Union.variants.count == 0) {
@@ -840,7 +961,11 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
Type *value_type = value.variant_type;
switch (value.kind) {
case ExactValue_Invalid:
return lb_const_nil(m, original_type);
// the zero value of a variant, e.g. a field omitted from a constant compound literal
if (value_type == nullptr || are_types_identical(value_type, original_type)) {
return lb_const_nil(m, original_type);
}
break;
case ExactValue_Compound: {
ast_node(cl, CompoundLit, value.value_compound);
@@ -1031,6 +1156,12 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
local_copy, alignment,
LLVMConstInt(lb_type(m, t_int), type_size_of(t), false)
);
} else if (LLVMIsALoadInst(backing_array.value) && LLVMIsAAllocaInst(LLVMGetOperand(backing_array.value, 0)) &&
LLVMGetFirstUse(backing_array.value) == nullptr) {
// NOTE(bill): the backing data was built in a local of its own which the slice uses rather than a copy of it
array_data = LLVMGetOperand(backing_array.value, 0);
LLVMSetAlignment(array_data, gb_max(LLVMGetAlignment(array_data), alignment));
LLVMInstructionEraseFromParent(backing_array.value);
} else {
array_data = llvm_alloca(p, LLVMTypeOf(backing_array.value), alignment);
LLVMBuildStore(p->builder, backing_array.value, array_data);
@@ -1207,8 +1338,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
isize len = value.value_string.len;
if (is_type_string16(res.type) || is_type_cstring16(res.type)) {
TEMPORARY_ALLOCATOR_GUARD();
String16 s16 = string_to_string16(temporary_allocator(), value.value_string);
String16 s16 = string_to_string16(permanent_allocator(), value.value_string);
len = s16.len;
ptr = lb_find_or_add_entity_string16_ptr(m, s16, custom_link_section);
} else {
@@ -1281,6 +1411,10 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
res.value = lb_big_int_to_llvm(m, original_type, &value.value_integer);
}
return res;
case ExactValue_Rational:
// Round the exact rational to the target float once, then emit as a float constant.
value = exact_value_to_float(value);
/*fallthrough*/
case ExactValue_Float:
if (is_type_different_to_arch_endianness(type)) {
if (type->Basic.kind == Basic_f32le || type->Basic.kind == Basic_f32be) {
@@ -1307,16 +1441,16 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
LLVMValueRef values[2] = {};
switch (8*type_size_of(type)) {
case 32:
values[0] = lb_const_f16(m, cast(f32)value.value_complex->real);
values[1] = lb_const_f16(m, cast(f32)value.value_complex->imag);
values[0] = lb_const_f16(m, cast(f32)exact_value_to_f64(value.value_complex->real));
values[1] = lb_const_f16(m, cast(f32)exact_value_to_f64(value.value_complex->imag));
break;
case 64:
values[0] = lb_const_f32(m, cast(f32)value.value_complex->real);
values[1] = lb_const_f32(m, cast(f32)value.value_complex->imag);
values[0] = lb_const_f32(m, cast(f32)exact_value_to_f64(value.value_complex->real));
values[1] = lb_const_f32(m, cast(f32)exact_value_to_f64(value.value_complex->imag));
break;
case 128:
values[0] = LLVMConstReal(lb_type(m, t_f64), value.value_complex->real);
values[1] = LLVMConstReal(lb_type(m, t_f64), value.value_complex->imag);
values[0] = LLVMConstReal(lb_type(m, t_f64), exact_value_to_f64(value.value_complex->real));
values[1] = LLVMConstReal(lb_type(m, t_f64), exact_value_to_f64(value.value_complex->imag));
break;
}
@@ -1330,24 +1464,24 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
switch (8*type_size_of(type)) {
case 64:
// @QuaternionLayout
values[3] = lb_const_f16(m, cast(f32)value.value_quaternion->real);
values[0] = lb_const_f16(m, cast(f32)value.value_quaternion->imag);
values[1] = lb_const_f16(m, cast(f32)value.value_quaternion->jmag);
values[2] = lb_const_f16(m, cast(f32)value.value_quaternion->kmag);
values[3] = lb_const_f16(m, cast(f32)exact_value_to_f64(value.value_quaternion->real));
values[0] = lb_const_f16(m, cast(f32)exact_value_to_f64(value.value_quaternion->imag));
values[1] = lb_const_f16(m, cast(f32)exact_value_to_f64(value.value_quaternion->jmag));
values[2] = lb_const_f16(m, cast(f32)exact_value_to_f64(value.value_quaternion->kmag));
break;
case 128:
// @QuaternionLayout
values[3] = lb_const_f32(m, cast(f32)value.value_quaternion->real);
values[0] = lb_const_f32(m, cast(f32)value.value_quaternion->imag);
values[1] = lb_const_f32(m, cast(f32)value.value_quaternion->jmag);
values[2] = lb_const_f32(m, cast(f32)value.value_quaternion->kmag);
values[3] = lb_const_f32(m, cast(f32)exact_value_to_f64(value.value_quaternion->real));
values[0] = lb_const_f32(m, cast(f32)exact_value_to_f64(value.value_quaternion->imag));
values[1] = lb_const_f32(m, cast(f32)exact_value_to_f64(value.value_quaternion->jmag));
values[2] = lb_const_f32(m, cast(f32)exact_value_to_f64(value.value_quaternion->kmag));
break;
case 256:
// @QuaternionLayout
values[3] = LLVMConstReal(lb_type(m, t_f64), value.value_quaternion->real);
values[0] = LLVMConstReal(lb_type(m, t_f64), value.value_quaternion->imag);
values[1] = LLVMConstReal(lb_type(m, t_f64), value.value_quaternion->jmag);
values[2] = LLVMConstReal(lb_type(m, t_f64), value.value_quaternion->kmag);
values[3] = LLVMConstReal(lb_type(m, t_f64), exact_value_to_f64(value.value_quaternion->real));
values[0] = LLVMConstReal(lb_type(m, t_f64), exact_value_to_f64(value.value_quaternion->imag));
values[1] = LLVMConstReal(lb_type(m, t_f64), exact_value_to_f64(value.value_quaternion->jmag));
values[2] = LLVMConstReal(lb_type(m, t_f64), exact_value_to_f64(value.value_quaternion->kmag));
break;
}
@@ -1949,6 +2083,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
bool *visited = gb_alloc_array(temporary_allocator(), bool, value_count);
if (cl->elems[0]->kind == Ast_FieldValue) {
lbConstAggregate *nested = gb_alloc_array(temporary_allocator(), lbConstAggregate, value_count);
isize elem_count = cl->elems.count;
for (isize i = 0; i < elem_count; i++) {
ast_node(fv, FieldValue, cl->elems[i]);
@@ -1970,6 +2106,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
GB_ASSERT_MSG(lb_sizeof(value_type) == type_size_of(f->type), "%s vs %s", LLVMPrintTypeToString(value_type), type_to_string(f->type));
values[index] = value.value;
visited[index] = true;
nested[index] = {};
} else {
if (!visited[index]) {
auto new_cc = cc;
@@ -2017,13 +2154,15 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
if (LLVMIsConstant(elem_value) && LLVMIsConstant(values[index])) {
if (is_type_union(cv_type) || is_type_raw_union(cv_type)) {
force_non_named = true;
values[index] = lb_const_aggregate_take(m, &nested[index], values[index]);
values[index] = llvm_const_insert_value_with_rebuild(m, values[index], elem_value, idx_list, idx_list_len);
} else {
values[index] = llvm_const_insert_value(m, values[index], elem_value, idx_list, idx_list_len);
lb_const_aggregate_insert(m, &nested[index], values[index], elem_value, idx_list, idx_list_len);
}
} else if (is_local) {
lbProcedure *p = m->curr_procedure;
GB_ASSERT(p != nullptr);
values[index] = lb_const_aggregate_take(m, &nested[index], values[index]);
LLVMTypeRef field_llvm_type = lb_type(m, f->type);
@@ -2048,13 +2187,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
LLVMValueRef dst = LLVMBuildGEP2(p->builder, field_llvm_type, ptr, indices, idx_list_len+1, "");
dst = LLVMBuildPointerCast(p->builder, dst, lb_type(m, alloc_type_pointer(tav.type)), "");
if (LLVMIsALoadInst(elem_value)) {
i64 sz = type_size_of(tav.type);
LLVMValueRef src = LLVMGetOperand(elem_value, 0);
lb_mem_copy_non_overlapping(p, {dst, t_rawptr}, {src, t_rawptr}, lb_const_int(m, t_int, sz), false);
} else {
LLVMBuildStore(p->builder, elem_value, dst);
}
lb_store_local_constant(p, dst, elem_value);
values[index] = LLVMBuildLoad2(p->builder, field_llvm_type, ptr, "");
@@ -2067,6 +2200,10 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
}
}
}
for (unsigned i = 0; i < value_count; i++) {
values[i] = lb_const_aggregate_take(m, &nested[i], values[i]);
}
} else {
isize multiple_return_offset = 0;
for_array(i, cl->elems) {
@@ -2140,15 +2277,7 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb
LLVMValueRef val = old_values[i];
if (!LLVMIsConstant(val)) {
LLVMValueRef dst = LLVMBuildStructGEP2(p->builder, llvm_addr_type(p->module, v.addr), v.addr.value, cast(unsigned)i, "");
// if (LLVMIsALoadInst(val)) {
// Type *ptr_type = v.addr.type;
// i64 sz = type_size_of(type_deref(ptr_type));
// LLVMValueRef src = LLVMGetOperand(val, 0);
// lb_mem_copy_non_overlapping(p, {dst, ptr_type}, {src, ptr_type}, lb_const_int(m, t_int, sz), false);
// } else {
LLVMBuildStore(p->builder, val, dst);
// }
lb_store_local_constant(p, dst, val);
}
}
return lb_addr_load(p, v);
+52 -14
View File
@@ -18,6 +18,21 @@ gb_internal void lb_set_llvm_metadata(lbModule *m, void *key, LLVMMetadataRef va
}
}
gb_internal LLVMMetadataRef lb_get_file_metadata(lbModule *m, AstFile *f) {
if (f == nullptr || m->debug_builder == nullptr) {
return nullptr;
}
MUTEX_GUARD(&m->debug_values_mutex);
LLVMMetadataRef res = lb_get_llvm_metadata(m, f);
if (res == nullptr) {
res = LLVMDIBuilderCreateFile(m->debug_builder,
cast(char const *)f->filename.text, f->filename.len,
cast(char const *)f->directory.text, f->directory.len);
lb_set_llvm_metadata(m, f, res);
}
return res;
}
gb_internal void lb_add_raddbg_string(lbModule *m, String const &str) {
mpsc_enqueue(&m->gen->raddebug_section_strings, copy_string(permanent_allocator(), str));
}
@@ -65,10 +80,12 @@ gb_internal LLVMMetadataRef lb_debug_end_location_from_ast(lbProcedure *p, Ast *
return lb_debug_location_from_token_pos(p, ast_end_token(node).pos);
}
gb_internal void lb_debug_file_line(lbModule *m, Ast *node, LLVMMetadataRef *file, unsigned *line) {
if (*file == nullptr) {
// NOTE(bill): not for an anonymous type, as identical ones are interchangeable, and which one is used
// (e.g. by a polymorphic instance) depends on the checking order
gb_internal void lb_debug_file_line(lbModule *m, Type *type, Ast *node, LLVMMetadataRef *file, unsigned *line) {
if (*file == nullptr && type->kind == Type_Named) {
if (node) {
*file = lb_get_llvm_metadata(m, node->file());
*file = lb_get_file_metadata(m, node->file());
*line = cast(unsigned)ast_token(node).pos.line;
}
}
@@ -172,7 +189,7 @@ gb_internal LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &nam
AstPackage *pkg = m->info->runtime_package;
GB_ASSERT(pkg->files.count != 0);
LLVMMetadataRef file = lb_get_llvm_metadata(m, pkg->files[0]);
LLVMMetadataRef file = lb_get_file_metadata(m, pkg->files[0]);
LLVMMetadataRef scope = file;
return LLVMDIBuilderCreateMemberType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, field_line,
@@ -183,7 +200,7 @@ gb_internal LLVMMetadataRef lb_debug_struct_field(lbModule *m, String const &nam
gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &name, u64 size_in_bits, u32 align_in_bits, LLVMMetadataRef *elements, unsigned element_count) {
AstPackage *pkg = m->info->runtime_package;
GB_ASSERT(pkg->files.count != 0);
LLVMMetadataRef file = lb_get_llvm_metadata(m, pkg->files[0]);
LLVMMetadataRef file = lb_get_file_metadata(m, pkg->files[0]);
LLVMMetadataRef scope = file;
return LLVMDIBuilderCreateStructType(m->debug_builder, scope, cast(char const *)name.text, name.len, file, 1, size_in_bits, align_in_bits, LLVMDIFlagZero, nullptr, elements, element_count, 0, nullptr, "", 0);
@@ -192,7 +209,7 @@ gb_internal LLVMMetadataRef lb_debug_basic_struct(lbModule *m, String const &nam
gb_internal LLVMMetadataRef lb_debug_struct(lbModule *m, Type *type, Type *bt, String name, LLVMMetadataRef scope, LLVMMetadataRef file, unsigned line) {
GB_ASSERT(bt->kind == Type_Struct);
lb_debug_file_line(m, bt->Struct.node, &file, &line);
lb_debug_file_line(m, type, bt->Struct.node, &file, &line);
unsigned tag = DW_TAG_structure_type;
if (is_type_raw_union(bt)) {
@@ -476,7 +493,7 @@ gb_internal LLVMMetadataRef lb_debug_union(lbModule *m, Type *type, String name,
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_Union);
lb_debug_file_line(m, bt->Union.node, &file, &line);
lb_debug_file_line(m, type, bt->Union.node, &file, &line);
u64 size_in_bits = 8*type_size_of(bt);
u32 align_in_bits = 8*cast(u32)type_align_of(bt);
@@ -560,7 +577,7 @@ gb_internal LLVMMetadataRef lb_debug_bitset(lbModule *m, Type *type, String name
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_BitSet);
lb_debug_file_line(m, bt->BitSet.node, &file, &line);
lb_debug_file_line(m, type, bt->BitSet.node, &file, &line);
u64 size_in_bits = 8*type_size_of(bt);
u32 align_in_bits = 8*cast(u32)type_align_of(bt);
@@ -641,7 +658,7 @@ gb_internal LLVMMetadataRef lb_debug_bitfield(lbModule *m, Type *type, String na
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_BitField);
lb_debug_file_line(m, bt->BitField.node, &file, &line);
lb_debug_file_line(m, type, bt->BitField.node, &file, &line);
u64 size_in_bits = 8*type_size_of(bt);
u32 align_in_bits = 8*cast(u32)type_align_of(bt);
@@ -682,7 +699,7 @@ gb_internal LLVMMetadataRef lb_debug_enum(lbModule *m, Type *type, String name,
Type *bt = base_type(type);
GB_ASSERT(bt->kind == Type_Enum);
lb_debug_file_line(m, bt->Enum.node, &file, &line);
lb_debug_file_line(m, type, bt->Enum.node, &file, &line);
u64 size_in_bits = 8*type_size_of(bt);
u32 align_in_bits = 8*cast(u32)type_align_of(bt);
@@ -1117,7 +1134,7 @@ gb_internal LLVMMetadataRef lb_get_base_scope_metadata(lbModule *m, Scope *scope
}
}
if (scope->flags & ScopeFlag_File) {
found = lb_get_llvm_metadata(m, scope->file);
found = lb_get_file_metadata(m, scope->file);
if (found) {
return found;
}
@@ -1189,6 +1206,25 @@ gb_internal LLVMMetadataRef lb_debug_type(lbModule *m, Type *type) {
return dt;
}
// A variable whose address is not a stack slot of its own (an argument, or an element or a pointer it refers to)
// would have its location tracked with `DBG_VALUE`s through every block of the procedure,
// so it is described through a stack slot holding that address instead
gb_internal LLVMValueRef lb_debug_storage(lbProcedure *p, LLVMValueRef storage, LLVMMetadataRef *expr) {
bool is_argument = LLVMIsAArgument(storage) != nullptr;
if (!is_argument && (!LLVMIsAInstruction(storage) || LLVMIsAAllocaInst(storage))) {
return storage;
}
LLVMBasicBlockRef insert_block = LLVMGetInsertBlock(p->builder);
LLVMValueRef slot = llvm_alloca(p, LLVMTypeOf(storage), build_context.ptr_size, "");
LLVMPositionBuilderAtEnd(p->builder, is_argument ? p->decl_block->block : insert_block);
LLVMBuildStore(p->builder, storage, slot);
LLVMPositionBuilderAtEnd(p->builder, insert_block);
uint64_t deref = 0x06; // DW_OP_deref
*expr = LLVMDIBuilderCreateExpression(p->module->debug_builder, &deref, 1);
return slot;
}
gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, Type *type, Token const &token) {
if (p->debug_info == nullptr) {
return;
@@ -1217,7 +1253,7 @@ gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, T
AstFile *file = p->body->file();
LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p);
LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file);
LLVMMetadataRef llvm_file = lb_get_file_metadata(m, file);
GB_ASSERT(llvm_scope != nullptr);
if (llvm_file == nullptr) {
llvm_file = LLVMDIScopeGetFile(llvm_scope);
@@ -1247,6 +1283,7 @@ gb_internal void lb_add_debug_local_variable(lbProcedure *p, LLVMValueRef ptr, T
LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos);
LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
lb_set_llvm_metadata(m, ptr, llvm_expr);
storage = lb_debug_storage(p, storage, &llvm_expr);
#if LLVM_VERSION_MAJOR <= 18
LLVMDIBuilderInsertDeclareAtEnd(m->debug_builder, storage, var_info, llvm_expr, llvm_debug_loc, block);
@@ -1284,7 +1321,7 @@ gb_internal void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, T
AstFile *file = p->body->file();
LLVMMetadataRef llvm_scope = lb_get_current_debug_scope(p);
LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file);
LLVMMetadataRef llvm_file = lb_get_file_metadata(m, file);
GB_ASSERT(llvm_scope != nullptr);
if (llvm_file == nullptr) {
llvm_file = LLVMDIScopeGetFile(llvm_scope);
@@ -1312,6 +1349,7 @@ gb_internal void lb_add_debug_param_variable(lbProcedure *p, LLVMValueRef ptr, T
LLVMMetadataRef llvm_debug_loc = lb_debug_location_from_token_pos(p, token.pos);
LLVMMetadataRef llvm_expr = LLVMDIBuilderCreateExpression(m->debug_builder, nullptr, 0);
lb_set_llvm_metadata(m, ptr, llvm_expr);
storage = lb_debug_storage(p, storage, &llvm_expr);
// NOTE(bill, 2022-02-01): For parameter values, you must insert them at the end of the decl block
// The reason is that if the parameter is at index 0 and a pointer, there is not such things as an
@@ -1477,7 +1515,7 @@ gb_internal void lb_add_debug_label(lbProcedure *p, Ast *label, lbBlock *target)
}
AstFile *file = label->file();
LLVMMetadataRef llvm_file = lb_get_llvm_metadata(m, file);
LLVMMetadataRef llvm_file = lb_get_file_metadata(m, file);
if (llvm_file == nullptr) {
debugf("llvm file not found for label\n");
return;
Loaded 100 of 187 files, more files were not shown because too many files have changed in this diff. Show more