diff options
| author | eunhhu <[email protected]> | 2026-10-08 15:57:16 +0100 |
|---|---|---|
| committer | eunhhu <[email protected]> | 2026-10-08 15:57:16 +0100 |
| commit | d371271c3fcf8ac527f2061ece9ba38f3e009e3e (patch) | |
| tree | 071e7a9a05c05cce585873064f50d3fe7292b482 | |
| parent | 6828a7d07f9de815c858a295124f6bcde9bd861a (diff) | |
| download | pure-d371271c3fcf8ac527f2061ece9ba38f3e009e3e.tar.gz pure-d371271c3fcf8ac527f2061ece9ba38f3e009e3e.zip | |
Batch executor, stage 3 of design 025: four-byte MUL (words_op): a product below 2^32 of whole numbers below it in four-byte lanes, past it the product's high half sends the lanes back to numbers as ADD's sum does (umull and umull2 over four lanes); matmul's products and sums stay in four bytes; seeds 1 2 3 5 23 (default and PURE_SELECT=all), the fixed sources and the unit tests pass
| -rw-r--r-- | core/module-batch.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/core/module-batch.c b/core/module-batch.c index 5766818..68941dc 100644 --- a/core/module-batch.c +++ b/core/module-batch.c @@ -410,6 +410,11 @@ static bool words_op(uint8_t op, uint32_t *restrict out, const uint32_t *restric else if (uy) for (unsigned l = 0; l < n; ++l) over |= xs[l] < yk; else for (unsigned l = 0; l < n; ++l) over |= xs[l] < ys[l]; break; + case PURE_OP_MUL: /* past 2^32: the product's high half */ + if (ux) for (unsigned l = 0; l < n; ++l) { uint64_t p = (uint64_t)xk * ys[l]; out[l] = (uint32_t)p, over |= (uint32_t)(p >> 32); } + else if (uy) for (unsigned l = 0; l < n; ++l) { uint64_t p = (uint64_t)xs[l] * yk; out[l] = (uint32_t)p, over |= (uint32_t)(p >> 32); } + else for (unsigned l = 0; l < n; ++l) { uint64_t p = (uint64_t)xs[l] * ys[l]; out[l] = (uint32_t)p, over |= (uint32_t)(p >> 32); } + break; case PURE_OP_MIN: EACH(uint32_t, a < c ? a : c); break; case PURE_OP_MAX: EACH(uint32_t, a > c ? a : c); break; case PURE_OP_LT: EACH(uint32_t, a < c); break; @@ -488,7 +493,7 @@ static void numbers_test(uint8_t op, uint32_t *restrict out, const double *restr static bool word_form(uint8_t op) { switch (op) { - case PURE_OP_ADD: case PURE_OP_SUB: case PURE_OP_MIN: case PURE_OP_MAX: case PURE_OP_LT: case PURE_OP_LE: + case PURE_OP_ADD: case PURE_OP_SUB: case PURE_OP_MUL: case PURE_OP_MIN: case PURE_OP_MAX: case PURE_OP_LT: case PURE_OP_LE: case PURE_OP_GT: case PURE_OP_GE: case PURE_OP_EQ: case PURE_OP_NE: case PURE_OP_AND: case PURE_OP_OR: return true; default: return false; } |
