All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: Peter Maydell <peter.maydell@linaro.org>,
	qemu-arm@nongnu.org, Stephen Long <steplong@quicinc.com>
Subject: [PATCH v7 42/92] target/arm: Implement SVE2 HISTCNT, HISTSEG
Date: Mon, 24 May 2021 18:03:08 -0700	[thread overview]
Message-ID: <20210525010358.152808-43-richard.henderson@linaro.org> (raw)
In-Reply-To: <20210525010358.152808-1-richard.henderson@linaro.org>

From: Stephen Long <steplong@quicinc.com>

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Stephen Long <steplong@quicinc.com>
Message-Id: <20200416173109.8856-1-steplong@quicinc.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
v2: Fix overlap between output and input vectors.
v4: Fix histseg counting (zhiwei).
---
 target/arm/helper-sve.h    |   7 ++
 target/arm/sve.decode      |   6 ++
 target/arm/sve_helper.c    | 131 +++++++++++++++++++++++++++++++++++++
 target/arm/translate-sve.c |  19 ++++++
 4 files changed, 163 insertions(+)

diff --git a/target/arm/helper-sve.h b/target/arm/helper-sve.h
index 98e6b57e38..507a2fea8e 100644
--- a/target/arm/helper-sve.h
+++ b/target/arm/helper-sve.h
@@ -2551,6 +2551,13 @@ DEF_HELPER_FLAGS_5(sve2_nmatch_ppzz_b, TCG_CALL_NO_RWG,
 DEF_HELPER_FLAGS_5(sve2_nmatch_ppzz_h, TCG_CALL_NO_RWG,
                    i32, ptr, ptr, ptr, ptr, i32)
 
+DEF_HELPER_FLAGS_5(sve2_histcnt_s, TCG_CALL_NO_RWG,
+                   void, ptr, ptr, ptr, ptr, i32)
+DEF_HELPER_FLAGS_5(sve2_histcnt_d, TCG_CALL_NO_RWG,
+                   void, ptr, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_4(sve2_histseg, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
 DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_h, TCG_CALL_NO_RWG,
                    void, ptr, ptr, ptr, ptr, ptr, i32)
 DEF_HELPER_FLAGS_6(sve2_faddp_zpzz_s, TCG_CALL_NO_RWG,
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index 388bf92acf..8f501a083c 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -146,6 +146,7 @@
                 &rprrr_esz rn=%reg_movprfx
 @rdn_pg_rm_ra   ........ esz:2 . ra:5  ... pg:3 rm:5 rd:5 \
                 &rprrr_esz rn=%reg_movprfx
+@rd_pg_rn_rm   ........ esz:2 . rm:5 ... pg:3 rn:5 rd:5       &rprr_esz
 
 # One register operand, with governing predicate, vector element size
 @rd_pg_rn       ........ esz:2 ... ... ... pg:3 rn:5 rd:5       &rpr_esz
@@ -1336,6 +1337,11 @@ RSUBHNT         01000101 .. 1 ..... 011 111 ..... .....  @rd_rn_rm
 MATCH           01000101 .. 1 ..... 100 ... ..... 0 .... @pd_pg_rn_rm
 NMATCH          01000101 .. 1 ..... 100 ... ..... 1 .... @pd_pg_rn_rm
 
+### SVE2 Histogram Computation
+
+HISTCNT         01000101 .. 1 ..... 110 ... ..... .....  @rd_pg_rn_rm
+HISTSEG         01000101 .. 1 ..... 101 000 ..... .....  @rd_rn_rm
+
 ## SVE2 floating-point pairwise operations
 
 FADDP           01100100 .. 010 00 0 100 ... ..... ..... @rdn_pg_rm
diff --git a/target/arm/sve_helper.c b/target/arm/sve_helper.c
index 891f6ff453..662ed80b1c 100644
--- a/target/arm/sve_helper.c
+++ b/target/arm/sve_helper.c
@@ -7071,3 +7071,134 @@ DO_PPZZ_MATCH(sve2_nmatch_ppzz_b, MO_8, true)
 DO_PPZZ_MATCH(sve2_nmatch_ppzz_h, MO_16, true)
 
 #undef DO_PPZZ_MATCH
+
+void HELPER(sve2_histcnt_s)(void *vd, void *vn, void *vm, void *vg,
+                            uint32_t desc)
+{
+    ARMVectorReg scratch;
+    intptr_t i, j;
+    intptr_t opr_sz = simd_oprsz(desc);
+    uint32_t *d = vd, *n = vn, *m = vm;
+    uint8_t *pg = vg;
+
+    if (d == n) {
+        n = memcpy(&scratch, n, opr_sz);
+        if (d == m) {
+            m = n;
+        }
+    } else if (d == m) {
+        m = memcpy(&scratch, m, opr_sz);
+    }
+
+    for (i = 0; i < opr_sz; i += 4) {
+        uint64_t count = 0;
+        uint8_t pred;
+
+        pred = pg[H1(i >> 3)] >> (i & 7);
+        if (pred & 1) {
+            uint32_t nn = n[H4(i >> 2)];
+
+            for (j = 0; j <= i; j += 4) {
+                pred = pg[H1(j >> 3)] >> (j & 7);
+                if ((pred & 1) && nn == m[H4(j >> 2)]) {
+                    ++count;
+                }
+            }
+        }
+        d[H4(i >> 2)] = count;
+    }
+}
+
+void HELPER(sve2_histcnt_d)(void *vd, void *vn, void *vm, void *vg,
+                            uint32_t desc)
+{
+    ARMVectorReg scratch;
+    intptr_t i, j;
+    intptr_t opr_sz = simd_oprsz(desc);
+    uint64_t *d = vd, *n = vn, *m = vm;
+    uint8_t *pg = vg;
+
+    if (d == n) {
+        n = memcpy(&scratch, n, opr_sz);
+        if (d == m) {
+            m = n;
+        }
+    } else if (d == m) {
+        m = memcpy(&scratch, m, opr_sz);
+    }
+
+    for (i = 0; i < opr_sz / 8; ++i) {
+        uint64_t count = 0;
+        if (pg[H1(i)] & 1) {
+            uint64_t nn = n[i];
+            for (j = 0; j <= i; ++j) {
+                if ((pg[H1(j)] & 1) && nn == m[j]) {
+                    ++count;
+                }
+            }
+        }
+        d[i] = count;
+    }
+}
+
+/*
+ * Returns the number of bytes in m0 and m1 that match n.
+ * Unlike do_match2 we don't just need true/false, we need an exact count.
+ * This requires two extra logical operations.
+ */
+static inline uint64_t do_histseg_cnt(uint8_t n, uint64_t m0, uint64_t m1)
+{
+    const uint64_t mask = dup_const(MO_8, 0x7f);
+    uint64_t cmp0, cmp1;
+
+    cmp1 = dup_const(MO_8, n);
+    cmp0 = cmp1 ^ m0;
+    cmp1 = cmp1 ^ m1;
+
+    /*
+     * 1: clear msb of each byte to avoid carry to next byte (& mask)
+     * 2: carry in to msb if byte != 0 (+ mask)
+     * 3: set msb if cmp has msb set (| cmp)
+     * 4: set ~msb to ignore them (| mask)
+     * We now have 0xff for byte != 0 or 0x7f for byte == 0.
+     * 5: invert, resulting in 0x80 if and only if byte == 0.
+     */
+    cmp0 = ~(((cmp0 & mask) + mask) | cmp0 | mask);
+    cmp1 = ~(((cmp1 & mask) + mask) | cmp1 | mask);
+
+    /*
+     * Combine the two compares in a way that the bits do
+     * not overlap, and so preserves the count of set bits.
+     * If the host has an efficient instruction for ctpop,
+     * then ctpop(x) + ctpop(y) has the same number of
+     * operations as ctpop(x | (y >> 1)).  If the host does
+     * not have an efficient ctpop, then we only want to
+     * use it once.
+     */
+    return ctpop64(cmp0 | (cmp1 >> 1));
+}
+
+void HELPER(sve2_histseg)(void *vd, void *vn, void *vm, uint32_t desc)
+{
+    intptr_t i, j;
+    intptr_t opr_sz = simd_oprsz(desc);
+
+    for (i = 0; i < opr_sz; i += 16) {
+        uint64_t n0 = *(uint64_t *)(vn + i);
+        uint64_t m0 = *(uint64_t *)(vm + i);
+        uint64_t n1 = *(uint64_t *)(vn + i + 8);
+        uint64_t m1 = *(uint64_t *)(vm + i + 8);
+        uint64_t out0 = 0;
+        uint64_t out1 = 0;
+
+        for (j = 0; j < 64; j += 8) {
+            uint64_t cnt0 = do_histseg_cnt(n0 >> j, m0, m1);
+            uint64_t cnt1 = do_histseg_cnt(n1 >> j, m0, m1);
+            out0 |= cnt0 << j;
+            out1 |= cnt1 << j;
+        }
+
+        *(uint64_t *)(vd + i) = out0;
+        *(uint64_t *)(vd + i + 8) = out1;
+    }
+}
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 484d4218b5..13f84d14d3 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -7504,6 +7504,25 @@ static bool trans_##NAME(DisasContext *s, arg_rprr_esz *a)                  \
 DO_SVE2_PPZZ_MATCH(MATCH, match)
 DO_SVE2_PPZZ_MATCH(NMATCH, nmatch)
 
+static bool trans_HISTCNT(DisasContext *s, arg_rprr_esz *a)
+{
+    static gen_helper_gvec_4 * const fns[2] = {
+        gen_helper_sve2_histcnt_s, gen_helper_sve2_histcnt_d
+    };
+    if (a->esz < 2) {
+        return false;
+    }
+    return do_sve2_zpzz_ool(s, a, fns[a->esz - 2]);
+}
+
+static bool trans_HISTSEG(DisasContext *s, arg_rrr_esz *a)
+{
+    if (a->esz != 0) {
+        return false;
+    }
+    return do_sve2_zzz_ool(s, a, gen_helper_sve2_histseg);
+}
+
 static bool do_sve2_zpzz_fp(DisasContext *s, arg_rprr_esz *a,
                             gen_helper_gvec_4_ptr *fn)
 {
-- 
2.25.1



  parent reply	other threads:[~2021-05-25  1:49 UTC|newest]

Thread overview: 97+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-25  1:02 [PATCH v7 00/92] target/arm: Implement SVE2 Richard Henderson
2021-05-25  1:02 ` [PATCH v7 01/92] target/arm: Add ID_AA64ZFR0 fields and isar_feature_aa64_sve2 Richard Henderson
2022-07-25  7:05   ` Zenghui Yu via
2022-07-25 14:46     ` Richard Henderson
2021-05-25  1:02 ` [PATCH v7 02/92] target/arm: Implement SVE2 Integer Multiply - Unpredicated Richard Henderson
2021-05-25  1:02 ` [PATCH v7 03/92] target/arm: Implement SVE2 integer pairwise add and accumulate long Richard Henderson
2021-05-25  1:02 ` [PATCH v7 04/92] target/arm: Implement SVE2 integer unary operations (predicated) Richard Henderson
2021-05-25  1:02 ` [PATCH v7 05/92] target/arm: Split out saturating/rounding shifts from neon Richard Henderson
2021-05-25  1:02 ` [PATCH v7 06/92] target/arm: Implement SVE2 saturating/rounding bitwise shift left (predicated) Richard Henderson
2021-05-25  1:02 ` [PATCH v7 07/92] target/arm: Implement SVE2 integer halving add/subtract (predicated) Richard Henderson
2021-05-25  1:02 ` [PATCH v7 08/92] target/arm: Implement SVE2 integer pairwise arithmetic Richard Henderson
2021-05-25  1:02 ` [PATCH v7 09/92] target/arm: Implement SVE2 saturating add/subtract (predicated) Richard Henderson
2021-05-25  1:02 ` [PATCH v7 10/92] target/arm: Implement SVE2 integer add/subtract long Richard Henderson
2021-05-25  1:02 ` [PATCH v7 11/92] target/arm: Implement SVE2 integer add/subtract interleaved long Richard Henderson
2021-05-25  1:02 ` [PATCH v7 12/92] target/arm: Implement SVE2 integer add/subtract wide Richard Henderson
2021-05-25  1:02 ` [PATCH v7 13/92] target/arm: Implement SVE2 integer multiply long Richard Henderson
2021-05-25  1:02 ` [PATCH v7 14/92] target/arm: Implement SVE2 PMULLB, PMULLT Richard Henderson
2021-05-25  1:02 ` [PATCH v7 15/92] target/arm: Implement SVE2 bitwise shift left long Richard Henderson
2021-05-25  1:02 ` [PATCH v7 16/92] target/arm: Implement SVE2 bitwise exclusive-or interleaved Richard Henderson
2021-05-25  1:02 ` [PATCH v7 17/92] target/arm: Implement SVE2 bitwise permute Richard Henderson
2021-05-25  1:02 ` [PATCH v7 18/92] target/arm: Implement SVE2 complex integer add Richard Henderson
2021-05-25  1:02 ` [PATCH v7 19/92] target/arm: Implement SVE2 integer absolute difference and accumulate long Richard Henderson
2021-05-25  1:02 ` [PATCH v7 20/92] target/arm: Implement SVE2 integer add/subtract long with carry Richard Henderson
2021-05-25  1:02 ` [PATCH v7 21/92] target/arm: Implement SVE2 bitwise shift right and accumulate Richard Henderson
2021-05-25  1:02 ` [PATCH v7 22/92] target/arm: Implement SVE2 bitwise shift and insert Richard Henderson
2021-05-25  1:02 ` [PATCH v7 23/92] target/arm: Implement SVE2 integer absolute difference and accumulate Richard Henderson
2021-05-25  1:02 ` [PATCH v7 24/92] target/arm: Implement SVE2 saturating extract narrow Richard Henderson
2021-05-25  1:02 ` [PATCH v7 25/92] target/arm: Implement SVE2 floating-point pairwise Richard Henderson
2021-05-25  1:02 ` [PATCH v7 26/92] target/arm: Implement SVE2 SHRN, RSHRN Richard Henderson
2021-05-25  1:02 ` [PATCH v7 27/92] target/arm: Implement SVE2 SQSHRUN, SQRSHRUN Richard Henderson
2021-05-25  1:02 ` [PATCH v7 28/92] target/arm: Implement SVE2 UQSHRN, UQRSHRN Richard Henderson
2021-05-25  1:02 ` [PATCH v7 29/92] target/arm: Implement SVE2 SQSHRN, SQRSHRN Richard Henderson
2021-05-25  1:02 ` [PATCH v7 30/92] target/arm: Implement SVE2 WHILEGT, WHILEGE, WHILEHI, WHILEHS Richard Henderson
2021-05-25  1:02 ` [PATCH v7 31/92] target/arm: Implement SVE2 WHILERW, WHILEWR Richard Henderson
2021-05-25  1:02 ` [PATCH v7 32/92] target/arm: Implement SVE2 bitwise ternary operations Richard Henderson
2021-05-25  1:02 ` [PATCH v7 33/92] target/arm: Implement SVE2 MATCH, NMATCH Richard Henderson
2021-05-25  1:03 ` [PATCH v7 34/92] target/arm: Implement SVE2 saturating multiply-add long Richard Henderson
2021-05-25  1:03 ` [PATCH v7 35/92] target/arm: Implement SVE2 saturating multiply-add high Richard Henderson
2021-05-25  1:03 ` [PATCH v7 36/92] target/arm: Implement SVE2 integer multiply-add long Richard Henderson
2021-05-25  1:03 ` [PATCH v7 37/92] target/arm: Implement SVE2 complex integer multiply-add Richard Henderson
2021-05-25  1:03 ` [PATCH v7 38/92] target/arm: Implement SVE2 ADDHNB, ADDHNT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 39/92] target/arm: Implement SVE2 RADDHNB, RADDHNT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 40/92] target/arm: Implement SVE2 SUBHNB, SUBHNT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 41/92] target/arm: Implement SVE2 RSUBHNB, RSUBHNT Richard Henderson
2021-05-25  1:03 ` Richard Henderson [this message]
2021-05-25  1:03 ` [PATCH v7 43/92] target/arm: Implement SVE2 XAR Richard Henderson
2021-05-25  1:03 ` [PATCH v7 44/92] target/arm: Implement SVE2 scatter store insns Richard Henderson
2021-05-25  1:03 ` [PATCH v7 45/92] target/arm: Implement SVE2 gather load insns Richard Henderson
2021-05-25  1:03 ` [PATCH v7 46/92] target/arm: Implement SVE2 FMMLA Richard Henderson
2021-05-25  1:03 ` [PATCH v7 47/92] target/arm: Implement SVE2 SPLICE, EXT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 48/92] target/arm: Use correct output type for gvec_sdot_*_b Richard Henderson
2021-05-25  1:03 ` [PATCH v7 49/92] target/arm: Pass separate addend to {U, S}DOT helpers Richard Henderson
2021-05-25  1:03 ` [PATCH v7 50/92] target/arm: Pass separate addend to FCMLA helpers Richard Henderson
2021-05-25  1:03 ` [PATCH v7 51/92] target/arm: Split out formats for 2 vectors + 1 index Richard Henderson
2021-05-25  1:03 ` [PATCH v7 52/92] target/arm: Split out formats for 3 " Richard Henderson
2021-05-25  1:03 ` [PATCH v7 53/92] target/arm: Implement SVE2 integer multiply (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 54/92] target/arm: Implement SVE2 integer multiply-add (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 55/92] target/arm: Implement SVE2 saturating multiply-add high (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 56/92] target/arm: Implement SVE2 saturating multiply-add (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 57/92] target/arm: Implement SVE2 saturating multiply (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 58/92] target/arm: Implement SVE2 signed saturating doubling multiply high Richard Henderson
2021-05-25  1:03 ` [PATCH v7 59/92] target/arm: Implement SVE2 saturating multiply high (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 60/92] target/arm: Implement SVE2 multiply-add long (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 61/92] target/arm: Implement SVE2 integer multiply " Richard Henderson
2021-05-25  1:03 ` [PATCH v7 62/92] target/arm: Implement SVE2 complex integer multiply-add (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 63/92] target/arm: Implement SVE2 complex integer dot product Richard Henderson
2021-05-25  1:03 ` [PATCH v7 64/92] target/arm: Macroize helper_gvec_{s,u}dot_{b,h} Richard Henderson
2021-05-25  1:03 ` [PATCH v7 65/92] target/arm: Macroize helper_gvec_{s,u}dot_idx_{b,h} Richard Henderson
2021-05-25  1:03 ` [PATCH v7 66/92] target/arm: Implement SVE mixed sign dot product (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 67/92] target/arm: Implement SVE mixed sign dot product Richard Henderson
2021-05-25  1:03 ` [PATCH v7 68/92] target/arm: Implement SVE2 crypto unary operations Richard Henderson
2021-05-25  1:03 ` [PATCH v7 69/92] target/arm: Implement SVE2 crypto destructive binary operations Richard Henderson
2021-05-25  1:03 ` [PATCH v7 70/92] target/arm: Implement SVE2 crypto constructive " Richard Henderson
2021-05-25  1:03 ` [PATCH v7 71/92] target/arm: Implement SVE2 TBL, TBX Richard Henderson
2021-05-25  1:03 ` [PATCH v7 72/92] target/arm: Implement SVE2 FCVTNT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 73/92] target/arm: Implement SVE2 FCVTLT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 74/92] target/arm: Implement SVE2 FCVTXNT, FCVTX Richard Henderson
2021-05-25  1:03 ` [PATCH v7 75/92] target/arm: Implement SVE2 FLOGB Richard Henderson
2021-05-25  1:03 ` [PATCH v7 76/92] target/arm: Share table of sve load functions Richard Henderson
2021-05-25  1:03 ` [PATCH v7 77/92] target/arm: Tidy do_ldrq Richard Henderson
2021-05-25  1:03 ` [PATCH v7 78/92] target/arm: Implement SVE2 LD1RO Richard Henderson
2021-05-25  1:03 ` [PATCH v7 79/92] target/arm: Implement 128-bit ZIP, UZP, TRN Richard Henderson
2021-05-25  1:03 ` [PATCH v7 80/92] target/arm: Implement SVE2 bitwise shift immediate Richard Henderson
2021-05-25  1:03 ` [PATCH v7 81/92] target/arm: Move endian adjustment macros to vec_internal.h Richard Henderson
2021-05-25  1:03 ` [PATCH v7 82/92] target/arm: Implement SVE2 fp multiply-add long Richard Henderson
2021-05-25  1:03 ` [PATCH v7 83/92] target/arm: Implement aarch64 SUDOT, USDOT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 84/92] target/arm: Split out do_neon_ddda_fpst Richard Henderson
2021-05-25  1:03 ` [PATCH v7 85/92] target/arm: Remove unused fpst from VDOT_scalar Richard Henderson
2021-05-25  1:03 ` [PATCH v7 86/92] target/arm: Fix decode for VDOT (indexed) Richard Henderson
2021-05-25  1:03 ` [PATCH v7 87/92] target/arm: Split out do_neon_ddda Richard Henderson
2021-05-25  1:03 ` [PATCH v7 88/92] target/arm: Split decode of VSDOT and VUDOT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 89/92] target/arm: Implement aarch32 VSUDOT, VUSDOT Richard Henderson
2021-05-25  1:03 ` [PATCH v7 90/92] target/arm: Implement integer matrix multiply accumulate Richard Henderson
2021-05-25  1:03 ` [PATCH v7 91/92] linux-user/aarch64: Enable hwcap bits for sve2 and related extensions Richard Henderson
2021-05-25  1:03 ` [PATCH v7 92/92] target/arm: Enable SVE2 " Richard Henderson
2021-05-25  2:37 ` [PATCH v7 00/92] target/arm: Implement SVE2 no-reply
2021-05-25 12:33 ` Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210525010358.152808-43-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=steplong@quicinc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.