Message ID | 20210924172527.904294-20-git@xen0n.name (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | LoongArch64 port of QEMU TCG | expand |
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>
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~
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 --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: