/*
 * RISC-V translation routines for the Zb[abcs] and Zbk[bcx] Standard Extension.
 *
 * Copyright (c) 2020 Kito Cheng, kito.cheng@sifive.com
 * Copyright (c) 2020 Frank Chang, frank.chang@sifive.com
 * Copyright (c) 2021 Philipp Tomsich, philipp.tomsich@vrull.eu
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#define REQUIRE_ZBA(ctx) do {                    \
    if (!ctx->cfg_ptr->ext_zba) {                \
        return false;                            \
    }                                            \
} while (0)

#define REQUIRE_ZBB(ctx) do {                    \
    if (!ctx->cfg_ptr->ext_zbb) {                \
        return false;                            \
    }                                            \
} while (0)

#define REQUIRE_ZBC(ctx) do {                    \
    if (!ctx->cfg_ptr->ext_zbc) {                \
        return false;                            \
    }                                            \
} while (0)

#define REQUIRE_ZBS(ctx) do {                    \
    if (!ctx->cfg_ptr->ext_zbs) {                \
        return false;                            \
    }                                            \
} while (0)

#define REQUIRE_ZBKB(ctx) do {                   \
    if (!ctx->cfg_ptr->ext_zbkb) {               \
        return false;                            \
    }                                            \
} while (0)

#define REQUIRE_ZBKX(ctx) do {                   \
    if (!ctx->cfg_ptr->ext_zbkx) {               \
        return false;                            \
    }                                            \
} while (0)

static void gen_clz(TCGv ret, TCGv arg1)
{
    tcg_gen_clzi_tl(ret, arg1, TARGET_LONG_BITS);
}

static void gen_clzw(TCGv ret, TCGv arg1)
{
    TCGv t = tcg_temp_new();
    tcg_gen_shli_tl(t, arg1, 32);
    tcg_gen_clzi_tl(ret, t, 32);
}

static bool trans_clz(DisasContext *ctx, arg_clz *a)
{
    REQUIRE_ZBB(ctx);
    return gen_unary_per_ol(ctx, a, EXT_NONE, gen_clz, gen_clzw);
}

static void gen_ctz(TCGv ret, TCGv arg1)
{
    tcg_gen_ctzi_tl(ret, arg1, TARGET_LONG_BITS);
}

static void gen_ctzw(TCGv ret, TCGv arg1)
{
    tcg_gen_ctzi_tl(ret, arg1, 32);
}

static bool trans_ctz(DisasContext *ctx, arg_ctz *a)
{
    REQUIRE_ZBB(ctx);
    return gen_unary_per_ol(ctx, a, EXT_ZERO, gen_ctz, gen_ctzw);
}

static bool trans_cpop(DisasContext *ctx, arg_cpop *a)
{
    REQUIRE_ZBB(ctx);
    return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
}

static bool trans_andn(DisasContext *ctx, arg_andn *a)
{
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    return gen_logic(ctx, a, tcg_gen_andc_tl);
}

static bool trans_orn(DisasContext *ctx, arg_orn *a)
{
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    return gen_logic(ctx, a, tcg_gen_orc_tl);
}

static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
{
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    return gen_logic(ctx, a, tcg_gen_eqv_tl);
}

static bool trans_min(DisasContext *ctx, arg_min *a)
{
    REQUIRE_ZBB(ctx);
    return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smin_tl, NULL);
}

static bool trans_max(DisasContext *ctx, arg_max *a)
{
    REQUIRE_ZBB(ctx);
    return gen_arith(ctx, a, EXT_SIGN, tcg_gen_smax_tl, NULL);
}

static bool trans_minu(DisasContext *ctx, arg_minu *a)
{
    REQUIRE_ZBB(ctx);
    return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umin_tl, NULL);
}

static bool trans_maxu(DisasContext *ctx, arg_maxu *a)
{
    REQUIRE_ZBB(ctx);
    return gen_arith(ctx, a, EXT_SIGN, tcg_gen_umax_tl, NULL);
}

static bool trans_sext_b(DisasContext *ctx, arg_sext_b *a)
{
    REQUIRE_ZBB(ctx);
    return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext8s_tl);
}

static bool trans_sext_h(DisasContext *ctx, arg_sext_h *a)
{
    REQUIRE_ZBB(ctx);
    return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16s_tl);
}

static void gen_sbop_mask(TCGv ret, TCGv shamt)
{
    tcg_gen_movi_tl(ret, 1);
    tcg_gen_shl_tl(ret, ret, shamt);
}

static void gen_bset(TCGv ret, TCGv arg1, TCGv shamt)
{
    TCGv t = tcg_temp_new();

    gen_sbop_mask(t, shamt);
    tcg_gen_or_tl(ret, arg1, t);
}

static bool trans_bset(DisasContext *ctx, arg_bset *a)
{
    REQUIRE_ZBS(ctx);
    return gen_shift(ctx, a, EXT_NONE, gen_bset, NULL);
}

static bool trans_bseti(DisasContext *ctx, arg_bseti *a)
{
    REQUIRE_ZBS(ctx);
    return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bset);
}

static void gen_bclr(TCGv ret, TCGv arg1, TCGv shamt)
{
    TCGv t = tcg_temp_new();

    gen_sbop_mask(t, shamt);
    tcg_gen_andc_tl(ret, arg1, t);
}

static bool trans_bclr(DisasContext *ctx, arg_bclr *a)
{
    REQUIRE_ZBS(ctx);
    return gen_shift(ctx, a, EXT_NONE, gen_bclr, NULL);
}

static bool trans_bclri(DisasContext *ctx, arg_bclri *a)
{
    REQUIRE_ZBS(ctx);
    return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bclr);
}

static void gen_binv(TCGv ret, TCGv arg1, TCGv shamt)
{
    TCGv t = tcg_temp_new();

    gen_sbop_mask(t, shamt);
    tcg_gen_xor_tl(ret, arg1, t);
}

static bool trans_binv(DisasContext *ctx, arg_binv *a)
{
    REQUIRE_ZBS(ctx);
    return gen_shift(ctx, a, EXT_NONE, gen_binv, NULL);
}

static bool trans_binvi(DisasContext *ctx, arg_binvi *a)
{
    REQUIRE_ZBS(ctx);
    return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_binv);
}

static void gen_bext(TCGv ret, TCGv arg1, TCGv shamt)
{
    tcg_gen_shr_tl(ret, arg1, shamt);
    tcg_gen_andi_tl(ret, ret, 1);
}

static bool trans_bext(DisasContext *ctx, arg_bext *a)
{
    REQUIRE_ZBS(ctx);
    return gen_shift(ctx, a, EXT_NONE, gen_bext, NULL);
}

static bool trans_bexti(DisasContext *ctx, arg_bexti *a)
{
    REQUIRE_ZBS(ctx);
    return gen_shift_imm_tl(ctx, a, EXT_NONE, gen_bext);
}

static void gen_rorw(TCGv ret, TCGv arg1, TCGv arg2)
{
    TCGv_i32 t1 = tcg_temp_new_i32();
    TCGv_i32 t2 = tcg_temp_new_i32();

    /* truncate to 32-bits */
    tcg_gen_trunc_tl_i32(t1, arg1);
    tcg_gen_trunc_tl_i32(t2, arg2);

    tcg_gen_rotr_i32(t1, t1, t2);

    /* sign-extend 64-bits */
    tcg_gen_ext_i32_tl(ret, t1);
}

static bool trans_ror(DisasContext *ctx, arg_ror *a)
{
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotr_tl, gen_rorw, NULL);
}

static void gen_roriw(TCGv ret, TCGv arg1, target_long shamt)
{
    TCGv_i32 t1 = tcg_temp_new_i32();

    tcg_gen_trunc_tl_i32(t1, arg1);
    tcg_gen_rotri_i32(t1, t1, shamt);
    tcg_gen_ext_i32_tl(ret, t1);
}

static bool trans_rori(DisasContext *ctx, arg_rori *a)
{
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    return gen_shift_imm_fn_per_ol(ctx, a, EXT_NONE,
                                   tcg_gen_rotri_tl, gen_roriw, NULL);
}

static void gen_rolw(TCGv ret, TCGv arg1, TCGv arg2)
{
    TCGv_i32 t1 = tcg_temp_new_i32();
    TCGv_i32 t2 = tcg_temp_new_i32();

    /* truncate to 32-bits */
    tcg_gen_trunc_tl_i32(t1, arg1);
    tcg_gen_trunc_tl_i32(t2, arg2);

    tcg_gen_rotl_i32(t1, t1, t2);

    /* sign-extend 64-bits */
    tcg_gen_ext_i32_tl(ret, t1);
}

static bool trans_rol(DisasContext *ctx, arg_rol *a)
{
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    return gen_shift_per_ol(ctx, a, EXT_NONE, tcg_gen_rotl_tl, gen_rolw, NULL);
}

static void gen_rev8_32(TCGv ret, TCGv src1)
{
    tcg_gen_bswap32_tl(ret, src1, TCG_BSWAP_OS);
}

static bool trans_rev8_32(DisasContext *ctx, arg_rev8_32 *a)
{
    REQUIRE_32BIT(ctx);
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    return gen_unary(ctx, a, EXT_NONE, gen_rev8_32);
}

static bool trans_rev8_64(DisasContext *ctx, arg_rev8_64 *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    return gen_unary(ctx, a, EXT_NONE, tcg_gen_bswap_tl);
}

static void gen_orc_b(TCGv ret, TCGv source1)
{
    TCGv  tmp = tcg_temp_new();
    TCGv  low7 = tcg_constant_tl(dup_const_tl(MO_8, 0x7f));

    /* Set msb in each byte if the byte was non-zero. */
    tcg_gen_and_tl(tmp, source1, low7);
    tcg_gen_add_tl(tmp, tmp, low7);
    tcg_gen_or_tl(tmp, tmp, source1);

    /* Extract the msb to the lsb in each byte */
    tcg_gen_andc_tl(tmp, tmp, low7);
    tcg_gen_shri_tl(tmp, tmp, 7);

    /* Replicate the lsb of each byte across the byte. */
    tcg_gen_muli_tl(ret, tmp, 0xff);
}

static bool trans_orc_b(DisasContext *ctx, arg_orc_b *a)
{
    REQUIRE_ZBB(ctx);
    return gen_unary(ctx, a, EXT_ZERO, gen_orc_b);
}

#define GEN_SHADD(SHAMT)                                       \
static void gen_sh##SHAMT##add(TCGv ret, TCGv arg1, TCGv arg2) \
{                                                              \
    TCGv t = tcg_temp_new();                                   \
                                                               \
    tcg_gen_shli_tl(t, arg1, SHAMT);                           \
    tcg_gen_add_tl(ret, t, arg2);                              \
}

GEN_SHADD(1)
GEN_SHADD(2)
GEN_SHADD(3)

#define GEN_TRANS_SHADD(SHAMT)                                             \
static bool trans_sh##SHAMT##add(DisasContext *ctx, arg_sh##SHAMT##add *a) \
{                                                                          \
    REQUIRE_ZBA(ctx);                                                      \
    return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add, NULL);          \
}

GEN_TRANS_SHADD(1)
GEN_TRANS_SHADD(2)
GEN_TRANS_SHADD(3)

static bool trans_zext_h_32(DisasContext *ctx, arg_zext_h_32 *a)
{
    REQUIRE_32BIT(ctx);
    REQUIRE_ZBB(ctx);
    return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
}

static bool trans_zext_h_64(DisasContext *ctx, arg_zext_h_64 *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_ZBB(ctx);
    return gen_unary(ctx, a, EXT_NONE, tcg_gen_ext16u_tl);
}

static bool trans_clzw(DisasContext *ctx, arg_clzw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_ZBB(ctx);
    return gen_unary(ctx, a, EXT_NONE, gen_clzw);
}

static bool trans_ctzw(DisasContext *ctx, arg_ctzw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_ZBB(ctx);
    ctx->ol = MXL_RV32;
    return gen_unary(ctx, a, EXT_ZERO, gen_ctzw);
}

static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_ZBB(ctx);
    ctx->ol = MXL_RV32;
    return gen_unary(ctx, a, EXT_ZERO, tcg_gen_ctpop_tl);
}

static bool trans_rorw(DisasContext *ctx, arg_rorw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    ctx->ol = MXL_RV32;
    return gen_shift(ctx, a, EXT_NONE, gen_rorw, NULL);
}

static bool trans_roriw(DisasContext *ctx, arg_roriw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    ctx->ol = MXL_RV32;
    return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_roriw, NULL);
}

static bool trans_rolw(DisasContext *ctx, arg_rolw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_EITHER_EXT(ctx, zbb, zbkb);
    ctx->ol = MXL_RV32;
    return gen_shift(ctx, a, EXT_NONE, gen_rolw, NULL);
}

#define GEN_SHADD_UW(SHAMT)                                       \
static void gen_sh##SHAMT##add_uw(TCGv ret, TCGv arg1, TCGv arg2) \
{                                                                 \
    TCGv t = tcg_temp_new();                                      \
                                                                  \
    tcg_gen_ext32u_tl(t, arg1);                                   \
                                                                  \
    tcg_gen_shli_tl(t, t, SHAMT);                                 \
    tcg_gen_add_tl(ret, t, arg2);                                 \
}

GEN_SHADD_UW(1)
GEN_SHADD_UW(2)
GEN_SHADD_UW(3)

#define GEN_TRANS_SHADD_UW(SHAMT)                             \
static bool trans_sh##SHAMT##add_uw(DisasContext *ctx,        \
                                    arg_sh##SHAMT##add_uw *a) \
{                                                             \
    REQUIRE_64BIT(ctx);                                       \
    REQUIRE_ZBA(ctx);                                         \
    return gen_arith(ctx, a, EXT_NONE, gen_sh##SHAMT##add_uw, NULL); \
}

GEN_TRANS_SHADD_UW(1)
GEN_TRANS_SHADD_UW(2)
GEN_TRANS_SHADD_UW(3)

static void gen_add_uw(TCGv ret, TCGv arg1, TCGv arg2)
{
    TCGv t = tcg_temp_new();
    tcg_gen_ext32u_tl(t, arg1);
    tcg_gen_add_tl(ret, t, arg2);
}

static bool trans_add_uw(DisasContext *ctx, arg_add_uw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_ZBA(ctx);
    return gen_arith(ctx, a, EXT_NONE, gen_add_uw, NULL);
}

static void gen_slli_uw(TCGv dest, TCGv src, target_long shamt)
{
    tcg_gen_deposit_z_tl(dest, src, shamt, MIN(32, TARGET_LONG_BITS - shamt));
}

static bool trans_slli_uw(DisasContext *ctx, arg_slli_uw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_ZBA(ctx);
    return gen_shift_imm_fn(ctx, a, EXT_NONE, gen_slli_uw, NULL);
}

static bool trans_clmul(DisasContext *ctx, arg_clmul *a)
{
    REQUIRE_EITHER_EXT(ctx, zbc, zbkc);
    return gen_arith(ctx, a, EXT_NONE, gen_helper_clmul, NULL);
}

static void gen_clmulh(TCGv dst, TCGv src1, TCGv src2)
{
     gen_helper_clmulr(dst, src1, src2);
     tcg_gen_shri_tl(dst, dst, 1);
}

static bool trans_clmulh(DisasContext *ctx, arg_clmulr *a)
{
    REQUIRE_EITHER_EXT(ctx, zbc, zbkc);
    return gen_arith(ctx, a, EXT_NONE, gen_clmulh, NULL);
}

static bool trans_clmulr(DisasContext *ctx, arg_clmulh *a)
{
    REQUIRE_ZBC(ctx);
    return gen_arith(ctx, a, EXT_NONE, gen_helper_clmulr, NULL);
}

static void gen_pack(TCGv ret, TCGv src1, TCGv src2)
{
    tcg_gen_deposit_tl(ret, src1, src2,
                       TARGET_LONG_BITS / 2,
                       TARGET_LONG_BITS / 2);
}

static void gen_packh(TCGv ret, TCGv src1, TCGv src2)
{
    TCGv t = tcg_temp_new();

    tcg_gen_ext8u_tl(t, src2);
    tcg_gen_deposit_tl(ret, src1, t, 8, TARGET_LONG_BITS - 8);
}

static void gen_packw(TCGv ret, TCGv src1, TCGv src2)
{
    TCGv t = tcg_temp_new();

    tcg_gen_ext16s_tl(t, src2);
    tcg_gen_deposit_tl(ret, src1, t, 16, TARGET_LONG_BITS - 16);
}

static bool trans_brev8(DisasContext *ctx, arg_brev8 *a)
{
    REQUIRE_ZBKB(ctx);
    return gen_unary(ctx, a, EXT_NONE, gen_helper_brev8);
}

static bool trans_pack(DisasContext *ctx, arg_pack *a)
{
    REQUIRE_ZBKB(ctx);
    return gen_arith(ctx, a, EXT_NONE, gen_pack, NULL);
}

static bool trans_packh(DisasContext *ctx, arg_packh *a)
{
    REQUIRE_ZBKB(ctx);
    return gen_arith(ctx, a, EXT_NONE, gen_packh, NULL);
}

static bool trans_packw(DisasContext *ctx, arg_packw *a)
{
    REQUIRE_64BIT(ctx);
    REQUIRE_ZBKB(ctx);
    return gen_arith(ctx, a, EXT_NONE, gen_packw, NULL);
}

static bool trans_unzip(DisasContext *ctx, arg_unzip *a)
{
    REQUIRE_32BIT(ctx);
    REQUIRE_ZBKB(ctx);
    return gen_unary(ctx, a, EXT_NONE, gen_helper_unzip);
}

static bool trans_zip(DisasContext *ctx, arg_zip *a)
{
    REQUIRE_32BIT(ctx);
    REQUIRE_ZBKB(ctx);
    return gen_unary(ctx, a, EXT_NONE, gen_helper_zip);
}

static bool trans_xperm4(DisasContext *ctx, arg_xperm4 *a)
{
    REQUIRE_ZBKX(ctx);
    return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm4, NULL);
}

static bool trans_xperm8(DisasContext *ctx, arg_xperm8 *a)
{
    REQUIRE_ZBKX(ctx);
    return gen_arith(ctx, a, EXT_NONE, gen_helper_xperm8, NULL);
}
