From d333902f74be4c12cd7041527279477a04bb19e6 Mon Sep 17 00:00:00 2001 From: dzaima Date: Tue, 21 Mar 2023 02:02:23 +0200 Subject: [PATCH] =?UTF-8?q?fast=20integer=20=F0=9D=95=A8|=F0=9D=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/arithd.c | 128 +++++++++++++++++++++++++++++++++--------- 1 file changed, 101 insertions(+), 27 deletions(-) diff --git a/src/builtins/arithd.c b/src/builtins/arithd.c index e920fff2..938a76d8 100644 --- a/src/builtins/arithd.c +++ b/src/builtins/arithd.c @@ -36,6 +36,68 @@ typedef void (*AndBytesFn)(u8*, u8*, u64, u64); static AndBytesFn andBytes_fn = base_andBytes; #endif +B floor_c1(B t, B x); +B sub_c1(B t, B x); +B fne_c1(B t, B x); +B shape_c2(B t, B w, B x); + +// all divint/floordiv/modint assume integer arguments +// floordiv will return float result only on ¯2147483648÷¯1 or n÷0, but may not otherwise squeeze integer types; integer argument requirement may be relaxed in the future +// divint will return float result if there's a fractional result, or in overflow cases same as floordiv +// TODO overflow-checked Singeli code for _AA cases? +typedef float f32; +#define DIVLOOP(RE, WE, EXPR) RE* rp; B r=m_##RE##arrc(&rp, w); usz ia=IA(w); WE* wp=WE##any_ptr(w); for(ux i=0; i0 && (wi32&(wi32-1))==0) { - if (wi32==1) { Arr* ra=allZeroes(IA(x)); arr_shCopy(ra, x); r = taga(ra); decG(x); return r; } - if (xe==el_bit) return x; // if n>1 (true from the above), 0‿1 ≡ (2⋆n)|0‿1 - u8 elw = elWidth(xe); - u32 mask0 = (u32)wi32; - if (mask0 > (1 << (elw*8-1))) { - if (mask0 > 32768) { x=taga(cpyI32Arr(x)); xe=el_i32; elw=4; } - else if (mask0 > 128) { x=taga(cpyI16Arr(x)); xe=el_i16; elw=2; } - else UD; + /*INT_SA*/ + if (q_i32(w)) { + i32 wi32 = o2iG(w); + if (wi32>0 && (wi32&(wi32-1))==0) { + if (wi32==1) { Arr* ra=allZeroes(IA(x)); arr_shCopy(ra, x); r = taga(ra); decG(x); return r; } + if (xe==el_bit) return x; // if n>1 (true from the above), 0‿1 ≡ (2⋆n)|0‿1 + u8 elw = elWidth(xe); + u32 mask0 = (u32)wi32; + if (mask0 > (1 << (elw*8-1))) { + if (mask0 > 32768) { x=taga(cpyI32Arr(x)); xe=el_i32; elw=4; } + else if (mask0 > 128) { x=taga(cpyI16Arr(x)); xe=el_i16; elw=2; } + else UD; + } + u64 mask = (mask0-1)*repeatNum[xe]; + usz bytes = IA(x)*elw; + u8* rp = m_tyarrc(&r, elw, x, el2t(xe)); + andBytes_fn(rp, tyany_ptr(x), mask, bytes); + decG(x); + if (wi32==2) return taga(cpyBitArr(r)); + else if (wi32<256) return taga(cpyI8Arr(r)); // these won't widen, as the code doesn't even get to here if 𝕨 > max possible in 𝕩 + else if (wi32<65536) return taga(cpyI16Arr(r)); + return r; + } else { + return modint_SA(wi32, x); } - u64 mask = (mask0-1)*repeatNum[xe]; - usz bytes = IA(x)*elw; - u8* rp = m_tyarrc(&r, elw, x, el2t(xe)); - andBytes_fn(rp, tyany_ptr(x), mask, bytes); - decG(x); - if (wi32==2) return taga(cpyBitArr(r)); - if (wi32<256) return taga(cpyI8Arr(r)); // these won't widen, as the code doesn't even get to here if 𝕨 > max possible in 𝕩 - if (wi32<65536) return taga(cpyI16Arr(r)); - return r; } + , /*INT_AS*/ if (q_i32(x)) return modint_AS(w, x); + , /*INT_AA*/ return modint_AA(w, x); ) #undef GC2f