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"
#pragma GCC diagnostic pop
typedef void (*CmpAAFn)(u64*, void*, void*, u64);
typedef void (*CmpASFn)(u64*, void*, u64, u64);
#define CMPFN(A,F,S,T) (Cmp##S##Fn) A##_##F##S##_##T
typedef void (*CmpAAFn)(u64*, u8*, u8*, u64);
typedef void (*CmpASFn)(u64*, u8*, u64, u64);
#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)}
FN_LUT(avx2, eq, AS); FN_LUT(avx2, eq, AA);
@ -49,14 +49,14 @@ static void* tyany_ptr(B x) {
w=tw; x=tx; \
} \
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; \
} \
} 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; \
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 (isC32(w)&isF64(x)) return m_i32(CF); \

View File

@ -5,13 +5,10 @@ include './cbqnDefs'
include './avx2'
include './bitops'
def name{T} = 'unknown'
def name{T & match{T,__eq}} = 'eq'
def name{T & match{T,__ne}} = 'ne'
def name{T & match{T,__gt}} = 'gt'
def name{T & match{T,__ge}} = 'ge'
def name{T & match{T,__lt}} = 'lt'
def name{T & match{T,__le}} = 'le'
def fmt{T} = 'unknown'
def fmt{T&match{T,__eq}}='='; def fmt{T&match{T,__ne}}='≠'
def fmt{T&match{T,__gt}}='>'; def fmt{T&match{T,__ge}}='≥'
def fmt{T&match{T,__lt}}='<'; def fmt{T&match{T,__le}}='≤'
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 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
ftrunc_i64{f}
}
def XC{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,__lt}|match{op,__ge}} = ftrunc_i64{ceil{f}}
def R{f & match{op,__gt}|match{op,__le}} = ftrunc_i64{floor{f}}
xf:f64 = interp_f64{x}
xi64:i64 = XC{xf}
xi64:i64 = R{xf}
xT:T = cast_i{T, 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{}; }
}}
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
}
}
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{}
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}
wv:= cast_vp{VT, wr}; ws:= cast_p{*eltype{VT}, wr}
xv:= cast_vp{VT, xr}; xs:= cast_p{*eltype{VT}, xr}
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{}
wv:*VT = cast_vp{VT, w}
xv: VT = 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}
wv:= cast_vp{VT, wr}; ws:= cast_p{*eltype{VT}, wr}
xv:= broadcast{VT, pathAS{dst, len, eltype{VT}, op, x}}
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 = {
@for (dst,w,x over _ from 0 to cdiv{len,64}) dst = bitop{w,x}
bitAA{bitop}(dst:*u64, wr:*u8, xr:*u8, len:Size) : void = {
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 }
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{}
xf:f64 = interp_f64{x}
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}
return{}
}
if (r0) call{not, dst, w, len}
else call{cpy, dst, w, len}
if (r0) call{not, dst, cast_p{*u64,wr}, 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 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_i64{x:f64} = emit{i64, '', x}