qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [RFC v2 11/24] riscv: tcg-target: Add the mov and movi


From: Richard Henderson
Subject: Re: [Qemu-devel] [RFC v2 11/24] riscv: tcg-target: Add the mov and movi instruction
Date: Wed, 28 Nov 2018 11:48:19 -0800
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.0

On 11/27/18 1:08 PM, Alistair Francis wrote:
> +static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
> +                         tcg_target_long val)
> +{
> +#if TCG_TARGET_REG_BITS == 64
> +    tcg_target_long lo = sextract64(val, 0, 12);
> +#else
> +    tcg_target_long lo = sextract32(val, 0, 12);
> +#endif

I really think this ifdef should be moved into a helper function.  There are
quite a number of copies of it throughout.

> +    tcg_target_long hi = val - lo;
> +    int shift;
> +    tcg_target_long tmp;
> +
> +    RISCVInsn add32_op = TCG_TARGET_REG_BITS == 64 ? OPC_ADDIW : OPC_ADDI;
> +
> +#if TCG_TARGET_REG_BITS == 64
> +    ptrdiff_t offset = tcg_pcrel_diff(s, (void *)val);
> +#endif
> +
> +    if (TCG_TARGET_REG_BITS == 32 || val == (int32_t)val) {
> +        tcg_out_opc_upper(s, OPC_LUI, rd, hi);
> +        if (lo != 0) {
> +            tcg_out_opc_imm(s, add32_op, rd, rd, lo);
> +        }
> +
> +        return;
> +    }

Your reorg has failed to keep the single insn ADDI(W) case.

> +    /* We can only be here if TCG_TARGET_REG_BITS != 32 */
> +    if (offset == sextract64(offset, 1, 31) << 1) {

The ifdef above won't compile for rv32, because offset is used unconditionally
here.  Remove the ifdef and allow that to be removed as dead code by the 
compiler.

> +        tcg_out_opc_upper(s, OPC_AUIPC, rd, 0);
> +        tcg_out_opc_imm(s, OPC_ADDI, rd, rd, 0);
> +        reloc_call(s->code_ptr - 2, (tcg_insn_unit *)val);
> +        return;
> +    }
> +
> +    shift = ctz64(val);
> +    tmp = val >> shift;
> +
> +    if (tmp == sextract64(tmp, 0, 12)) {
> +        tcg_out_opc_imm(s, OPC_ADDI, rd, TCG_REG_ZERO, 1);

s/1/tmp/

> +        tcg_out_opc_imm(s, OPC_SLLI, rd, rd, ctz64(val));
> +    } else if (!(val >> 31 == 0 || val >> 31 == -1)) {
> +        shift = ctz64(hi);
> +        hi >>= shift;
> +        tcg_out_movi(s, type, rd, hi);
> +        tcg_out_opc_imm(s, OPC_SLLI, rd, rd, shift);
> +        if (lo != 0) {
> +            tcg_out_opc_imm(s, OPC_ADDI, rd, rd, lo);
> +        }
> +    } else {
> +        if (hi != 0) {
> +            tcg_out_opc_upper(s, OPC_LUI, rd, hi);
> +        }
> +        if (lo != 0) {
> +            tcg_out_opc_imm(s, add32_op, rd, hi == 0 ? TCG_REG_ZERO : rd, 
> lo);
> +        }
> +    }

The final else case is identical with the first if.


r~



reply via email to

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