/*
 * OpenRISC translation
 *
 * Copyright (c) 2011-2012 Jia Liu <proljc@gmail.com>
 *                         Feng Gao <gf91597@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "disas/disas.h"
#include "tcg/tcg-op.h"
#include "qemu/log.h"
#include "qemu/bitops.h"
#include "qemu/qemu-print.h"
#include "exec/cpu_ldst.h"
#include "exec/translator.h"

#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
#include "exec/gen-icount.h"

#include "exec/log.h"

/* is_jmp field values */
#define DISAS_EXIT    DISAS_TARGET_0  /* force exit to main loop */
#define DISAS_JUMP    DISAS_TARGET_1  /* exit via jmp_pc/jmp_pc_imm */

typedef struct DisasContext {
    DisasContextBase base;
    uint32_t mem_idx;
    uint32_t tb_flags;
    uint32_t delayed_branch;
    uint32_t cpucfgr;
    uint32_t avr;

    /* If not -1, jmp_pc contains this value and so is a direct jump.  */
    target_ulong jmp_pc_imm;

    /* The temporary corresponding to register 0 for this compilation.  */
    TCGv R0;
    /* The constant zero. */
    TCGv zero;
} DisasContext;

static inline bool is_user(DisasContext *dc)
{
#ifdef CONFIG_USER_ONLY
    return true;
#else
    return !(dc->tb_flags & TB_FLAGS_SM);
#endif
}

/* Include the auto-generated decoder.  */
#include "decode-insns.c.inc"

static TCGv cpu_sr;
static TCGv cpu_regs[32];
static TCGv cpu_pc;
static TCGv jmp_pc;            /* l.jr/l.jalr temp pc */
static TCGv cpu_ppc;
static TCGv cpu_sr_f;           /* bf/bnf, F flag taken */
static TCGv cpu_sr_cy;          /* carry (unsigned overflow) */
static TCGv cpu_sr_ov;          /* signed overflow */
static TCGv cpu_lock_addr;
static TCGv cpu_lock_value;
static TCGv_i32 fpcsr;
static TCGv_i64 cpu_mac;        /* MACHI:MACLO */
static TCGv_i32 cpu_dflag;

void openrisc_translate_init(void)
{
    static const char * const regnames[] = {
        "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
        "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
        "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
        "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
    };
    int i;

    cpu_sr = tcg_global_mem_new(cpu_env,
                                offsetof(CPUOpenRISCState, sr), "sr");
    cpu_dflag = tcg_global_mem_new_i32(cpu_env,
                                       offsetof(CPUOpenRISCState, dflag),
                                       "dflag");
    cpu_pc = tcg_global_mem_new(cpu_env,
                                offsetof(CPUOpenRISCState, pc), "pc");
    cpu_ppc = tcg_global_mem_new(cpu_env,
                                 offsetof(CPUOpenRISCState, ppc), "ppc");
    jmp_pc = tcg_global_mem_new(cpu_env,
                                offsetof(CPUOpenRISCState, jmp_pc), "jmp_pc");
    cpu_sr_f = tcg_global_mem_new(cpu_env,
                                  offsetof(CPUOpenRISCState, sr_f), "sr_f");
    cpu_sr_cy = tcg_global_mem_new(cpu_env,
                                   offsetof(CPUOpenRISCState, sr_cy), "sr_cy");
    cpu_sr_ov = tcg_global_mem_new(cpu_env,
                                   offsetof(CPUOpenRISCState, sr_ov), "sr_ov");
    cpu_lock_addr = tcg_global_mem_new(cpu_env,
                                       offsetof(CPUOpenRISCState, lock_addr),
                                       "lock_addr");
    cpu_lock_value = tcg_global_mem_new(cpu_env,
                                        offsetof(CPUOpenRISCState, lock_value),
                                        "lock_value");
    fpcsr = tcg_global_mem_new_i32(cpu_env,
                                   offsetof(CPUOpenRISCState, fpcsr),
                                   "fpcsr");
    cpu_mac = tcg_global_mem_new_i64(cpu_env,
                                     offsetof(CPUOpenRISCState, mac),
                                     "mac");
    for (i = 0; i < 32; i++) {
        cpu_regs[i] = tcg_global_mem_new(cpu_env,
                                         offsetof(CPUOpenRISCState,
                                                  shadow_gpr[0][i]),
                                         regnames[i]);
    }
}

static void gen_exception(DisasContext *dc, unsigned int excp)
{
    gen_helper_exception(cpu_env, tcg_constant_i32(excp));
}

static void gen_illegal_exception(DisasContext *dc)
{
    tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
    gen_exception(dc, EXCP_ILLEGAL);
    dc->base.is_jmp = DISAS_NORETURN;
}

static bool check_v1_3(DisasContext *dc)
{
    return dc->avr >= 0x01030000;
}

static bool check_of32s(DisasContext *dc)
{
    return dc->cpucfgr & CPUCFGR_OF32S;
}

static bool check_of64a32s(DisasContext *dc)
{
    return dc->cpucfgr & CPUCFGR_OF64A32S;
}

static TCGv cpu_R(DisasContext *dc, int reg)
{
    if (reg == 0) {
        return dc->R0;
    } else {
        return cpu_regs[reg];
    }
}

/*
 * We're about to write to REG.  On the off-chance that the user is
 * writing to R0, re-instate the architectural register.
 */
static void check_r0_write(DisasContext *dc, int reg)
{
    if (unlikely(reg == 0)) {
        dc->R0 = cpu_regs[0];
    }
}

static void gen_ove_cy(DisasContext *dc)
{
    if (dc->tb_flags & SR_OVE) {
        gen_helper_ove_cy(cpu_env);
    }
}

static void gen_ove_ov(DisasContext *dc)
{
    if (dc->tb_flags & SR_OVE) {
        gen_helper_ove_ov(cpu_env);
    }
}

static void gen_ove_cyov(DisasContext *dc)
{
    if (dc->tb_flags & SR_OVE) {
        gen_helper_ove_cyov(cpu_env);
    }
}

static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
    TCGv t0 = tcg_temp_new();
    TCGv res = tcg_temp_new();

    tcg_gen_add2_tl(res, cpu_sr_cy, srca, dc->zero, srcb, dc->zero);
    tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
    tcg_gen_xor_tl(t0, res, srcb);
    tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
    tcg_temp_free(t0);

    tcg_gen_mov_tl(dest, res);
    tcg_temp_free(res);

    gen_ove_cyov(dc);
}

static void gen_addc(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
    TCGv t0 = tcg_temp_new();
    TCGv res = tcg_temp_new();

    tcg_gen_add2_tl(res, cpu_sr_cy, srca, dc->zero, cpu_sr_cy, dc->zero);
    tcg_gen_add2_tl(res, cpu_sr_cy, res, cpu_sr_cy, srcb, dc->zero);
    tcg_gen_xor_tl(cpu_sr_ov, srca, srcb);
    tcg_gen_xor_tl(t0, res, srcb);
    tcg_gen_andc_tl(cpu_sr_ov, t0, cpu_sr_ov);
    tcg_temp_free(t0);

    tcg_gen_mov_tl(dest, res);
    tcg_temp_free(res);

    gen_ove_cyov(dc);
}

static void gen_sub(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
    TCGv res = tcg_temp_new();

    tcg_gen_sub_tl(res, srca, srcb);
    tcg_gen_xor_tl(cpu_sr_cy, srca, srcb);
    tcg_gen_xor_tl(cpu_sr_ov, res, srcb);
    tcg_gen_and_tl(cpu_sr_ov, cpu_sr_ov, cpu_sr_cy);
    tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_cy, srca, srcb);

    tcg_gen_mov_tl(dest, res);
    tcg_temp_free(res);

    gen_ove_cyov(dc);
}

static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
    TCGv t0 = tcg_temp_new();

    tcg_gen_muls2_tl(dest, cpu_sr_ov, srca, srcb);
    tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);
    tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_ov, cpu_sr_ov, t0);
    tcg_temp_free(t0);

    tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
    gen_ove_ov(dc);
}

static void gen_mulu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
    tcg_gen_muls2_tl(dest, cpu_sr_cy, srca, srcb);
    tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_cy, cpu_sr_cy, 0);

    gen_ove_cy(dc);
}

static void gen_div(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
    TCGv t0 = tcg_temp_new();

    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_ov, srcb, 0);
    /* The result of divide-by-zero is undefined.
       Supress the host-side exception by dividing by 1.  */
    tcg_gen_or_tl(t0, srcb, cpu_sr_ov);
    tcg_gen_div_tl(dest, srca, t0);
    tcg_temp_free(t0);

    tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);
    gen_ove_ov(dc);
}

static void gen_divu(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)
{
    TCGv t0 = tcg_temp_new();

    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_cy, srcb, 0);
    /* The result of divide-by-zero is undefined.
       Supress the host-side exception by dividing by 1.  */
    tcg_gen_or_tl(t0, srcb, cpu_sr_cy);
    tcg_gen_divu_tl(dest, srca, t0);
    tcg_temp_free(t0);

    gen_ove_cy(dc);
}

static void gen_muld(DisasContext *dc, TCGv srca, TCGv srcb)
{
    TCGv_i64 t1 = tcg_temp_new_i64();
    TCGv_i64 t2 = tcg_temp_new_i64();

    tcg_gen_ext_tl_i64(t1, srca);
    tcg_gen_ext_tl_i64(t2, srcb);
    if (TARGET_LONG_BITS == 32) {
        tcg_gen_mul_i64(cpu_mac, t1, t2);
        tcg_gen_movi_tl(cpu_sr_ov, 0);
    } else {
        TCGv_i64 high = tcg_temp_new_i64();

        tcg_gen_muls2_i64(cpu_mac, high, t1, t2);
        tcg_gen_sari_i64(t1, cpu_mac, 63);
        tcg_gen_setcond_i64(TCG_COND_NE, t1, t1, high);
        tcg_temp_free_i64(high);
        tcg_gen_trunc_i64_tl(cpu_sr_ov, t1);
        tcg_gen_neg_tl(cpu_sr_ov, cpu_sr_ov);

        gen_ove_ov(dc);
    }
    tcg_temp_free_i64(t1);
    tcg_temp_free_i64(t2);
}

static void gen_muldu(DisasContext *dc, TCGv srca, TCGv srcb)
{
    TCGv_i64 t1 = tcg_temp_new_i64();
    TCGv_i64 t2 = tcg_temp_new_i64();

    tcg_gen_extu_tl_i64(t1, srca);
    tcg_gen_extu_tl_i64(t2, srcb);
    if (TARGET_LONG_BITS == 32) {
        tcg_gen_mul_i64(cpu_mac, t1, t2);
        tcg_gen_movi_tl(cpu_sr_cy, 0);
    } else {
        TCGv_i64 high = tcg_temp_new_i64();

        tcg_gen_mulu2_i64(cpu_mac, high, t1, t2);
        tcg_gen_setcondi_i64(TCG_COND_NE, high, high, 0);
        tcg_gen_trunc_i64_tl(cpu_sr_cy, high);
        tcg_temp_free_i64(high);

        gen_ove_cy(dc);
    }
    tcg_temp_free_i64(t1);
    tcg_temp_free_i64(t2);
}

static void gen_mac(DisasContext *dc, TCGv srca, TCGv srcb)
{
    TCGv_i64 t1 = tcg_temp_new_i64();
    TCGv_i64 t2 = tcg_temp_new_i64();

    tcg_gen_ext_tl_i64(t1, srca);
    tcg_gen_ext_tl_i64(t2, srcb);
    tcg_gen_mul_i64(t1, t1, t2);

    /* Note that overflow is only computed during addition stage.  */
    tcg_gen_xor_i64(t2, cpu_mac, t1);
    tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
    tcg_gen_xor_i64(t1, t1, cpu_mac);
    tcg_gen_andc_i64(t1, t1, t2);
    tcg_temp_free_i64(t2);

#if TARGET_LONG_BITS == 32
    tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
#else
    tcg_gen_mov_i64(cpu_sr_ov, t1);
#endif
    tcg_temp_free_i64(t1);

    gen_ove_ov(dc);
}

static void gen_macu(DisasContext *dc, TCGv srca, TCGv srcb)
{
    TCGv_i64 t1 = tcg_temp_new_i64();
    TCGv_i64 t2 = tcg_temp_new_i64();

    tcg_gen_extu_tl_i64(t1, srca);
    tcg_gen_extu_tl_i64(t2, srcb);
    tcg_gen_mul_i64(t1, t1, t2);
    tcg_temp_free_i64(t2);

    /* Note that overflow is only computed during addition stage.  */
    tcg_gen_add_i64(cpu_mac, cpu_mac, t1);
    tcg_gen_setcond_i64(TCG_COND_LTU, t1, cpu_mac, t1);
    tcg_gen_trunc_i64_tl(cpu_sr_cy, t1);
    tcg_temp_free_i64(t1);

    gen_ove_cy(dc);
}

static void gen_msb(DisasContext *dc, TCGv srca, TCGv srcb)
{
    TCGv_i64 t1 = tcg_temp_new_i64();
    TCGv_i64 t2 = tcg_temp_new_i64();

    tcg_gen_ext_tl_i64(t1, srca);
    tcg_gen_ext_tl_i64(t2, srcb);
    tcg_gen_mul_i64(t1, t1, t2);

    /* Note that overflow is only computed during subtraction stage.  */
    tcg_gen_xor_i64(t2, cpu_mac, t1);
    tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
    tcg_gen_xor_i64(t1, t1, cpu_mac);
    tcg_gen_and_i64(t1, t1, t2);
    tcg_temp_free_i64(t2);

#if TARGET_LONG_BITS == 32
    tcg_gen_extrh_i64_i32(cpu_sr_ov, t1);
#else
    tcg_gen_mov_i64(cpu_sr_ov, t1);
#endif
    tcg_temp_free_i64(t1);

    gen_ove_ov(dc);
}

static void gen_msbu(DisasContext *dc, TCGv srca, TCGv srcb)
{
    TCGv_i64 t1 = tcg_temp_new_i64();
    TCGv_i64 t2 = tcg_temp_new_i64();

    tcg_gen_extu_tl_i64(t1, srca);
    tcg_gen_extu_tl_i64(t2, srcb);
    tcg_gen_mul_i64(t1, t1, t2);

    /* Note that overflow is only computed during subtraction stage.  */
    tcg_gen_setcond_i64(TCG_COND_LTU, t2, cpu_mac, t1);
    tcg_gen_sub_i64(cpu_mac, cpu_mac, t1);
    tcg_gen_trunc_i64_tl(cpu_sr_cy, t2);
    tcg_temp_free_i64(t2);
    tcg_temp_free_i64(t1);

    gen_ove_cy(dc);
}

static bool trans_l_add(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_addc(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sub(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    gen_sub(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_and(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_and_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_or(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_or_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_xor(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_xor_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sll(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_shl_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_srl(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_shr_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sra(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_sar_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_ror(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_rotr_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_exths(DisasContext *dc, arg_da *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_ext16s_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
    return true;
}

static bool trans_l_extbs(DisasContext *dc, arg_da *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_ext8s_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
    return true;
}

static bool trans_l_exthz(DisasContext *dc, arg_da *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_ext16u_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
    return true;
}

static bool trans_l_extbz(DisasContext *dc, arg_da *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_ext8u_tl(cpu_R(dc, a->d), cpu_R(dc, a->a));
    return true;
}

static bool trans_l_cmov(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_movcond_tl(TCG_COND_NE, cpu_R(dc, a->d), cpu_sr_f, dc->zero,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_ff1(DisasContext *dc, arg_da *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_ctzi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), -1);
    tcg_gen_addi_tl(cpu_R(dc, a->d), cpu_R(dc, a->d), 1);
    return true;
}

static bool trans_l_fl1(DisasContext *dc, arg_da *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_clzi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), TARGET_LONG_BITS);
    tcg_gen_subfi_tl(cpu_R(dc, a->d), TARGET_LONG_BITS, cpu_R(dc, a->d));
    return true;
}

static bool trans_l_mul(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_mulu(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    gen_mulu(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_div(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    gen_div(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_divu(DisasContext *dc, arg_dab *a)
{
    check_r0_write(dc, a->d);
    gen_divu(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_muld(DisasContext *dc, arg_ab *a)
{
    gen_muld(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_muldu(DisasContext *dc, arg_ab *a)
{
    gen_muldu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_j(DisasContext *dc, arg_l_j *a)
{
    target_ulong tmp_pc = dc->base.pc_next + a->n * 4;

    tcg_gen_movi_tl(jmp_pc, tmp_pc);
    dc->jmp_pc_imm = tmp_pc;
    dc->delayed_branch = 2;
    return true;
}

static bool trans_l_jal(DisasContext *dc, arg_l_jal *a)
{
    target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
    target_ulong ret_pc = dc->base.pc_next + 8;

    tcg_gen_movi_tl(cpu_regs[9], ret_pc);
    /* Optimize jal being used to load the PC for PIC.  */
    if (tmp_pc != ret_pc) {
        tcg_gen_movi_tl(jmp_pc, tmp_pc);
        dc->jmp_pc_imm = tmp_pc;
        dc->delayed_branch = 2;
    }
    return true;
}

static void do_bf(DisasContext *dc, arg_l_bf *a, TCGCond cond)
{
    target_ulong tmp_pc = dc->base.pc_next + a->n * 4;
    TCGv t_next = tcg_constant_tl(dc->base.pc_next + 8);
    TCGv t_true = tcg_constant_tl(tmp_pc);

    tcg_gen_movcond_tl(cond, jmp_pc, cpu_sr_f, dc->zero, t_true, t_next);
    dc->delayed_branch = 2;
}

static bool trans_l_bf(DisasContext *dc, arg_l_bf *a)
{
    do_bf(dc, a, TCG_COND_NE);
    return true;
}

static bool trans_l_bnf(DisasContext *dc, arg_l_bf *a)
{
    do_bf(dc, a, TCG_COND_EQ);
    return true;
}

static bool trans_l_jr(DisasContext *dc, arg_l_jr *a)
{
    tcg_gen_mov_tl(jmp_pc, cpu_R(dc, a->b));
    dc->delayed_branch = 2;
    return true;
}

static bool trans_l_jalr(DisasContext *dc, arg_l_jalr *a)
{
    tcg_gen_mov_tl(jmp_pc, cpu_R(dc, a->b));
    tcg_gen_movi_tl(cpu_regs[9], dc->base.pc_next + 8);
    dc->delayed_branch = 2;
    return true;
}

static bool trans_l_lwa(DisasContext *dc, arg_load *a)
{
    TCGv ea;

    check_r0_write(dc, a->d);
    ea = tcg_temp_new();
    tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
    tcg_gen_qemu_ld_tl(cpu_R(dc, a->d), ea, dc->mem_idx, MO_TEUL);
    tcg_gen_mov_tl(cpu_lock_addr, ea);
    tcg_gen_mov_tl(cpu_lock_value, cpu_R(dc, a->d));
    tcg_temp_free(ea);
    return true;
}

static void do_load(DisasContext *dc, arg_load *a, MemOp mop)
{
    TCGv ea;

    check_r0_write(dc, a->d);
    ea = tcg_temp_new();
    tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);
    tcg_gen_qemu_ld_tl(cpu_R(dc, a->d), ea, dc->mem_idx, mop);
    tcg_temp_free(ea);
}

static bool trans_l_lwz(DisasContext *dc, arg_load *a)
{
    do_load(dc, a, MO_TEUL);
    return true;
}

static bool trans_l_lws(DisasContext *dc, arg_load *a)
{
    do_load(dc, a, MO_TESL);
    return true;
}

static bool trans_l_lbz(DisasContext *dc, arg_load *a)
{
    do_load(dc, a, MO_UB);
    return true;
}

static bool trans_l_lbs(DisasContext *dc, arg_load *a)
{
    do_load(dc, a, MO_SB);
    return true;
}

static bool trans_l_lhz(DisasContext *dc, arg_load *a)
{
    do_load(dc, a, MO_TEUW);
    return true;
}

static bool trans_l_lhs(DisasContext *dc, arg_load *a)
{
    do_load(dc, a, MO_TESW);
    return true;
}

static bool trans_l_swa(DisasContext *dc, arg_store *a)
{
    TCGv ea, val;
    TCGLabel *lab_fail, *lab_done;

    ea = tcg_temp_new();
    tcg_gen_addi_tl(ea, cpu_R(dc, a->a), a->i);

    lab_fail = gen_new_label();
    lab_done = gen_new_label();
    tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);
    tcg_temp_free(ea);

    val = tcg_temp_new();
    tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,
                              cpu_R(dc, a->b), dc->mem_idx, MO_TEUL);
    tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);
    tcg_temp_free(val);

    tcg_gen_br(lab_done);

    gen_set_label(lab_fail);
    tcg_gen_movi_tl(cpu_sr_f, 0);

    gen_set_label(lab_done);
    tcg_gen_movi_tl(cpu_lock_addr, -1);
    return true;
}

static void do_store(DisasContext *dc, arg_store *a, MemOp mop)
{
    TCGv t0 = tcg_temp_new();
    tcg_gen_addi_tl(t0, cpu_R(dc, a->a), a->i);
    tcg_gen_qemu_st_tl(cpu_R(dc, a->b), t0, dc->mem_idx, mop);
    tcg_temp_free(t0);
}

static bool trans_l_sw(DisasContext *dc, arg_store *a)
{
    do_store(dc, a, MO_TEUL);
    return true;
}

static bool trans_l_sb(DisasContext *dc, arg_store *a)
{
    do_store(dc, a, MO_UB);
    return true;
}

static bool trans_l_sh(DisasContext *dc, arg_store *a)
{
    do_store(dc, a, MO_TEUW);
    return true;
}

static bool trans_l_nop(DisasContext *dc, arg_l_nop *a)
{
    return true;
}

static bool trans_l_adrp(DisasContext *dc, arg_l_adrp *a)
{
    if (!check_v1_3(dc)) {
        return false;
    }
    check_r0_write(dc, a->d);

    tcg_gen_movi_i32(cpu_R(dc, a->d),
                     (dc->base.pc_next & TARGET_PAGE_MASK) +
                     ((target_long)a->i << TARGET_PAGE_BITS));
    return true;
}

static bool trans_l_addi(DisasContext *dc, arg_rri *a)
{
    check_r0_write(dc, a->d);
    gen_add(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
    return true;
}

static bool trans_l_addic(DisasContext *dc, arg_rri *a)
{
    check_r0_write(dc, a->d);
    gen_addc(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
    return true;
}

static bool trans_l_muli(DisasContext *dc, arg_rri *a)
{
    check_r0_write(dc, a->d);
    gen_mul(dc, cpu_R(dc, a->d), cpu_R(dc, a->a), tcg_constant_tl(a->i));
    return true;
}

static bool trans_l_maci(DisasContext *dc, arg_l_maci *a)
{
    gen_mac(dc, cpu_R(dc, a->a), tcg_constant_tl(a->i));
    return true;
}

static bool trans_l_andi(DisasContext *dc, arg_rrk *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_andi_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->k);
    return true;
}

static bool trans_l_ori(DisasContext *dc, arg_rrk *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_ori_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->k);
    return true;
}

static bool trans_l_xori(DisasContext *dc, arg_rri *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_xori_tl(cpu_R(dc, a->d), cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_mfspr(DisasContext *dc, arg_l_mfspr *a)
{
    check_r0_write(dc, a->d);

    if (is_user(dc)) {
        gen_illegal_exception(dc);
    } else {
        TCGv spr = tcg_temp_new();

        if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
            gen_io_start();
            if (dc->delayed_branch) {
                tcg_gen_mov_tl(cpu_pc, jmp_pc);
                tcg_gen_discard_tl(jmp_pc);
            } else {
                tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
            }
            dc->base.is_jmp = DISAS_EXIT;
        }

        tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
        gen_helper_mfspr(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d), spr);
        tcg_temp_free(spr);
    }
    return true;
}

static bool trans_l_mtspr(DisasContext *dc, arg_l_mtspr *a)
{
    if (is_user(dc)) {
        gen_illegal_exception(dc);
    } else {
        TCGv spr;

        if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
            gen_io_start();
        }
        /* For SR, we will need to exit the TB to recognize the new
         * exception state.  For NPC, in theory this counts as a branch
         * (although the SPR only exists for use by an ICE).  Save all
         * of the cpu state first, allowing it to be overwritten.
         */
        if (dc->delayed_branch) {
            tcg_gen_mov_tl(cpu_pc, jmp_pc);
            tcg_gen_discard_tl(jmp_pc);
        } else {
            tcg_gen_movi_tl(cpu_pc, dc->base.pc_next + 4);
        }
        dc->base.is_jmp = DISAS_EXIT;

        spr = tcg_temp_new();
        tcg_gen_ori_tl(spr, cpu_R(dc, a->a), a->k);
        gen_helper_mtspr(cpu_env, spr, cpu_R(dc, a->b));
        tcg_temp_free(spr);
    }
    return true;
}

static bool trans_l_mac(DisasContext *dc, arg_ab *a)
{
    gen_mac(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_msb(DisasContext *dc, arg_ab *a)
{
    gen_msb(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_macu(DisasContext *dc, arg_ab *a)
{
    gen_macu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_msbu(DisasContext *dc, arg_ab *a)
{
    gen_msbu(dc, cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_slli(DisasContext *dc, arg_dal *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_shli_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
                    a->l & (TARGET_LONG_BITS - 1));
    return true;
}

static bool trans_l_srli(DisasContext *dc, arg_dal *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_shri_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
                    a->l & (TARGET_LONG_BITS - 1));
    return true;
}

static bool trans_l_srai(DisasContext *dc, arg_dal *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_sari_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
                    a->l & (TARGET_LONG_BITS - 1));
    return true;
}

static bool trans_l_rori(DisasContext *dc, arg_dal *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_rotri_tl(cpu_R(dc, a->d), cpu_R(dc, a->a),
                     a->l & (TARGET_LONG_BITS - 1));
    return true;
}

static bool trans_l_movhi(DisasContext *dc, arg_l_movhi *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_movi_tl(cpu_R(dc, a->d), a->k << 16);
    return true;
}

static bool trans_l_macrc(DisasContext *dc, arg_l_macrc *a)
{
    check_r0_write(dc, a->d);
    tcg_gen_trunc_i64_tl(cpu_R(dc, a->d), cpu_mac);
    tcg_gen_movi_i64(cpu_mac, 0);
    return true;
}

static bool trans_l_sfeq(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfne(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_NE, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfgtu(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_GTU, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfgeu(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_GEU, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfltu(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_LTU, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfleu(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_LEU, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfgts(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_GT, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfges(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_GE, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sflts(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_LT, cpu_sr_f,
                       cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfles(DisasContext *dc, arg_ab *a)
{
    tcg_gen_setcond_tl(TCG_COND_LE,
                       cpu_sr_f, cpu_R(dc, a->a), cpu_R(dc, a->b));
    return true;
}

static bool trans_l_sfeqi(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sfnei(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_NE, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sfgtui(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_GTU, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sfgeui(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_GEU, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sfltui(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sfleui(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_LEU, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sfgtsi(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_GT, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sfgesi(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_GE, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sfltsi(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_LT, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sflesi(DisasContext *dc, arg_ai *a)
{
    tcg_gen_setcondi_tl(TCG_COND_LE, cpu_sr_f, cpu_R(dc, a->a), a->i);
    return true;
}

static bool trans_l_sys(DisasContext *dc, arg_l_sys *a)
{
    tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
    gen_exception(dc, EXCP_SYSCALL);
    dc->base.is_jmp = DISAS_NORETURN;
    return true;
}

static bool trans_l_trap(DisasContext *dc, arg_l_trap *a)
{
    tcg_gen_movi_tl(cpu_pc, dc->base.pc_next);
    gen_exception(dc, EXCP_TRAP);
    dc->base.is_jmp = DISAS_NORETURN;
    return true;
}

static bool trans_l_msync(DisasContext *dc, arg_l_msync *a)
{
    tcg_gen_mb(TCG_MO_ALL);
    return true;
}

static bool trans_l_psync(DisasContext *dc, arg_l_psync *a)
{
    return true;
}

static bool trans_l_csync(DisasContext *dc, arg_l_csync *a)
{
    return true;
}

static bool trans_l_rfe(DisasContext *dc, arg_l_rfe *a)
{
    if (is_user(dc)) {
        gen_illegal_exception(dc);
    } else {
        gen_helper_rfe(cpu_env);
        dc->base.is_jmp = DISAS_EXIT;
    }
    return true;
}

static bool do_fp2(DisasContext *dc, arg_da *a,
                   void (*fn)(TCGv, TCGv_env, TCGv))
{
    if (!check_of32s(dc)) {
        return false;
    }
    check_r0_write(dc, a->d);
    fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a));
    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool do_fp3(DisasContext *dc, arg_dab *a,
                   void (*fn)(TCGv, TCGv_env, TCGv, TCGv))
{
    if (!check_of32s(dc)) {
        return false;
    }
    check_r0_write(dc, a->d);
    fn(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->a), cpu_R(dc, a->b));
    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool do_fpcmp(DisasContext *dc, arg_ab *a,
                     void (*fn)(TCGv, TCGv_env, TCGv, TCGv),
                     bool inv, bool swap)
{
    if (!check_of32s(dc)) {
        return false;
    }
    if (swap) {
        fn(cpu_sr_f, cpu_env, cpu_R(dc, a->b), cpu_R(dc, a->a));
    } else {
        fn(cpu_sr_f, cpu_env, cpu_R(dc, a->a), cpu_R(dc, a->b));
    }
    if (inv) {
        tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
    }
    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool trans_lf_add_s(DisasContext *dc, arg_dab *a)
{
    return do_fp3(dc, a, gen_helper_float_add_s);
}

static bool trans_lf_sub_s(DisasContext *dc, arg_dab *a)
{
    return do_fp3(dc, a, gen_helper_float_sub_s);
}

static bool trans_lf_mul_s(DisasContext *dc, arg_dab *a)
{
    return do_fp3(dc, a, gen_helper_float_mul_s);
}

static bool trans_lf_div_s(DisasContext *dc, arg_dab *a)
{
    return do_fp3(dc, a, gen_helper_float_div_s);
}

static bool trans_lf_rem_s(DisasContext *dc, arg_dab *a)
{
    return do_fp3(dc, a, gen_helper_float_rem_s);
    return true;
}

static bool trans_lf_itof_s(DisasContext *dc, arg_da *a)
{
    return do_fp2(dc, a, gen_helper_itofs);
}

static bool trans_lf_ftoi_s(DisasContext *dc, arg_da *a)
{
    return do_fp2(dc, a, gen_helper_ftois);
}

static bool trans_lf_madd_s(DisasContext *dc, arg_dab *a)
{
    if (!check_of32s(dc)) {
        return false;
    }
    check_r0_write(dc, a->d);
    gen_helper_float_madd_s(cpu_R(dc, a->d), cpu_env, cpu_R(dc, a->d),
                            cpu_R(dc, a->a), cpu_R(dc, a->b));
    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool trans_lf_sfeq_s(DisasContext *dc, arg_ab *a)
{
    return do_fpcmp(dc, a, gen_helper_float_eq_s, false, false);
}

static bool trans_lf_sfne_s(DisasContext *dc, arg_ab *a)
{
    return do_fpcmp(dc, a, gen_helper_float_eq_s, true, false);
}

static bool trans_lf_sfgt_s(DisasContext *dc, arg_ab *a)
{
    return do_fpcmp(dc, a, gen_helper_float_lt_s, false, true);
}

static bool trans_lf_sfge_s(DisasContext *dc, arg_ab *a)
{
    return do_fpcmp(dc, a, gen_helper_float_le_s, false, true);
}

static bool trans_lf_sflt_s(DisasContext *dc, arg_ab *a)
{
    return do_fpcmp(dc, a, gen_helper_float_lt_s, false, false);
}

static bool trans_lf_sfle_s(DisasContext *dc, arg_ab *a)
{
    return do_fpcmp(dc, a, gen_helper_float_le_s, false, false);
}

static bool trans_lf_sfueq_s(DisasContext *dc, arg_ab *a)
{
    if (!check_v1_3(dc)) {
        return false;
    }
    return do_fpcmp(dc, a, gen_helper_float_ueq_s, false, false);
}

static bool trans_lf_sfult_s(DisasContext *dc, arg_ab *a)
{
    if (!check_v1_3(dc)) {
        return false;
    }
    return do_fpcmp(dc, a, gen_helper_float_ult_s, false, false);
}

static bool trans_lf_sfugt_s(DisasContext *dc, arg_ab *a)
{
    if (!check_v1_3(dc)) {
        return false;
    }
    return do_fpcmp(dc, a, gen_helper_float_ult_s, false, true);
}

static bool trans_lf_sfule_s(DisasContext *dc, arg_ab *a)
{
    if (!check_v1_3(dc)) {
        return false;
    }
    return do_fpcmp(dc, a, gen_helper_float_ule_s, false, false);
}

static bool trans_lf_sfuge_s(DisasContext *dc, arg_ab *a)
{
    if (!check_v1_3(dc)) {
        return false;
    }
    return do_fpcmp(dc, a, gen_helper_float_ule_s, false, true);
}

static bool trans_lf_sfun_s(DisasContext *dc, arg_ab *a)
{
    if (!check_v1_3(dc)) {
        return false;
    }
    return do_fpcmp(dc, a, gen_helper_float_un_s, false, false);
}

static bool check_pair(DisasContext *dc, int r, int p)
{
    return r + 1 + p < 32;
}

static void load_pair(DisasContext *dc, TCGv_i64 t, int r, int p)
{
    tcg_gen_concat_i32_i64(t, cpu_R(dc, r + 1 + p), cpu_R(dc, r));
}

static void save_pair(DisasContext *dc, TCGv_i64 t, int r, int p)
{
    tcg_gen_extr_i64_i32(cpu_R(dc, r + 1 + p), cpu_R(dc, r), t);
}

static bool do_dp3(DisasContext *dc, arg_dab_pair *a,
                   void (*fn)(TCGv_i64, TCGv_env, TCGv_i64, TCGv_i64))
{
    TCGv_i64 t0, t1;

    if (!check_of64a32s(dc) ||
        !check_pair(dc, a->a, a->ap) ||
        !check_pair(dc, a->b, a->bp) ||
        !check_pair(dc, a->d, a->dp)) {
        return false;
    }
    check_r0_write(dc, a->d);

    t0 = tcg_temp_new_i64();
    t1 = tcg_temp_new_i64();
    load_pair(dc, t0, a->a, a->ap);
    load_pair(dc, t1, a->b, a->bp);
    fn(t0, cpu_env, t0, t1);
    save_pair(dc, t0, a->d, a->dp);
    tcg_temp_free_i64(t0);
    tcg_temp_free_i64(t1);

    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool do_dp2(DisasContext *dc, arg_da_pair *a,
                   void (*fn)(TCGv_i64, TCGv_env, TCGv_i64))
{
    TCGv_i64 t0;

    if (!check_of64a32s(dc) ||
        !check_pair(dc, a->a, a->ap) ||
        !check_pair(dc, a->d, a->dp)) {
        return false;
    }
    check_r0_write(dc, a->d);

    t0 = tcg_temp_new_i64();
    load_pair(dc, t0, a->a, a->ap);
    fn(t0, cpu_env, t0);
    save_pair(dc, t0, a->d, a->dp);
    tcg_temp_free_i64(t0);

    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool do_dpcmp(DisasContext *dc, arg_ab_pair *a,
                     void (*fn)(TCGv, TCGv_env, TCGv_i64, TCGv_i64),
                     bool inv, bool swap)
{
    TCGv_i64 t0, t1;

    if (!check_of64a32s(dc) ||
        !check_pair(dc, a->a, a->ap) ||
        !check_pair(dc, a->b, a->bp)) {
        return false;
    }

    t0 = tcg_temp_new_i64();
    t1 = tcg_temp_new_i64();
    load_pair(dc, t0, a->a, a->ap);
    load_pair(dc, t1, a->b, a->bp);
    if (swap) {
        fn(cpu_sr_f, cpu_env, t1, t0);
    } else {
        fn(cpu_sr_f, cpu_env, t0, t1);
    }
    tcg_temp_free_i64(t0);
    tcg_temp_free_i64(t1);

    if (inv) {
        tcg_gen_xori_tl(cpu_sr_f, cpu_sr_f, 1);
    }
    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool trans_lf_add_d(DisasContext *dc, arg_dab_pair *a)
{
    return do_dp3(dc, a, gen_helper_float_add_d);
}

static bool trans_lf_sub_d(DisasContext *dc, arg_dab_pair *a)
{
    return do_dp3(dc, a, gen_helper_float_sub_d);
}

static bool trans_lf_mul_d(DisasContext *dc, arg_dab_pair *a)
{
    return do_dp3(dc, a, gen_helper_float_mul_d);
}

static bool trans_lf_div_d(DisasContext *dc, arg_dab_pair *a)
{
    return do_dp3(dc, a, gen_helper_float_div_d);
}

static bool trans_lf_rem_d(DisasContext *dc, arg_dab_pair *a)
{
    return do_dp3(dc, a, gen_helper_float_rem_d);
}

static bool trans_lf_itof_d(DisasContext *dc, arg_da_pair *a)
{
    return do_dp2(dc, a, gen_helper_itofd);
}

static bool trans_lf_ftoi_d(DisasContext *dc, arg_da_pair *a)
{
    return do_dp2(dc, a, gen_helper_ftoid);
}

static bool trans_lf_stod_d(DisasContext *dc, arg_lf_stod_d *a)
{
    TCGv_i64 t0;

    if (!check_of64a32s(dc) ||
        !check_pair(dc, a->d, a->dp)) {
        return false;
    }
    check_r0_write(dc, a->d);

    t0 = tcg_temp_new_i64();
    gen_helper_stod(t0, cpu_env, cpu_R(dc, a->a));
    save_pair(dc, t0, a->d, a->dp);
    tcg_temp_free_i64(t0);

    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool trans_lf_dtos_d(DisasContext *dc, arg_lf_dtos_d *a)
{
    TCGv_i64 t0;

    if (!check_of64a32s(dc) ||
        !check_pair(dc, a->a, a->ap)) {
        return false;
    }
    check_r0_write(dc, a->d);

    t0 = tcg_temp_new_i64();
    load_pair(dc, t0, a->a, a->ap);
    gen_helper_dtos(cpu_R(dc, a->d), cpu_env, t0);
    tcg_temp_free_i64(t0);

    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool trans_lf_madd_d(DisasContext *dc, arg_dab_pair *a)
{
    TCGv_i64 t0, t1, t2;

    if (!check_of64a32s(dc) ||
        !check_pair(dc, a->a, a->ap) ||
        !check_pair(dc, a->b, a->bp) ||
        !check_pair(dc, a->d, a->dp)) {
        return false;
    }
    check_r0_write(dc, a->d);

    t0 = tcg_temp_new_i64();
    t1 = tcg_temp_new_i64();
    t2 = tcg_temp_new_i64();
    load_pair(dc, t0, a->d, a->dp);
    load_pair(dc, t1, a->a, a->ap);
    load_pair(dc, t2, a->b, a->bp);
    gen_helper_float_madd_d(t0, cpu_env, t0, t1, t2);
    save_pair(dc, t0, a->d, a->dp);
    tcg_temp_free_i64(t0);
    tcg_temp_free_i64(t1);
    tcg_temp_free_i64(t2);

    gen_helper_update_fpcsr(cpu_env);
    return true;
}

static bool trans_lf_sfeq_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_eq_d, false, false);
}

static bool trans_lf_sfne_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_eq_d, true, false);
}

static bool trans_lf_sfgt_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_lt_d, false, true);
}

static bool trans_lf_sfge_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_le_d, false, true);
}

static bool trans_lf_sflt_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_lt_d, false, false);
}

static bool trans_lf_sfle_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_le_d, false, false);
}

static bool trans_lf_sfueq_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_ueq_d, false, false);
}

static bool trans_lf_sfule_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_ule_d, false, false);
}

static bool trans_lf_sfuge_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_ule_d, false, true);
}

static bool trans_lf_sfult_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_ult_d, false, false);
}

static bool trans_lf_sfugt_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_ult_d, false, true);
}

static bool trans_lf_sfun_d(DisasContext *dc, arg_ab_pair *a)
{
    return do_dpcmp(dc, a, gen_helper_float_un_d, false, false);
}

static void openrisc_tr_init_disas_context(DisasContextBase *dcb, CPUState *cs)
{
    DisasContext *dc = container_of(dcb, DisasContext, base);
    CPUOpenRISCState *env = cs->env_ptr;
    int bound;

    dc->mem_idx = cpu_mmu_index(env, false);
    dc->tb_flags = dc->base.tb->flags;
    dc->delayed_branch = (dc->tb_flags & TB_FLAGS_DFLAG) != 0;
    dc->cpucfgr = env->cpucfgr;
    dc->avr = env->avr;
    dc->jmp_pc_imm = -1;

    bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
    dc->base.max_insns = MIN(dc->base.max_insns, bound);
}

static void openrisc_tr_tb_start(DisasContextBase *db, CPUState *cs)
{
    DisasContext *dc = container_of(db, DisasContext, base);

    /* Allow the TCG optimizer to see that R0 == 0,
       when it's true, which is the common case.  */
    dc->zero = tcg_constant_tl(0);
    if (dc->tb_flags & TB_FLAGS_R0_0) {
        dc->R0 = dc->zero;
    } else {
        dc->R0 = cpu_regs[0];
    }
}

static void openrisc_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);

    tcg_gen_insn_start(dc->base.pc_next, (dc->delayed_branch ? 1 : 0)
                       | (dc->base.num_insns > 1 ? 2 : 0));
}

static void openrisc_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    uint32_t insn = translator_ldl(&cpu->env, &dc->base, dc->base.pc_next);

    if (!decode(dc, insn)) {
        gen_illegal_exception(dc);
    }
    dc->base.pc_next += 4;

    /* When exiting the delay slot normally, exit via jmp_pc.
     * For DISAS_NORETURN, we have raised an exception and already exited.
     * For DISAS_EXIT, we found l.rfe in a delay slot.  There's nothing
     * in the manual saying this is illegal, but it surely it should.
     * At least or1ksim overrides pcnext and ignores the branch.
     */
    if (dc->delayed_branch
        && --dc->delayed_branch == 0
        && dc->base.is_jmp == DISAS_NEXT) {
        dc->base.is_jmp = DISAS_JUMP;
    }
}

static void openrisc_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
{
    DisasContext *dc = container_of(dcbase, DisasContext, base);
    target_ulong jmp_dest;

    /* If we have already exited the TB, nothing following has effect.  */
    if (dc->base.is_jmp == DISAS_NORETURN) {
        return;
    }

    /* Adjust the delayed branch state for the next TB.  */
    if ((dc->tb_flags & TB_FLAGS_DFLAG ? 1 : 0) != (dc->delayed_branch != 0)) {
        tcg_gen_movi_i32(cpu_dflag, dc->delayed_branch != 0);
    }

    /* For DISAS_TOO_MANY, jump to the next insn.  */
    jmp_dest = dc->base.pc_next;
    tcg_gen_movi_tl(cpu_ppc, jmp_dest - 4);

    switch (dc->base.is_jmp) {
    case DISAS_JUMP:
        jmp_dest = dc->jmp_pc_imm;
        if (jmp_dest == -1) {
            /* The jump destination is indirect/computed; use jmp_pc.  */
            tcg_gen_mov_tl(cpu_pc, jmp_pc);
            tcg_gen_discard_tl(jmp_pc);
            tcg_gen_lookup_and_goto_ptr();
            break;
        }
        /* The jump destination is direct; use jmp_pc_imm.
           However, we will have stored into jmp_pc as well;
           we know now that it wasn't needed.  */
        tcg_gen_discard_tl(jmp_pc);
        /* fallthru */

    case DISAS_TOO_MANY:
        if (translator_use_goto_tb(&dc->base, jmp_dest)) {
            tcg_gen_goto_tb(0);
            tcg_gen_movi_tl(cpu_pc, jmp_dest);
            tcg_gen_exit_tb(dc->base.tb, 0);
            break;
        }
        tcg_gen_movi_tl(cpu_pc, jmp_dest);
        tcg_gen_lookup_and_goto_ptr();
        break;

    case DISAS_EXIT:
        tcg_gen_exit_tb(NULL, 0);
        break;
    default:
        g_assert_not_reached();
    }
}

static void openrisc_tr_disas_log(const DisasContextBase *dcbase,
                                  CPUState *cs, FILE *logfile)
{
    DisasContext *s = container_of(dcbase, DisasContext, base);

    fprintf(logfile, "IN: %s\n", lookup_symbol(s->base.pc_first));
    target_disas(logfile, cs, s->base.pc_first, s->base.tb->size);
}

static const TranslatorOps openrisc_tr_ops = {
    .init_disas_context = openrisc_tr_init_disas_context,
    .tb_start           = openrisc_tr_tb_start,
    .insn_start         = openrisc_tr_insn_start,
    .translate_insn     = openrisc_tr_translate_insn,
    .tb_stop            = openrisc_tr_tb_stop,
    .disas_log          = openrisc_tr_disas_log,
};

void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns,
                           target_ulong pc, void *host_pc)
{
    DisasContext ctx;

    translator_loop(cs, tb, max_insns, pc, host_pc,
                    &openrisc_tr_ops, &ctx.base);
}

void openrisc_cpu_dump_state(CPUState *cs, FILE *f, int flags)
{
    OpenRISCCPU *cpu = OPENRISC_CPU(cs);
    CPUOpenRISCState *env = &cpu->env;
    int i;

    qemu_fprintf(f, "PC=%08x\n", env->pc);
    for (i = 0; i < 32; ++i) {
        qemu_fprintf(f, "R%02d=%08x%c", i, cpu_get_gpr(env, i),
                     (i % 4) == 3 ? '\n' : ' ');
    }
}
