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~