All of lore.kernel.org
 help / color / mirror / Atom feed
From: Taylor Simpson <tsimpson@quicinc.com>
To: qemu-devel@nongnu.org
Cc: tsimpson@quicinc.com, richard.henderson@linaro.org,
	philmd@linaro.org, peter.maydell@linaro.org, bcain@quicinc.com,
	quic_mathbern@quicinc.com, stefanha@redhat.com
Subject: [PULL 09/21] Hexagon (target/hexagon) Add overrides for various forms of jump
Date: Fri, 16 Dec 2022 12:48:33 -0800	[thread overview]
Message-ID: <20221216204845.19290-10-tsimpson@quicinc.com> (raw)
In-Reply-To: <20221216204845.19290-1-tsimpson@quicinc.com>

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
Message-Id: <20221108162906.3166-10-tsimpson@quicinc.com>
---
 target/hexagon/gen_tcg.h | 201 +++++++++++++++++++++++++++++++++++++++
 target/hexagon/genptr.c  |  43 +++++++++
 2 files changed, 244 insertions(+)

diff --git a/target/hexagon/gen_tcg.h b/target/hexagon/gen_tcg.h
index 506b454e4e..3583f390e9 100644
--- a/target/hexagon/gen_tcg.h
+++ b/target/hexagon/gen_tcg.h
@@ -797,6 +797,207 @@
 #define fGEN_TCG_J4_tstbit0_fp1_jump_t(SHORTCODE) \
     gen_cmpnd_tstbit0_jmp(ctx, 1, RsV, TCG_COND_NE, riV)
 
+#define fGEN_TCG_J2_jump(SHORTCODE) \
+    gen_jump(ctx, riV)
+#define fGEN_TCG_J2_jumpr(SHORTCODE) \
+    gen_jumpr(ctx, RsV)
+#define fGEN_TCG_J4_jumpseti(SHORTCODE) \
+    do { \
+        tcg_gen_movi_tl(RdV, UiV); \
+        gen_jump(ctx, riV); \
+    } while (0)
+
+#define fGEN_TCG_cond_jumpt(COND) \
+    do { \
+        TCGv LSB = tcg_temp_new(); \
+        COND; \
+        gen_cond_jump(ctx, TCG_COND_EQ, LSB, riV); \
+        tcg_temp_free(LSB); \
+    } while (0)
+#define fGEN_TCG_cond_jumpf(COND) \
+    do { \
+        TCGv LSB = tcg_temp_new(); \
+        COND; \
+        gen_cond_jump(ctx, TCG_COND_NE, LSB, riV); \
+        tcg_temp_free(LSB); \
+    } while (0)
+
+#define fGEN_TCG_J2_jumpt(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumptpt(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumpf(SHORTCODE) \
+    fGEN_TCG_cond_jumpf(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumpfpt(SHORTCODE) \
+    fGEN_TCG_cond_jumpf(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumptnew(SHORTCODE) \
+    gen_cond_jump(ctx, TCG_COND_EQ, PuN, riV)
+#define fGEN_TCG_J2_jumptnewpt(SHORTCODE) \
+    gen_cond_jump(ctx, TCG_COND_EQ, PuN, riV)
+#define fGEN_TCG_J2_jumpfnewpt(SHORTCODE) \
+    fGEN_TCG_cond_jumpf(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumpfnew(SHORTCODE) \
+    fGEN_TCG_cond_jumpf(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprz(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprzpt(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_NE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprnz(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_EQ, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprnzpt(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_EQ, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprgtez(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_GE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprgtezpt(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_GE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprltez(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0))
+#define fGEN_TCG_J2_jumprltezpt(SHORTCODE) \
+    fGEN_TCG_cond_jumpt(tcg_gen_setcondi_tl(TCG_COND_LE, LSB, RsV, 0))
+
+#define fGEN_TCG_cond_jumprt(COND) \
+    do { \
+        TCGv LSB = tcg_temp_new(); \
+        COND; \
+        gen_cond_jumpr(ctx, RsV, TCG_COND_EQ, LSB); \
+        tcg_temp_free(LSB); \
+    } while (0)
+#define fGEN_TCG_cond_jumprf(COND) \
+    do { \
+        TCGv LSB = tcg_temp_new(); \
+        COND; \
+        gen_cond_jumpr(ctx, RsV, TCG_COND_NE, LSB); \
+        tcg_temp_free(LSB); \
+    } while (0)
+
+#define fGEN_TCG_J2_jumprt(SHORTCODE) \
+    fGEN_TCG_cond_jumprt(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprtpt(SHORTCODE) \
+    fGEN_TCG_cond_jumprt(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprf(SHORTCODE) \
+    fGEN_TCG_cond_jumprf(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprfpt(SHORTCODE) \
+    fGEN_TCG_cond_jumprf(fLSBOLD(PuV))
+#define fGEN_TCG_J2_jumprtnew(SHORTCODE) \
+    fGEN_TCG_cond_jumprt(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprtnewpt(SHORTCODE) \
+    fGEN_TCG_cond_jumprt(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprfnew(SHORTCODE) \
+    fGEN_TCG_cond_jumprf(fLSBNEW(PuN))
+#define fGEN_TCG_J2_jumprfnewpt(SHORTCODE) \
+    fGEN_TCG_cond_jumprf(fLSBNEW(PuN))
+
+/*
+ * New value compare & jump instructions
+ * if ([!]COND(r0.new, r1) jump:t address
+ * if ([!]COND(r0.new, #7) jump:t address
+ */
+#define fGEN_TCG_J4_cmpgt_t_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_GT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_t_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_GT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_f_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_LE, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgt_f_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_LE, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmpeq_t_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_EQ, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_t_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_EQ, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_f_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_NE, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpeq_f_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_NE, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmplt_t_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_LT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmplt_t_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_LT, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmplt_f_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_GE, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmplt_f_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_GE, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmpeqi_t_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_t_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_f_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_NE, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpeqi_f_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_NE, NsN, UiV, riV)
+
+#define fGEN_TCG_J4_cmpgti_t_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_GT, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpgti_t_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_GT, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpgti_f_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpgti_f_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, UiV, riV)
+
+#define fGEN_TCG_J4_cmpltu_t_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_LTU, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpltu_t_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_LTU, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpltu_f_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_GEU, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpltu_f_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_GEU, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmpgtui_t_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_GTU, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpgtui_t_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_GTU, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpgtui_f_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_LEU, NsN, UiV, riV)
+#define fGEN_TCG_J4_cmpgtui_f_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_LEU, NsN, UiV, riV)
+
+#define fGEN_TCG_J4_cmpgtu_t_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_GTU, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_t_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_GTU, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_f_jumpnv_t(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_LEU, NsN, RtV, riV)
+#define fGEN_TCG_J4_cmpgtu_f_jumpnv_nt(SHORTCODE) \
+    gen_cmp_jumpnv(ctx, TCG_COND_LEU, NsN, RtV, riV)
+
+#define fGEN_TCG_J4_cmpeqn1_t_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, -1, riV)
+#define fGEN_TCG_J4_cmpeqn1_t_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_EQ, NsN, -1, riV)
+#define fGEN_TCG_J4_cmpeqn1_f_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_NE, NsN, -1, riV)
+#define fGEN_TCG_J4_cmpeqn1_f_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_NE, NsN, -1, riV)
+
+#define fGEN_TCG_J4_cmpgtn1_t_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_GT, NsN, -1, riV)
+#define fGEN_TCG_J4_cmpgtn1_t_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_GT, NsN, -1, riV)
+#define fGEN_TCG_J4_cmpgtn1_f_jumpnv_t(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, -1, riV)
+#define fGEN_TCG_J4_cmpgtn1_f_jumpnv_nt(SHORTCODE) \
+    gen_cmpi_jumpnv(ctx, TCG_COND_LE, NsN, -1, riV)
+
+#define fGEN_TCG_J4_tstbit0_t_jumpnv_t(SHORTCODE) \
+    gen_testbit0_jumpnv(ctx, NsN, TCG_COND_EQ, riV)
+#define fGEN_TCG_J4_tstbit0_t_jumpnv_nt(SHORTCODE) \
+    gen_testbit0_jumpnv(ctx, NsN, TCG_COND_EQ, riV)
+#define fGEN_TCG_J4_tstbit0_f_jumpnv_t(SHORTCODE) \
+    gen_testbit0_jumpnv(ctx, NsN, TCG_COND_NE, riV)
+#define fGEN_TCG_J4_tstbit0_f_jumpnv_nt(SHORTCODE) \
+    gen_testbit0_jumpnv(ctx, NsN, TCG_COND_NE, riV)
+
+/* r0 = r1 ; jump address */
+#define fGEN_TCG_J4_jumpsetr(SHORTCODE) \
+    do { \
+        tcg_gen_mov_tl(RdV, RsV); \
+        gen_jump(ctx, riV); \
+    } while (0)
+
 #define fGEN_TCG_J2_pause(SHORTCODE) \
     do { \
         uiV = uiV; \
diff --git a/target/hexagon/genptr.c b/target/hexagon/genptr.c
index c003800247..be9c715ea8 100644
--- a/target/hexagon/genptr.c
+++ b/target/hexagon/genptr.c
@@ -495,6 +495,12 @@ static void gen_compare(TCGCond cond, TCGv res, TCGv arg1, TCGv arg2)
     tcg_gen_movcond_tl(cond, res, arg1, arg2, one, zero);
 }
 
+static void gen_cond_jumpr(DisasContext *ctx, TCGv dst_pc,
+                           TCGCond cond, TCGv pred)
+{
+    gen_write_new_pc_addr(ctx, dst_pc, cond, pred);
+}
+
 static void gen_cond_jump(DisasContext *ctx, TCGCond cond, TCGv pred,
                           int pc_off)
 {
@@ -577,6 +583,25 @@ static void gen_cmpnd_tstbit0_jmp(DisasContext *ctx,
     }
 }
 
+static void gen_testbit0_jumpnv(DisasContext *ctx,
+                                TCGv arg, TCGCond cond, int pc_off)
+{
+    TCGv pred = tcg_temp_new();
+    tcg_gen_andi_tl(pred, arg, 1);
+    gen_cond_jump(ctx, cond, pred, pc_off);
+    tcg_temp_free(pred);
+}
+
+static void gen_jump(DisasContext *ctx, int pc_off)
+{
+    gen_write_new_pc_pcrel(ctx, pc_off, TCG_COND_ALWAYS, NULL);
+}
+
+static void gen_jumpr(DisasContext *ctx, TCGv new_pc)
+{
+    gen_write_new_pc_addr(ctx, new_pc, TCG_COND_ALWAYS, NULL);
+}
+
 static void gen_call(DisasContext *ctx, int pc_off)
 {
     TCGv next_PC =
@@ -601,6 +626,24 @@ static void gen_cond_call(DisasContext *ctx, TCGv pred,
     gen_set_label(skip);
 }
 
+static void gen_cmp_jumpnv(DisasContext *ctx,
+                           TCGCond cond, TCGv val, TCGv src, int pc_off)
+{
+    TCGv pred = tcg_temp_new();
+    tcg_gen_setcond_tl(cond, pred, val, src);
+    gen_cond_jump(ctx, TCG_COND_EQ, pred, pc_off);
+    tcg_temp_free(pred);
+}
+
+static void gen_cmpi_jumpnv(DisasContext *ctx,
+                            TCGCond cond, TCGv val, int src, int pc_off)
+{
+    TCGv pred = tcg_temp_new();
+    tcg_gen_setcondi_tl(cond, pred, val, src);
+    gen_cond_jump(ctx, TCG_COND_EQ, pred, pc_off);
+    tcg_temp_free(pred);
+}
+
 /* Shift left with saturation */
 static void gen_shl_sat(TCGv dst, TCGv src, TCGv shift_amt)
 {
-- 
2.17.1


  parent reply	other threads:[~2022-12-16 21:05 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-16 20:48 [PULL 00/21] Hexagon update: bug fixes, performance, idef-parser Taylor Simpson
2022-12-16 20:48 ` [PULL 01/21] Hexagon (target/hexagon) Add pkt and insn to DisasContext Taylor Simpson
2022-12-16 20:48 ` [PULL 02/21] Hexagon (target/hexagon) Fix predicated assignment to .tmp and .cur Taylor Simpson
2022-12-16 20:48 ` [PULL 03/21] Hexagon (target/hexagon) Add overrides for S2_asr_r_r_sat/S2_asl_r_r_sat Taylor Simpson
2022-12-16 20:48 ` [PULL 04/21] Hexagon (target/hexagon) Only use branch_taken when packet has multi cof Taylor Simpson
2022-12-16 20:48 ` [PULL 05/21] Hexagon (target/hexagon) Remove PC from the runtime state Taylor Simpson
2022-12-16 20:48 ` [PULL 06/21] Hexagon (target/hexagon) Remove next_PC from " Taylor Simpson
2022-12-16 20:48 ` [PULL 07/21] Hexagon (target/hexagon) Add overrides for direct call instructions Taylor Simpson
2022-12-16 20:48 ` [PULL 08/21] Hexagon (target/hexagon) Add overrides for compound compare and jump Taylor Simpson
2022-12-16 20:48 ` Taylor Simpson [this message]
2022-12-16 20:48 ` [PULL 10/21] Hexagon (target/hexagon) Use direct block chaining for direct jump/branch Taylor Simpson
2022-12-16 20:48 ` [PULL 11/21] Hexagon (target/hexagon) Use direct block chaining for tight loops Taylor Simpson
2022-12-16 20:48 ` [PULL 12/21] target/hexagon: update MAINTAINERS for idef-parser Taylor Simpson
2022-12-16 20:48 ` [PULL 13/21] target/hexagon: import README " Taylor Simpson
2022-12-16 20:48 ` [PULL 14/21] target/hexagon: make slot number an unsigned Taylor Simpson
2022-12-16 20:48 ` [PULL 15/21] target/hexagon: make helper functions non-static Taylor Simpson
2022-12-16 20:48 ` [PULL 16/21] target/hexagon: introduce new helper functions Taylor Simpson
2022-12-16 20:48 ` [PULL 17/21] target/hexagon: prepare input for the idef-parser Taylor Simpson
2022-12-29 10:41   ` Thomas Huth
2022-12-31 14:00     ` Alessandro Di Federico via
2022-12-16 20:48 ` [PULL 18/21] target/hexagon: import lexer for idef-parser Taylor Simpson
2022-12-16 20:48 ` [PULL 19/21] target/hexagon: import parser " Taylor Simpson
2023-06-23 12:50   ` Peter Maydell
2023-06-26  9:54     ` Anton Johansson via
2022-12-16 20:48 ` [PULL 20/21] target/hexagon: call idef-parser functions Taylor Simpson
2022-12-16 20:48 ` [PULL 21/21] target/hexagon: import additional tests Taylor Simpson
2022-12-17 21:21 ` [PULL 00/21] Hexagon update: bug fixes, performance, idef-parser Peter Maydell
2022-12-18  9:33   ` Anton Johansson via
2022-12-18 13:52 ` Peter Maydell
2022-12-18 15:34   ` Anton Johansson via
2022-12-18 16:53   ` Richard Henderson
2022-12-18 17:01     ` Peter Maydell
2022-12-19 11:18       ` Philippe Mathieu-Daudé
2022-12-19 10:28 ` Peter Maydell
2022-12-19 18:54   ` Taylor Simpson
2022-12-20 12:49     ` Alessandro Di Federico via
2022-12-19 23:19 ` Philippe Mathieu-Daudé
2022-12-20  7:30   ` Philippe Mathieu-Daudé
2022-12-20 12:51     ` Alessandro Di Federico via
2022-12-20 14:19       ` Philippe Mathieu-Daudé
2022-12-20 18:13         ` Taylor Simpson

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=20221216204845.19290-10-tsimpson@quicinc.com \
    --to=tsimpson@quicinc.com \
    --cc=bcain@quicinc.com \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=quic_mathbern@quicinc.com \
    --cc=richard.henderson@linaro.org \
    --cc=stefanha@redhat.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.