get rid of function pointer cast

This commit is contained in:
dzaima 2021-10-25 13:35:11 +03:00
parent 4717023167
commit 4e17e28d4a
3 changed files with 31 additions and 32 deletions

View File

@ -17,9 +17,9 @@ static NORETURN void cmp_err() { thrM("Invalid comparison"); }
#include "../gen/cmp.c" #include "../gen/cmp.c"
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
typedef void (*CmpAAFn)(u64*, void*, void*, u64); typedef void (*CmpAAFn)(u64*, u8*, u8*, u64);
typedef void (*CmpASFn)(u64*, void*, u64, u64); typedef void (*CmpASFn)(u64*, u8*, u64, u64);
#define CMPFN(A,F,S,T) (Cmp##S##Fn) A##_##F##S##_##T #define CMPFN(A,F,S,T) A##_##F##S##_##T
#define FN_LUT(A,F,S) static const Cmp##S##Fn lut_##A##_##F##S[] = {CMPFN(A,F,S,u1), CMPFN(A,F,S,i8), CMPFN(A,F,S,i16), CMPFN(A,F,S,i32), CMPFN(A,F,S,f64), CMPFN(A,F,S,u8), CMPFN(A,F,S,u16), CMPFN(A,F,S,u32)} #define FN_LUT(A,F,S) static const Cmp##S##Fn lut_##A##_##F##S[] = {CMPFN(A,F,S,u1), CMPFN(A,F,S,i8), CMPFN(A,F,S,i16), CMPFN(A,F,S,i32), CMPFN(A,F,S,f64), CMPFN(A,F,S,u8), CMPFN(A,F,S,u16), CMPFN(A,F,S,u32)}
FN_LUT(avx2, eq, AS); FN_LUT(avx2, eq, AA); FN_LUT(avx2, eq, AS); FN_LUT(avx2, eq, AA);
@ -49,14 +49,14 @@ static void* tyany_ptr(B x) {
w=tw; x=tx; \ w=tw; x=tx; \
} \ } \
AL(x) \ AL(x) \
lut_avx2_##PNAME##AA[we](rp, tyany_ptr(L), tyany_ptr(R), ria); \ lut_avx2_##PNAME##AA[we](rp, (u8*)tyany_ptr(L), (u8*)tyany_ptr(R), ria); \
dec(w);dec(x); return r; \ dec(w);dec(x); return r; \
} \ } \
} else { \ } else { \
AL(w) lut_avx2_##NAME##AS[we](rp, tyany_ptr(w), x.u, ria); dec(w); return r; \ AL(w) lut_avx2_##NAME##AS[we](rp, (u8*)tyany_ptr(w), x.u, ria); dec(w); return r; \
} \ } \
} else if (isArr(x)) { u8 xe = TI(x,elType); if (xe==el_B) goto end; \ } else if (isArr(x)) { u8 xe = TI(x,elType); if (xe==el_B) goto end; \
AL(x) lut_avx2_##RNAME##AS[xe](rp, tyany_ptr(x), w.u, ria); dec(x); return r; \ AL(x) lut_avx2_##RNAME##AS[xe](rp, (u8*)tyany_ptr(x), w.u, ria); dec(x); return r; \
} \ } \
if (isF64(w)&isC32(x)) return m_i32(FC); \ if (isF64(w)&isC32(x)) return m_i32(FC); \
if (isC32(w)&isF64(x)) return m_i32(CF); \ if (isC32(w)&isF64(x)) return m_i32(CF); \

View File

@ -5,13 +5,10 @@ include './cbqnDefs'
include './avx2' include './avx2'
include './bitops' include './bitops'
def name{T} = 'unknown' def fmt{T} = 'unknown'
def name{T & match{T,__eq}} = 'eq' def fmt{T&match{T,__eq}}='='; def fmt{T&match{T,__ne}}='≠'
def name{T & match{T,__ne}} = 'ne' def fmt{T&match{T,__gt}}='>'; def fmt{T&match{T,__ge}}='≥'
def name{T & match{T,__gt}} = 'gt' def fmt{T&match{T,__lt}}='<'; def fmt{T&match{T,__le}}='≤'
def name{T & match{T,__ge}} = 'ge'
def name{T & match{T,__lt}} = 'lt'
def name{T & match{T,__le}} = 'le'
def cif{v, G} = { show{'cif argument not known at compile time!'}; G{} } def cif{v, G} = { show{'cif argument not known at compile time!'}; G{} }
@ -33,19 +30,18 @@ cmpIX(dst:*u64, len:Size, x:u64, v:u1) : void = {
def eqne{op} = match{op,__eq}|match{op,__ne} def eqne{op} = match{op,__eq}|match{op,__ne}
def pathAS{dst, len, T, op, x & issigned{T}} = { def pathAS{dst, len, T, op, x & issigned{T}} = {
def XC{f & eqne{op}} = { def R{f & eqne{op}} = {
if (rare{floor{f}!=f}) fillbits{dst, len, op{0,1}} # also includes check for NaN/sNaN if (rare{floor{f}!=f}) fillbits{dst, len, op{0,1}} # also includes check for NaN/sNaN
ftrunc_i64{f} ftrunc_i64{f}
} }
def XC{f & match{op,__lt}|match{op,__ge}} = ftrunc_i64{ceil{f}} def R{f & match{op,__lt}|match{op,__ge}} = ftrunc_i64{ceil{f}}
def XC{f & match{op,__gt}|match{op,__le}} = ftrunc_i64{floor{f}} def R{f & match{op,__gt}|match{op,__le}} = ftrunc_i64{floor{f}}
xf:f64 = interp_f64{x} xf:f64 = interp_f64{x}
xi64:i64 = XC{xf} xi64:i64 = R{xf}
xT:T = cast_i{T, xi64} xT:T = cast_i{T, xi64}
if (rare{(cast_i{i64, xT}!=xi64)}) { if (rare{(cast_i{i64, xT}!=xi64)}) {
cif{~eqne{op}, {_}=>{ cif{~eqne{op}, {_}=>{ # NaN was already checked for ≠/=
if (isNaN{xf}) { call{cmpIX, dst, len, x, op{0,1}}; return{}; } if (isNaN{xf}) { call{cmpIX, dst, len, x, op{0,1}}; return{}; }
}} }}
fillbits{dst, len, op{0,xf}} fillbits{dst, len, op{0,xf}}
@ -87,28 +83,30 @@ def any2bit{VT, unr, op, wS, wV, xS, xV, dst:*u64, len:(Size)} = {
ri = ri+1 ri = ri+1
} }
} }
aa2bit{VT, unr, op}(dst:*u64, w:*eltype{VT}, x:*eltype{VT}, len:Size) : void = { aa2bit{VT, unr, op}(dst:*u64, wr:*u8, xr:*u8, len:Size) : void = {
if (len==0) return{} if (len==0) return{}
wv:*VT = cast_vp{VT, w} wv:= cast_vp{VT, wr}; ws:= cast_p{*eltype{VT}, wr}
xv:*VT = cast_vp{VT, x} xv:= cast_vp{VT, xr}; xs:= cast_p{*eltype{VT}, xr}
any2bit{VT, unr, op, {i}=>load{w,i}, {i}=>vload{wv,i}, {i}=>load{x,i}, {i}=>vload{xv,i}, dst, len} any2bit{VT, unr, op, {i}=>load{ws,i}, {i}=>vload{wv,i}, {i}=>load{xs,i}, {i}=>vload{xv,i}, dst, len}
} }
as2bit{VT, unr, op}(dst:*u64, w:*eltype{VT}, x:u64, len:Size) : void = { show{VT,unr,name{op}} as2bit{VT, unr, op}(dst:*u64, wr:*u8, x:u64, len:Size) : void = { show{VT,unr,fmt{op}}
if (len==0) return{} if (len==0) return{}
wv:*VT = cast_vp{VT, w} wv:= cast_vp{VT, wr}; ws:= cast_p{*eltype{VT}, wr}
xv: VT = broadcast{VT, pathAS{dst, len, eltype{VT}, op, x}} xv:= broadcast{VT, pathAS{dst, len, eltype{VT}, op, x}}
any2bit{VT, unr, op, {i}=>load{w,i}, {i}=>vload{wv,i}, {i}=>x, {i}=>xv, dst, len} any2bit{VT, unr, op, {i}=>load{ws,i}, {i}=>vload{wv,i}, {i}=>x, {i}=>xv, dst, len}
} }
bitAA{bitop}(dst:*u64, w:*u64, x:*u64, len:Size) : void = { bitAA{bitop}(dst:*u64, wr:*u8, xr:*u8, len:Size) : void = {
@for (dst,w,x over _ from 0 to cdiv{len,64}) dst = bitop{w,x} ws:= cast_p{*u64, wr}
xs:= cast_p{*u64, xr}
@for (dst,ws,xs over _ from 0 to cdiv{len,64}) dst = bitop{ws,xs}
} }
not(dst:*u64, x:*u64, len:Size) : void = { @for (dst,x over _ from 0 to cdiv{len,64}) dst = ~x } not(dst:*u64, x:*u64, len:Size) : void = { @for (dst,x over _ from 0 to cdiv{len,64}) dst = ~x }
cpy(dst:*u64, x:*u64, len:Size) : void = { @for (dst,x over _ from 0 to cdiv{len,64}) dst = x } cpy(dst:*u64, x:*u64, len:Size) : void = { @for (dst,x over _ from 0 to cdiv{len,64}) dst = x }
bitAS{op}(dst:*u64, w:*u64, x:u64, len:Size) : void = { show{'bitAS'} bitAS{op}(dst:*u64, wr:*u8, x:u64, len:Size) : void = { show{'bitAS'}
if (len==0) return{} if (len==0) return{}
xf:f64 = interp_f64{x} xf:f64 = interp_f64{x}
r0:u1 = op{0,xf} r0:u1 = op{0,xf}
@ -120,8 +118,8 @@ bitAS{op}(dst:*u64, w:*u64, x:u64, len:Size) : void = { show{'bitAS'}
fillbits{dst, len, r0} fillbits{dst, len, r0}
return{} return{}
} }
if (r0) call{not, dst, w, len} if (r0) call{not, dst, cast_p{*u64,wr}, len}
else call{cpy, dst, w, len} else call{cpy, dst, cast_p{*u64,wr}, len}
} }

View File

@ -3,6 +3,7 @@ def floor{x:f64} = emit{f64, 'floor', x}
def NaN = 0.0/0.0 def NaN = 0.0/0.0
def isNaN{x:f64} = x!=x def isNaN{x:f64} = x!=x
def qNaN{x:u64} = (x<<1) == (cast{u64, 0x8ff8} << 49)
def ftrunc_i32{x:f64} = emit{i32, '', x} # maybe explicitly use _mm_cvtsd_si32 def ftrunc_i32{x:f64} = emit{i32, '', x} # maybe explicitly use _mm_cvtsd_si32
def ftrunc_i64{x:f64} = emit{i64, '', x} def ftrunc_i64{x:f64} = emit{i64, '', x}