qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Taylor Simpson <tsimpson@quicinc.com>
To: qemu-devel@nongnu.org
Cc: riku.voipio@iki.fi, richard.henderson@linaro.org,
	laurent@vivier.eu, Taylor Simpson <tsimpson@quicinc.com>,
	philmd@redhat.com, aleksandar.m.mail@gmail.com
Subject: [RFC PATCH v2 66/67] Hexagon HVX translation
Date: Fri, 28 Feb 2020 10:44:02 -0600	[thread overview]
Message-ID: <1582908244-304-67-git-send-email-tsimpson@quicinc.com> (raw)
In-Reply-To: <1582908244-304-1-git-send-email-tsimpson@quicinc.com>

Changes to packet semantics to support HVX

Signed-off-by: Taylor Simpson <tsimpson@quicinc.com>
---
 target/hexagon/translate.h |  30 ++++++++
 target/hexagon/translate.c | 188 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 218 insertions(+)

diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h
index 65b721e..481dbbd 100644
--- a/target/hexagon/translate.h
+++ b/target/hexagon/translate.h
@@ -32,6 +32,14 @@ typedef struct DisasContext {
     int ctx_preg_log[PRED_WRITES_MAX];
     int ctx_preg_log_idx;
     uint8_t ctx_store_width[STORES_MAX];
+    int ctx_temp_vregs_idx;
+    int ctx_temp_qregs_idx;
+    int ctx_vreg_log[NUM_VREGS];
+    int ctx_vreg_is_predicated[NUM_VREGS];
+    int ctx_vreg_log_idx;
+    int ctx_qreg_log[NUM_QREGS];
+    int ctx_qreg_is_predicated[NUM_QREGS];
+    int ctx_qreg_log_idx;
 } DisasContext;
 
 static inline void ctx_log_reg_write(DisasContext *ctx, int rnum)
@@ -54,6 +62,22 @@ static inline void ctx_log_pred_write(DisasContext *ctx, int pnum)
     ctx->ctx_preg_log_idx++;
 }
 
+static inline void ctx_log_vreg_write(DisasContext *ctx,
+                                      int rnum, int is_predicated)
+{
+    ctx->ctx_vreg_log[ctx->ctx_vreg_log_idx] = rnum;
+    ctx->ctx_vreg_is_predicated[ctx->ctx_vreg_log_idx] = is_predicated;
+    ctx->ctx_vreg_log_idx++;
+}
+
+static inline void ctx_log_qreg_write(DisasContext *ctx,
+                                      int rnum, int is_predicated)
+{
+    ctx->ctx_qreg_log[ctx->ctx_qreg_log_idx] = rnum;
+    ctx->ctx_qreg_is_predicated[ctx->ctx_qreg_log_idx] = is_predicated;
+    ctx->ctx_qreg_log_idx++;
+}
+
 extern TCGv hex_gpr[TOTAL_PER_THREAD_REGS];
 extern TCGv hex_pred[NUM_PREGS];
 extern TCGv hex_next_PC;
@@ -74,9 +98,15 @@ extern TCGv llsc_val;
 extern TCGv_i64 llsc_val_i64;
 extern TCGv hex_is_gather_store_insn;
 extern TCGv hex_gather_issued;
+extern TCGv hex_VRegs_updated_tmp;
+extern TCGv hex_VRegs_updated;
+extern TCGv hex_VRegs_select;
+extern TCGv hex_QRegs_updated;
 
 void hexagon_translate_init(void);
 extern void gen_exception(int excp);
 extern void gen_exception_debug(void);
 
+extern void gen_memcpy(TCGv_ptr dest, TCGv_ptr src, size_t n);
+
 #endif
diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c
index 57ab294..f5c135b 100644
--- a/target/hexagon/translate.c
+++ b/target/hexagon/translate.c
@@ -51,6 +51,10 @@ TCGv llsc_val;
 TCGv_i64 llsc_val_i64;
 TCGv hex_is_gather_store_insn;
 TCGv hex_gather_issued;
+TCGv hex_VRegs_updated_tmp;
+TCGv hex_VRegs_updated;
+TCGv hex_VRegs_select;
+TCGv hex_QRegs_updated;
 
 static const char * const hexagon_prednames[] = {
   "p0", "p1", "p2", "p3"
@@ -137,6 +141,10 @@ static void gen_start_packet(DisasContext *ctx, packet_t *pkt)
     /* Clear out the disassembly context */
     ctx->ctx_reg_log_idx = 0;
     ctx->ctx_preg_log_idx = 0;
+    ctx->ctx_temp_vregs_idx = 0;
+    ctx->ctx_temp_qregs_idx = 0;
+    ctx->ctx_vreg_log_idx = 0;
+    ctx->ctx_qreg_log_idx = 0;
     for (i = 0; i < STORES_MAX; i++) {
         ctx->ctx_store_width[i] = 0;
     }
@@ -155,6 +163,15 @@ static void gen_start_packet(DisasContext *ctx, packet_t *pkt)
         tcg_gen_movi_tl(hex_next_PC, next_PC);
     }
     tcg_gen_movi_tl(hex_pred_written, 0);
+
+    if (pkt->pkt_has_hvx) {
+        tcg_gen_movi_tl(hex_VRegs_updated_tmp, 0);
+        tcg_gen_movi_tl(hex_VRegs_updated, 0);
+        tcg_gen_movi_tl(hex_VRegs_select, 0);
+        tcg_gen_movi_tl(hex_QRegs_updated, 0);
+        tcg_gen_movi_tl(hex_is_gather_store_insn, 0);
+        tcg_gen_movi_tl(hex_gather_issued, 0);
+    }
 }
 
 static int is_gather_store_insn(insn_t *insn)
@@ -445,10 +462,163 @@ static bool process_change_of_flow(DisasContext *ctx, packet_t *pkt)
     return false;
 }
 
+void gen_memcpy(TCGv_ptr dest, TCGv_ptr src, size_t n)
+{
+    TCGv_ptr d = tcg_temp_new_ptr();
+    TCGv_ptr s = tcg_temp_new_ptr();
+    int i;
+
+    tcg_gen_addi_ptr(d, dest, 0);
+    tcg_gen_addi_ptr(s, src, 0);
+    if (n % 8 == 0) {
+        TCGv_i64 temp = tcg_temp_new_i64();
+        for (i = 0; i < n / 8; i++) {
+            tcg_gen_ld_i64(temp, s, 0);
+            tcg_gen_st_i64(temp, d, 0);
+            tcg_gen_addi_ptr(s, s, 8);
+            tcg_gen_addi_ptr(d, d, 8);
+        }
+        tcg_temp_free_i64(temp);
+    } else if (n % 4 == 0) {
+        TCGv temp = tcg_temp_new();
+        for (i = 0; i < n / 4; i++) {
+            tcg_gen_ld32u_tl(temp, s, 0);
+            tcg_gen_st32_tl(temp, d, 0);
+            tcg_gen_addi_ptr(s, s, 4);
+            tcg_gen_addi_ptr(d, d, 4);
+        }
+        tcg_temp_free(temp);
+    } else if (n % 2 == 0) {
+        TCGv temp = tcg_temp_new();
+        for (i = 0; i < n / 2; i++) {
+            tcg_gen_ld16u_tl(temp, s, 0);
+            tcg_gen_st16_tl(temp, d, 0);
+            tcg_gen_addi_ptr(s, s, 2);
+            tcg_gen_addi_ptr(d, d, 2);
+        }
+        tcg_temp_free(temp);
+    } else {
+        TCGv temp = tcg_temp_new();
+        for (i = 0; i < n; i++) {
+            tcg_gen_ld8u_tl(temp, s, 0);
+            tcg_gen_st8_tl(temp, d, 0);
+            tcg_gen_addi_ptr(s, s, 1);
+            tcg_gen_addi_ptr(d, d, 1);
+        }
+        tcg_temp_free(temp);
+    }
+
+    tcg_temp_free_ptr(d);
+    tcg_temp_free_ptr(s);
+}
+
+static inline void gen_vec_copy(intptr_t dstoff, intptr_t srcoff, size_t size)
+{
+    TCGv_ptr src = tcg_temp_new_ptr();
+    TCGv_ptr dst = tcg_temp_new_ptr();
+    tcg_gen_addi_ptr(src, cpu_env, srcoff);
+    tcg_gen_addi_ptr(dst, cpu_env, dstoff);
+    gen_memcpy(dst, src, size);
+    tcg_temp_free_ptr(src);
+    tcg_temp_free_ptr(dst);
+}
+
+static inline bool pkt_has_hvx_store(packet_t *pkt)
+{
+    int i;
+    for (i = 0; i < pkt->num_insns; i++) {
+        int opcode = pkt->insn[i].opcode;
+        if (GET_ATTRIB(opcode, A_CVI) && GET_ATTRIB(opcode, A_STORE)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static void gen_commit_hvx(DisasContext *ctx, packet_t *pkt)
+{
+    int i;
+
+    /*
+     *    for (i = 0; i < ctx->ctx_vreg_log_idx; i++) {
+     *        int rnum = ctx->ctx_vreg_log[i];
+     *        if (ctx->ctx_vreg_is_predicated[i]) {
+     *            if (env->VRegs_updated & (1 << rnum)) {
+     *                env->VRegs[rnum] = env->future_VRegs[rnum];
+     *            }
+     *        } else {
+     *            env->VRegs[rnum] = env->future_VRegs[rnum];
+     *        }
+     *    }
+     */
+    for (i = 0; i < ctx->ctx_vreg_log_idx; i++) {
+        int rnum = ctx->ctx_vreg_log[i];
+        int is_predicated = ctx->ctx_vreg_is_predicated[i];
+        intptr_t dstoff = offsetof(CPUHexagonState, VRegs[rnum]);
+        intptr_t srcoff = offsetof(CPUHexagonState, future_VRegs[rnum]);
+        size_t size = sizeof(mmvector_t);
+
+        if (is_predicated) {
+            TCGv cmp = tcg_temp_local_new();
+            TCGLabel *label_skip = gen_new_label();
+
+            tcg_gen_andi_tl(cmp, hex_VRegs_updated, 1 << rnum);
+            tcg_gen_brcondi_tl(TCG_COND_EQ, cmp, 0, label_skip);
+            {
+                gen_vec_copy(dstoff, srcoff, size);
+            }
+            gen_set_label(label_skip);
+            tcg_temp_free(cmp);
+        } else {
+            gen_vec_copy(dstoff, srcoff, size);
+        }
+    }
+
+    /*
+     *    for (i = 0; i < ctx-_ctx_qreg_log_idx; i++) {
+     *        int rnum = ctx->ctx_qreg_log[i];
+     *        if (ctx->ctx_qreg_is_predicated[i]) {
+     *            if (env->QRegs_updated) & (1 << rnum)) {
+     *                env->QRegs[rnum] = env->future_QRegs[rnum];
+     *            }
+     *        } else {
+     *            env->QRegs[rnum] = env->future_QRegs[rnum];
+     *        }
+     *    }
+     */
+    for (i = 0; i < ctx->ctx_qreg_log_idx; i++) {
+        int rnum = ctx->ctx_qreg_log[i];
+        int is_predicated = ctx->ctx_qreg_is_predicated[i];
+        intptr_t dstoff = offsetof(CPUHexagonState, QRegs[rnum]);
+        intptr_t srcoff = offsetof(CPUHexagonState, future_QRegs[rnum]);
+        size_t size = sizeof(mmqreg_t);
+
+        if (is_predicated) {
+            TCGv cmp = tcg_temp_local_new();
+            TCGLabel *label_skip = gen_new_label();
+
+            tcg_gen_andi_tl(cmp, hex_QRegs_updated, 1 << rnum);
+            tcg_gen_brcondi_tl(TCG_COND_EQ, cmp, 0, label_skip);
+            {
+                gen_vec_copy(dstoff, srcoff, size);
+            }
+            gen_set_label(label_skip);
+            tcg_temp_free(cmp);
+        } else {
+            gen_vec_copy(dstoff, srcoff, size);
+        }
+    }
+
+    if (pkt_has_hvx_store(pkt)) {
+        gen_helper_commit_hvx_stores(cpu_env);
+    }
+}
+
 static void gen_exec_counters(packet_t *pkt)
 {
     int num_insns = pkt->num_insns;
     int num_real_insns = 0;
+    int num_hvx_insns = 0;
     int i;
 
     for (i = 0; i < num_insns; i++) {
@@ -457,6 +627,9 @@ static void gen_exec_counters(packet_t *pkt)
             !GET_ATTRIB(pkt->insn[i].opcode, A_IT_NOP)) {
             num_real_insns++;
         }
+        if (pkt->insn[i].hvx_resource) {
+            num_hvx_insns++;
+        }
     }
 
     tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_PKT_CNT],
@@ -465,6 +638,10 @@ static void gen_exec_counters(packet_t *pkt)
         tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_INSN_CNT],
                         hex_gpr[HEX_REG_QEMU_INSN_CNT], num_real_insns);
     }
+    if (num_hvx_insns) {
+        tcg_gen_addi_tl(hex_gpr[HEX_REG_QEMU_HVX_CNT],
+                        hex_gpr[HEX_REG_QEMU_HVX_CNT], num_hvx_insns);
+    }
 }
 
 static void gen_commit_packet(DisasContext *ctx, packet_t *pkt)
@@ -476,6 +653,9 @@ static void gen_commit_packet(DisasContext *ctx, packet_t *pkt)
     process_store_log(ctx, pkt);
     process_dczeroa(ctx, pkt);
     end_tb |= process_change_of_flow(ctx, pkt);
+    if (pkt->pkt_has_hvx) {
+        gen_commit_hvx(ctx, pkt);
+    }
     gen_exec_counters(pkt);
 #if HEX_DEBUG
     {
@@ -702,6 +882,14 @@ void hexagon_translate_init(void)
         "is_gather_store_insn");
     hex_gather_issued = tcg_global_mem_new(cpu_env,
         offsetof(CPUHexagonState, gather_issued), "gather_issued");
+    hex_VRegs_updated_tmp = tcg_global_mem_new(cpu_env,
+        offsetof(CPUHexagonState, VRegs_updated_tmp), "VRegs_updated_tmp");
+    hex_VRegs_updated = tcg_global_mem_new(cpu_env,
+        offsetof(CPUHexagonState, VRegs_updated), "VRegs_updated");
+    hex_VRegs_select = tcg_global_mem_new(cpu_env,
+        offsetof(CPUHexagonState, VRegs_select), "VRegs_select");
+    hex_QRegs_updated = tcg_global_mem_new(cpu_env,
+        offsetof(CPUHexagonState, QRegs_updated), "QRegs_updated");
     for (i = 0; i < STORES_MAX; i++) {
         sprintf(store_addr_names[i], "store_addr_%d", i);
         hex_store_addr[i] = tcg_global_mem_new(cpu_env,
-- 
2.7.4


  parent reply	other threads:[~2020-02-28 17:29 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-28 16:42 [RFC PATCH v2 00/67] Hexagon patch series Taylor Simpson
2020-02-28 16:42 ` [RFC PATCH v2 01/67] Hexagon Maintainers Taylor Simpson
2020-02-28 16:42 ` [RFC PATCH v2 02/67] Hexagon README Taylor Simpson
2020-02-28 16:42 ` [RFC PATCH v2 03/67] Hexagon ELF Machine Definition Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 04/67] Hexagon CPU Scalar Core Definition Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 05/67] Hexagon register names Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 06/67] Hexagon Disassembler Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 07/67] Hexagon CPU Scalar Core Helpers Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 08/67] Hexagon GDB Stub Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 09/67] Hexagon architecture types Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 10/67] Hexagon instruction and packet types Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 11/67] Hexagon register fields Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 12/67] Hexagon instruction attributes Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 13/67] Hexagon register map Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 14/67] Hexagon instruction/packet decode Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 15/67] Hexagon instruction printing Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 16/67] Hexagon arch import - instruction semantics definitions Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 17/67] Hexagon arch import - macro definitions Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 18/67] Hexagon arch import - instruction encoding Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 19/67] Hexagon instruction class definitions Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 20/67] Hexagon instruction utility functions Taylor Simpson
2020-04-09 18:53   ` Brian Cain
2020-04-09 20:22     ` Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 21/67] Hexagon generator phase 1 - C preprocessor for semantics Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 22/67] Hexagon generator phase 2 - qemu_def_generated.h Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 23/67] Hexagon generator phase 2 - qemu_wrap_generated.h Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 24/67] Hexagon generator phase 2 - opcodes_def_generated.h Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 25/67] Hexagon generator phase 2 - op_attribs_generated.h Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 26/67] Hexagon generator phase 2 - op_regs_generated.h Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 27/67] Hexagon generator phase 2 - printinsn-generated.h Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 28/67] Hexagon generator phase 3 - C preprocessor for decode tree Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 29/67] Hexagon generater phase 4 - Decode tree Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 30/67] Hexagon opcode data structures Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 31/67] Hexagon macros to interface with the generator Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 32/67] Hexagon macros referenced in instruction semantics Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 33/67] Hexagon instruction classes Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 34/67] Hexagon TCG generation helpers - step 1 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 35/67] Hexagon TCG generation helpers - step 2 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 36/67] Hexagon TCG generation helpers - step 3 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 37/67] Hexagon TCG generation helpers - step 4 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 38/67] Hexagon TCG generation helpers - step 5 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 39/67] Hexagon TCG generation - step 01 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 40/67] Hexagon TCG generation - step 02 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 41/67] Hexagon TCG generation - step 03 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 42/67] Hexagon TCG generation - step 04 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 43/67] Hexagon TCG generation - step 05 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 44/67] Hexagon TCG generation - step 06 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 45/67] Hexagon TCG generation - step 07 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 46/67] Hexagon TCG generation - step 08 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 47/67] Hexagon TCG generation - step 09 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 48/67] Hexagon TCG generation - step 10 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 49/67] Hexagon TCG generation - step 11 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 50/67] Hexagon TCG generation - step 12 Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 51/67] Hexagon translation Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 52/67] Hexagon Linux user emulation Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 53/67] Hexagon build infrastructure Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 54/67] Hexagon - Add Hexagon Vector eXtensions (HVX) to core definition Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 55/67] Hexagon HVX support in gdbstub Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 56/67] Hexagon HVX import instruction encodings Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 57/67] Hexagon HVX import semantics Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 58/67] Hexagon HVX import macro definitions Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 59/67] Hexagon HVX semantics generator Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 60/67] Hexagon HVX instruction decoding Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 61/67] Hexagon HVX instruction utility functions Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 62/67] Hexagon HVX macros to interface with the generator Taylor Simpson
2020-02-28 16:43 ` [RFC PATCH v2 63/67] Hexagon HVX macros referenced in instruction semantics Taylor Simpson
2020-02-28 16:44 ` [RFC PATCH v2 64/67] Hexagon HVX helper to commit vector stores (masked and scatter/gather) Taylor Simpson
2020-02-28 16:44 ` [RFC PATCH v2 65/67] Hexagon HVX TCG generation Taylor Simpson
2020-02-28 16:44 ` Taylor Simpson [this message]
2020-02-28 16:44 ` [RFC PATCH v2 67/67] Hexagon HVX build infrastructure Taylor Simpson
2020-03-25 21:13 ` [RFC PATCH v2 00/67] Hexagon patch series Taylor Simpson
2020-04-30 20:53   ` 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=1582908244-304-67-git-send-email-tsimpson@quicinc.com \
    --to=tsimpson@quicinc.com \
    --cc=aleksandar.m.mail@gmail.com \
    --cc=laurent@vivier.eu \
    --cc=philmd@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.org \
    --cc=riku.voipio@iki.fi \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).