From 80f8ac96435d632eeae14a94d897743918686975 Mon Sep 17 00:00:00 2001 From: Marshall Lochbaum Date: Mon, 10 Oct 2022 22:06:51 -0400 Subject: [PATCH] =?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); }