From 8f5259e77ddb45509f345e716ab8c456c207a8c7 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Mon, 10 Oct 2022 21:02:05 -0400 Subject: [PATCH 1/8] =?UTF-8?q?Implement=201-argument=20=E2=80=A2bit=20ope?= =?UTF-8?q?rations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins.h | 2 +- src/builtins/sysfn.c | 129 +++++++++++++++++++++++++++++++++---------- 2 files changed, 100 insertions(+), 31 deletions(-) diff --git a/src/builtins.h b/src/builtins.h index bab03036..8d7555ce 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -24,7 +24,7 @@ /*inverse.c*/A(undo,"⁼") \ /* everything before the definition of •_timed is defined to be pure, and everything after is not */ \ /*md1.c*/A(timed,"•_timed") \ - /*bit.c*/M(bitcast,"•bit._cast") + /*bit.c*/M(bitcast,"•bit._cast") M(bitnot,"•bit._not") M(bitneg,"•bit._neg") #define FOR_PM2(A,M,D) \ /*md2.c*/A(val,"⊘") A(repeat,"⍟") A(rank,"⎉") A(depth,"⚇") A(fillBy,"•_fillBy_") A(catch,"⎊") \ diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 4bd177cb..7341384a 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1131,44 +1131,48 @@ static u8 typeOfCast(CastType t) { default: thrM("•bit._cast: unsupported result width"); } } +static B set_bit_result(B r, u8 rt, ur rr, usz rl, usz *sh) { + // Cast to output type + v(r)->type = IS_SLICE(v(r)->type) ? TO_SLICE(rt) : rt; + // Adjust shape + Arr* a = a(r); + if (rr<=1) { + a->ia = rl; + a->sh = &a->ia; + } else { + if (shObj(r)->refc>1) { + shObj(r)->refc--; // won't go to zero as refc>1; preparation for being overwritten by new shape + usz* rsh = a->sh = m_shArr(rr)->a; + shcpy(rsh, sh, rr-1); + sh = rsh; + SPRNK(a, rr); + } + sh[rr-1] = rl; + a->ia = rl * shProd(sh, 0, rr-1); + } + return r; +} + B bitcast_impl(B el0, B el1, B x) { ur xr; if (!isArr(x) || (xr=RNK(x))<1) thrM("•bit._cast: 𝕩 must have rank at least 1"); - CastType xt = getCastType(el0, x); - CastType zt = getCastType(el1, bi_N); + CastType xct = getCastType(el0, x); + CastType rct = getCastType(el1, bi_N); usz* sh = SH(x); - u64 s=xt.s*(u64)sh[xr-1], zl=s/zt.s; - if (zl*zt.s != s) thrM("•bit._cast: incompatible lengths"); - if (zl>=USZ_MAX) thrM("•bit._cast: output too large"); - // Convert to input type - B r = convert(xt, x); - u8 rt = typeOfCast(zt); + u64 s=xct.s*(u64)sh[xr-1], rl=s/rct.s; + if (rl*rct.s != s) thrM("•bit._cast: incompatible lengths"); + if (rl>=USZ_MAX) thrM("•bit._cast: output too large"); + B r = convert(xct, x); + u8 rt = typeOfCast(rct); if (rt==t_bitarr && (v(r)->refc!=1 || IS_SLICE(TY(r)))) { - r = taga(copy(xt, r)); + r = taga(copy(xct, r)); } else if (v(r)->refc!=1) { B pr = r; r = taga(TI(r,slice)(r, 0, IA(r))); arr_shSetI(a(r), xr, shObj(pr)); // safe to use pr because r has refcount>1 and slice only consumes one, leaving some behind } - // Cast to output type - v(r)->type = IS_SLICE(v(r)->type) ? TO_SLICE(rt) : rt; - // Adjust shape - if (xr<=1) { - Arr* a = a(r); - a->ia = zl; - a->sh = &a->ia; - } else { - if (shObj(r)->refc>1) { - shObj(r)->refc--; // won't go to zero as refc>1; preparation for being overwritten by new shape - usz* zsh = arr_shAlloc(a(r), xr); - shcpy(zsh, sh, xr-1); - sh = zsh; - } - sh[xr-1]=zl; - a(r)->ia = zl*shProd(sh, 0, xr-1); - } - return r; + return set_bit_result(r, rt, xr, rl, sh); } B bitcast_c1(Md1D* d, B x) { B f = d->f; @@ -1176,18 +1180,83 @@ B bitcast_c1(Md1D* d, B x) { B f = d->f; SGetU(f) return bitcast_impl(GetU(f,0), GetU(f,1), x); } - B bitcast_im(Md1D* d, B x) { B f = d->f; if (!isArr(f) || RNK(f)!=1 || IA(f)!=2) thrM("•bit._cast: 𝕗 must be a 2-element list (from‿to)"); SGetU(f) return bitcast_impl(GetU(f,1), GetU(f,0), x); } + +static usz req2(usz s, char* name) { + if (s & (s-1)) thrF("•bit._%U: sizes in 𝕗 must be powers of 2 (contained %s)", name, s); + return s; +} + +enum BitOp1 { op_not, op_neg }; +B bitop1(B f, B x, enum BitOp1 op, char* name) { + usz ow, rw, xw; // Operation width, result width, x width + if (isAtm(f)) { + ow = rw = xw = req2(o2s(f), name); + } else { + if (RNK(f)>1) thrF("•bit._%U: 𝕗 must have rank at most 1 (%i≡≠𝕗)", name, RNK(f)); + usz ia = IA(f); + if (ia<1 || ia>3) thrF("•bit._%U: 𝕗 must contain between 1 and 3 numbers (%s≡≠𝕗)", name, ia); + SGetU(f) + usz t[3]; + for (usz i=0 ; i> rws; + if ((s & (ow-1)) || (rl<=USZ_MAX) thrF("•bit._%U: output too large", name); + + x = convert((CastType){ xw, 0 }, x); + u8 rt = typeOfCast((CastType){ rw, 0 }); + u64* xp = tyany_ptr(x); + B r; u64* rp; + if (v(x)->refc!=1 || (rt==t_bitarr && IS_SLICE(TY(x)))) { + Arr* ra = m_arr(offsetof(TyArr,a) + (n+7)/8, rt, n>>rws); + arr_shCopy(ra, x); + r = taga(ra); rp = tyany_ptr(r); + } else { + r = inc(x); rp = xp; + } + switch (op) { default: UD; + case op_not: { + usz l = n/64; for (usz i=0; i> q) & (rp[l]^~xp[l]); + } break; + case op_neg: switch (ow) { + default: thrF("•bit._%U: unhandled width %s", name, ow); + #define CASE(W) case W: \ + for (usz i=0; if, x, op_not, "not"); } +B bitneg_c1(Md1D* d, B x) { return bitop1(d->f, x, op_neg, "neg"); } + static B bitNS; B getBitNS() { if (bitNS.u == 0) { #define F(X) incG(bi_bit##X), - Body* d = m_nnsDesc("cast"); - bitNS = m_nns(d, F(cast)); + Body* d = m_nnsDesc("cast","not","neg"); + bitNS = m_nns(d, F(cast)F(not)F(neg)); #undef F gc_add(bitNS); } From 80f8ac96435d632eeae14a94d897743918686975 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Mon, 10 Oct 2022 22:06:51 -0400 Subject: [PATCH 2/8] =?UTF-8?q?2-argument=20=E2=80=A2bit=20operations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins.h | 3 +- src/builtins/sysfn.c | 74 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 3 deletions(-) diff --git a/src/builtins.h b/src/builtins.h index 8d7555ce..8fee97d6 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -24,7 +24,8 @@ /*inverse.c*/A(undo,"⁼") \ /* everything before the definition of •_timed is defined to be pure, and everything after is not */ \ /*md1.c*/A(timed,"•_timed") \ - /*bit.c*/M(bitcast,"•bit._cast") M(bitnot,"•bit._not") M(bitneg,"•bit._neg") + /*bit.c*/M(bitcast,"•bit._cast") M(bitnot,"•bit._not") M(bitneg,"•bit._neg") \ + /*bit.c*/D(bitand,"•bit._and") D(bitor,"•bit._or") D(bitxor,"•bit._xor") D(bitadd,"•bit._add") D(bitsub,"•bit._sub") D(bitmul,"•bit._mul") #define FOR_PM2(A,M,D) \ /*md2.c*/A(val,"⊘") A(repeat,"⍟") A(rank,"⎉") A(depth,"⚇") A(fillBy,"•_fillBy_") A(catch,"⎊") \ diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 7341384a..958e512a 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1251,12 +1251,82 @@ B bitop1(B f, B x, enum BitOp1 op, char* name) { B bitnot_c1(Md1D* d, B x) { return bitop1(d->f, x, op_not, "not"); } B bitneg_c1(Md1D* d, B x) { return bitop1(d->f, x, op_neg, "neg"); } +enum BitOp2 { op_and, op_or, op_xor, op_add, op_sub, op_mul }; +B bitop2(B f, B w, B x, enum BitOp2 op, char* name) { + usz ow, rw, xw, ww; // Operation width, result width, x width, w width + if (isAtm(f)) { + ow = rw = xw = ww = req2(o2s(f), name); + } else { + if (RNK(f)>1) thrF("•bit._%U: 𝕗 must have rank at most 1 (%i≡≠𝕗)", name, RNK(f)); + usz ia = IA(f); + if (ia<1 || ia>4) thrF("•bit._%U: 𝕗 must contain between 1 and 4 numbers (%s≡≠𝕗)", name, ia); + SGetU(f) + usz t[4]; + for (usz i=0 ; i> rws; + if ((s & (ow-1)) || (rl<=USZ_MAX) thrF("•bit._%U: output too large", name); + + w = convert((CastType){ ww, 0 }, w); + x = convert((CastType){ xw, 0 }, x); + u8 rt = typeOfCast((CastType){ rw, 0 }); + Arr* ra = m_arr(offsetof(TyArr,a) + (n+7)/8, rt, n>>rws); + arr_shCopy(ra, x); + B r = taga(ra); + u64* wp = tyany_ptr(w); + u64* xp = tyany_ptr(x); + u64* rp = tyany_ptr(r); + switch (op) { default: UD; + #define OP(O,P) case op_##O: { \ + usz l = n/64; for (usz i=0; i> q) & (rp[l]^(wp[l] P xp[l])); \ + } break; + OP(and,&) OP(or,|) OP(xor,^) + #undef OP + #define CASE(W, Q, P) case W: \ + for (usz i=0; if, w, x, op_##OP, #OP); } +DEF_OP2(and) DEF_OP2(or) DEF_OP2(xor) +DEF_OP2(add) DEF_OP2(sub) DEF_OP2(mul) +#undef DEF_OP2 + static B bitNS; B getBitNS() { if (bitNS.u == 0) { #define F(X) incG(bi_bit##X), - Body* d = m_nnsDesc("cast","not","neg"); - bitNS = m_nns(d, F(cast)F(not)F(neg)); + Body* d = m_nnsDesc("cast","not","neg","and","or","xor","add","sub","mul"); + bitNS = m_nns(d, F(cast)F(not)F(neg)F(and)F(or)F(xor)F(add)F(sub)F(mul)); #undef F gc_add(bitNS); } From 022ef64f6ba5adb1e8407a95ba681f04e90211df Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Tue, 11 Oct 2022 20:12:04 -0400 Subject: [PATCH 3/8] Add NOUNROLLs to bitwise functions --- src/builtins/sysfn.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 958e512a..505963ad 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1232,13 +1232,13 @@ B bitop1(B f, B x, enum BitOp1 op, char* name) { } switch (op) { default: UD; case op_not: { - usz l = n/64; for (usz i=0; i> q) & (rp[l]^~xp[l]); } break; case op_neg: switch (ow) { default: thrF("•bit._%U: unhandled width %s", name, ow); #define CASE(W) case W: \ - for (usz i=0; i> q) & (rp[l]^(wp[l] P xp[l])); \ } break; OP(and,&) OP(or,|) OP(xor,^) #undef OP #define CASE(W, Q, P) case W: \ - for (usz i=0; i Date: Tue, 11 Oct 2022 21:36:07 -0400 Subject: [PATCH 4/8] =?UTF-8?q?Implement=20scalar=20extension=20for=20?= =?UTF-8?q?=E2=80=A2=5Fbit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/sysfn.c | 80 +++++++++++++++++++++++++++++++------------- 1 file changed, 57 insertions(+), 23 deletions(-) diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 505963ad..419a9017 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1267,22 +1267,33 @@ B bitop2(B f, B w, B x, enum BitOp2 op, char* name) { ow = t[0]; rw = t[1]; xw = t[2]; ww = t[3]; } - ur xr; - if (!isArr(x) || (xr=RNK(x))<1) thrF("•bit._%U: 𝕩 must have rank at least 1", name); - if (!isArr(w) || RNK(w) != xr ) thrF("•bit._%U: 𝕨 must have rank equal to 𝕩", name); - usz* sh = SH(x); - usz* wsh = SH(w); - for (usz i=0; i1 || s!=ow || xr==0) { // Need to extend 𝕩 + if (xr>1 || t!=ow || wr==0) { + if (wr!=xr && wr>1 && xr>1) thrF("•bit._%U: 𝕨 and 𝕩 must have equal ranks if more than 1", name); + thrF("•bit._%U: 𝕨 or 𝕩 1-cell width must equal operation width if extended", name); + } + { B t=w; w=x; x=t; } + { usz t=ww; ww=xw; xw=t; } + negw=op==op_sub; if (negw) op=op_add; + t = s; xr = wr; sh = wsh; + } + } usz rws = CTZ(rw); - usz xws = CTZ(xw); - u64 s = (u64)sh[xr-1] << xws; - if (s != ww*(u64)wsh[xr-1]) thrF("•bit._%U: 𝕨 and 𝕩 1-cell widths must match", name); - u64 n = IA(x) << xws; - u64 rl = s >> rws; - if ((s & (ow-1)) || (rl<> rws; + if ((t & (ow-1)) || (rl<=USZ_MAX) thrF("•bit._%U: output too large", name); - + w = convert((CastType){ ww, 0 }, w); x = convert((CastType){ xw, 0 }, x); u8 rt = typeOfCast((CastType){ rw, 0 }); @@ -1292,25 +1303,48 @@ B bitop2(B f, B w, B x, enum BitOp2 op, char* name) { u64* wp = tyany_ptr(w); u64* xp = tyany_ptr(x); u64* rp = tyany_ptr(r); - switch (op) { default: UD; - #define OP(O,P) case op_##O: { \ + + #define CASES(O,Q,P) case op_##O: \ + switch(ow) { default: thrF("•bit._%U: unhandled width %s", name, ow); \ + CASE(8,Q,P) CASE(16,Q,P) CASE(32,Q,P) CASE(64,Q,P) \ + } break; + #define SWITCH \ + switch (op) { default: UD; \ + BINOP(and,&) BINOP(or,|) BINOP(xor,^) \ + CASES(add,u,+) CASES(sub,u,-) CASES(mul,i,*) \ + } + if (noextend) { + #define BINOP(O,P) case op_##O: { \ usz l = n/64; NOUNROLL for (usz i=0; i> q) & (rp[l]^(wp[l] P xp[l])); \ } break; - OP(and,&) OP(or,|) OP(xor,^) - #undef OP #define CASE(W, Q, P) case W: \ NOUNROLL for (usz i=0; i64) thrF("•bit._%U: scalar extension with width over 64 unhandled", name); \ + u64 wv = *wp & (~(u64)0>>(64-ow)); \ + for (usz tw=ow; tw<64; tw*=2) wv|=wv<> q) & (rp[l]^(wv P xp[l])); \ } break; - OP(add,u,+) OP(sub,u,-) OP(mul,i,*) - #undef OP + #define CASE(W, Q, P) case W: { \ + Q##W wv = *(Q##W*)wp; \ + NOUNROLL for (usz i=0; i Date: Tue, 11 Oct 2022 21:59:40 -0400 Subject: [PATCH 5/8] =?UTF-8?q?Don't=20allow=200=20as=20a=20width=20for=20?= =?UTF-8?q?=E2=80=A2bit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/sysfn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index 419a9017..d23dae96 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1187,7 +1187,8 @@ B bitcast_im(Md1D* d, B x) { B f = d->f; } static usz req2(usz s, char* name) { - if (s & (s-1)) thrF("•bit._%U: sizes in 𝕗 must be powers of 2 (contained %s)", name, s); + usz top = 1ull << (8*sizeof(usz)-1); // Prevent 0 from passing + if ((top|s) & (s-1)) thrF("•bit._%U: sizes in 𝕗 must be powers of 2 (contained %s)", name, s); return s; } From d23d9b8c8fbf5f26369d9afdc9f842297a5c1f0b Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 12 Oct 2022 21:43:04 -0400 Subject: [PATCH 6/8] =?UTF-8?q?=E2=80=A2bit.=5Fcast=20fuzz=20tester,=20for?= =?UTF-8?q?=20refcount=201=20lists?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/bit.bqn | 27 +++++++++++++++++++++++++++ test/utils.bqn | 3 ++- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 test/bit.bqn diff --git a/test/bit.bqn b/test/bit.bqn new file mode 100644 index 00000000..121320cb --- /dev/null +++ b/test/bit.bqn @@ -0,0 +1,27 @@ +u ← ⌊100×(•UnixTime+1|100וMonoTime)@ +r ← •MakeRand •Show u +⟨RandVals, casts⟩ ← ⟨r⟩ •Import "utils.bqn" + +# Test •bit._cast first +# Convert unsigned width 𝕗 to 𝕘 +_cvtu_ ← { + 𝕗=𝕘 ? 𝕩 ; + 𝕗<𝕘 ? b←2⋆𝕗 ⋄ +⟜(b⊸×)˝⍉∘‿(𝕘÷𝕗)⥊𝕩 ; + b←2⋆𝕘 ⋄ ⥊⍉>1(-⊸↓-b×↓)⌊∘÷⟜b⍟(↕1+𝕗÷𝕘)𝕩 +} +_bitcast ← { fr‿to _𝕣 𝕩: + S ← {𝕊:𝕩+𝕨×𝕩<0; 𝕊⁼:𝕩-𝕨×𝕩≥𝕨÷2} + _off ← {(⊑"uci"⊐1⊑𝕗)⊑⟨⊢,-⟜@,(2⋆⊑𝕗)⊸S⟩} + f‿t ← ⊑¨𝕗 + to _off⁼ f _cvtu_ t fr _off 𝕩 +} + +TestCast ← { f‿t 𝕊 len: + c ← 𝕨 ⊏ casts + len +↩ (1⌈÷˜´⊑¨c) | -len # Round up to exact conversion + (c _bitcast ≡ c •bit._cast) len RandVals f +} +cs ← / 64>⊑¨casts # TODO floats +cx ← ⊏⟜(32‿'c'⊸≢¨casts)⊸/ cs # TODO 32-bit char output +ls ← (↕100) ∾ r.Range¨⊸+ ⌊ 100 × ↕∘⌈⌾(1.5⊸⋆⁼) 100 +{cs (⋈ !∘TestCast 𝕩˙)⌜ cx}¨ ls diff --git a/test/utils.bqn b/test/utils.bqn index 817781f2..5aba7103 100644 --- a/test/utils.bqn +++ b/test/utils.bqn @@ -11,6 +11,7 @@ chr ← 0‿0‿0‿0‿0‿1‿1‿1 specF64 ⇐ ∾⟜- π‿2∾ ÷⟜0⊸∾ 1‿0 specI32 ⇐ "Ai32" •internal.Variation ∧ (<⟜(2⋆31)∧≥⟜(-2⋆31))⊸/ ∾⟜- ≥⟜0⊸/ ∧⥊(¯4+↕8) +⌜ 2⋆↕32 vars ⇐ "Ab"‿"Ai8"‿"Ai16"‿"Ai32"‿"Af64"‿"Ac8"‿"Ac16"‿"Ac32" +casts ⇐ 1‿8‿16‿32‿64‿8‿16‿32⋈¨"uiiifccc" specInts ⇐ 7‿15({(<⟜(2⋆𝕨)∧≥⟜(-2⋆𝕨))⊸/𝕩}¨⟜<∾⋈∘⊢)specI32 # TODO 8-bit integer spec is kinda stupid spec0 ← ⟨0‿1⟩∾specInts∾⟨specF64⟩∾@+∾⟜(⌽1114111-↕16)⌾(2⊸⊑) (<⟜1114111∧≥⟜0)⊸/¨ specInts spec0 (5/¯128‿¯127‿¯126‿¯2‿¯1‿0‿1‿2‿125‿126‿127)⊸∾⌾(1⊸⊑)↩ @@ -43,4 +44,4 @@ RandVals ⇐ { ! "f64arr" ≡ •internal.Type 10 RandVals 4 ! "c8arr" ≡ •internal.Type 10 RandVals 5 ! "c16arr" ≡ •internal.Type 10 RandVals 6 -! "c32arr" ≡ •internal.Type 10 RandVals 7 \ No newline at end of file +! "c32arr" ≡ •internal.Type 10 RandVals 7 From 130653dbdaac7ccfce9661754b8b2f9976558bf1 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Wed, 12 Oct 2022 22:16:45 -0400 Subject: [PATCH 7/8] =?UTF-8?q?Allow=20character=20arguments=20to=20?= =?UTF-8?q?=E2=80=A2bit=20operations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/builtins/sysfn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/builtins/sysfn.c b/src/builtins/sysfn.c index d23dae96..d0983d49 100644 --- a/src/builtins/sysfn.c +++ b/src/builtins/sysfn.c @@ -1220,7 +1220,7 @@ B bitop1(B f, B x, enum BitOp1 op, char* name) { if ((s & (ow-1)) || (rl<=USZ_MAX) thrF("•bit._%U: output too large", name); - x = convert((CastType){ xw, 0 }, x); + x = convert((CastType){ xw, isCharType(TY(x)) }, x); u8 rt = typeOfCast((CastType){ rw, 0 }); u64* xp = tyany_ptr(x); B r; u64* rp; @@ -1295,8 +1295,8 @@ B bitop2(B f, B w, B x, enum BitOp2 op, char* name) { if ((t & (ow-1)) || (rl<=USZ_MAX) thrF("•bit._%U: output too large", name); - w = convert((CastType){ ww, 0 }, w); - x = convert((CastType){ xw, 0 }, x); + w = convert((CastType){ ww, isCharType(TY(w)) }, w); + x = convert((CastType){ xw, isCharType(TY(x)) }, x); u8 rt = typeOfCast((CastType){ rw, 0 }); Arr* ra = m_arr(offsetof(TyArr,a) + (n+7)/8, rt, n>>rws); arr_shCopy(ra, x); From e5a7dface408657e9da13ac38dd0040ad99f5bb4 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Sat, 15 Oct 2022 17:59:20 -0400 Subject: [PATCH 8/8] =?UTF-8?q?Add=20=E2=80=A2bit=20op=20fuzz=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/bit.bqn | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/test/bit.bqn b/test/bit.bqn index 121320cb..f10cabf2 100644 --- a/test/bit.bqn +++ b/test/bit.bqn @@ -1,6 +1,7 @@ u ← ⌊100×(•UnixTime+1|100וMonoTime)@ r ← •MakeRand •Show u ⟨RandVals, casts⟩ ← ⟨r⟩ •Import "utils.bqn" +widths ← ⊑¨casts # Test •bit._cast first # Convert unsigned width 𝕗 to 𝕘 @@ -21,7 +22,42 @@ TestCast ← { f‿t 𝕊 len: len +↩ (1⌈÷˜´⊑¨c) | -len # Round up to exact conversion (c _bitcast ≡ c •bit._cast) len RandVals f } -cs ← / 64>⊑¨casts # TODO floats +cs ← / 64>widths # TODO floats cx ← ⊏⟜(32‿'c'⊸≢¨casts)⊸/ cs # TODO 32-bit char output ls ← (↕100) ∾ r.Range¨⊸+ ⌊ 100 × ↕∘⌈⌾(1.5⊸⋆⁼) 100 {cs (⋈ !∘TestCast 𝕩˙)⌜ cx}¨ ls + +# Now other •bit operations +OpArgs ← {_b‿F‿a: + m←(1