#include "../core.h" #include "../utils/calls.h" NOINLINE i32 compareF(B w, B x) { if (isNum(w) & isC32(x)) return -1; if (isC32(w) & isNum(x)) return 1; i32 atmNeg; if (isAtm(w)) { atmNeg = 0; atmW:; if (isAtm(x)) thrM("Invalid comparison"); if (IA(x)==0) return atmNeg? -1 : 1; i32 c = compare(w, IGetU(x,0)); return (c<=0)^atmNeg? -1 : 1; } if (isAtm(x)) { B t=w; w=x; x=t; atmNeg=1; goto atmW; } if (w.u==x.u && TI(w,arrD1)) return 0; ur wr=RNK(w); usz* wsh=SH(w); ur xr=RNK(x); usz* xsh=SH(x); i32 rc = ICMP(wr, xr); ur rr = wr0); u64* wp = w; u64* xp = x; usz q = l/64; for (usz i=0; i0); \ if (d!=0) { void* t=w; w=x; x=t; } \ u64* wp = w; T* xp = x; \ for (usz i=0; i0); INIT \ S* wp = w; T* xp = x; \ for (usz i=0; i0); return false; } #define MAKE_TABLE(NAME, F64_F64) \ INIT_GLOBAL MatchFn NAME[] = { \ F(1_1), F(1_8), F(1_16), F(1_32), F(1_f64), notEq, notEq, notEq, \ F(1_8), F(8_8), F(s8_16), F(s8_32), F(s8_f64), notEq, notEq, notEq, \ F(1_16), F(s8_16), F(8_8), F(s16_32), F(s16_f64), notEq, notEq, notEq, \ F(1_32), F(s8_32), F(s16_32), F(8_8), F(s32_f64), notEq, notEq, notEq, \ F(1_f64), F(s8_f64), F(s16_f64), F(s32_f64), F(F64_F64), notEq, notEq, notEq, \ notEq, notEq, notEq, notEq, notEq, F(8_8), F(u8_16), F(u8_32), \ notEq, notEq, notEq, notEq, notEq, F(u8_16), F(8_8), F(u16_32), \ notEq, notEq, notEq, notEq, notEq, F(u8_32), F(u16_32), F(8_8), \ }; MAKE_TABLE(matchFns, f64_f64); MAKE_TABLE(matchFnsR, f64_f64_reflexive); #undef MAKE_TABLE #undef F static NOINLINE bool equalSlow(B w, B x, usz ia) { SLOW2("equal", w, x); SGetU(x) SGetU(w) for (usz i = 0; i < ia; i++) if(!equal(GetU(w,i),GetU(x,i))) return false; return true; } static NOINLINE bool eequalSlow(B w, B x, usz ia) { SLOW2("eequal", w, x); SGetU(x) SGetU(w) for (usz i = 0; i < ia; i++) if(!eequal(GetU(w,i),GetU(x,i))) return false; return true; } #define MATCH_IMPL(ATOM, SLOW, MATCH) \ if (isAtm(w)) { \ if (!isAtm(x)) return false; \ return ATOM(w, x); \ } \ if (isAtm(x)) return false; \ ur wr = RNK(w); \ if (wr!=RNK(x)) return false; \ usz ia = IA(x); \ if (LIKELY(wr==1)) { if (ia != IA(w)) return false; } \ else if (!eqShPart(SH(w), SH(x), wr)) return false; \ if (ia==0) return true; \ u8 we = TI(w,elType); \ u8 xe = TI(x,elType); \ if (we!=el_B && xe!=el_B) { \ MatchFnObj f = MATCH(we,xe); \ return MATCH_CALL(f, tyany_ptr(w), tyany_ptr(x), ia); \ } \ return SLOW(w, x, ia); NOINLINE bool equal(B w, B x) { // doesn't consume NOGC_CHECK("cannot use equal(w,x) during noAlloc"); MATCH_IMPL(atomEqual, equalSlow, MATCH_GET); } bool eequal(B w, B x) { // doesn't consume NOGC_CHECK("cannot use eequal(w,x) during noAlloc"); if (w.u==x.u) return true; MATCH_IMPL(atomEEqual, eequalSlow, MATCHR_GET); }