singeli
This commit is contained in:
parent
f50b8ab503
commit
71c454235c
9
.gitignore
vendored
9
.gitignore
vendored
@ -1,5 +1,6 @@
|
|||||||
BQN
|
/BQN
|
||||||
c.bqn
|
|
||||||
perf.*
|
perf.*
|
||||||
obj/
|
/obj/
|
||||||
asm_*
|
/asm_*
|
||||||
|
/src/singeli/gen
|
||||||
|
/Singeli/
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "SingeliClone"]
|
||||||
|
path = SingeliClone
|
||||||
|
url = https://github.com/mlochbaum/Singeli
|
||||||
1
SingeliClone
Submodule
1
SingeliClone
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 3c474f3ce8ba38e48f51a33c305168cda79fc74c
|
||||||
18
SingeliMake.bqn
Executable file
18
SingeliMake.bqn
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
# •Show •args
|
||||||
|
|
||||||
|
# resolve arguments & files
|
||||||
|
siDirR‿srcfileR‿resfileR‿buildDir ← •args
|
||||||
|
siDir ← •file.At siDirR
|
||||||
|
tmpfile ← •file.At "obj/singeliDeps"
|
||||||
|
srcfile ← •file.At srcfileR
|
||||||
|
resfile ← •file.At resfileR
|
||||||
|
depfile ← (•file.At buildDir) •file.At ".d"∾˜ (⊐⟜'/'↑⊢)⌾⌽ srcfile
|
||||||
|
|
||||||
|
# invoke singeli, which creates the result file
|
||||||
|
(⟨"-d" ⋄ tmpfile ⋄ "-o" ⋄ resfile ⋄ srcfile⟩) •Import siDir •file.At "singeli"
|
||||||
|
|
||||||
|
# output dependency file
|
||||||
|
deps ← siDir⊸•file.At¨ •file.Lines tmpfile
|
||||||
|
lnln ← @+10‿10
|
||||||
|
depfile •file.Chars ∾⟨resfileR ⋄ ": " ⋄ srcfile ⋄ ∾' '⊸∾¨deps ⋄ lnln ⋄ ∾ ∾⟜(":"∾lnln)¨ deps⟩
|
||||||
|
|
||||||
138
makefile
138
makefile
@ -2,40 +2,55 @@ SHELL = /usr/bin/env bash
|
|||||||
MAKEFLAGS+= --no-print-directory
|
MAKEFLAGS+= --no-print-directory
|
||||||
|
|
||||||
o3:
|
o3:
|
||||||
@${MAKE} t=o3 b
|
@${MAKE} singeli=0 t=o3 f="-O3" c
|
||||||
o3g:
|
o3g:
|
||||||
@${MAKE} t=o3g b
|
@${MAKE} singeli=0 t=o3g f="-O3 -g" c
|
||||||
o3n:
|
o3n:
|
||||||
@${MAKE} t=o3n b
|
@${MAKE} singeli=0 t=o3n f="-O3 -march=native" c
|
||||||
rtperf:
|
|
||||||
@${MAKE} t=rtperf b
|
|
||||||
rtverify:
|
|
||||||
@${MAKE} t=rtverify b
|
|
||||||
debug:
|
debug:
|
||||||
@${MAKE} t=debug b
|
@${MAKE} singeli=0 t=debug f="-g -DDEBUG" c
|
||||||
debug1:
|
debug1:
|
||||||
@${MAKE} t=debug1 b
|
@${MAKE} singeli=0 t=debug1 f="-g -DDEBUG" c
|
||||||
|
rtperf:
|
||||||
|
@${MAKE} singeli=0 t=rtperf f="-O3 -DRT_PERF" c
|
||||||
|
rtverify:
|
||||||
|
@${MAKE} singeli=0 t=rtverify f="-DDEBUG -O3 -DRT_VERIFY" c
|
||||||
heapverify:
|
heapverify:
|
||||||
@${MAKE} t=heapverify b
|
@${MAKE} singeli=0 t=heapverify f="-DDEBUG -g -DHEAP_VERIFY" c
|
||||||
|
o3n-singeli:
|
||||||
|
@${MAKE} singeli=1 t=o3n_si f="-O3 -march=native" c
|
||||||
|
debugn-singeli:
|
||||||
|
@${MAKE} singeli=1 t=debugn_si f="-g -DDEBUG -march=native" c
|
||||||
|
debug-singeli:
|
||||||
|
@${MAKE} singeli=1 t=debug_si f="-g -DDEBUG" c
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bd = obj/${t}
|
||||||
|
|
||||||
c: # custom
|
c: # custom
|
||||||
@${MAKE} t=${t} FLAGS.${t}="${f}" b
|
@mkdir -p ${bd}
|
||||||
|
@if [ "${singeli}" -eq 1 ]; then \
|
||||||
b: gen
|
mkdir -p src/singeli/gen; \
|
||||||
|
${MAKE} gen-singeli; \
|
||||||
PIE = -no-pie
|
echo "post-singeli build:"; \
|
||||||
|
fi
|
||||||
|
@${MAKE} t=${t} FLAGS="${f}" gen
|
||||||
|
|
||||||
single-o3:
|
single-o3:
|
||||||
$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) ${PIE} $(f) -O3 -o BQN src/opt/single.c -lm
|
$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) $(PIE) $(f) -O3 -o BQN src/opt/single.c -lm
|
||||||
single-o3g:
|
single-o3g:
|
||||||
$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) ${PIE} $(f) -O3 -g -o BQN src/opt/single.c -lm
|
$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) $(PIE) $(f) -O3 -g -o BQN src/opt/single.c -lm
|
||||||
single-debug:
|
single-debug:
|
||||||
$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) ${PIE} $(f) -DDEBUG -g -o BQN src/opt/single.c -lm
|
$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) $(PIE) $(f) -DDEBUG -g -o BQN src/opt/single.c -lm
|
||||||
single-c:
|
single-c:
|
||||||
$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) ${PIE} $(f) -o BQN src/opt/single.c -lm
|
$(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) $(PIE) $(f) -o BQN src/opt/single.c -lm
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# compiler setup
|
# compiler setup
|
||||||
CC = clang
|
CC = clang
|
||||||
|
PIE = -no-pie
|
||||||
|
|
||||||
# Detects if we are running GCC instead of Clang
|
# Detects if we are running GCC instead of Clang
|
||||||
CC_IS_GCC = $(shell $(CC) --version | head -n1 | grep -m 1 -c "gcc")
|
CC_IS_GCC = $(shell $(CC) --version | head -n1 | grep -m 1 -c "gcc")
|
||||||
@ -44,84 +59,105 @@ CCFLAGS = -Wno-parentheses
|
|||||||
else
|
else
|
||||||
CCFLAGS = -Wno-microsoft-anon-tag
|
CCFLAGS = -Wno-microsoft-anon-tag
|
||||||
endif
|
endif
|
||||||
CMD = $(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions ${CCFLAGS} $(FLAGS) -fPIE -MMD -MP -MF
|
ifeq (${singeli}, 1)
|
||||||
|
SINGELIFLAGS = '-DSINGELI'
|
||||||
|
else
|
||||||
|
singeli = 0
|
||||||
|
endif
|
||||||
|
CMD = $(CC) -std=gnu11 -Wall -Wno-unused-function -fms-extensions $(CCFLAGS) $(FLAGS) $(SINGELIFLAGS) -fPIE -MMD -MP -MF
|
||||||
|
|
||||||
# `if` to allow `make clean` alone to clean everything, but `make t=debug clean` to just clean obj/debug
|
# `if` to allow `make clean` alone to clean everything, but `make t=debug clean` to just clean obj/debug
|
||||||
ifeq ($(MAKECMDGOALS),clean)
|
ifeq ($(MAKECMDGOALS),clean)
|
||||||
|
ifndef t
|
||||||
t = *
|
t = *
|
||||||
else ifeq ($(t),)
|
endif
|
||||||
t = o3
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (${t},debug1)
|
ifneq (${t},debug1)
|
||||||
# don't make makefile cry about something idk
|
ifneq (${J4added},yes)
|
||||||
ifeq (${MAKECMDGOALS},b)
|
ifeq (${MAKECMDGOALS},gen)
|
||||||
MAKEFLAGS += -j4
|
MAKEFLAGS+= -j4 J4added=yes
|
||||||
endif
|
endif
|
||||||
|
ifeq (${MAKECMDGOALS},gen-singeli)
|
||||||
|
MAKEFLAGS+= -j4 J4added=yes
|
||||||
|
endif
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# per-type flags
|
|
||||||
FLAGS.o3 := -O3
|
|
||||||
FLAGS.o3n := -O3 -march=native
|
|
||||||
FLAGS.o3g := -O3 -g
|
|
||||||
FLAGS.debug := -g -DDEBUG
|
|
||||||
FLAGS.debug1 := -g -DDEBUG
|
|
||||||
FLAGS.rtperf := -O3 -DRT_PERF
|
|
||||||
FLAGS.heapverify := -DDEBUG -g -DHEAP_VERIFY
|
|
||||||
FLAGS.rtverify := -DDEBUG -O3 -DRT_VERIFY
|
|
||||||
FLAGS = ${FLAGS.${t}}
|
|
||||||
bd = obj/${t}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gen: builtins core base jit utils # build the final binary
|
gen: builtins core base jit utils # build the final binary
|
||||||
@$(CC) ${PIE} -o BQN ${bd}/*.o -lm
|
@$(CC) ${PIE} -o BQN ${bd}/*.o -lm
|
||||||
@echo
|
@echo ${postmsg}
|
||||||
|
|
||||||
builddir: # create the build directory. makefiles are stupid
|
|
||||||
@mkdir -p ${bd}
|
|
||||||
|
|
||||||
# build individual object files
|
# build individual object files
|
||||||
core: builddir ${addprefix ${bd}/, tyarr.o harr.o fillarr.o stuff.o derv.o mm.o heap.o}
|
core: ${addprefix ${bd}/, tyarr.o harr.o fillarr.o stuff.o derv.o mm.o heap.o}
|
||||||
${bd}/%.o: src/core/%.c
|
${bd}/%.o: src/core/%.c
|
||||||
@echo $< | cut -c 5-
|
@echo $< | cut -c 5-
|
||||||
@$(CMD) $@.d -o $@ -c $<
|
@$(CMD) $@.d -o $@ -c $<
|
||||||
|
|
||||||
base: builddir ${addprefix ${bd}/, load.o main.o rtwrap.o vm.o ns.o nfns.o}
|
base: ${addprefix ${bd}/, load.o main.o rtwrap.o vm.o ns.o nfns.o}
|
||||||
${bd}/%.o: src/%.c
|
${bd}/%.o: src/%.c
|
||||||
@echo $< | cut -c 5-
|
@echo $< | cut -c 5-
|
||||||
@$(CMD) $@.d -o $@ -c $<
|
@$(CMD) $@.d -o $@ -c $<
|
||||||
|
|
||||||
utils: builddir ${addprefix ${bd}/, utf.o hash.o file.o mut.o each.o bits.o}
|
utils: ${addprefix ${bd}/, utf.o hash.o file.o mut.o each.o bits.o}
|
||||||
${bd}/%.o: src/utils/%.c
|
${bd}/%.o: src/utils/%.c
|
||||||
@echo $< | cut -c 5-
|
@echo $< | cut -c 5-
|
||||||
@$(CMD) $@.d -o $@ -c $<
|
@$(CMD) $@.d -o $@ -c $<
|
||||||
|
|
||||||
jit: builddir ${addprefix ${bd}/, nvm.o}
|
jit: ${addprefix ${bd}/, nvm.o}
|
||||||
${bd}/%.o: src/jit/%.c
|
${bd}/%.o: src/jit/%.c
|
||||||
@echo $< | cut -c 5-
|
@echo $< | cut -c 5-
|
||||||
@$(CMD) $@.d -o $@ -c $<
|
@$(CMD) $@.d -o $@ -c $<
|
||||||
|
|
||||||
builtins: builddir ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o sort.o md1.o md2.o fns.o sysfn.o internal.o}
|
builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o sort.o md1.o md2.o fns.o sysfn.o internal.o}
|
||||||
${bd}/%.o: src/builtins/%.c
|
${bd}/%.o: src/builtins/%.c
|
||||||
@echo $< | cut -c 5-
|
@echo $< | cut -c 5-
|
||||||
@$(CMD) $@.d -o $@ -c $<
|
@$(CMD) $@.d -o $@ -c $<
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
src/gen/customRuntime:
|
src/gen/customRuntime:
|
||||||
@echo "Copying precompiled bytecode from the bytecode branch"
|
@echo "Copying precompiled bytecode from the bytecode branch"
|
||||||
git checkout remotes/origin/bytecode src/gen/{compiler,formatter,runtime0,runtime1,src}
|
git checkout remotes/origin/bytecode src/gen/{compiler,formatter,runtime0,runtime1,src}
|
||||||
git reset src/gen/{compiler,formatter,runtime0,runtime1,src}
|
git reset src/gen/{compiler,formatter,runtime0,runtime1,src}
|
||||||
${bd}/load.o: src/gen/customRuntime
|
${bd}/load.o: src/gen/customRuntime
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# singeli
|
||||||
|
.INTERMEDIATE: preSingeliBin
|
||||||
|
preSingeliBin:
|
||||||
|
@if [ ! -d Singeli ]; then \
|
||||||
|
echo "Updating Singeli submodule; link custom Singeli to Singeli/ to avoid"; \
|
||||||
|
git submodule update --init; \
|
||||||
|
fi
|
||||||
|
@echo "pre-singeli build:"
|
||||||
|
@${MAKE} singeli=0 postmsg="singeli sources:" t=presingeli f='' c
|
||||||
|
@mv BQN obj/presingeli/BQN
|
||||||
|
|
||||||
|
|
||||||
|
gen-singeli: ${addprefix src/singeli/gen/, cmp.c}
|
||||||
|
@:
|
||||||
|
src/singeli/gen/%.c: src/singeli/src/%.singeli preSingeliBin
|
||||||
|
@echo $< | cut -c 17- | sed 's/^/ /'
|
||||||
|
@obj/presingeli/BQN SingeliMake.bqn "$$(if [ -d Singeli ]; then echo Singeli; else echo SingeliClone; fi)" $< $@ "${bd}"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# dependency files
|
||||||
-include $(bd)/*.d
|
-include $(bd)/*.d
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
clean-singeli:
|
||||||
|
rm -rf src/singeli/gen/
|
||||||
|
|
||||||
|
ifeq ($(t), *)
|
||||||
|
clean: clean-singeli
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f ${bd}/*.o
|
rm -f ${bd}/*.o
|
||||||
rm -f ${bd}/*.d
|
rm -f ${bd}/*.d
|
||||||
|
|||||||
@ -1,35 +1,16 @@
|
|||||||
#include "../core.h"
|
#include "../core.h"
|
||||||
#include "../utils/each.h"
|
#include "../utils/each.h"
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#define P2(N) { if (isArr(w)|isArr(x)) { \
|
#define P2(N) { if (isArr(w)|isArr(x)) { \
|
||||||
SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("cmp " #N, w, x); \
|
SLOWIF((!isArr(w) || TI(w,elType)!=el_B) && (!isArr(x) || TI(x,elType)!=el_B)) SLOW2("cmp " #N, w, x); \
|
||||||
return arith_recd(N##_c2, w, x); \
|
return arith_recd(N##_c2, w, x); \
|
||||||
}}
|
}}
|
||||||
|
|
||||||
#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=a(r)->ia; usz bia = BIT_N(ria);
|
#define AL(X) u64* rp; B r = m_bitarrc(&rp, X); usz ria=a(r)->ia; usz bia = BIT_N(ria);
|
||||||
|
|
||||||
static NOINLINE u8 aMakeEq(B* w, B* x, u8 we, u8 xe) { // returns el_MAX if failed
|
#if SINGELI
|
||||||
B s = we<xe?*w:*x;
|
#include "../singeli/builtins/cmp.c"
|
||||||
u8 me = we>xe?we:xe;
|
#else
|
||||||
if (elNum(we) & elNum(xe)) {
|
#define CMP_IMPL(CHR, NAME, RNAME, OP, FC, CF, BX) \
|
||||||
switch(me) { default: UD;
|
|
||||||
case el_i8: s = taga(cpyI8Arr (s)); break;
|
|
||||||
case el_i16: s = taga(cpyI16Arr(s)); break;
|
|
||||||
case el_i32: s = taga(cpyI32Arr(s)); break;
|
|
||||||
case el_f64: s = taga(cpyF64Arr(s)); break;
|
|
||||||
}
|
|
||||||
} else if (elChr(we) & elChr(xe)) {
|
|
||||||
switch(me) { default: UD;
|
|
||||||
case el_c16: s = taga(cpyC16Arr(s)); break;
|
|
||||||
case el_c32: s = taga(cpyC32Arr(s)); break;
|
|
||||||
}
|
|
||||||
} else return el_MAX;
|
|
||||||
*(we<xe?w:x) = s;
|
|
||||||
return me;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CMP_IMPL(CHR, OP, FC, CF, BX) \
|
|
||||||
if (isF64(w)&isF64(x)) return m_i32(w.f OP x.f); \
|
if (isF64(w)&isF64(x)) return m_i32(w.f OP x.f); \
|
||||||
if (isC32(w)&isC32(x)) return m_i32(w.u OP x.u); \
|
if (isC32(w)&isC32(x)) return m_i32(w.u OP x.u); \
|
||||||
if (isF64(w)&isC32(x)) return m_i32(FC); \
|
if (isF64(w)&isC32(x)) return m_i32(FC); \
|
||||||
@ -84,34 +65,57 @@ static NOINLINE u8 aMakeEq(B* w, B* x, u8 we, u8 xe) { // returns el_MAX if fail
|
|||||||
dec(r); \
|
dec(r); \
|
||||||
} \
|
} \
|
||||||
end:;
|
end:;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CMP(CHR,NAME,OP,FC,CF,BX) \
|
|
||||||
B NAME##_c2(B t, B w, B x) { \
|
static NOINLINE u8 aMakeEq(B* w, B* x, u8 we, u8 xe) { // returns el_MAX if failed
|
||||||
CMP_IMPL(CHR, OP, FC, CF, BX); \
|
B s = we<xe?*w:*x;
|
||||||
P2(NAME); \
|
u8 me = we>xe?we:xe;
|
||||||
return m_i32(compare(w, x) OP 0); \
|
if (elNum(we) & elNum(xe)) {
|
||||||
|
switch(me) { default: UD;
|
||||||
|
case el_i8: s = taga(cpyI8Arr (s)); break;
|
||||||
|
case el_i16: s = taga(cpyI16Arr(s)); break;
|
||||||
|
case el_i32: s = taga(cpyI32Arr(s)); break;
|
||||||
|
case el_f64: s = taga(cpyF64Arr(s)); break;
|
||||||
|
}
|
||||||
|
} else if (elChr(we) & elChr(xe)) {
|
||||||
|
switch(me) { default: UD;
|
||||||
|
case el_c16: s = taga(cpyC16Arr(s)); break;
|
||||||
|
case el_c32: s = taga(cpyC32Arr(s)); break;
|
||||||
|
}
|
||||||
|
} else return el_MAX;
|
||||||
|
*(we<xe?w:x) = s;
|
||||||
|
return me;
|
||||||
}
|
}
|
||||||
CMP("≤", le, <=, 1, 0, ~wv | xv)
|
|
||||||
CMP("≥", ge, >=, 0, 1, wv | ~xv)
|
#define CMP(CHR,NAME,RNAME,OP,FC,CF,BX) \
|
||||||
CMP("<", lt, < , 1, 0, ~wv & xv)
|
B NAME##_c2(B t, B w, B x) { \
|
||||||
CMP(">", gt, > , 0, 1, wv & ~xv)
|
CMP_IMPL(CHR,NAME,RNAME,OP,FC,CF,BX); \
|
||||||
|
P2(NAME); \
|
||||||
|
return m_i32(compare(w, x) OP 0); \
|
||||||
|
}
|
||||||
|
CMP("≤", le, ge, <=, 1, 0, ~wv | xv)
|
||||||
|
CMP("≥", ge, le, >=, 0, 1, wv | ~xv)
|
||||||
|
CMP("<", lt, gt, < , 1, 0, ~wv & xv)
|
||||||
|
CMP(">", gt, lt, > , 0, 1, wv & ~xv)
|
||||||
#undef CMP
|
#undef CMP
|
||||||
|
|
||||||
B eq_c2(B t, B w, B x) {
|
B eq_c2(B t, B w, B x) {
|
||||||
CMP_IMPL("=", ==, 0, 0, ~wv^xv);
|
CMP_IMPL("=", eq, eq, ==, 0, 0, ~wv^xv);
|
||||||
P2(eq);
|
P2(eq);
|
||||||
B r = m_i32(atomEqual(w, x));
|
B r = m_i32(atomEqual(w, x));
|
||||||
dec(w); dec(x);
|
dec(w); dec(x);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
B ne_c2(B t, B w, B x) {
|
B ne_c2(B t, B w, B x) {
|
||||||
CMP_IMPL("≠", !=, 1, 1, wv^xv);
|
CMP_IMPL("≠", ne, ne, !=, 1, 1, wv^xv);
|
||||||
P2(ne);
|
P2(ne);
|
||||||
B r = m_i32(!atomEqual(w, x));
|
B r = m_i32(!atomEqual(w, x));
|
||||||
dec(w); dec(x);
|
dec(w); dec(x);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern B rt_merge;
|
extern B rt_merge;
|
||||||
B gt_c1(B t, B x) {
|
B gt_c1(B t, B x) {
|
||||||
if (isAtm(x)) return x;
|
if (isAtm(x)) return x;
|
||||||
|
|||||||
88
src/singeli/builtins/cmp.c
Normal file
88
src/singeli/builtins/cmp.c
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||||
|
#include "../gen/cmp.c"
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
#define avx2_eqAA_u8( d,w,x,l) avx2_eqAA_i8 (d,(i8 *)(w),(i8 *)(x),l)
|
||||||
|
#define avx2_eqAA_u16(d,w,x,l) avx2_eqAA_i16(d,(i16*)(w),(i16*)(x),l)
|
||||||
|
#define avx2_eqAA_u32(d,w,x,l) avx2_eqAA_i32(d,(i32*)(w),(i32*)(x),l)
|
||||||
|
#define avx2_neAA_u8( d,w,x,l) avx2_neAA_i8 (d,(i8 *)(w),(i8 *)(x),l)
|
||||||
|
#define avx2_neAA_u16(d,w,x,l) avx2_neAA_i16(d,(i16*)(w),(i16*)(x),l)
|
||||||
|
#define avx2_neAA_u32(d,w,x,l) avx2_neAA_i32(d,(i32*)(w),(i32*)(x),l)
|
||||||
|
#define avx2_eqAS_u8( d,w,x,l) avx2_eqAS_i8 (d,(i8 *)(w),x,l)
|
||||||
|
#define avx2_eqAS_u16(d,w,x,l) avx2_eqAS_i16(d,(i16*)(w),x,l)
|
||||||
|
#define avx2_eqAS_u32(d,w,x,l) avx2_eqAS_i32(d,(i32*)(w),x,l)
|
||||||
|
#define avx2_neAS_u8( d,w,x,l) avx2_neAS_i8 (d,(i8 *)(w),x,l)
|
||||||
|
#define avx2_neAS_u16(d,w,x,l) avx2_neAS_i16(d,(i16*)(w),x,l)
|
||||||
|
#define avx2_neAS_u32(d,w,x,l) avx2_neAS_i32(d,(i32*)(w),x,l)
|
||||||
|
|
||||||
|
#define avx2_ltAA_i8(d,w,x,l) avx2_gtAA_i8(d,x,w,l)
|
||||||
|
#define avx2_leAA_i8(d,w,x,l) avx2_geAA_i8(d,x,w,l)
|
||||||
|
#define avx2_ltAA_i16(d,w,x,l) avx2_gtAA_i16(d,x,w,l)
|
||||||
|
#define avx2_leAA_i16(d,w,x,l) avx2_geAA_i16(d,x,w,l)
|
||||||
|
#define avx2_ltAA_i32(d,w,x,l) avx2_gtAA_i32(d,x,w,l)
|
||||||
|
#define avx2_leAA_i32(d,w,x,l) avx2_geAA_i32(d,x,w,l)
|
||||||
|
#define avx2_leAA_u8( d,w,x,l) avx2_geAA_u8 (d,x,w,l)
|
||||||
|
#define avx2_leAA_u16(d,w,x,l) avx2_geAA_u16(d,x,w,l)
|
||||||
|
#define avx2_leAA_u32(d,w,x,l) avx2_geAA_u32(d,x,w,l)
|
||||||
|
#define avx2_ltAA_u8( d,w,x,l) avx2_gtAA_u8 (d,x,w,l)
|
||||||
|
#define avx2_ltAA_u16(d,w,x,l) avx2_gtAA_u16(d,x,w,l)
|
||||||
|
#define avx2_ltAA_u32(d,w,x,l) avx2_gtAA_u32(d,x,w,l)
|
||||||
|
#define avx2_ltAA_f64(d,w,x,l) avx2_gtAA_f64(d,x,w,l)
|
||||||
|
#define avx2_leAA_f64(d,w,x,l) avx2_geAA_f64(d,x,w,l)
|
||||||
|
|
||||||
|
#define CMP_IMPL(CHR, NAME, RNAME, OP, FC, CF, BX) \
|
||||||
|
if (isF64(w)&isF64(x)) return m_i32(w.f OP x.f); \
|
||||||
|
if (isC32(w)&isC32(x)) return m_i32(w.u OP x.u); \
|
||||||
|
if (isF64(w)&isC32(x)) return m_i32(FC); \
|
||||||
|
if (isC32(w)&isF64(x)) return m_i32(CF); \
|
||||||
|
if (isArr(w)) { u8 we = TI(w,elType); \
|
||||||
|
if (we==el_B) goto end; \
|
||||||
|
if (isArr(x)) { u8 xe = TI(x,elType); \
|
||||||
|
if (xe==el_B) goto end; \
|
||||||
|
if (rnk(w)==rnk(x)) { if (!eqShape(w, x)) thrF(CHR": Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); \
|
||||||
|
if (we!=xe) { B tw=w,tx=x; \
|
||||||
|
we = aMakeEq(&tw, &tx, we, xe); \
|
||||||
|
if (we==el_MAX) goto end; \
|
||||||
|
w=tw; x=tx; \
|
||||||
|
} \
|
||||||
|
AL(x) \
|
||||||
|
switch(we) { default: UD; \
|
||||||
|
case el_bit: { u64* wp=bitarr_ptr(w); u64* xp=bitarr_ptr(x); for(usz i=0;i<bia;i++) { u64 wv=wp[i]; u64 xv=xp[i]; rp[i]=BX; } break; } \
|
||||||
|
case el_i8: avx2_##NAME##AA_i8 (rp, i8any_ptr (w), i8any_ptr (x), ria); break; \
|
||||||
|
case el_i16: avx2_##NAME##AA_i16(rp, i16any_ptr(w), i16any_ptr(x), ria); break; \
|
||||||
|
case el_i32: avx2_##NAME##AA_i32(rp, i32any_ptr(w), i32any_ptr(x), ria); break; \
|
||||||
|
case el_f64: avx2_##NAME##AA_f64(rp, f64any_ptr(w), f64any_ptr(x), ria); break; \
|
||||||
|
case el_c8: avx2_##NAME##AA_u8 (rp, c8any_ptr (w), c8any_ptr (x), ria); break; \
|
||||||
|
case el_c16: avx2_##NAME##AA_u16(rp, c16any_ptr(w), c16any_ptr(x), ria); break; \
|
||||||
|
case el_c32: avx2_##NAME##AA_i32(rp, (i32*)c32any_ptr(w), (i32*)c32any_ptr(x), ria); break; \
|
||||||
|
} \
|
||||||
|
dec(w);dec(x); return r; \
|
||||||
|
} \
|
||||||
|
} else { AL(w) \
|
||||||
|
switch(we) { default: UD; \
|
||||||
|
case el_bit: { if (!q_bit(x)) break; u64 xv=bitx(x); u64* wp=bitarr_ptr(w); for(usz i=0;i<bia;i++) { u64 wv=wp[i]; rp[i]=BX; } dec(w); return r; } \
|
||||||
|
case el_i8: if (!q_i8 (x))break; avx2_##NAME##AS_i8 (rp, i8any_ptr (w), o2iu(x), ria); dec(w); return r; \
|
||||||
|
case el_i16: if (!q_i16(x))break; avx2_##NAME##AS_i16(rp, i16any_ptr(w), o2iu(x), ria); dec(w); return r; \
|
||||||
|
case el_i32: if (!q_i32(x))break; avx2_##NAME##AS_i32(rp, i32any_ptr(w), o2iu(x), ria); dec(w); return r; \
|
||||||
|
case el_f64: if (!q_f64(x))break; avx2_##NAME##AS_f64(rp, f64any_ptr(w), o2fu(x), ria); dec(w); return r; \
|
||||||
|
case el_c8: if (!q_c8 (x))break; avx2_##NAME##AS_u8 (rp, c8any_ptr (w), o2cu(x), ria); dec(w); return r; \
|
||||||
|
case el_c16: if (!q_c16(x))break; avx2_##NAME##AS_u16(rp, c16any_ptr(w), o2cu(x), ria); dec(w); return r; \
|
||||||
|
case el_c32: if (!q_c32(x))break; avx2_##NAME##AS_i32(rp, (i32*)c32any_ptr(w), o2cu(x), ria); dec(w); return r; \
|
||||||
|
} \
|
||||||
|
dec(r); \
|
||||||
|
} \
|
||||||
|
} else if (isArr(x)) { u8 xe = TI(x,elType); if (xe==el_B) goto end; AL(x) \
|
||||||
|
switch(xe) { default: UD; \
|
||||||
|
case el_bit: { if (!q_bit(w)) break; u64 wv=bitx(w); u64* xp=bitarr_ptr(x); for(usz i=0;i<bia;i++) { u64 xv=xp[i]; rp[i]=BX; } dec(x); return r; } \
|
||||||
|
case el_i8: if (!q_i8 (w))break; avx2_##RNAME##AS_i8 (rp, i8any_ptr (x), o2iu(w), ria); dec(x); return r; \
|
||||||
|
case el_i16: if (!q_i16(w))break; avx2_##RNAME##AS_i16(rp, i16any_ptr(x), o2iu(w), ria); dec(x); return r; \
|
||||||
|
case el_i32: if (!q_i32(w))break; avx2_##RNAME##AS_i32(rp, i32any_ptr(x), o2iu(w), ria); dec(x); return r; \
|
||||||
|
case el_f64: if (!q_f64(w))break; avx2_##RNAME##AS_f64(rp, f64any_ptr(x), o2fu(w), ria); dec(x); return r; \
|
||||||
|
case el_c8: if (!q_c8 (w))break; avx2_##RNAME##AS_u8 (rp, c8any_ptr (x), o2cu(w), ria); dec(x); return r; \
|
||||||
|
case el_c16: if (!q_c16(w))break; avx2_##RNAME##AS_u16(rp, c16any_ptr(x), o2cu(w), ria); dec(x); return r; \
|
||||||
|
case el_c32: if (!q_c32(w))break; avx2_##RNAME##AS_i32(rp, (i32*)c32any_ptr(x), o2cu(w), ria); dec(x); return r; \
|
||||||
|
} \
|
||||||
|
dec(r); \
|
||||||
|
} \
|
||||||
|
end:;
|
||||||
77
src/singeli/src/avx2.singeli
Normal file
77
src/singeli/src/avx2.singeli
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
# ugh the intrinsics have their own broken type system
|
||||||
|
def r_d2i{R, a:T} = emit{R, '_mm256_castpd_si256', a}
|
||||||
|
def r_f2i{R, a:T} = emit{R, '_mm256_castps_si256', a}
|
||||||
|
def r_i2d{a:T} = emit{[4]f64, '_mm256_castsi256_pd', a}
|
||||||
|
def r_f2d{a:T} = emit{[4]f64, '_mm256_castps_pd', a}
|
||||||
|
def r_d2f{a:T} = emit{[8]f32, '_mm256_castpd_ps', a}
|
||||||
|
def r_i2f{a:T} = emit{[8]f32, '_mm256_castsi256_ps', a}
|
||||||
|
# various utilities
|
||||||
|
def isunsigned{T} = isint{T} & ~issigned{T}
|
||||||
|
def isintv{T} = isint{eltype{T}}
|
||||||
|
def isfloatv{T} = isfloat{eltype{T}}
|
||||||
|
def issignedv{T} = issigned{eltype{T}}
|
||||||
|
def isunsignedv{T} = isunsigned{eltype{T}}
|
||||||
|
def w256{T} = width{T}==256
|
||||||
|
def isintv{T,w} = isintv{T} & width{eltype{T}}==w
|
||||||
|
# load
|
||||||
|
def cast_vp{T, a & w256{T}} = emit{*T, '(void*)', a}
|
||||||
|
def vload{a:T, n & w256{eltype{T}} & isintv{eltype{T}}} = emit{eltype{T}, '_mm256_loadu_si256', emit{T, 'op +', a, n}}
|
||||||
|
def vload{a:T, n & w256{eltype{T}} & isfloatv{eltype{T}}} = r_i2d{vload{cast_vp{[4]u64, a}, n}} # TODO use the proper float load
|
||||||
|
|
||||||
|
# ops
|
||||||
|
|
||||||
|
# broadcast; TODO restrict v
|
||||||
|
def broadcast{T, v & w256{T} & isintv{T, 8}} = emit{T, '_mm256_set1_epi8', v}
|
||||||
|
def broadcast{T, v & w256{T} & isintv{T, 16}} = emit{T, '_mm256_set1_epi16', v}
|
||||||
|
def broadcast{T, v & w256{T} & isintv{T, 32}} = emit{T, '_mm256_set1_epi32', v}
|
||||||
|
def broadcast{T, v & w256{T} & isintv{T, 64}} = emit{T, '_mm256_set1_epi64x',v}
|
||||||
|
def broadcast{T, v & w256{T} & eltype{T}==f64} = emit{T, '_mm256_set1_pd', v}
|
||||||
|
|
||||||
|
def __xor{a:T, b:T & w256{T} & isunsignedv{T}} = r_f2i{T, emit{[8]f32, '_mm256_xor_ps', r_i2f{a}, r_i2f{b}}}
|
||||||
|
|
||||||
|
def __not{a:T & w256{T} & isunsignedv{T}} = a ^ broadcast{T, ~cast{eltype{T},0}}
|
||||||
|
|
||||||
|
# min & max
|
||||||
|
def min{a:T,b:T & T==[32]i8 } = emit{T, '_mm256_min_epi8', a, b}; def min{a:T,b:T & T==[32]u8 } = emit{T, '_mm256_min_epu8', a, b}
|
||||||
|
def min{a:T,b:T & T==[16]i16} = emit{T, '_mm256_min_epi16', a, b}; def min{a:T,b:T & T==[16]u16} = emit{T, '_mm256_min_epu16', a, b}
|
||||||
|
def min{a:T,b:T & T==[ 8]i32} = emit{T, '_mm256_min_epi32', a, b}; def min{a:T,b:T & T==[ 8]u32} = emit{T, '_mm256_min_epu32', a, b}
|
||||||
|
def max{a:T,b:T & T==[32]i8 } = emit{T, '_mm256_max_epi8', a, b}; def max{a:T,b:T & T==[32]u8 } = emit{T, '_mm256_max_epu8', a, b}
|
||||||
|
def max{a:T,b:T & T==[16]i16} = emit{T, '_mm256_max_epi16', a, b}; def max{a:T,b:T & T==[16]u16} = emit{T, '_mm256_max_epu16', a, b}
|
||||||
|
def max{a:T,b:T & T==[ 8]i32} = emit{T, '_mm256_max_epi32', a, b}; def max{a:T,b:T & T==[ 8]u32} = emit{T, '_mm256_max_epu32', a, b}
|
||||||
|
|
||||||
|
# float comparison
|
||||||
|
def fcmpAVX{a,b,n} = r_d2i{[4]u64, emit{[4]f64, '_mm256_cmp_pd', a, b, n}}
|
||||||
|
def __eq{a:T,b:T & T==[4]f64} = fcmpAVX{a,b, 0}
|
||||||
|
def __ne{a:T,b:T & T==[4]f64} = fcmpAVX{a,b, 4}
|
||||||
|
def __gt{a:T,b:T & T==[4]f64} = fcmpAVX{a,b,30}
|
||||||
|
def __ge{a:T,b:T & T==[4]f64} = fcmpAVX{a,b,29}
|
||||||
|
def __lt{a:T,b:T & T==[4]f64} = fcmpAVX{a,b,17}
|
||||||
|
def __le{a:T,b:T & T==[4]f64} = fcmpAVX{a,b,18}
|
||||||
|
# signed comparison
|
||||||
|
def __eq{a:T,b:T & T==[32]i8 } = emit{[32]u8, '_mm256_cmpeq_epi8', a, b}
|
||||||
|
def __eq{a:T,b:T & T==[16]i16} = emit{[16]u16, '_mm256_cmpeq_epi16', a, b}
|
||||||
|
def __eq{a:T,b:T & T==[ 8]i32} = emit{[ 8]u32, '_mm256_cmpeq_epi32', a, b}
|
||||||
|
def __gt{a:T,b:T & T==[32]i8 } = emit{[32]u8, '_mm256_cmpgt_epi8', a, b}
|
||||||
|
def __gt{a:T,b:T & T==[16]i16} = emit{[16]u16, '_mm256_cmpgt_epi16', a, b}
|
||||||
|
def __gt{a:T,b:T & T==[ 8]i32} = emit{[ 8]u32, '_mm256_cmpgt_epi32', a, b}
|
||||||
|
def __lt{a:T,b:T & w256{T} & issignedv{T}} = b>a
|
||||||
|
def __ge{a:T,b:T & w256{T} & issignedv{T}} = ~(b>a)
|
||||||
|
def __le{a:T,b:T & w256{T} & issignedv{T}} = ~(a>b)
|
||||||
|
# unsigned comparison
|
||||||
|
def __eq{a:T,b:T & T==[32]u8 } = emit{[32]u8, '_mm256_cmpeq_epi8', a, b}
|
||||||
|
def __eq{a:T,b:T & T==[16]u16} = emit{[16]u16, '_mm256_cmpeq_epi16', a, b}
|
||||||
|
def __eq{a:T,b:T & T==[ 8]u32} = emit{[ 8]u32, '_mm256_cmpeq_epi32', a, b}
|
||||||
|
def __le{a:T,b:T & w256{T} & isunsignedv{T}} = a==min{a,b}
|
||||||
|
def __ge{a:T,b:T & w256{T} & isunsignedv{T}} = a==max{a,b}
|
||||||
|
def __lt{a:T,b:T & w256{T} & isunsignedv{T}} = ~(a>=b)
|
||||||
|
def __gt{a:T,b:T & w256{T} & isunsignedv{T}} = ~(a<=b)
|
||||||
|
# rest of comparison
|
||||||
|
def __ne{a:T,b:T & w256{T} & isintv{T}} = ~(b==a)
|
||||||
|
|
||||||
|
def getmask{x:[32]u8} = emit{u32, '_mm256_movemask_epi8', x}
|
||||||
|
def getmask{x:[8]u32} = emit{u8, '_mm256_movemask_ps', r_i2f{x}}
|
||||||
|
def getmask{x:[4]u64} = emit{u8, '_mm256_movemask_pd', r_i2d{x}}
|
||||||
|
def getmask{x:[16]u16} = {
|
||||||
|
msk:u32 = getmask{emit{[32]u8, '_mm256_packs_epi16', x, broadcast{[16]u16, 0}}}
|
||||||
|
(msk&255) | (msk>>8) # TODO try out permute4x64 for fixing up
|
||||||
|
}
|
||||||
45
src/singeli/src/bitops.singeli
Normal file
45
src/singeli/src/bitops.singeli
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
def ones{T, n} = (cast{T,1}<<cast{T,n}) - 1
|
||||||
|
|
||||||
|
def b_get{x:*u64, n:(Size)} = {
|
||||||
|
((load{x,n>>6}>>(n&63)) & 1) != 0
|
||||||
|
}
|
||||||
|
|
||||||
|
def b_set{x:*u64, n:(Size), v:u1} = {
|
||||||
|
m:u64 = cast{u64,1}<<(n&63)
|
||||||
|
p:u64 = load{x,n>>6}
|
||||||
|
if (v) store{x,n>>6,p | m}
|
||||||
|
else store{x,n>>6,p & ~m}
|
||||||
|
}
|
||||||
|
|
||||||
|
def b_set{sz, x:*u64, n:(Size), v} = { vc:u64 = cast_i{u64,v}
|
||||||
|
am:u64 = 64/sz;
|
||||||
|
w:u64 = load{x,n/am}
|
||||||
|
sh:u64 = (n&(am-1)) * sz
|
||||||
|
w = w & ~(ones{u64,sz}<<sh)
|
||||||
|
w = w | (vc<<sh)
|
||||||
|
store{x, n/am, w}
|
||||||
|
}
|
||||||
|
|
||||||
|
def b_set{sz, x:*u64, n:(Size), v & sz==4} = {
|
||||||
|
x8:= cast_p{*u8, x}
|
||||||
|
|
||||||
|
#w:u64 = cast_i{u64, load{x8,n/2}}
|
||||||
|
#sh:u64 = (n&1) * 4
|
||||||
|
#w = w & ~(15<<sh)
|
||||||
|
#w = w | (cast_i{u64,v}<<sh)
|
||||||
|
|
||||||
|
w:u8 = load{x8,n/2}
|
||||||
|
if ((n&1)==1) {
|
||||||
|
w = w & ~(cast {u8,15}<<4)
|
||||||
|
w = w | (cast_i{u8,v}<<4)
|
||||||
|
} else {
|
||||||
|
w = w & ~(cast {u8,15})
|
||||||
|
w = w | (cast_i{u8,v}<<0)
|
||||||
|
}
|
||||||
|
|
||||||
|
store{x8, n/2, cast_i{u8,w}}
|
||||||
|
}
|
||||||
|
def b_set{sz, x:*u64, n:(Size), v & sz== 8} = store{cast_p{*u8, x}, n, cast_i{u8, v}}
|
||||||
|
def b_set{sz, x:*u64, n:(Size), v & sz==16} = store{cast_p{*u16, x}, n, cast_i{u16,v}}
|
||||||
|
def b_set{sz, x:*u64, n:(Size), v & sz==32} = store{cast_p{*u32, x}, n, cast_i{u32,v}}
|
||||||
|
def b_set{sz, x:*u64, n:(Size), v & sz==64} = store{x, n, cast_i{u64,v}}
|
||||||
60
src/singeli/src/cmp.singeli
Normal file
60
src/singeli/src/cmp.singeli
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
include 'skin/c'
|
||||||
|
include 'arch/c'
|
||||||
|
def Size = u64
|
||||||
|
include './avx2'
|
||||||
|
include './bitops'
|
||||||
|
|
||||||
|
def unroll{vars,begin,end,block & match{kind{begin},'number'} & match{kind{end},'number'}} = {
|
||||||
|
def f{i,l & i==l} = 0
|
||||||
|
def f{i,l & i!=l} = {
|
||||||
|
exec{i, vars, block}
|
||||||
|
f{i+1, l}
|
||||||
|
}
|
||||||
|
f{begin,end}
|
||||||
|
}
|
||||||
|
|
||||||
|
def cdiv{a,b} = (a+b-1)/b
|
||||||
|
|
||||||
|
def any2bit{VT, unr, op, wS, wV, xS, xV, dst:*u64, len:Size} = {
|
||||||
|
xi:Size = 0
|
||||||
|
ri:Size = 0
|
||||||
|
def bam = vcount{VT}*unr
|
||||||
|
while (ri < cdiv{len,bam}) {
|
||||||
|
r:u64 = 0
|
||||||
|
@unroll (j from 0 to unr) r = r | (cast_i{u64, getmask{op{wV{xi+j}, xV{xi+j}}}} << (j*vcount{VT}))
|
||||||
|
b_set{bam, dst, ri, r}
|
||||||
|
xi = xi+unr
|
||||||
|
ri = ri+1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aa2bit{VT, unr, op}(dst:*u64, w:*eltype{VT}, x:*eltype{VT}, len:Size) : void = {
|
||||||
|
wv:*VT = cast_vp{VT, w}
|
||||||
|
xv:*VT = cast_vp{VT, x}
|
||||||
|
any2bit{VT, unr, op, {i}=>load{w,i}, {i}=>vload{wv,i}, {i}=>load{x,i}, {i}=>vload{xv,i}, dst, len}
|
||||||
|
}
|
||||||
|
|
||||||
|
as2bit{VT, unr, op}(dst:*u64, w:*eltype{VT}, x:eltype{VT}, len:Size) : void = {
|
||||||
|
wv:*VT = cast_vp{VT, w}
|
||||||
|
xv: VT = broadcast{VT, x}
|
||||||
|
any2bit{VT, unr, op, {i}=>load{w,i}, {i}=>vload{wv,i}, {i}=>x, {i}=>xv, dst, len}
|
||||||
|
}
|
||||||
|
|
||||||
|
#'avx2_eqAA_f64'=aa2bit{[4]f64,4,__eq}
|
||||||
|
|
||||||
|
'avx2_eqAA_i8'=aa2bit{[32]i8,1,__eq}; 'avx2_eqAA_i16'=aa2bit{[16]i16,1,__eq}; 'avx2_eqAA_i32'=aa2bit{[8]i32,1,__eq}; 'avx2_eqAA_f64'=aa2bit{[4]f64,2,__eq}
|
||||||
|
'avx2_neAA_i8'=aa2bit{[32]i8,1,__ne}; 'avx2_neAA_i16'=aa2bit{[16]i16,1,__ne}; 'avx2_neAA_i32'=aa2bit{[8]i32,1,__ne}; 'avx2_neAA_f64'=aa2bit{[4]f64,2,__ne}
|
||||||
|
'avx2_gtAA_i8'=aa2bit{[32]i8,1,__gt}; 'avx2_gtAA_i16'=aa2bit{[16]i16,1,__gt}; 'avx2_gtAA_i32'=aa2bit{[8]i32,1,__gt}; 'avx2_gtAA_f64'=aa2bit{[4]f64,2,__gt}
|
||||||
|
'avx2_geAA_i8'=aa2bit{[32]i8,1,__ge}; 'avx2_geAA_i16'=aa2bit{[16]i16,1,__ge}; 'avx2_geAA_i32'=aa2bit{[8]i32,1,__ge}; 'avx2_geAA_f64'=aa2bit{[4]f64,2,__ge}
|
||||||
|
'avx2_gtAA_u8'=aa2bit{[32]u8,1,__gt}; 'avx2_gtAA_u16'=aa2bit{[16]u16,1,__gt}
|
||||||
|
'avx2_geAA_u8'=aa2bit{[32]u8,1,__ge}; 'avx2_geAA_u16'=aa2bit{[16]u16,1,__ge}
|
||||||
|
|
||||||
|
'avx2_eqAS_i8'=as2bit{[32]i8,1,__eq}; 'avx2_eqAS_i16'=as2bit{[16]i16,1,__eq}; 'avx2_eqAS_i32'=as2bit{[8]i32,1,__eq}; 'avx2_eqAS_f64'=as2bit{[4]f64,2,__eq}
|
||||||
|
'avx2_neAS_i8'=as2bit{[32]i8,1,__ne}; 'avx2_neAS_i16'=as2bit{[16]i16,1,__ne}; 'avx2_neAS_i32'=as2bit{[8]i32,1,__ne}; 'avx2_neAS_f64'=as2bit{[4]f64,2,__ne}
|
||||||
|
'avx2_gtAS_i8'=as2bit{[32]i8,1,__gt}; 'avx2_gtAS_i16'=as2bit{[16]i16,1,__gt}; 'avx2_gtAS_i32'=as2bit{[8]i32,1,__gt}; 'avx2_gtAS_f64'=as2bit{[4]f64,2,__gt}
|
||||||
|
'avx2_geAS_i8'=as2bit{[32]i8,1,__ge}; 'avx2_geAS_i16'=as2bit{[16]i16,1,__ge}; 'avx2_geAS_i32'=as2bit{[8]i32,1,__ge}; 'avx2_geAS_f64'=as2bit{[4]f64,2,__ge}
|
||||||
|
'avx2_ltAS_i8'=as2bit{[32]i8,1,__lt}; 'avx2_ltAS_i16'=as2bit{[16]i16,1,__lt}; 'avx2_ltAS_i32'=as2bit{[8]i32,1,__lt}; 'avx2_ltAS_f64'=as2bit{[4]f64,2,__lt}
|
||||||
|
'avx2_leAS_i8'=as2bit{[32]i8,1,__le}; 'avx2_leAS_i16'=as2bit{[16]i16,1,__le}; 'avx2_leAS_i32'=as2bit{[8]i32,1,__le}; 'avx2_leAS_f64'=as2bit{[4]f64,2,__le}
|
||||||
|
'avx2_gtAS_u8'=as2bit{[32]u8,1,__gt}; 'avx2_gtAS_u16'=as2bit{[16]u16,1,__gt}
|
||||||
|
'avx2_geAS_u8'=as2bit{[32]u8,1,__ge}; 'avx2_geAS_u16'=as2bit{[16]u16,1,__ge}
|
||||||
|
'avx2_ltAS_u8'=as2bit{[32]u8,1,__lt}; 'avx2_ltAS_u16'=as2bit{[16]u16,1,__lt}
|
||||||
|
'avx2_leAS_u8'=as2bit{[32]u8,1,__le}; 'avx2_leAS_u16'=as2bit{[16]u16,1,__le}
|
||||||
Loading…
Reference in New Issue
Block a user