qemu-riscv
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-riscv] [RFC v2 23/24] WIP: Add missing instructions


From: Richard Henderson
Subject: Re: [Qemu-riscv] [RFC v2 23/24] WIP: Add missing instructions
Date: Wed, 28 Nov 2018 12:30:03 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.0

On 11/27/18 1:10 PM, Alistair Francis wrote:
> Signed-off-by: Alistair Francis <address@hidden>
> ---
>  tcg/riscv/tcg-target.inc.c | 77 ++++++++++++++++++++++++++++++++++++++
>  1 file changed, 77 insertions(+)
> 
> diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c
> index 13756f6d0d..b8e9c0e126 100644
> --- a/tcg/riscv/tcg-target.inc.c
> +++ b/tcg/riscv/tcg-target.inc.c
> @@ -606,6 +606,57 @@ static bool tcg_out_sti(TCGContext *s, TCGType type, 
> TCGArg val,
>      return false;
>  }
>  
> +static void tcg_out_addsub2(TCGContext *s,
> +                            TCGReg rl, TCGReg rh,
> +                            TCGReg al, TCGReg ah,
> +                            TCGReg bl, TCGReg bh,
> +                            bool cbl, bool cbh, bool is_sub)
> +{
> +    /* FIXME: This is just copied from MIPS */
> +    TCGReg th = TCG_REG_TMP1;
> +
> +    /* If we have a negative constant such that negating it would
> +       make the high part zero, we can (usually) eliminate one insn.  */
> +    if (cbl && cbh && bh == -1 && bl != 0) {
> +        bl = -bl;
> +        bh = 0;
> +        is_sub = !is_sub;
> +    }
> +
> +    /* By operating on the high part first, we get to use the final
> +       carry operation to move back from the temporary.  */
> +    if (!cbh) {
> +        tcg_out_opc_reg(s, (is_sub ? OPC_SUB : OPC_ADDI), th, ah, bh);
> +    } else if (bh != 0 || ah == rl) {
> +        tcg_out_opc_imm(s, OPC_ADDI, th, ah, (is_sub ? -bh : bh));
> +    } else {
> +        th = ah;
> +    }
> +
> +    if (is_sub) {
> +        if (cbl) {
> +            tcg_out_opc_imm(s, OPC_SLLI, TCG_REG_TMP0, al, bl);

s/SLLI/SLTIU/

> +            tcg_out_opc_imm(s, OPC_ADDI, rl, al, -bl);
> +        } else {
> +            tcg_out_opc_reg(s, OPC_SLLI, TCG_REG_TMP0, al, bl);

s/SLLI/SLTU/

> +            tcg_out_opc_reg(s, OPC_SUB, rl, al, bl);
> +        }
> +        tcg_out_opc_reg(s, OPC_SUB, rh, th, TCG_REG_TMP0);
> +    } else {
> +        if (cbl) {
> +            tcg_out_opc_imm(s, OPC_ADDI, rl, al, bl);
> +            tcg_out_opc_imm(s, OPC_SLLI, TCG_REG_TMP0, rl, bl);

SLTIU

> +        } else if (rl == al && rl == bl) {
> +            tcg_out_opc_imm(s, OPC_SRLI, TCG_REG_TMP0, al, 31);

s/31/TCG_TARGET_REG_BITS - 1/
or somesuch.  I think that's an existing mips bug too...

> +            tcg_out_opc_reg(s, OPC_ADDI, rl, al, bl);

ADD, not ADDI.

> +        } else {
> +            tcg_out_opc_reg(s, OPC_ADDI, rl, al, bl);
> +            tcg_out_opc_reg(s, OPC_SLLI, TCG_REG_TMP0, rl, (rl == bl ? al : 
> bl));

Similarly.

> +        }
> +        tcg_out_opc_reg(s, OPC_ADDI, rh, th, TCG_REG_TMP0);

ADD.

> @@ -1537,6 +1604,8 @@ static const TCGTargetOpDef 
> *tcg_target_op_def(TCGOpcode op)
>      case INDEX_op_ext16s_i32:
>      case INDEX_op_ext16s_i64:
>      case INDEX_op_ext32s_i64:
> +    case INDEX_op_extrl_i64_i32:
> +    case INDEX_op_extrh_i64_i32:

This belongs in a previous patch.


> +    case INDEX_op_add2_i32:
> +    case INDEX_op_add2_i64:
> +        return &rZ_rZ_rZ_rZ_rZ_rZ;
> +
> +    case INDEX_op_sub2_i32:
> +    case INDEX_op_sub2_i64:
> +        return &rZ_rZ_rZ_rZ_rZ_rZ;

Adding 0 with TCG_REG_ZERO is sorta pointless.  You want the I and N
constraints.  Note that MIPS uses a modified symmetric N that can always be
negated [-32767, 32767] instead of [-32767, 32768].  Otherwise that first if
statement doesn't work.


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]