diff mbox series

[v5,19/30] tcg/loongarch64: Implement br/brcond ops

Message ID 20210924172527.904294-20-git@xen0n.name (mailing list archive)
State New, archived
Headers show
Series LoongArch64 port of QEMU TCG | expand

Commit Message

WANG Xuerui Sept. 24, 2021, 5:25 p.m. UTC
Signed-off-by: WANG Xuerui <git@xen0n.name>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 tcg/loongarch64/tcg-target-con-set.h |  1 +
 tcg/loongarch64/tcg-target.c.inc     | 53 ++++++++++++++++++++++++++++
 2 files changed, 54 insertions(+)

Comments

Philippe Mathieu-Daudé Sept. 25, 2021, 10:13 a.m. UTC | #1
On 9/24/21 19:25, WANG Xuerui wrote:
> Signed-off-by: WANG Xuerui <git@xen0n.name>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tcg/loongarch64/tcg-target-con-set.h |  1 +
>   tcg/loongarch64/tcg-target.c.inc     | 53 ++++++++++++++++++++++++++++
>   2 files changed, 54 insertions(+)

> diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
> index e3aac6c3de..d2339d823d 100644
> --- a/tcg/loongarch64/tcg-target.c.inc
> +++ b/tcg/loongarch64/tcg-target.c.inc
> @@ -406,6 +406,44 @@ static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
>       tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
>   }
>   
> +/*
> + * Branch helpers
> + */
> +
> +static const struct {
> +    LoongArchInsn op;
> +    bool swap;
> +} tcg_brcond_to_loongarch[] = {

Richard, TCGCond is 4-bit, shouldn't we explicit this array
size to 16, and even better define TCG_COND_COUNT = 16 in
"tcg/tcg-cond.h"?

> +    [TCG_COND_EQ] =  { OPC_BEQ,  false },
> +    [TCG_COND_NE] =  { OPC_BNE,  false },
> +    [TCG_COND_LT] =  { OPC_BGT,  true  },
> +    [TCG_COND_GE] =  { OPC_BLE,  true  },
> +    [TCG_COND_LE] =  { OPC_BLE,  false },
> +    [TCG_COND_GT] =  { OPC_BGT,  false },
> +    [TCG_COND_LTU] = { OPC_BGTU, true  },
> +    [TCG_COND_GEU] = { OPC_BLEU, true  },
> +    [TCG_COND_LEU] = { OPC_BLEU, false },
> +    [TCG_COND_GTU] = { OPC_BGTU, false }
> +};

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Richard Henderson Sept. 25, 2021, 2:12 p.m. UTC | #2
On 9/25/21 6:13 AM, Philippe Mathieu-Daudé wrote:
>> +static const struct {
>> +    LoongArchInsn op;
>> +    bool swap;
>> +} tcg_brcond_to_loongarch[] = {
> 
> Richard, TCGCond is 4-bit, shouldn't we explicit this array
> size to 16, and even better define TCG_COND_COUNT = 16 in
> "tcg/tcg-cond.h"?

Perhaps.  Not in this patch though.  None of the other instances in tcg/host/ do that, so 
I'd want to fix them all at once.


r~
Philippe Mathieu-Daudé Sept. 25, 2021, 2:38 p.m. UTC | #3
On 9/25/21 16:12, Richard Henderson wrote:
> On 9/25/21 6:13 AM, Philippe Mathieu-Daudé wrote:
>>> +static const struct {
>>> +    LoongArchInsn op;
>>> +    bool swap;
>>> +} tcg_brcond_to_loongarch[] = {
>>
>> Richard, TCGCond is 4-bit, shouldn't we explicit this array
>> size to 16, and even better define TCG_COND_COUNT = 16 in
>> "tcg/tcg-cond.h"?
> 
> Perhaps.  Not in this patch though.  None of the other instances in 
> tcg/host/ do that, so I'd want to fix them all at once.

Ack.

FYI some (outside of tcg/host/) do, tcg/tci.c:

static const char *str_c(TCGCond c)
{
     static const char cond[16][8] = {
         [TCG_COND_NEVER] = "never",
         [TCG_COND_ALWAYS] = "always",
         [TCG_COND_EQ] = "eq",
         [TCG_COND_NE] = "ne",
         [TCG_COND_LT] = "lt",
         [TCG_COND_GE] = "ge",
         [TCG_COND_LE] = "le",
         [TCG_COND_GT] = "gt",
         [TCG_COND_LTU] = "ltu",
         [TCG_COND_GEU] = "geu",
         [TCG_COND_LEU] = "leu",
         [TCG_COND_GTU] = "gtu",
     };

And target/s390x/tcg/translate.c:

/* Table of mask values to comparison codes, given a comparison as input.
    For such, CC=3 should not be possible.  */
static const TCGCond ltgt_cond[16] = {
     TCG_COND_NEVER,  TCG_COND_NEVER,     /*    |    |    | x */
     TCG_COND_GT,     TCG_COND_GT,        /*    |    | GT | x */
     TCG_COND_LT,     TCG_COND_LT,        /*    | LT |    | x */
     TCG_COND_NE,     TCG_COND_NE,        /*    | LT | GT | x */
     TCG_COND_EQ,     TCG_COND_EQ,        /* EQ |    |    | x */
     TCG_COND_GE,     TCG_COND_GE,        /* EQ |    | GT | x */
     TCG_COND_LE,     TCG_COND_LE,        /* EQ | LT |    | x */
     TCG_COND_ALWAYS, TCG_COND_ALWAYS,    /* EQ | LT | GT | x */
};

/* Table of mask values to comparison codes, given a logic op as input.
    For such, only CC=0 and CC=1 should be possible.  */
static const TCGCond nz_cond[16] = {
     TCG_COND_NEVER, TCG_COND_NEVER,      /*    |    | x | x */
     TCG_COND_NEVER, TCG_COND_NEVER,
     TCG_COND_NE, TCG_COND_NE,            /*    | NE | x | x */
     TCG_COND_NE, TCG_COND_NE,
     TCG_COND_EQ, TCG_COND_EQ,            /* EQ |    | x | x */
     TCG_COND_EQ, TCG_COND_EQ,
     TCG_COND_ALWAYS, TCG_COND_ALWAYS,    /* EQ | NE | x | x */
     TCG_COND_ALWAYS, TCG_COND_ALWAYS,
};
diff mbox series

Patch

diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
index fb56f3a295..367689c2e2 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -15,6 +15,7 @@ 
  * tcg-target-con-str.h; the constraint combination is inclusive or.
  */
 C_O0_I1(r)
+C_O0_I2(rZ, rZ)
 C_O1_I1(r, r)
 C_O1_I2(r, r, rC)
 C_O1_I2(r, r, ri)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index e3aac6c3de..d2339d823d 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -406,6 +406,44 @@  static void tcg_out_clzctz(TCGContext *s, LoongArchInsn opc,
     tcg_out_opc_or(s, a0, TCG_REG_TMP0, a0);
 }
 
+/*
+ * Branch helpers
+ */
+
+static const struct {
+    LoongArchInsn op;
+    bool swap;
+} tcg_brcond_to_loongarch[] = {
+    [TCG_COND_EQ] =  { OPC_BEQ,  false },
+    [TCG_COND_NE] =  { OPC_BNE,  false },
+    [TCG_COND_LT] =  { OPC_BGT,  true  },
+    [TCG_COND_GE] =  { OPC_BLE,  true  },
+    [TCG_COND_LE] =  { OPC_BLE,  false },
+    [TCG_COND_GT] =  { OPC_BGT,  false },
+    [TCG_COND_LTU] = { OPC_BGTU, true  },
+    [TCG_COND_GEU] = { OPC_BLEU, true  },
+    [TCG_COND_LEU] = { OPC_BLEU, false },
+    [TCG_COND_GTU] = { OPC_BGTU, false }
+};
+
+static void tcg_out_brcond(TCGContext *s, TCGCond cond, TCGReg arg1,
+                           TCGReg arg2, TCGLabel *l)
+{
+    LoongArchInsn op = tcg_brcond_to_loongarch[cond].op;
+
+    tcg_debug_assert(op != 0);
+
+    if (tcg_brcond_to_loongarch[cond].swap) {
+        TCGReg t = arg1;
+        arg1 = arg2;
+        arg2 = t;
+    }
+
+    /* all conditional branch insns belong to DJSk16-format */
+    tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SK16, l, 0);
+    tcg_out32(s, encode_djsk16_insn(op, arg1, arg2, 0));
+}
+
 /*
  * Entry-points
  */
@@ -428,6 +466,17 @@  static void tcg_out_op(TCGContext *s, TCGOpcode opc,
         tcg_out_opc_jirl(s, TCG_REG_ZERO, a0, 0);
         break;
 
+    case INDEX_op_br:
+        tcg_out_reloc(s, s->code_ptr, R_LOONGARCH_BR_SD10K16, arg_label(a0),
+                      0);
+        tcg_out_opc_b(s, 0);
+        break;
+
+    case INDEX_op_brcond_i32:
+    case INDEX_op_brcond_i64:
+        tcg_out_brcond(s, a2, a0, a1, arg_label(args[3]));
+        break;
+
     case INDEX_op_ext8s_i32:
     case INDEX_op_ext8s_i64:
         tcg_out_ext8s(s, a0, a1);
@@ -751,6 +800,10 @@  static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
     case INDEX_op_goto_ptr:
         return C_O0_I1(r);
 
+    case INDEX_op_brcond_i32:
+    case INDEX_op_brcond_i64:
+        return C_O0_I2(rZ, rZ);
+
     case INDEX_op_ext8s_i32:
     case INDEX_op_ext8s_i64:
     case INDEX_op_ext8u_i32: