qemu/target/tricore/translate.c
<<
>>
Prefs
   1/*
   2 *  TriCore emulation for qemu: main translation routines.
   3 *
   4 *  Copyright (c) 2013-2014 Bastian Koppelmann C-Lab/University Paderborn
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2.1 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20
  21#include "qemu/osdep.h"
  22#include "cpu.h"
  23#include "disas/disas.h"
  24#include "exec/exec-all.h"
  25#include "tcg-op.h"
  26#include "exec/cpu_ldst.h"
  27#include "qemu/qemu-print.h"
  28
  29#include "exec/helper-proto.h"
  30#include "exec/helper-gen.h"
  31
  32#include "tricore-opcodes.h"
  33#include "exec/translator.h"
  34#include "exec/log.h"
  35
  36/*
  37 * TCG registers
  38 */
  39static TCGv cpu_PC;
  40static TCGv cpu_PCXI;
  41static TCGv cpu_PSW;
  42static TCGv cpu_ICR;
  43/* GPR registers */
  44static TCGv cpu_gpr_a[16];
  45static TCGv cpu_gpr_d[16];
  46/* PSW Flag cache */
  47static TCGv cpu_PSW_C;
  48static TCGv cpu_PSW_V;
  49static TCGv cpu_PSW_SV;
  50static TCGv cpu_PSW_AV;
  51static TCGv cpu_PSW_SAV;
  52
  53#include "exec/gen-icount.h"
  54
  55static const char *regnames_a[] = {
  56      "a0"  , "a1"  , "a2"  , "a3" , "a4"  , "a5" ,
  57      "a6"  , "a7"  , "a8"  , "a9" , "sp" , "a11" ,
  58      "a12" , "a13" , "a14" , "a15",
  59    };
  60
  61static const char *regnames_d[] = {
  62      "d0"  , "d1"  , "d2"  , "d3" , "d4"  , "d5"  ,
  63      "d6"  , "d7"  , "d8"  , "d9" , "d10" , "d11" ,
  64      "d12" , "d13" , "d14" , "d15",
  65    };
  66
  67typedef struct DisasContext {
  68    DisasContextBase base;
  69    CPUTriCoreState *env;
  70    target_ulong pc_succ_insn;
  71    uint32_t opcode;
  72    /* Routine used to access memory */
  73    int mem_idx;
  74    uint32_t hflags, saved_hflags;
  75} DisasContext;
  76
  77enum {
  78    MODE_LL = 0,
  79    MODE_LU = 1,
  80    MODE_UL = 2,
  81    MODE_UU = 3,
  82};
  83
  84void tricore_cpu_dump_state(CPUState *cs, FILE *f, int flags)
  85{
  86    TriCoreCPU *cpu = TRICORE_CPU(cs);
  87    CPUTriCoreState *env = &cpu->env;
  88    uint32_t psw;
  89    int i;
  90
  91    psw = psw_read(env);
  92
  93    qemu_fprintf(f, "PC: " TARGET_FMT_lx, env->PC);
  94    qemu_fprintf(f, " PSW: " TARGET_FMT_lx, psw);
  95    qemu_fprintf(f, " ICR: " TARGET_FMT_lx, env->ICR);
  96    qemu_fprintf(f, "\nPCXI: " TARGET_FMT_lx, env->PCXI);
  97    qemu_fprintf(f, " FCX: " TARGET_FMT_lx, env->FCX);
  98    qemu_fprintf(f, " LCX: " TARGET_FMT_lx, env->LCX);
  99
 100    for (i = 0; i < 16; ++i) {
 101        if ((i & 3) == 0) {
 102            qemu_fprintf(f, "\nGPR A%02d:", i);
 103        }
 104        qemu_fprintf(f, " " TARGET_FMT_lx, env->gpr_a[i]);
 105    }
 106    for (i = 0; i < 16; ++i) {
 107        if ((i & 3) == 0) {
 108            qemu_fprintf(f, "\nGPR D%02d:", i);
 109        }
 110        qemu_fprintf(f, " " TARGET_FMT_lx, env->gpr_d[i]);
 111    }
 112    qemu_fprintf(f, "\n");
 113}
 114
 115/*
 116 * Functions to generate micro-ops
 117 */
 118
 119/* Makros for generating helpers */
 120
 121#define gen_helper_1arg(name, arg) do {                           \
 122    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
 123    gen_helper_##name(cpu_env, helper_tmp);                       \
 124    tcg_temp_free_i32(helper_tmp);                                \
 125    } while (0)
 126
 127#define GEN_HELPER_LL(name, ret, arg0, arg1, n) do {         \
 128    TCGv arg00 = tcg_temp_new();                             \
 129    TCGv arg01 = tcg_temp_new();                             \
 130    TCGv arg11 = tcg_temp_new();                             \
 131    tcg_gen_sari_tl(arg00, arg0, 16);                        \
 132    tcg_gen_ext16s_tl(arg01, arg0);                          \
 133    tcg_gen_ext16s_tl(arg11, arg1);                          \
 134    gen_helper_##name(ret, arg00, arg01, arg11, arg11, n);   \
 135    tcg_temp_free(arg00);                                    \
 136    tcg_temp_free(arg01);                                    \
 137    tcg_temp_free(arg11);                                    \
 138} while (0)
 139
 140#define GEN_HELPER_LU(name, ret, arg0, arg1, n) do {         \
 141    TCGv arg00 = tcg_temp_new();                             \
 142    TCGv arg01 = tcg_temp_new();                             \
 143    TCGv arg10 = tcg_temp_new();                             \
 144    TCGv arg11 = tcg_temp_new();                             \
 145    tcg_gen_sari_tl(arg00, arg0, 16);                        \
 146    tcg_gen_ext16s_tl(arg01, arg0);                          \
 147    tcg_gen_sari_tl(arg11, arg1, 16);                        \
 148    tcg_gen_ext16s_tl(arg10, arg1);                          \
 149    gen_helper_##name(ret, arg00, arg01, arg10, arg11, n);   \
 150    tcg_temp_free(arg00);                                    \
 151    tcg_temp_free(arg01);                                    \
 152    tcg_temp_free(arg10);                                    \
 153    tcg_temp_free(arg11);                                    \
 154} while (0)
 155
 156#define GEN_HELPER_UL(name, ret, arg0, arg1, n) do {         \
 157    TCGv arg00 = tcg_temp_new();                             \
 158    TCGv arg01 = tcg_temp_new();                             \
 159    TCGv arg10 = tcg_temp_new();                             \
 160    TCGv arg11 = tcg_temp_new();                             \
 161    tcg_gen_sari_tl(arg00, arg0, 16);                        \
 162    tcg_gen_ext16s_tl(arg01, arg0);                          \
 163    tcg_gen_sari_tl(arg10, arg1, 16);                        \
 164    tcg_gen_ext16s_tl(arg11, arg1);                          \
 165    gen_helper_##name(ret, arg00, arg01, arg10, arg11, n);   \
 166    tcg_temp_free(arg00);                                    \
 167    tcg_temp_free(arg01);                                    \
 168    tcg_temp_free(arg10);                                    \
 169    tcg_temp_free(arg11);                                    \
 170} while (0)
 171
 172#define GEN_HELPER_UU(name, ret, arg0, arg1, n) do {         \
 173    TCGv arg00 = tcg_temp_new();                             \
 174    TCGv arg01 = tcg_temp_new();                             \
 175    TCGv arg11 = tcg_temp_new();                             \
 176    tcg_gen_sari_tl(arg01, arg0, 16);                        \
 177    tcg_gen_ext16s_tl(arg00, arg0);                          \
 178    tcg_gen_sari_tl(arg11, arg1, 16);                        \
 179    gen_helper_##name(ret, arg00, arg01, arg11, arg11, n);   \
 180    tcg_temp_free(arg00);                                    \
 181    tcg_temp_free(arg01);                                    \
 182    tcg_temp_free(arg11);                                    \
 183} while (0)
 184
 185#define GEN_HELPER_RRR(name, rl, rh, al1, ah1, arg2) do {    \
 186    TCGv_i64 ret = tcg_temp_new_i64();                       \
 187    TCGv_i64 arg1 = tcg_temp_new_i64();                      \
 188                                                             \
 189    tcg_gen_concat_i32_i64(arg1, al1, ah1);                  \
 190    gen_helper_##name(ret, arg1, arg2);                      \
 191    tcg_gen_extr_i64_i32(rl, rh, ret);                       \
 192                                                             \
 193    tcg_temp_free_i64(ret);                                  \
 194    tcg_temp_free_i64(arg1);                                 \
 195} while (0)
 196
 197#define GEN_HELPER_RR(name, rl, rh, arg1, arg2) do {        \
 198    TCGv_i64 ret = tcg_temp_new_i64();                      \
 199                                                            \
 200    gen_helper_##name(ret, cpu_env, arg1, arg2);            \
 201    tcg_gen_extr_i64_i32(rl, rh, ret);                      \
 202                                                            \
 203    tcg_temp_free_i64(ret);                                 \
 204} while (0)
 205
 206#define EA_ABS_FORMAT(con) (((con & 0x3C000) << 14) + (con & 0x3FFF))
 207#define EA_B_ABSOLUT(con) (((offset & 0xf00000) << 8) | \
 208                           ((offset & 0x0fffff) << 1))
 209
 210/* For two 32-bit registers used a 64-bit register, the first
 211   registernumber needs to be even. Otherwise we trap. */
 212static inline void generate_trap(DisasContext *ctx, int class, int tin);
 213#define CHECK_REG_PAIR(reg) do {                      \
 214    if (reg & 0x1) {                                  \
 215        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_OPD); \
 216    }                                                 \
 217} while (0)
 218
 219/* Functions for load/save to/from memory */
 220
 221static inline void gen_offset_ld(DisasContext *ctx, TCGv r1, TCGv r2,
 222                                 int16_t con, MemOp mop)
 223{
 224    TCGv temp = tcg_temp_new();
 225    tcg_gen_addi_tl(temp, r2, con);
 226    tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
 227    tcg_temp_free(temp);
 228}
 229
 230static inline void gen_offset_st(DisasContext *ctx, TCGv r1, TCGv r2,
 231                                 int16_t con, MemOp mop)
 232{
 233    TCGv temp = tcg_temp_new();
 234    tcg_gen_addi_tl(temp, r2, con);
 235    tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
 236    tcg_temp_free(temp);
 237}
 238
 239static void gen_st_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
 240{
 241    TCGv_i64 temp = tcg_temp_new_i64();
 242
 243    tcg_gen_concat_i32_i64(temp, rl, rh);
 244    tcg_gen_qemu_st_i64(temp, address, ctx->mem_idx, MO_LEQ);
 245
 246    tcg_temp_free_i64(temp);
 247}
 248
 249static void gen_offset_st_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
 250                                DisasContext *ctx)
 251{
 252    TCGv temp = tcg_temp_new();
 253    tcg_gen_addi_tl(temp, base, con);
 254    gen_st_2regs_64(rh, rl, temp, ctx);
 255    tcg_temp_free(temp);
 256}
 257
 258static void gen_ld_2regs_64(TCGv rh, TCGv rl, TCGv address, DisasContext *ctx)
 259{
 260    TCGv_i64 temp = tcg_temp_new_i64();
 261
 262    tcg_gen_qemu_ld_i64(temp, address, ctx->mem_idx, MO_LEQ);
 263    /* write back to two 32 bit regs */
 264    tcg_gen_extr_i64_i32(rl, rh, temp);
 265
 266    tcg_temp_free_i64(temp);
 267}
 268
 269static void gen_offset_ld_2regs(TCGv rh, TCGv rl, TCGv base, int16_t con,
 270                                DisasContext *ctx)
 271{
 272    TCGv temp = tcg_temp_new();
 273    tcg_gen_addi_tl(temp, base, con);
 274    gen_ld_2regs_64(rh, rl, temp, ctx);
 275    tcg_temp_free(temp);
 276}
 277
 278static void gen_st_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off,
 279                           MemOp mop)
 280{
 281    TCGv temp = tcg_temp_new();
 282    tcg_gen_addi_tl(temp, r2, off);
 283    tcg_gen_qemu_st_tl(r1, temp, ctx->mem_idx, mop);
 284    tcg_gen_mov_tl(r2, temp);
 285    tcg_temp_free(temp);
 286}
 287
 288static void gen_ld_preincr(DisasContext *ctx, TCGv r1, TCGv r2, int16_t off,
 289                           MemOp mop)
 290{
 291    TCGv temp = tcg_temp_new();
 292    tcg_gen_addi_tl(temp, r2, off);
 293    tcg_gen_qemu_ld_tl(r1, temp, ctx->mem_idx, mop);
 294    tcg_gen_mov_tl(r2, temp);
 295    tcg_temp_free(temp);
 296}
 297
 298/* M(EA, word) = (M(EA, word) & ~E[a][63:32]) | (E[a][31:0] & E[a][63:32]); */
 299static void gen_ldmst(DisasContext *ctx, int ereg, TCGv ea)
 300{
 301    TCGv temp = tcg_temp_new();
 302    TCGv temp2 = tcg_temp_new();
 303
 304    CHECK_REG_PAIR(ereg);
 305    /* temp = (M(EA, word) */
 306    tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
 307    /* temp = temp & ~E[a][63:32]) */
 308    tcg_gen_andc_tl(temp, temp, cpu_gpr_d[ereg+1]);
 309    /* temp2 = (E[a][31:0] & E[a][63:32]); */
 310    tcg_gen_and_tl(temp2, cpu_gpr_d[ereg], cpu_gpr_d[ereg+1]);
 311    /* temp = temp | temp2; */
 312    tcg_gen_or_tl(temp, temp, temp2);
 313    /* M(EA, word) = temp; */
 314    tcg_gen_qemu_st_tl(temp, ea, ctx->mem_idx, MO_LEUL);
 315
 316    tcg_temp_free(temp);
 317    tcg_temp_free(temp2);
 318}
 319
 320/* tmp = M(EA, word);
 321   M(EA, word) = D[a];
 322   D[a] = tmp[31:0];*/
 323static void gen_swap(DisasContext *ctx, int reg, TCGv ea)
 324{
 325    TCGv temp = tcg_temp_new();
 326
 327    tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
 328    tcg_gen_qemu_st_tl(cpu_gpr_d[reg], ea, ctx->mem_idx, MO_LEUL);
 329    tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
 330
 331    tcg_temp_free(temp);
 332}
 333
 334static void gen_cmpswap(DisasContext *ctx, int reg, TCGv ea)
 335{
 336    TCGv temp = tcg_temp_new();
 337    TCGv temp2 = tcg_temp_new();
 338    tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
 339    tcg_gen_movcond_tl(TCG_COND_EQ, temp2, cpu_gpr_d[reg+1], temp,
 340                       cpu_gpr_d[reg], temp);
 341    tcg_gen_qemu_st_tl(temp2, ea, ctx->mem_idx, MO_LEUL);
 342    tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
 343
 344    tcg_temp_free(temp);
 345    tcg_temp_free(temp2);
 346}
 347
 348static void gen_swapmsk(DisasContext *ctx, int reg, TCGv ea)
 349{
 350    TCGv temp = tcg_temp_new();
 351    TCGv temp2 = tcg_temp_new();
 352    TCGv temp3 = tcg_temp_new();
 353
 354    tcg_gen_qemu_ld_tl(temp, ea, ctx->mem_idx, MO_LEUL);
 355    tcg_gen_and_tl(temp2, cpu_gpr_d[reg], cpu_gpr_d[reg+1]);
 356    tcg_gen_andc_tl(temp3, temp, cpu_gpr_d[reg+1]);
 357    tcg_gen_or_tl(temp2, temp2, temp3);
 358    tcg_gen_qemu_st_tl(temp2, ea, ctx->mem_idx, MO_LEUL);
 359    tcg_gen_mov_tl(cpu_gpr_d[reg], temp);
 360
 361    tcg_temp_free(temp);
 362    tcg_temp_free(temp2);
 363    tcg_temp_free(temp3);
 364}
 365
 366
 367/* We generate loads and store to core special function register (csfr) through
 368   the function gen_mfcr and gen_mtcr. To handle access permissions, we use 3
 369   makros R, A and E, which allow read-only, all and endinit protected access.
 370   These makros also specify in which ISA version the csfr was introduced. */
 371#define R(ADDRESS, REG, FEATURE)                                         \
 372    case ADDRESS:                                                        \
 373        if (tricore_feature(ctx->env, FEATURE)) {                        \
 374            tcg_gen_ld_tl(ret, cpu_env, offsetof(CPUTriCoreState, REG)); \
 375        }                                                                \
 376        break;
 377#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
 378#define E(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)
 379static inline void gen_mfcr(DisasContext *ctx, TCGv ret, int32_t offset)
 380{
 381    /* since we're caching PSW make this a special case */
 382    if (offset == 0xfe04) {
 383        gen_helper_psw_read(ret, cpu_env);
 384    } else {
 385        switch (offset) {
 386#include "csfr.def"
 387        }
 388    }
 389}
 390#undef R
 391#undef A
 392#undef E
 393
 394#define R(ADDRESS, REG, FEATURE) /* don't gen writes to read-only reg,
 395                                    since no execption occurs */
 396#define A(ADDRESS, REG, FEATURE) R(ADDRESS, REG, FEATURE)                \
 397    case ADDRESS:                                                        \
 398        if (tricore_feature(ctx->env, FEATURE)) {                        \
 399            tcg_gen_st_tl(r1, cpu_env, offsetof(CPUTriCoreState, REG));  \
 400        }                                                                \
 401        break;
 402/* Endinit protected registers
 403   TODO: Since the endinit bit is in a register of a not yet implemented
 404         watchdog device, we handle endinit protected registers like
 405         all-access registers for now. */
 406#define E(ADDRESS, REG, FEATURE) A(ADDRESS, REG, FEATURE)
 407static inline void gen_mtcr(DisasContext *ctx, TCGv r1,
 408                            int32_t offset)
 409{
 410    if ((ctx->hflags & TRICORE_HFLAG_KUU) == TRICORE_HFLAG_SM) {
 411        /* since we're caching PSW make this a special case */
 412        if (offset == 0xfe04) {
 413            gen_helper_psw_write(cpu_env, r1);
 414        } else {
 415            switch (offset) {
 416#include "csfr.def"
 417            }
 418        }
 419    } else {
 420        /* generate privilege trap */
 421    }
 422}
 423
 424/* Functions for arithmetic instructions  */
 425
 426static inline void gen_add_d(TCGv ret, TCGv r1, TCGv r2)
 427{
 428    TCGv t0 = tcg_temp_new_i32();
 429    TCGv result = tcg_temp_new_i32();
 430    /* Addition and set V/SV bits */
 431    tcg_gen_add_tl(result, r1, r2);
 432    /* calc V bit */
 433    tcg_gen_xor_tl(cpu_PSW_V, result, r1);
 434    tcg_gen_xor_tl(t0, r1, r2);
 435    tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
 436    /* Calc SV bit */
 437    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 438    /* Calc AV/SAV bits */
 439    tcg_gen_add_tl(cpu_PSW_AV, result, result);
 440    tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
 441    /* calc SAV */
 442    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
 443    /* write back result */
 444    tcg_gen_mov_tl(ret, result);
 445
 446    tcg_temp_free(result);
 447    tcg_temp_free(t0);
 448}
 449
 450static inline void
 451gen_add64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
 452{
 453    TCGv temp = tcg_temp_new();
 454    TCGv_i64 t0 = tcg_temp_new_i64();
 455    TCGv_i64 t1 = tcg_temp_new_i64();
 456    TCGv_i64 result = tcg_temp_new_i64();
 457
 458    tcg_gen_add_i64(result, r1, r2);
 459    /* calc v bit */
 460    tcg_gen_xor_i64(t1, result, r1);
 461    tcg_gen_xor_i64(t0, r1, r2);
 462    tcg_gen_andc_i64(t1, t1, t0);
 463    tcg_gen_extrh_i64_i32(cpu_PSW_V, t1);
 464    /* calc SV bit */
 465    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 466    /* calc AV/SAV bits */
 467    tcg_gen_extrh_i64_i32(temp, result);
 468    tcg_gen_add_tl(cpu_PSW_AV, temp, temp);
 469    tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV);
 470    /* calc SAV */
 471    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
 472    /* write back result */
 473    tcg_gen_mov_i64(ret, result);
 474
 475    tcg_temp_free(temp);
 476    tcg_temp_free_i64(result);
 477    tcg_temp_free_i64(t0);
 478    tcg_temp_free_i64(t1);
 479}
 480
 481static inline void
 482gen_addsub64_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 483               TCGv r3, void(*op1)(TCGv, TCGv, TCGv),
 484               void(*op2)(TCGv, TCGv, TCGv))
 485{
 486    TCGv temp = tcg_temp_new();
 487    TCGv temp2 = tcg_temp_new();
 488    TCGv temp3 = tcg_temp_new();
 489    TCGv temp4 = tcg_temp_new();
 490
 491    (*op1)(temp, r1_low, r2);
 492    /* calc V0 bit */
 493    tcg_gen_xor_tl(temp2, temp, r1_low);
 494    tcg_gen_xor_tl(temp3, r1_low, r2);
 495    if (op1 == tcg_gen_add_tl) {
 496        tcg_gen_andc_tl(temp2, temp2, temp3);
 497    } else {
 498        tcg_gen_and_tl(temp2, temp2, temp3);
 499    }
 500
 501    (*op2)(temp3, r1_high, r3);
 502    /* calc V1 bit */
 503    tcg_gen_xor_tl(cpu_PSW_V, temp3, r1_high);
 504    tcg_gen_xor_tl(temp4, r1_high, r3);
 505    if (op2 == tcg_gen_add_tl) {
 506        tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, temp4);
 507    } else {
 508        tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp4);
 509    }
 510    /* combine V0/V1 bits */
 511    tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp2);
 512    /* calc sv bit */
 513    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 514    /* write result */
 515    tcg_gen_mov_tl(ret_low, temp);
 516    tcg_gen_mov_tl(ret_high, temp3);
 517    /* calc AV bit */
 518    tcg_gen_add_tl(temp, ret_low, ret_low);
 519    tcg_gen_xor_tl(temp, temp, ret_low);
 520    tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
 521    tcg_gen_xor_tl(cpu_PSW_AV, cpu_PSW_AV, ret_high);
 522    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
 523    /* calc SAV bit */
 524    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
 525
 526    tcg_temp_free(temp);
 527    tcg_temp_free(temp2);
 528    tcg_temp_free(temp3);
 529    tcg_temp_free(temp4);
 530}
 531
 532/* ret = r2 + (r1 * r3); */
 533static inline void gen_madd32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
 534{
 535    TCGv_i64 t1 = tcg_temp_new_i64();
 536    TCGv_i64 t2 = tcg_temp_new_i64();
 537    TCGv_i64 t3 = tcg_temp_new_i64();
 538
 539    tcg_gen_ext_i32_i64(t1, r1);
 540    tcg_gen_ext_i32_i64(t2, r2);
 541    tcg_gen_ext_i32_i64(t3, r3);
 542
 543    tcg_gen_mul_i64(t1, t1, t3);
 544    tcg_gen_add_i64(t1, t2, t1);
 545
 546    tcg_gen_extrl_i64_i32(ret, t1);
 547    /* calc V
 548       t1 > 0x7fffffff */
 549    tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
 550    /* t1 < -0x80000000 */
 551    tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
 552    tcg_gen_or_i64(t2, t2, t3);
 553    tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
 554    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
 555    /* Calc SV bit */
 556    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 557    /* Calc AV/SAV bits */
 558    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
 559    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
 560    /* calc SAV */
 561    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
 562
 563    tcg_temp_free_i64(t1);
 564    tcg_temp_free_i64(t2);
 565    tcg_temp_free_i64(t3);
 566}
 567
 568static inline void gen_maddi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
 569{
 570    TCGv temp = tcg_const_i32(con);
 571    gen_madd32_d(ret, r1, r2, temp);
 572    tcg_temp_free(temp);
 573}
 574
 575static inline void
 576gen_madd64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
 577             TCGv r3)
 578{
 579    TCGv t1 = tcg_temp_new();
 580    TCGv t2 = tcg_temp_new();
 581    TCGv t3 = tcg_temp_new();
 582    TCGv t4 = tcg_temp_new();
 583
 584    tcg_gen_muls2_tl(t1, t2, r1, r3);
 585    /* only the add can overflow */
 586    tcg_gen_add2_tl(t3, t4, r2_low, r2_high, t1, t2);
 587    /* calc V bit */
 588    tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
 589    tcg_gen_xor_tl(t1, r2_high, t2);
 590    tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t1);
 591    /* Calc SV bit */
 592    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 593    /* Calc AV/SAV bits */
 594    tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
 595    tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
 596    /* calc SAV */
 597    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
 598    /* write back the result */
 599    tcg_gen_mov_tl(ret_low, t3);
 600    tcg_gen_mov_tl(ret_high, t4);
 601
 602    tcg_temp_free(t1);
 603    tcg_temp_free(t2);
 604    tcg_temp_free(t3);
 605    tcg_temp_free(t4);
 606}
 607
 608static inline void
 609gen_maddu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
 610              TCGv r3)
 611{
 612    TCGv_i64 t1 = tcg_temp_new_i64();
 613    TCGv_i64 t2 = tcg_temp_new_i64();
 614    TCGv_i64 t3 = tcg_temp_new_i64();
 615
 616    tcg_gen_extu_i32_i64(t1, r1);
 617    tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
 618    tcg_gen_extu_i32_i64(t3, r3);
 619
 620    tcg_gen_mul_i64(t1, t1, t3);
 621    tcg_gen_add_i64(t2, t2, t1);
 622    /* write back result */
 623    tcg_gen_extr_i64_i32(ret_low, ret_high, t2);
 624    /* only the add overflows, if t2 < t1
 625       calc V bit */
 626    tcg_gen_setcond_i64(TCG_COND_LTU, t2, t2, t1);
 627    tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
 628    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
 629    /* Calc SV bit */
 630    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
 631    /* Calc AV/SAV bits */
 632    tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
 633    tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
 634    /* calc SAV */
 635    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
 636
 637    tcg_temp_free_i64(t1);
 638    tcg_temp_free_i64(t2);
 639    tcg_temp_free_i64(t3);
 640}
 641
 642static inline void
 643gen_maddi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
 644              int32_t con)
 645{
 646    TCGv temp = tcg_const_i32(con);
 647    gen_madd64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
 648    tcg_temp_free(temp);
 649}
 650
 651static inline void
 652gen_maddui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
 653               int32_t con)
 654{
 655    TCGv temp = tcg_const_i32(con);
 656    gen_maddu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
 657    tcg_temp_free(temp);
 658}
 659
 660static inline void
 661gen_madd_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 662           TCGv r3, uint32_t n, uint32_t mode)
 663{
 664    TCGv temp = tcg_const_i32(n);
 665    TCGv temp2 = tcg_temp_new();
 666    TCGv_i64 temp64 = tcg_temp_new_i64();
 667    switch (mode) {
 668    case MODE_LL:
 669        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
 670        break;
 671    case MODE_LU:
 672        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
 673        break;
 674    case MODE_UL:
 675        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
 676        break;
 677    case MODE_UU:
 678        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
 679        break;
 680    }
 681    tcg_gen_extr_i64_i32(temp, temp2, temp64);
 682    gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
 683                   tcg_gen_add_tl, tcg_gen_add_tl);
 684    tcg_temp_free(temp);
 685    tcg_temp_free(temp2);
 686    tcg_temp_free_i64(temp64);
 687}
 688
 689static inline void
 690gen_maddsu_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 691             TCGv r3, uint32_t n, uint32_t mode)
 692{
 693    TCGv temp = tcg_const_i32(n);
 694    TCGv temp2 = tcg_temp_new();
 695    TCGv_i64 temp64 = tcg_temp_new_i64();
 696    switch (mode) {
 697    case MODE_LL:
 698        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
 699        break;
 700    case MODE_LU:
 701        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
 702        break;
 703    case MODE_UL:
 704        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
 705        break;
 706    case MODE_UU:
 707        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
 708        break;
 709    }
 710    tcg_gen_extr_i64_i32(temp, temp2, temp64);
 711    gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
 712                   tcg_gen_sub_tl, tcg_gen_add_tl);
 713    tcg_temp_free(temp);
 714    tcg_temp_free(temp2);
 715    tcg_temp_free_i64(temp64);
 716}
 717
 718static inline void
 719gen_maddsum_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 720              TCGv r3, uint32_t n, uint32_t mode)
 721{
 722    TCGv temp = tcg_const_i32(n);
 723    TCGv_i64 temp64 = tcg_temp_new_i64();
 724    TCGv_i64 temp64_2 = tcg_temp_new_i64();
 725    TCGv_i64 temp64_3 = tcg_temp_new_i64();
 726    switch (mode) {
 727    case MODE_LL:
 728        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
 729        break;
 730    case MODE_LU:
 731        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
 732        break;
 733    case MODE_UL:
 734        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
 735        break;
 736    case MODE_UU:
 737        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
 738        break;
 739    }
 740    tcg_gen_concat_i32_i64(temp64_3, r1_low, r1_high);
 741    tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
 742    tcg_gen_ext32s_i64(temp64, temp64); /* low */
 743    tcg_gen_sub_i64(temp64, temp64_2, temp64);
 744    tcg_gen_shli_i64(temp64, temp64, 16);
 745
 746    gen_add64_d(temp64_2, temp64_3, temp64);
 747    /* write back result */
 748    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_2);
 749
 750    tcg_temp_free(temp);
 751    tcg_temp_free_i64(temp64);
 752    tcg_temp_free_i64(temp64_2);
 753    tcg_temp_free_i64(temp64_3);
 754}
 755
 756static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2);
 757
 758static inline void
 759gen_madds_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 760           TCGv r3, uint32_t n, uint32_t mode)
 761{
 762    TCGv temp = tcg_const_i32(n);
 763    TCGv temp2 = tcg_temp_new();
 764    TCGv temp3 = tcg_temp_new();
 765    TCGv_i64 temp64 = tcg_temp_new_i64();
 766
 767    switch (mode) {
 768    case MODE_LL:
 769        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
 770        break;
 771    case MODE_LU:
 772        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
 773        break;
 774    case MODE_UL:
 775        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
 776        break;
 777    case MODE_UU:
 778        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
 779        break;
 780    }
 781    tcg_gen_extr_i64_i32(temp, temp2, temp64);
 782    gen_adds(ret_low, r1_low, temp);
 783    tcg_gen_mov_tl(temp, cpu_PSW_V);
 784    tcg_gen_mov_tl(temp3, cpu_PSW_AV);
 785    gen_adds(ret_high, r1_high, temp2);
 786    /* combine v bits */
 787    tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
 788    /* combine av bits */
 789    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
 790
 791    tcg_temp_free(temp);
 792    tcg_temp_free(temp2);
 793    tcg_temp_free(temp3);
 794    tcg_temp_free_i64(temp64);
 795
 796}
 797
 798static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2);
 799
 800static inline void
 801gen_maddsus_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 802              TCGv r3, uint32_t n, uint32_t mode)
 803{
 804    TCGv temp = tcg_const_i32(n);
 805    TCGv temp2 = tcg_temp_new();
 806    TCGv temp3 = tcg_temp_new();
 807    TCGv_i64 temp64 = tcg_temp_new_i64();
 808
 809    switch (mode) {
 810    case MODE_LL:
 811        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
 812        break;
 813    case MODE_LU:
 814        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
 815        break;
 816    case MODE_UL:
 817        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
 818        break;
 819    case MODE_UU:
 820        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
 821        break;
 822    }
 823    tcg_gen_extr_i64_i32(temp, temp2, temp64);
 824    gen_subs(ret_low, r1_low, temp);
 825    tcg_gen_mov_tl(temp, cpu_PSW_V);
 826    tcg_gen_mov_tl(temp3, cpu_PSW_AV);
 827    gen_adds(ret_high, r1_high, temp2);
 828    /* combine v bits */
 829    tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
 830    /* combine av bits */
 831    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
 832
 833    tcg_temp_free(temp);
 834    tcg_temp_free(temp2);
 835    tcg_temp_free(temp3);
 836    tcg_temp_free_i64(temp64);
 837
 838}
 839
 840static inline void
 841gen_maddsums_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 842               TCGv r3, uint32_t n, uint32_t mode)
 843{
 844    TCGv temp = tcg_const_i32(n);
 845    TCGv_i64 temp64 = tcg_temp_new_i64();
 846    TCGv_i64 temp64_2 = tcg_temp_new_i64();
 847
 848    switch (mode) {
 849    case MODE_LL:
 850        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
 851        break;
 852    case MODE_LU:
 853        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
 854        break;
 855    case MODE_UL:
 856        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
 857        break;
 858    case MODE_UU:
 859        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
 860        break;
 861    }
 862    tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
 863    tcg_gen_ext32s_i64(temp64, temp64); /* low */
 864    tcg_gen_sub_i64(temp64, temp64_2, temp64);
 865    tcg_gen_shli_i64(temp64, temp64, 16);
 866    tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
 867
 868    gen_helper_add64_ssov(temp64, cpu_env, temp64_2, temp64);
 869    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
 870
 871    tcg_temp_free(temp);
 872    tcg_temp_free_i64(temp64);
 873    tcg_temp_free_i64(temp64_2);
 874}
 875
 876
 877static inline void
 878gen_maddm_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 879           TCGv r3, uint32_t n, uint32_t mode)
 880{
 881    TCGv temp = tcg_const_i32(n);
 882    TCGv_i64 temp64 = tcg_temp_new_i64();
 883    TCGv_i64 temp64_2 = tcg_temp_new_i64();
 884    TCGv_i64 temp64_3 = tcg_temp_new_i64();
 885    switch (mode) {
 886    case MODE_LL:
 887        GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
 888        break;
 889    case MODE_LU:
 890        GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
 891        break;
 892    case MODE_UL:
 893        GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
 894        break;
 895    case MODE_UU:
 896        GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
 897        break;
 898    }
 899    tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
 900    gen_add64_d(temp64_3, temp64_2, temp64);
 901    /* write back result */
 902    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_3);
 903
 904    tcg_temp_free(temp);
 905    tcg_temp_free_i64(temp64);
 906    tcg_temp_free_i64(temp64_2);
 907    tcg_temp_free_i64(temp64_3);
 908}
 909
 910static inline void
 911gen_maddms_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
 912           TCGv r3, uint32_t n, uint32_t mode)
 913{
 914    TCGv temp = tcg_const_i32(n);
 915    TCGv_i64 temp64 = tcg_temp_new_i64();
 916    TCGv_i64 temp64_2 = tcg_temp_new_i64();
 917    switch (mode) {
 918    case MODE_LL:
 919        GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
 920        break;
 921    case MODE_LU:
 922        GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
 923        break;
 924    case MODE_UL:
 925        GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
 926        break;
 927    case MODE_UU:
 928        GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
 929        break;
 930    }
 931    tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
 932    gen_helper_add64_ssov(temp64, cpu_env, temp64_2, temp64);
 933    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
 934
 935    tcg_temp_free(temp);
 936    tcg_temp_free_i64(temp64);
 937    tcg_temp_free_i64(temp64_2);
 938}
 939
 940static inline void
 941gen_maddr64_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n,
 942              uint32_t mode)
 943{
 944    TCGv temp = tcg_const_i32(n);
 945    TCGv_i64 temp64 = tcg_temp_new_i64();
 946    switch (mode) {
 947    case MODE_LL:
 948        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
 949        break;
 950    case MODE_LU:
 951        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
 952        break;
 953    case MODE_UL:
 954        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
 955        break;
 956    case MODE_UU:
 957        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
 958        break;
 959    }
 960    gen_helper_addr_h(ret, cpu_env, temp64, r1_low, r1_high);
 961
 962    tcg_temp_free(temp);
 963    tcg_temp_free_i64(temp64);
 964}
 965
 966static inline void
 967gen_maddr32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
 968{
 969    TCGv temp = tcg_temp_new();
 970    TCGv temp2 = tcg_temp_new();
 971
 972    tcg_gen_andi_tl(temp2, r1, 0xffff0000);
 973    tcg_gen_shli_tl(temp, r1, 16);
 974    gen_maddr64_h(ret, temp, temp2, r2, r3, n, mode);
 975
 976    tcg_temp_free(temp);
 977    tcg_temp_free(temp2);
 978}
 979
 980static inline void
 981gen_maddsur32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
 982{
 983    TCGv temp = tcg_const_i32(n);
 984    TCGv temp2 = tcg_temp_new();
 985    TCGv_i64 temp64 = tcg_temp_new_i64();
 986    switch (mode) {
 987    case MODE_LL:
 988        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
 989        break;
 990    case MODE_LU:
 991        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
 992        break;
 993    case MODE_UL:
 994        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
 995        break;
 996    case MODE_UU:
 997        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
 998        break;
 999    }
1000    tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1001    tcg_gen_shli_tl(temp, r1, 16);
1002    gen_helper_addsur_h(ret, cpu_env, temp64, temp, temp2);
1003
1004    tcg_temp_free(temp);
1005    tcg_temp_free(temp2);
1006    tcg_temp_free_i64(temp64);
1007}
1008
1009
1010static inline void
1011gen_maddr64s_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3,
1012               uint32_t n, uint32_t mode)
1013{
1014    TCGv temp = tcg_const_i32(n);
1015    TCGv_i64 temp64 = tcg_temp_new_i64();
1016    switch (mode) {
1017    case MODE_LL:
1018        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1019        break;
1020    case MODE_LU:
1021        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1022        break;
1023    case MODE_UL:
1024        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1025        break;
1026    case MODE_UU:
1027        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1028        break;
1029    }
1030    gen_helper_addr_h_ssov(ret, cpu_env, temp64, r1_low, r1_high);
1031
1032    tcg_temp_free(temp);
1033    tcg_temp_free_i64(temp64);
1034}
1035
1036static inline void
1037gen_maddr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
1038{
1039    TCGv temp = tcg_temp_new();
1040    TCGv temp2 = tcg_temp_new();
1041
1042    tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1043    tcg_gen_shli_tl(temp, r1, 16);
1044    gen_maddr64s_h(ret, temp, temp2, r2, r3, n, mode);
1045
1046    tcg_temp_free(temp);
1047    tcg_temp_free(temp2);
1048}
1049
1050static inline void
1051gen_maddsur32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
1052{
1053    TCGv temp = tcg_const_i32(n);
1054    TCGv temp2 = tcg_temp_new();
1055    TCGv_i64 temp64 = tcg_temp_new_i64();
1056    switch (mode) {
1057    case MODE_LL:
1058        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1059        break;
1060    case MODE_LU:
1061        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1062        break;
1063    case MODE_UL:
1064        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1065        break;
1066    case MODE_UU:
1067        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1068        break;
1069    }
1070    tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1071    tcg_gen_shli_tl(temp, r1, 16);
1072    gen_helper_addsur_h_ssov(ret, cpu_env, temp64, temp, temp2);
1073
1074    tcg_temp_free(temp);
1075    tcg_temp_free(temp2);
1076    tcg_temp_free_i64(temp64);
1077}
1078
1079static inline void
1080gen_maddr_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
1081{
1082    TCGv temp = tcg_const_i32(n);
1083    gen_helper_maddr_q(ret, cpu_env, r1, r2, r3, temp);
1084    tcg_temp_free(temp);
1085}
1086
1087static inline void
1088gen_maddrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
1089{
1090    TCGv temp = tcg_const_i32(n);
1091    gen_helper_maddr_q_ssov(ret, cpu_env, r1, r2, r3, temp);
1092    tcg_temp_free(temp);
1093}
1094
1095static inline void
1096gen_madd32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
1097             uint32_t up_shift)
1098{
1099    TCGv temp = tcg_temp_new();
1100    TCGv temp2 = tcg_temp_new();
1101    TCGv temp3 = tcg_temp_new();
1102    TCGv_i64 t1 = tcg_temp_new_i64();
1103    TCGv_i64 t2 = tcg_temp_new_i64();
1104    TCGv_i64 t3 = tcg_temp_new_i64();
1105
1106    tcg_gen_ext_i32_i64(t2, arg2);
1107    tcg_gen_ext_i32_i64(t3, arg3);
1108
1109    tcg_gen_mul_i64(t2, t2, t3);
1110    tcg_gen_shli_i64(t2, t2, n);
1111
1112    tcg_gen_ext_i32_i64(t1, arg1);
1113    tcg_gen_sari_i64(t2, t2, up_shift);
1114
1115    tcg_gen_add_i64(t3, t1, t2);
1116    tcg_gen_extrl_i64_i32(temp3, t3);
1117    /* calc v bit */
1118    tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL);
1119    tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL);
1120    tcg_gen_or_i64(t1, t1, t2);
1121    tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1122    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
1123    /* We produce an overflow on the host if the mul before was
1124       (0x80000000 * 0x80000000) << 1). If this is the
1125       case, we negate the ovf. */
1126    if (n == 1) {
1127        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, arg2, 0x80000000);
1128        tcg_gen_setcond_tl(TCG_COND_EQ, temp2, arg2, arg3);
1129        tcg_gen_and_tl(temp, temp, temp2);
1130        tcg_gen_shli_tl(temp, temp, 31);
1131        /* negate v bit, if special condition */
1132        tcg_gen_xor_tl(cpu_PSW_V, cpu_PSW_V, temp);
1133    }
1134    /* Calc SV bit */
1135    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1136    /* Calc AV/SAV bits */
1137    tcg_gen_add_tl(cpu_PSW_AV, temp3, temp3);
1138    tcg_gen_xor_tl(cpu_PSW_AV, temp3, cpu_PSW_AV);
1139    /* calc SAV */
1140    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1141    /* write back result */
1142    tcg_gen_mov_tl(ret, temp3);
1143
1144    tcg_temp_free(temp);
1145    tcg_temp_free(temp2);
1146    tcg_temp_free(temp3);
1147    tcg_temp_free_i64(t1);
1148    tcg_temp_free_i64(t2);
1149    tcg_temp_free_i64(t3);
1150}
1151
1152static inline void
1153gen_m16add32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n)
1154{
1155    TCGv temp = tcg_temp_new();
1156    TCGv temp2 = tcg_temp_new();
1157    if (n == 0) {
1158        tcg_gen_mul_tl(temp, arg2, arg3);
1159    } else { /* n is expected to be 1 */
1160        tcg_gen_mul_tl(temp, arg2, arg3);
1161        tcg_gen_shli_tl(temp, temp, 1);
1162        /* catch special case r1 = r2 = 0x8000 */
1163        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
1164        tcg_gen_sub_tl(temp, temp, temp2);
1165    }
1166    gen_add_d(ret, arg1, temp);
1167
1168    tcg_temp_free(temp);
1169    tcg_temp_free(temp2);
1170}
1171
1172static inline void
1173gen_m16adds32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n)
1174{
1175    TCGv temp = tcg_temp_new();
1176    TCGv temp2 = tcg_temp_new();
1177    if (n == 0) {
1178        tcg_gen_mul_tl(temp, arg2, arg3);
1179    } else { /* n is expected to be 1 */
1180        tcg_gen_mul_tl(temp, arg2, arg3);
1181        tcg_gen_shli_tl(temp, temp, 1);
1182        /* catch special case r1 = r2 = 0x8000 */
1183        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
1184        tcg_gen_sub_tl(temp, temp, temp2);
1185    }
1186    gen_adds(ret, arg1, temp);
1187
1188    tcg_temp_free(temp);
1189    tcg_temp_free(temp2);
1190}
1191
1192static inline void
1193gen_m16add64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
1194               TCGv arg3, uint32_t n)
1195{
1196    TCGv temp = tcg_temp_new();
1197    TCGv temp2 = tcg_temp_new();
1198    TCGv_i64 t1 = tcg_temp_new_i64();
1199    TCGv_i64 t2 = tcg_temp_new_i64();
1200    TCGv_i64 t3 = tcg_temp_new_i64();
1201
1202    if (n == 0) {
1203        tcg_gen_mul_tl(temp, arg2, arg3);
1204    } else { /* n is expected to be 1 */
1205        tcg_gen_mul_tl(temp, arg2, arg3);
1206        tcg_gen_shli_tl(temp, temp, 1);
1207        /* catch special case r1 = r2 = 0x8000 */
1208        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
1209        tcg_gen_sub_tl(temp, temp, temp2);
1210    }
1211    tcg_gen_ext_i32_i64(t2, temp);
1212    tcg_gen_shli_i64(t2, t2, 16);
1213    tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1214    gen_add64_d(t3, t1, t2);
1215    /* write back result */
1216    tcg_gen_extr_i64_i32(rl, rh, t3);
1217
1218    tcg_temp_free_i64(t1);
1219    tcg_temp_free_i64(t2);
1220    tcg_temp_free_i64(t3);
1221    tcg_temp_free(temp);
1222    tcg_temp_free(temp2);
1223}
1224
1225static inline void
1226gen_m16adds64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
1227               TCGv arg3, uint32_t n)
1228{
1229    TCGv temp = tcg_temp_new();
1230    TCGv temp2 = tcg_temp_new();
1231    TCGv_i64 t1 = tcg_temp_new_i64();
1232    TCGv_i64 t2 = tcg_temp_new_i64();
1233
1234    if (n == 0) {
1235        tcg_gen_mul_tl(temp, arg2, arg3);
1236    } else { /* n is expected to be 1 */
1237        tcg_gen_mul_tl(temp, arg2, arg3);
1238        tcg_gen_shli_tl(temp, temp, 1);
1239        /* catch special case r1 = r2 = 0x8000 */
1240        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
1241        tcg_gen_sub_tl(temp, temp, temp2);
1242    }
1243    tcg_gen_ext_i32_i64(t2, temp);
1244    tcg_gen_shli_i64(t2, t2, 16);
1245    tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1246
1247    gen_helper_add64_ssov(t1, cpu_env, t1, t2);
1248    tcg_gen_extr_i64_i32(rl, rh, t1);
1249
1250    tcg_temp_free(temp);
1251    tcg_temp_free(temp2);
1252    tcg_temp_free_i64(t1);
1253    tcg_temp_free_i64(t2);
1254}
1255
1256static inline void
1257gen_madd64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
1258             TCGv arg3, uint32_t n)
1259{
1260    TCGv_i64 t1 = tcg_temp_new_i64();
1261    TCGv_i64 t2 = tcg_temp_new_i64();
1262    TCGv_i64 t3 = tcg_temp_new_i64();
1263    TCGv_i64 t4 = tcg_temp_new_i64();
1264    TCGv temp, temp2;
1265
1266    tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
1267    tcg_gen_ext_i32_i64(t2, arg2);
1268    tcg_gen_ext_i32_i64(t3, arg3);
1269
1270    tcg_gen_mul_i64(t2, t2, t3);
1271    if (n != 0) {
1272        tcg_gen_shli_i64(t2, t2, 1);
1273    }
1274    tcg_gen_add_i64(t4, t1, t2);
1275    /* calc v bit */
1276    tcg_gen_xor_i64(t3, t4, t1);
1277    tcg_gen_xor_i64(t2, t1, t2);
1278    tcg_gen_andc_i64(t3, t3, t2);
1279    tcg_gen_extrh_i64_i32(cpu_PSW_V, t3);
1280    /* We produce an overflow on the host if the mul before was
1281       (0x80000000 * 0x80000000) << 1). If this is the
1282       case, we negate the ovf. */
1283    if (n == 1) {
1284        temp = tcg_temp_new();
1285        temp2 = tcg_temp_new();
1286        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, arg2, 0x80000000);
1287        tcg_gen_setcond_tl(TCG_COND_EQ, temp2, arg2, arg3);
1288        tcg_gen_and_tl(temp, temp, temp2);
1289        tcg_gen_shli_tl(temp, temp, 31);
1290        /* negate v bit, if special condition */
1291        tcg_gen_xor_tl(cpu_PSW_V, cpu_PSW_V, temp);
1292
1293        tcg_temp_free(temp);
1294        tcg_temp_free(temp2);
1295    }
1296    /* write back result */
1297    tcg_gen_extr_i64_i32(rl, rh, t4);
1298    /* Calc SV bit */
1299    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1300    /* Calc AV/SAV bits */
1301    tcg_gen_add_tl(cpu_PSW_AV, rh, rh);
1302    tcg_gen_xor_tl(cpu_PSW_AV, rh, cpu_PSW_AV);
1303    /* calc SAV */
1304    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1305
1306    tcg_temp_free_i64(t1);
1307    tcg_temp_free_i64(t2);
1308    tcg_temp_free_i64(t3);
1309    tcg_temp_free_i64(t4);
1310}
1311
1312static inline void
1313gen_madds32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
1314              uint32_t up_shift)
1315{
1316    TCGv_i64 t1 = tcg_temp_new_i64();
1317    TCGv_i64 t2 = tcg_temp_new_i64();
1318    TCGv_i64 t3 = tcg_temp_new_i64();
1319
1320    tcg_gen_ext_i32_i64(t1, arg1);
1321    tcg_gen_ext_i32_i64(t2, arg2);
1322    tcg_gen_ext_i32_i64(t3, arg3);
1323
1324    tcg_gen_mul_i64(t2, t2, t3);
1325    tcg_gen_sari_i64(t2, t2, up_shift - n);
1326
1327    gen_helper_madd32_q_add_ssov(ret, cpu_env, t1, t2);
1328
1329    tcg_temp_free_i64(t1);
1330    tcg_temp_free_i64(t2);
1331    tcg_temp_free_i64(t3);
1332}
1333
1334static inline void
1335gen_madds64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
1336             TCGv arg3, uint32_t n)
1337{
1338    TCGv_i64 r1 = tcg_temp_new_i64();
1339    TCGv temp = tcg_const_i32(n);
1340
1341    tcg_gen_concat_i32_i64(r1, arg1_low, arg1_high);
1342    gen_helper_madd64_q_ssov(r1, cpu_env, r1, arg2, arg3, temp);
1343    tcg_gen_extr_i64_i32(rl, rh, r1);
1344
1345    tcg_temp_free_i64(r1);
1346    tcg_temp_free(temp);
1347}
1348/* ret = r2 - (r1 * r3); */
1349static inline void gen_msub32_d(TCGv ret, TCGv r1, TCGv r2, TCGv r3)
1350{
1351    TCGv_i64 t1 = tcg_temp_new_i64();
1352    TCGv_i64 t2 = tcg_temp_new_i64();
1353    TCGv_i64 t3 = tcg_temp_new_i64();
1354
1355    tcg_gen_ext_i32_i64(t1, r1);
1356    tcg_gen_ext_i32_i64(t2, r2);
1357    tcg_gen_ext_i32_i64(t3, r3);
1358
1359    tcg_gen_mul_i64(t1, t1, t3);
1360    tcg_gen_sub_i64(t1, t2, t1);
1361
1362    tcg_gen_extrl_i64_i32(ret, t1);
1363    /* calc V
1364       t2 > 0x7fffffff */
1365    tcg_gen_setcondi_i64(TCG_COND_GT, t3, t1, 0x7fffffffLL);
1366    /* result < -0x80000000 */
1367    tcg_gen_setcondi_i64(TCG_COND_LT, t2, t1, -0x80000000LL);
1368    tcg_gen_or_i64(t2, t2, t3);
1369    tcg_gen_extrl_i64_i32(cpu_PSW_V, t2);
1370    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
1371
1372    /* Calc SV bit */
1373    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1374    /* Calc AV/SAV bits */
1375    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
1376    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
1377    /* calc SAV */
1378    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1379
1380    tcg_temp_free_i64(t1);
1381    tcg_temp_free_i64(t2);
1382    tcg_temp_free_i64(t3);
1383}
1384
1385static inline void gen_msubi32_d(TCGv ret, TCGv r1, TCGv r2, int32_t con)
1386{
1387    TCGv temp = tcg_const_i32(con);
1388    gen_msub32_d(ret, r1, r2, temp);
1389    tcg_temp_free(temp);
1390}
1391
1392static inline void
1393gen_msub64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
1394             TCGv r3)
1395{
1396    TCGv t1 = tcg_temp_new();
1397    TCGv t2 = tcg_temp_new();
1398    TCGv t3 = tcg_temp_new();
1399    TCGv t4 = tcg_temp_new();
1400
1401    tcg_gen_muls2_tl(t1, t2, r1, r3);
1402    /* only the sub can overflow */
1403    tcg_gen_sub2_tl(t3, t4, r2_low, r2_high, t1, t2);
1404    /* calc V bit */
1405    tcg_gen_xor_tl(cpu_PSW_V, t4, r2_high);
1406    tcg_gen_xor_tl(t1, r2_high, t2);
1407    tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, t1);
1408    /* Calc SV bit */
1409    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1410    /* Calc AV/SAV bits */
1411    tcg_gen_add_tl(cpu_PSW_AV, t4, t4);
1412    tcg_gen_xor_tl(cpu_PSW_AV, t4, cpu_PSW_AV);
1413    /* calc SAV */
1414    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1415    /* write back the result */
1416    tcg_gen_mov_tl(ret_low, t3);
1417    tcg_gen_mov_tl(ret_high, t4);
1418
1419    tcg_temp_free(t1);
1420    tcg_temp_free(t2);
1421    tcg_temp_free(t3);
1422    tcg_temp_free(t4);
1423}
1424
1425static inline void
1426gen_msubi64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
1427              int32_t con)
1428{
1429    TCGv temp = tcg_const_i32(con);
1430    gen_msub64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
1431    tcg_temp_free(temp);
1432}
1433
1434static inline void
1435gen_msubu64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
1436              TCGv r3)
1437{
1438    TCGv_i64 t1 = tcg_temp_new_i64();
1439    TCGv_i64 t2 = tcg_temp_new_i64();
1440    TCGv_i64 t3 = tcg_temp_new_i64();
1441
1442    tcg_gen_extu_i32_i64(t1, r1);
1443    tcg_gen_concat_i32_i64(t2, r2_low, r2_high);
1444    tcg_gen_extu_i32_i64(t3, r3);
1445
1446    tcg_gen_mul_i64(t1, t1, t3);
1447    tcg_gen_sub_i64(t3, t2, t1);
1448    tcg_gen_extr_i64_i32(ret_low, ret_high, t3);
1449    /* calc V bit, only the sub can overflow, if t1 > t2 */
1450    tcg_gen_setcond_i64(TCG_COND_GTU, t1, t1, t2);
1451    tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1452    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
1453    /* Calc SV bit */
1454    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1455    /* Calc AV/SAV bits */
1456    tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
1457    tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
1458    /* calc SAV */
1459    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1460
1461    tcg_temp_free_i64(t1);
1462    tcg_temp_free_i64(t2);
1463    tcg_temp_free_i64(t3);
1464}
1465
1466static inline void
1467gen_msubui64_d(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
1468               int32_t con)
1469{
1470    TCGv temp = tcg_const_i32(con);
1471    gen_msubu64_d(ret_low, ret_high, r1, r2_low, r2_high, temp);
1472    tcg_temp_free(temp);
1473}
1474
1475static inline void gen_addi_d(TCGv ret, TCGv r1, target_ulong r2)
1476{
1477    TCGv temp = tcg_const_i32(r2);
1478    gen_add_d(ret, r1, temp);
1479    tcg_temp_free(temp);
1480}
1481/* calculate the carry bit too */
1482static inline void gen_add_CC(TCGv ret, TCGv r1, TCGv r2)
1483{
1484    TCGv t0    = tcg_temp_new_i32();
1485    TCGv result = tcg_temp_new_i32();
1486
1487    tcg_gen_movi_tl(t0, 0);
1488    /* Addition and set C/V/SV bits */
1489    tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, r2, t0);
1490    /* calc V bit */
1491    tcg_gen_xor_tl(cpu_PSW_V, result, r1);
1492    tcg_gen_xor_tl(t0, r1, r2);
1493    tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
1494    /* Calc SV bit */
1495    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1496    /* Calc AV/SAV bits */
1497    tcg_gen_add_tl(cpu_PSW_AV, result, result);
1498    tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
1499    /* calc SAV */
1500    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1501    /* write back result */
1502    tcg_gen_mov_tl(ret, result);
1503
1504    tcg_temp_free(result);
1505    tcg_temp_free(t0);
1506}
1507
1508static inline void gen_addi_CC(TCGv ret, TCGv r1, int32_t con)
1509{
1510    TCGv temp = tcg_const_i32(con);
1511    gen_add_CC(ret, r1, temp);
1512    tcg_temp_free(temp);
1513}
1514
1515static inline void gen_addc_CC(TCGv ret, TCGv r1, TCGv r2)
1516{
1517    TCGv carry = tcg_temp_new_i32();
1518    TCGv t0    = tcg_temp_new_i32();
1519    TCGv result = tcg_temp_new_i32();
1520
1521    tcg_gen_movi_tl(t0, 0);
1522    tcg_gen_setcondi_tl(TCG_COND_NE, carry, cpu_PSW_C, 0);
1523    /* Addition, carry and set C/V/SV bits */
1524    tcg_gen_add2_i32(result, cpu_PSW_C, r1, t0, carry, t0);
1525    tcg_gen_add2_i32(result, cpu_PSW_C, result, cpu_PSW_C, r2, t0);
1526    /* calc V bit */
1527    tcg_gen_xor_tl(cpu_PSW_V, result, r1);
1528    tcg_gen_xor_tl(t0, r1, r2);
1529    tcg_gen_andc_tl(cpu_PSW_V, cpu_PSW_V, t0);
1530    /* Calc SV bit */
1531    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1532    /* Calc AV/SAV bits */
1533    tcg_gen_add_tl(cpu_PSW_AV, result, result);
1534    tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
1535    /* calc SAV */
1536    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1537    /* write back result */
1538    tcg_gen_mov_tl(ret, result);
1539
1540    tcg_temp_free(result);
1541    tcg_temp_free(t0);
1542    tcg_temp_free(carry);
1543}
1544
1545static inline void gen_addci_CC(TCGv ret, TCGv r1, int32_t con)
1546{
1547    TCGv temp = tcg_const_i32(con);
1548    gen_addc_CC(ret, r1, temp);
1549    tcg_temp_free(temp);
1550}
1551
1552static inline void gen_cond_add(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
1553                                TCGv r4)
1554{
1555    TCGv temp = tcg_temp_new();
1556    TCGv temp2 = tcg_temp_new();
1557    TCGv result = tcg_temp_new();
1558    TCGv mask = tcg_temp_new();
1559    TCGv t0 = tcg_const_i32(0);
1560
1561    /* create mask for sticky bits */
1562    tcg_gen_setcond_tl(cond, mask, r4, t0);
1563    tcg_gen_shli_tl(mask, mask, 31);
1564
1565    tcg_gen_add_tl(result, r1, r2);
1566    /* Calc PSW_V */
1567    tcg_gen_xor_tl(temp, result, r1);
1568    tcg_gen_xor_tl(temp2, r1, r2);
1569    tcg_gen_andc_tl(temp, temp, temp2);
1570    tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
1571    /* Set PSW_SV */
1572    tcg_gen_and_tl(temp, temp, mask);
1573    tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
1574    /* calc AV bit */
1575    tcg_gen_add_tl(temp, result, result);
1576    tcg_gen_xor_tl(temp, temp, result);
1577    tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
1578    /* calc SAV bit */
1579    tcg_gen_and_tl(temp, temp, mask);
1580    tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
1581    /* write back result */
1582    tcg_gen_movcond_tl(cond, r3, r4, t0, result, r1);
1583
1584    tcg_temp_free(t0);
1585    tcg_temp_free(temp);
1586    tcg_temp_free(temp2);
1587    tcg_temp_free(result);
1588    tcg_temp_free(mask);
1589}
1590
1591static inline void gen_condi_add(TCGCond cond, TCGv r1, int32_t r2,
1592                                 TCGv r3, TCGv r4)
1593{
1594    TCGv temp = tcg_const_i32(r2);
1595    gen_cond_add(cond, r1, temp, r3, r4);
1596    tcg_temp_free(temp);
1597}
1598
1599static inline void gen_sub_d(TCGv ret, TCGv r1, TCGv r2)
1600{
1601    TCGv temp = tcg_temp_new_i32();
1602    TCGv result = tcg_temp_new_i32();
1603
1604    tcg_gen_sub_tl(result, r1, r2);
1605    /* calc V bit */
1606    tcg_gen_xor_tl(cpu_PSW_V, result, r1);
1607    tcg_gen_xor_tl(temp, r1, r2);
1608    tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
1609    /* calc SV bit */
1610    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1611    /* Calc AV bit */
1612    tcg_gen_add_tl(cpu_PSW_AV, result, result);
1613    tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
1614    /* calc SAV bit */
1615    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1616    /* write back result */
1617    tcg_gen_mov_tl(ret, result);
1618
1619    tcg_temp_free(temp);
1620    tcg_temp_free(result);
1621}
1622
1623static inline void
1624gen_sub64_d(TCGv_i64 ret, TCGv_i64 r1, TCGv_i64 r2)
1625{
1626    TCGv temp = tcg_temp_new();
1627    TCGv_i64 t0 = tcg_temp_new_i64();
1628    TCGv_i64 t1 = tcg_temp_new_i64();
1629    TCGv_i64 result = tcg_temp_new_i64();
1630
1631    tcg_gen_sub_i64(result, r1, r2);
1632    /* calc v bit */
1633    tcg_gen_xor_i64(t1, result, r1);
1634    tcg_gen_xor_i64(t0, r1, r2);
1635    tcg_gen_and_i64(t1, t1, t0);
1636    tcg_gen_extrh_i64_i32(cpu_PSW_V, t1);
1637    /* calc SV bit */
1638    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1639    /* calc AV/SAV bits */
1640    tcg_gen_extrh_i64_i32(temp, result);
1641    tcg_gen_add_tl(cpu_PSW_AV, temp, temp);
1642    tcg_gen_xor_tl(cpu_PSW_AV, temp, cpu_PSW_AV);
1643    /* calc SAV */
1644    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1645    /* write back result */
1646    tcg_gen_mov_i64(ret, result);
1647
1648    tcg_temp_free(temp);
1649    tcg_temp_free_i64(result);
1650    tcg_temp_free_i64(t0);
1651    tcg_temp_free_i64(t1);
1652}
1653
1654static inline void gen_sub_CC(TCGv ret, TCGv r1, TCGv r2)
1655{
1656    TCGv result = tcg_temp_new();
1657    TCGv temp = tcg_temp_new();
1658
1659    tcg_gen_sub_tl(result, r1, r2);
1660    /* calc C bit */
1661    tcg_gen_setcond_tl(TCG_COND_GEU, cpu_PSW_C, r1, r2);
1662    /* calc V bit */
1663    tcg_gen_xor_tl(cpu_PSW_V, result, r1);
1664    tcg_gen_xor_tl(temp, r1, r2);
1665    tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
1666    /* calc SV bit */
1667    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1668    /* Calc AV bit */
1669    tcg_gen_add_tl(cpu_PSW_AV, result, result);
1670    tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
1671    /* calc SAV bit */
1672    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1673    /* write back result */
1674    tcg_gen_mov_tl(ret, result);
1675
1676    tcg_temp_free(result);
1677    tcg_temp_free(temp);
1678}
1679
1680static inline void gen_subc_CC(TCGv ret, TCGv r1, TCGv r2)
1681{
1682    TCGv temp = tcg_temp_new();
1683    tcg_gen_not_tl(temp, r2);
1684    gen_addc_CC(ret, r1, temp);
1685    tcg_temp_free(temp);
1686}
1687
1688static inline void gen_cond_sub(TCGCond cond, TCGv r1, TCGv r2, TCGv r3,
1689                                TCGv r4)
1690{
1691    TCGv temp = tcg_temp_new();
1692    TCGv temp2 = tcg_temp_new();
1693    TCGv result = tcg_temp_new();
1694    TCGv mask = tcg_temp_new();
1695    TCGv t0 = tcg_const_i32(0);
1696
1697    /* create mask for sticky bits */
1698    tcg_gen_setcond_tl(cond, mask, r4, t0);
1699    tcg_gen_shli_tl(mask, mask, 31);
1700
1701    tcg_gen_sub_tl(result, r1, r2);
1702    /* Calc PSW_V */
1703    tcg_gen_xor_tl(temp, result, r1);
1704    tcg_gen_xor_tl(temp2, r1, r2);
1705    tcg_gen_and_tl(temp, temp, temp2);
1706    tcg_gen_movcond_tl(cond, cpu_PSW_V, r4, t0, temp, cpu_PSW_V);
1707    /* Set PSW_SV */
1708    tcg_gen_and_tl(temp, temp, mask);
1709    tcg_gen_or_tl(cpu_PSW_SV, temp, cpu_PSW_SV);
1710    /* calc AV bit */
1711    tcg_gen_add_tl(temp, result, result);
1712    tcg_gen_xor_tl(temp, temp, result);
1713    tcg_gen_movcond_tl(cond, cpu_PSW_AV, r4, t0, temp, cpu_PSW_AV);
1714    /* calc SAV bit */
1715    tcg_gen_and_tl(temp, temp, mask);
1716    tcg_gen_or_tl(cpu_PSW_SAV, temp, cpu_PSW_SAV);
1717    /* write back result */
1718    tcg_gen_movcond_tl(cond, r3, r4, t0, result, r1);
1719
1720    tcg_temp_free(t0);
1721    tcg_temp_free(temp);
1722    tcg_temp_free(temp2);
1723    tcg_temp_free(result);
1724    tcg_temp_free(mask);
1725}
1726
1727static inline void
1728gen_msub_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
1729           TCGv r3, uint32_t n, uint32_t mode)
1730{
1731    TCGv temp = tcg_const_i32(n);
1732    TCGv temp2 = tcg_temp_new();
1733    TCGv_i64 temp64 = tcg_temp_new_i64();
1734    switch (mode) {
1735    case MODE_LL:
1736        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1737        break;
1738    case MODE_LU:
1739        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1740        break;
1741    case MODE_UL:
1742        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1743        break;
1744    case MODE_UU:
1745        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1746        break;
1747    }
1748    tcg_gen_extr_i64_i32(temp, temp2, temp64);
1749    gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
1750                   tcg_gen_sub_tl, tcg_gen_sub_tl);
1751    tcg_temp_free(temp);
1752    tcg_temp_free(temp2);
1753    tcg_temp_free_i64(temp64);
1754}
1755
1756static inline void
1757gen_msubs_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
1758            TCGv r3, uint32_t n, uint32_t mode)
1759{
1760    TCGv temp = tcg_const_i32(n);
1761    TCGv temp2 = tcg_temp_new();
1762    TCGv temp3 = tcg_temp_new();
1763    TCGv_i64 temp64 = tcg_temp_new_i64();
1764
1765    switch (mode) {
1766    case MODE_LL:
1767        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1768        break;
1769    case MODE_LU:
1770        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1771        break;
1772    case MODE_UL:
1773        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1774        break;
1775    case MODE_UU:
1776        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1777        break;
1778    }
1779    tcg_gen_extr_i64_i32(temp, temp2, temp64);
1780    gen_subs(ret_low, r1_low, temp);
1781    tcg_gen_mov_tl(temp, cpu_PSW_V);
1782    tcg_gen_mov_tl(temp3, cpu_PSW_AV);
1783    gen_subs(ret_high, r1_high, temp2);
1784    /* combine v bits */
1785    tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
1786    /* combine av bits */
1787    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
1788
1789    tcg_temp_free(temp);
1790    tcg_temp_free(temp2);
1791    tcg_temp_free(temp3);
1792    tcg_temp_free_i64(temp64);
1793}
1794
1795static inline void
1796gen_msubm_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
1797            TCGv r3, uint32_t n, uint32_t mode)
1798{
1799    TCGv temp = tcg_const_i32(n);
1800    TCGv_i64 temp64 = tcg_temp_new_i64();
1801    TCGv_i64 temp64_2 = tcg_temp_new_i64();
1802    TCGv_i64 temp64_3 = tcg_temp_new_i64();
1803    switch (mode) {
1804    case MODE_LL:
1805        GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
1806        break;
1807    case MODE_LU:
1808        GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
1809        break;
1810    case MODE_UL:
1811        GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
1812        break;
1813    case MODE_UU:
1814        GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
1815        break;
1816    }
1817    tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
1818    gen_sub64_d(temp64_3, temp64_2, temp64);
1819    /* write back result */
1820    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_3);
1821
1822    tcg_temp_free(temp);
1823    tcg_temp_free_i64(temp64);
1824    tcg_temp_free_i64(temp64_2);
1825    tcg_temp_free_i64(temp64_3);
1826}
1827
1828static inline void
1829gen_msubms_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
1830             TCGv r3, uint32_t n, uint32_t mode)
1831{
1832    TCGv temp = tcg_const_i32(n);
1833    TCGv_i64 temp64 = tcg_temp_new_i64();
1834    TCGv_i64 temp64_2 = tcg_temp_new_i64();
1835    switch (mode) {
1836    case MODE_LL:
1837        GEN_HELPER_LL(mulm_h, temp64, r2, r3, temp);
1838        break;
1839    case MODE_LU:
1840        GEN_HELPER_LU(mulm_h, temp64, r2, r3, temp);
1841        break;
1842    case MODE_UL:
1843        GEN_HELPER_UL(mulm_h, temp64, r2, r3, temp);
1844        break;
1845    case MODE_UU:
1846        GEN_HELPER_UU(mulm_h, temp64, r2, r3, temp);
1847        break;
1848    }
1849    tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
1850    gen_helper_sub64_ssov(temp64, cpu_env, temp64_2, temp64);
1851    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
1852
1853    tcg_temp_free(temp);
1854    tcg_temp_free_i64(temp64);
1855    tcg_temp_free_i64(temp64_2);
1856}
1857
1858static inline void
1859gen_msubr64_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3, uint32_t n,
1860              uint32_t mode)
1861{
1862    TCGv temp = tcg_const_i32(n);
1863    TCGv_i64 temp64 = tcg_temp_new_i64();
1864    switch (mode) {
1865    case MODE_LL:
1866        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1867        break;
1868    case MODE_LU:
1869        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1870        break;
1871    case MODE_UL:
1872        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1873        break;
1874    case MODE_UU:
1875        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1876        break;
1877    }
1878    gen_helper_subr_h(ret, cpu_env, temp64, r1_low, r1_high);
1879
1880    tcg_temp_free(temp);
1881    tcg_temp_free_i64(temp64);
1882}
1883
1884static inline void
1885gen_msubr32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
1886{
1887    TCGv temp = tcg_temp_new();
1888    TCGv temp2 = tcg_temp_new();
1889
1890    tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1891    tcg_gen_shli_tl(temp, r1, 16);
1892    gen_msubr64_h(ret, temp, temp2, r2, r3, n, mode);
1893
1894    tcg_temp_free(temp);
1895    tcg_temp_free(temp2);
1896}
1897
1898static inline void
1899gen_msubr64s_h(TCGv ret, TCGv r1_low, TCGv r1_high, TCGv r2, TCGv r3,
1900               uint32_t n, uint32_t mode)
1901{
1902    TCGv temp = tcg_const_i32(n);
1903    TCGv_i64 temp64 = tcg_temp_new_i64();
1904    switch (mode) {
1905    case MODE_LL:
1906        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
1907        break;
1908    case MODE_LU:
1909        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
1910        break;
1911    case MODE_UL:
1912        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
1913        break;
1914    case MODE_UU:
1915        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
1916        break;
1917    }
1918    gen_helper_subr_h_ssov(ret, cpu_env, temp64, r1_low, r1_high);
1919
1920    tcg_temp_free(temp);
1921    tcg_temp_free_i64(temp64);
1922}
1923
1924static inline void
1925gen_msubr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
1926{
1927    TCGv temp = tcg_temp_new();
1928    TCGv temp2 = tcg_temp_new();
1929
1930    tcg_gen_andi_tl(temp2, r1, 0xffff0000);
1931    tcg_gen_shli_tl(temp, r1, 16);
1932    gen_msubr64s_h(ret, temp, temp2, r2, r3, n, mode);
1933
1934    tcg_temp_free(temp);
1935    tcg_temp_free(temp2);
1936}
1937
1938static inline void
1939gen_msubr_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
1940{
1941    TCGv temp = tcg_const_i32(n);
1942    gen_helper_msubr_q(ret, cpu_env, r1, r2, r3, temp);
1943    tcg_temp_free(temp);
1944}
1945
1946static inline void
1947gen_msubrs_q(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n)
1948{
1949    TCGv temp = tcg_const_i32(n);
1950    gen_helper_msubr_q_ssov(ret, cpu_env, r1, r2, r3, temp);
1951    tcg_temp_free(temp);
1952}
1953
1954static inline void
1955gen_msub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
1956             uint32_t up_shift)
1957{
1958    TCGv temp = tcg_temp_new();
1959    TCGv temp2 = tcg_temp_new();
1960    TCGv temp3 = tcg_temp_new();
1961    TCGv_i64 t1 = tcg_temp_new_i64();
1962    TCGv_i64 t2 = tcg_temp_new_i64();
1963    TCGv_i64 t3 = tcg_temp_new_i64();
1964    TCGv_i64 t4 = tcg_temp_new_i64();
1965
1966    tcg_gen_ext_i32_i64(t2, arg2);
1967    tcg_gen_ext_i32_i64(t3, arg3);
1968
1969    tcg_gen_mul_i64(t2, t2, t3);
1970
1971    tcg_gen_ext_i32_i64(t1, arg1);
1972    /* if we shift part of the fraction out, we need to round up */
1973    tcg_gen_andi_i64(t4, t2, (1ll << (up_shift - n)) - 1);
1974    tcg_gen_setcondi_i64(TCG_COND_NE, t4, t4, 0);
1975    tcg_gen_sari_i64(t2, t2, up_shift - n);
1976    tcg_gen_add_i64(t2, t2, t4);
1977
1978    tcg_gen_sub_i64(t3, t1, t2);
1979    tcg_gen_extrl_i64_i32(temp3, t3);
1980    /* calc v bit */
1981    tcg_gen_setcondi_i64(TCG_COND_GT, t1, t3, 0x7fffffffLL);
1982    tcg_gen_setcondi_i64(TCG_COND_LT, t2, t3, -0x80000000LL);
1983    tcg_gen_or_i64(t1, t1, t2);
1984    tcg_gen_extrl_i64_i32(cpu_PSW_V, t1);
1985    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
1986    /* Calc SV bit */
1987    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
1988    /* Calc AV/SAV bits */
1989    tcg_gen_add_tl(cpu_PSW_AV, temp3, temp3);
1990    tcg_gen_xor_tl(cpu_PSW_AV, temp3, cpu_PSW_AV);
1991    /* calc SAV */
1992    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
1993    /* write back result */
1994    tcg_gen_mov_tl(ret, temp3);
1995
1996    tcg_temp_free(temp);
1997    tcg_temp_free(temp2);
1998    tcg_temp_free(temp3);
1999    tcg_temp_free_i64(t1);
2000    tcg_temp_free_i64(t2);
2001    tcg_temp_free_i64(t3);
2002    tcg_temp_free_i64(t4);
2003}
2004
2005static inline void
2006gen_m16sub32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n)
2007{
2008    TCGv temp = tcg_temp_new();
2009    TCGv temp2 = tcg_temp_new();
2010    if (n == 0) {
2011        tcg_gen_mul_tl(temp, arg2, arg3);
2012    } else { /* n is expected to be 1 */
2013        tcg_gen_mul_tl(temp, arg2, arg3);
2014        tcg_gen_shli_tl(temp, temp, 1);
2015        /* catch special case r1 = r2 = 0x8000 */
2016        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
2017        tcg_gen_sub_tl(temp, temp, temp2);
2018    }
2019    gen_sub_d(ret, arg1, temp);
2020
2021    tcg_temp_free(temp);
2022    tcg_temp_free(temp2);
2023}
2024
2025static inline void
2026gen_m16subs32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n)
2027{
2028    TCGv temp = tcg_temp_new();
2029    TCGv temp2 = tcg_temp_new();
2030    if (n == 0) {
2031        tcg_gen_mul_tl(temp, arg2, arg3);
2032    } else { /* n is expected to be 1 */
2033        tcg_gen_mul_tl(temp, arg2, arg3);
2034        tcg_gen_shli_tl(temp, temp, 1);
2035        /* catch special case r1 = r2 = 0x8000 */
2036        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
2037        tcg_gen_sub_tl(temp, temp, temp2);
2038    }
2039    gen_subs(ret, arg1, temp);
2040
2041    tcg_temp_free(temp);
2042    tcg_temp_free(temp2);
2043}
2044
2045static inline void
2046gen_m16sub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
2047               TCGv arg3, uint32_t n)
2048{
2049    TCGv temp = tcg_temp_new();
2050    TCGv temp2 = tcg_temp_new();
2051    TCGv_i64 t1 = tcg_temp_new_i64();
2052    TCGv_i64 t2 = tcg_temp_new_i64();
2053    TCGv_i64 t3 = tcg_temp_new_i64();
2054
2055    if (n == 0) {
2056        tcg_gen_mul_tl(temp, arg2, arg3);
2057    } else { /* n is expected to be 1 */
2058        tcg_gen_mul_tl(temp, arg2, arg3);
2059        tcg_gen_shli_tl(temp, temp, 1);
2060        /* catch special case r1 = r2 = 0x8000 */
2061        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
2062        tcg_gen_sub_tl(temp, temp, temp2);
2063    }
2064    tcg_gen_ext_i32_i64(t2, temp);
2065    tcg_gen_shli_i64(t2, t2, 16);
2066    tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
2067    gen_sub64_d(t3, t1, t2);
2068    /* write back result */
2069    tcg_gen_extr_i64_i32(rl, rh, t3);
2070
2071    tcg_temp_free_i64(t1);
2072    tcg_temp_free_i64(t2);
2073    tcg_temp_free_i64(t3);
2074    tcg_temp_free(temp);
2075    tcg_temp_free(temp2);
2076}
2077
2078static inline void
2079gen_m16subs64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
2080               TCGv arg3, uint32_t n)
2081{
2082    TCGv temp = tcg_temp_new();
2083    TCGv temp2 = tcg_temp_new();
2084    TCGv_i64 t1 = tcg_temp_new_i64();
2085    TCGv_i64 t2 = tcg_temp_new_i64();
2086
2087    if (n == 0) {
2088        tcg_gen_mul_tl(temp, arg2, arg3);
2089    } else { /* n is expected to be 1 */
2090        tcg_gen_mul_tl(temp, arg2, arg3);
2091        tcg_gen_shli_tl(temp, temp, 1);
2092        /* catch special case r1 = r2 = 0x8000 */
2093        tcg_gen_setcondi_tl(TCG_COND_EQ, temp2, temp, 0x80000000);
2094        tcg_gen_sub_tl(temp, temp, temp2);
2095    }
2096    tcg_gen_ext_i32_i64(t2, temp);
2097    tcg_gen_shli_i64(t2, t2, 16);
2098    tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
2099
2100    gen_helper_sub64_ssov(t1, cpu_env, t1, t2);
2101    tcg_gen_extr_i64_i32(rl, rh, t1);
2102
2103    tcg_temp_free(temp);
2104    tcg_temp_free(temp2);
2105    tcg_temp_free_i64(t1);
2106    tcg_temp_free_i64(t2);
2107}
2108
2109static inline void
2110gen_msub64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
2111             TCGv arg3, uint32_t n)
2112{
2113    TCGv_i64 t1 = tcg_temp_new_i64();
2114    TCGv_i64 t2 = tcg_temp_new_i64();
2115    TCGv_i64 t3 = tcg_temp_new_i64();
2116    TCGv_i64 t4 = tcg_temp_new_i64();
2117    TCGv temp, temp2;
2118
2119    tcg_gen_concat_i32_i64(t1, arg1_low, arg1_high);
2120    tcg_gen_ext_i32_i64(t2, arg2);
2121    tcg_gen_ext_i32_i64(t3, arg3);
2122
2123    tcg_gen_mul_i64(t2, t2, t3);
2124    if (n != 0) {
2125        tcg_gen_shli_i64(t2, t2, 1);
2126    }
2127    tcg_gen_sub_i64(t4, t1, t2);
2128    /* calc v bit */
2129    tcg_gen_xor_i64(t3, t4, t1);
2130    tcg_gen_xor_i64(t2, t1, t2);
2131    tcg_gen_and_i64(t3, t3, t2);
2132    tcg_gen_extrh_i64_i32(cpu_PSW_V, t3);
2133    /* We produce an overflow on the host if the mul before was
2134       (0x80000000 * 0x80000000) << 1). If this is the
2135       case, we negate the ovf. */
2136    if (n == 1) {
2137        temp = tcg_temp_new();
2138        temp2 = tcg_temp_new();
2139        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, arg2, 0x80000000);
2140        tcg_gen_setcond_tl(TCG_COND_EQ, temp2, arg2, arg3);
2141        tcg_gen_and_tl(temp, temp, temp2);
2142        tcg_gen_shli_tl(temp, temp, 31);
2143        /* negate v bit, if special condition */
2144        tcg_gen_xor_tl(cpu_PSW_V, cpu_PSW_V, temp);
2145
2146        tcg_temp_free(temp);
2147        tcg_temp_free(temp2);
2148    }
2149    /* write back result */
2150    tcg_gen_extr_i64_i32(rl, rh, t4);
2151    /* Calc SV bit */
2152    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2153    /* Calc AV/SAV bits */
2154    tcg_gen_add_tl(cpu_PSW_AV, rh, rh);
2155    tcg_gen_xor_tl(cpu_PSW_AV, rh, cpu_PSW_AV);
2156    /* calc SAV */
2157    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2158
2159    tcg_temp_free_i64(t1);
2160    tcg_temp_free_i64(t2);
2161    tcg_temp_free_i64(t3);
2162    tcg_temp_free_i64(t4);
2163}
2164
2165static inline void
2166gen_msubs32_q(TCGv ret, TCGv arg1, TCGv arg2, TCGv arg3, uint32_t n,
2167              uint32_t up_shift)
2168{
2169    TCGv_i64 t1 = tcg_temp_new_i64();
2170    TCGv_i64 t2 = tcg_temp_new_i64();
2171    TCGv_i64 t3 = tcg_temp_new_i64();
2172    TCGv_i64 t4 = tcg_temp_new_i64();
2173
2174    tcg_gen_ext_i32_i64(t1, arg1);
2175    tcg_gen_ext_i32_i64(t2, arg2);
2176    tcg_gen_ext_i32_i64(t3, arg3);
2177
2178    tcg_gen_mul_i64(t2, t2, t3);
2179    /* if we shift part of the fraction out, we need to round up */
2180    tcg_gen_andi_i64(t4, t2, (1ll << (up_shift - n)) - 1);
2181    tcg_gen_setcondi_i64(TCG_COND_NE, t4, t4, 0);
2182    tcg_gen_sari_i64(t3, t2, up_shift - n);
2183    tcg_gen_add_i64(t3, t3, t4);
2184
2185    gen_helper_msub32_q_sub_ssov(ret, cpu_env, t1, t3);
2186
2187    tcg_temp_free_i64(t1);
2188    tcg_temp_free_i64(t2);
2189    tcg_temp_free_i64(t3);
2190    tcg_temp_free_i64(t4);
2191}
2192
2193static inline void
2194gen_msubs64_q(TCGv rl, TCGv rh, TCGv arg1_low, TCGv arg1_high, TCGv arg2,
2195             TCGv arg3, uint32_t n)
2196{
2197    TCGv_i64 r1 = tcg_temp_new_i64();
2198    TCGv temp = tcg_const_i32(n);
2199
2200    tcg_gen_concat_i32_i64(r1, arg1_low, arg1_high);
2201    gen_helper_msub64_q_ssov(r1, cpu_env, r1, arg2, arg3, temp);
2202    tcg_gen_extr_i64_i32(rl, rh, r1);
2203
2204    tcg_temp_free_i64(r1);
2205    tcg_temp_free(temp);
2206}
2207
2208static inline void
2209gen_msubad_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
2210             TCGv r3, uint32_t n, uint32_t mode)
2211{
2212    TCGv temp = tcg_const_i32(n);
2213    TCGv temp2 = tcg_temp_new();
2214    TCGv_i64 temp64 = tcg_temp_new_i64();
2215    switch (mode) {
2216    case MODE_LL:
2217        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2218        break;
2219    case MODE_LU:
2220        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2221        break;
2222    case MODE_UL:
2223        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2224        break;
2225    case MODE_UU:
2226        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2227        break;
2228    }
2229    tcg_gen_extr_i64_i32(temp, temp2, temp64);
2230    gen_addsub64_h(ret_low, ret_high, r1_low, r1_high, temp, temp2,
2231                   tcg_gen_add_tl, tcg_gen_sub_tl);
2232    tcg_temp_free(temp);
2233    tcg_temp_free(temp2);
2234    tcg_temp_free_i64(temp64);
2235}
2236
2237static inline void
2238gen_msubadm_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
2239              TCGv r3, uint32_t n, uint32_t mode)
2240{
2241    TCGv temp = tcg_const_i32(n);
2242    TCGv_i64 temp64 = tcg_temp_new_i64();
2243    TCGv_i64 temp64_2 = tcg_temp_new_i64();
2244    TCGv_i64 temp64_3 = tcg_temp_new_i64();
2245    switch (mode) {
2246    case MODE_LL:
2247        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2248        break;
2249    case MODE_LU:
2250        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2251        break;
2252    case MODE_UL:
2253        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2254        break;
2255    case MODE_UU:
2256        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2257        break;
2258    }
2259    tcg_gen_concat_i32_i64(temp64_3, r1_low, r1_high);
2260    tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
2261    tcg_gen_ext32s_i64(temp64, temp64); /* low */
2262    tcg_gen_sub_i64(temp64, temp64_2, temp64);
2263    tcg_gen_shli_i64(temp64, temp64, 16);
2264
2265    gen_sub64_d(temp64_2, temp64_3, temp64);
2266    /* write back result */
2267    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64_2);
2268
2269    tcg_temp_free(temp);
2270    tcg_temp_free_i64(temp64);
2271    tcg_temp_free_i64(temp64_2);
2272    tcg_temp_free_i64(temp64_3);
2273}
2274
2275static inline void
2276gen_msubadr32_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
2277{
2278    TCGv temp = tcg_const_i32(n);
2279    TCGv temp2 = tcg_temp_new();
2280    TCGv_i64 temp64 = tcg_temp_new_i64();
2281    switch (mode) {
2282    case MODE_LL:
2283        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2284        break;
2285    case MODE_LU:
2286        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2287        break;
2288    case MODE_UL:
2289        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2290        break;
2291    case MODE_UU:
2292        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2293        break;
2294    }
2295    tcg_gen_andi_tl(temp2, r1, 0xffff0000);
2296    tcg_gen_shli_tl(temp, r1, 16);
2297    gen_helper_subadr_h(ret, cpu_env, temp64, temp, temp2);
2298
2299    tcg_temp_free(temp);
2300    tcg_temp_free(temp2);
2301    tcg_temp_free_i64(temp64);
2302}
2303
2304static inline void
2305gen_msubads_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
2306              TCGv r3, uint32_t n, uint32_t mode)
2307{
2308    TCGv temp = tcg_const_i32(n);
2309    TCGv temp2 = tcg_temp_new();
2310    TCGv temp3 = tcg_temp_new();
2311    TCGv_i64 temp64 = tcg_temp_new_i64();
2312
2313    switch (mode) {
2314    case MODE_LL:
2315        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2316        break;
2317    case MODE_LU:
2318        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2319        break;
2320    case MODE_UL:
2321        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2322        break;
2323    case MODE_UU:
2324        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2325        break;
2326    }
2327    tcg_gen_extr_i64_i32(temp, temp2, temp64);
2328    gen_adds(ret_low, r1_low, temp);
2329    tcg_gen_mov_tl(temp, cpu_PSW_V);
2330    tcg_gen_mov_tl(temp3, cpu_PSW_AV);
2331    gen_subs(ret_high, r1_high, temp2);
2332    /* combine v bits */
2333    tcg_gen_or_tl(cpu_PSW_V, cpu_PSW_V, temp);
2334    /* combine av bits */
2335    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp3);
2336
2337    tcg_temp_free(temp);
2338    tcg_temp_free(temp2);
2339    tcg_temp_free(temp3);
2340    tcg_temp_free_i64(temp64);
2341}
2342
2343static inline void
2344gen_msubadms_h(TCGv ret_low, TCGv ret_high, TCGv r1_low, TCGv r1_high, TCGv r2,
2345               TCGv r3, uint32_t n, uint32_t mode)
2346{
2347    TCGv temp = tcg_const_i32(n);
2348    TCGv_i64 temp64 = tcg_temp_new_i64();
2349    TCGv_i64 temp64_2 = tcg_temp_new_i64();
2350
2351    switch (mode) {
2352    case MODE_LL:
2353        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2354        break;
2355    case MODE_LU:
2356        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2357        break;
2358    case MODE_UL:
2359        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2360        break;
2361    case MODE_UU:
2362        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2363        break;
2364    }
2365    tcg_gen_sari_i64(temp64_2, temp64, 32); /* high */
2366    tcg_gen_ext32s_i64(temp64, temp64); /* low */
2367    tcg_gen_sub_i64(temp64, temp64_2, temp64);
2368    tcg_gen_shli_i64(temp64, temp64, 16);
2369    tcg_gen_concat_i32_i64(temp64_2, r1_low, r1_high);
2370
2371    gen_helper_sub64_ssov(temp64, cpu_env, temp64_2, temp64);
2372    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2373
2374    tcg_temp_free(temp);
2375    tcg_temp_free_i64(temp64);
2376    tcg_temp_free_i64(temp64_2);
2377}
2378
2379static inline void
2380gen_msubadr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
2381{
2382    TCGv temp = tcg_const_i32(n);
2383    TCGv temp2 = tcg_temp_new();
2384    TCGv_i64 temp64 = tcg_temp_new_i64();
2385    switch (mode) {
2386    case MODE_LL:
2387        GEN_HELPER_LL(mul_h, temp64, r2, r3, temp);
2388        break;
2389    case MODE_LU:
2390        GEN_HELPER_LU(mul_h, temp64, r2, r3, temp);
2391        break;
2392    case MODE_UL:
2393        GEN_HELPER_UL(mul_h, temp64, r2, r3, temp);
2394        break;
2395    case MODE_UU:
2396        GEN_HELPER_UU(mul_h, temp64, r2, r3, temp);
2397        break;
2398    }
2399    tcg_gen_andi_tl(temp2, r1, 0xffff0000);
2400    tcg_gen_shli_tl(temp, r1, 16);
2401    gen_helper_subadr_h_ssov(ret, cpu_env, temp64, temp, temp2);
2402
2403    tcg_temp_free(temp);
2404    tcg_temp_free(temp2);
2405    tcg_temp_free_i64(temp64);
2406}
2407
2408static inline void gen_abs(TCGv ret, TCGv r1)
2409{
2410    tcg_gen_abs_tl(ret, r1);
2411    /* overflow can only happen, if r1 = 0x80000000 */
2412    tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, r1, 0x80000000);
2413    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
2414    /* calc SV bit */
2415    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2416    /* Calc AV bit */
2417    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2418    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2419    /* calc SAV bit */
2420    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2421}
2422
2423static inline void gen_absdif(TCGv ret, TCGv r1, TCGv r2)
2424{
2425    TCGv temp = tcg_temp_new_i32();
2426    TCGv result = tcg_temp_new_i32();
2427
2428    tcg_gen_sub_tl(result, r1, r2);
2429    tcg_gen_sub_tl(temp, r2, r1);
2430    tcg_gen_movcond_tl(TCG_COND_GT, result, r1, r2, result, temp);
2431
2432    /* calc V bit */
2433    tcg_gen_xor_tl(cpu_PSW_V, result, r1);
2434    tcg_gen_xor_tl(temp, result, r2);
2435    tcg_gen_movcond_tl(TCG_COND_GT, cpu_PSW_V, r1, r2, cpu_PSW_V, temp);
2436    tcg_gen_xor_tl(temp, r1, r2);
2437    tcg_gen_and_tl(cpu_PSW_V, cpu_PSW_V, temp);
2438    /* calc SV bit */
2439    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2440    /* Calc AV bit */
2441    tcg_gen_add_tl(cpu_PSW_AV, result, result);
2442    tcg_gen_xor_tl(cpu_PSW_AV, result, cpu_PSW_AV);
2443    /* calc SAV bit */
2444    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2445    /* write back result */
2446    tcg_gen_mov_tl(ret, result);
2447
2448    tcg_temp_free(temp);
2449    tcg_temp_free(result);
2450}
2451
2452static inline void gen_absdifi(TCGv ret, TCGv r1, int32_t con)
2453{
2454    TCGv temp = tcg_const_i32(con);
2455    gen_absdif(ret, r1, temp);
2456    tcg_temp_free(temp);
2457}
2458
2459static inline void gen_absdifsi(TCGv ret, TCGv r1, int32_t con)
2460{
2461    TCGv temp = tcg_const_i32(con);
2462    gen_helper_absdif_ssov(ret, cpu_env, r1, temp);
2463    tcg_temp_free(temp);
2464}
2465
2466static inline void gen_mul_i32s(TCGv ret, TCGv r1, TCGv r2)
2467{
2468    TCGv high = tcg_temp_new();
2469    TCGv low = tcg_temp_new();
2470
2471    tcg_gen_muls2_tl(low, high, r1, r2);
2472    tcg_gen_mov_tl(ret, low);
2473    /* calc V bit */
2474    tcg_gen_sari_tl(low, low, 31);
2475    tcg_gen_setcond_tl(TCG_COND_NE, cpu_PSW_V, high, low);
2476    tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
2477    /* calc SV bit */
2478    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2479    /* Calc AV bit */
2480    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2481    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2482    /* calc SAV bit */
2483    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2484
2485    tcg_temp_free(high);
2486    tcg_temp_free(low);
2487}
2488
2489static inline void gen_muli_i32s(TCGv ret, TCGv r1, int32_t con)
2490{
2491    TCGv temp = tcg_const_i32(con);
2492    gen_mul_i32s(ret, r1, temp);
2493    tcg_temp_free(temp);
2494}
2495
2496static inline void gen_mul_i64s(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2)
2497{
2498    tcg_gen_muls2_tl(ret_low, ret_high, r1, r2);
2499    /* clear V bit */
2500    tcg_gen_movi_tl(cpu_PSW_V, 0);
2501    /* calc SV bit */
2502    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2503    /* Calc AV bit */
2504    tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
2505    tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
2506    /* calc SAV bit */
2507    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2508}
2509
2510static inline void gen_muli_i64s(TCGv ret_low, TCGv ret_high, TCGv r1,
2511                                int32_t con)
2512{
2513    TCGv temp = tcg_const_i32(con);
2514    gen_mul_i64s(ret_low, ret_high, r1, temp);
2515    tcg_temp_free(temp);
2516}
2517
2518static inline void gen_mul_i64u(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2)
2519{
2520    tcg_gen_mulu2_tl(ret_low, ret_high, r1, r2);
2521    /* clear V bit */
2522    tcg_gen_movi_tl(cpu_PSW_V, 0);
2523    /* calc SV bit */
2524    tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2525    /* Calc AV bit */
2526    tcg_gen_add_tl(cpu_PSW_AV, ret_high, ret_high);
2527    tcg_gen_xor_tl(cpu_PSW_AV, ret_high, cpu_PSW_AV);
2528    /* calc SAV bit */
2529    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2530}
2531
2532static inline void gen_muli_i64u(TCGv ret_low, TCGv ret_high, TCGv r1,
2533                                int32_t con)
2534{
2535    TCGv temp = tcg_const_i32(con);
2536    gen_mul_i64u(ret_low, ret_high, r1, temp);
2537    tcg_temp_free(temp);
2538}
2539
2540static inline void gen_mulsi_i32(TCGv ret, TCGv r1, int32_t con)
2541{
2542    TCGv temp = tcg_const_i32(con);
2543    gen_helper_mul_ssov(ret, cpu_env, r1, temp);
2544    tcg_temp_free(temp);
2545}
2546
2547static inline void gen_mulsui_i32(TCGv ret, TCGv r1, int32_t con)
2548{
2549    TCGv temp = tcg_const_i32(con);
2550    gen_helper_mul_suov(ret, cpu_env, r1, temp);
2551    tcg_temp_free(temp);
2552}
2553/* gen_maddsi_32(cpu_gpr_d[r4], cpu_gpr_d[r1], cpu_gpr_d[r3], const9); */
2554static inline void gen_maddsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
2555{
2556    TCGv temp = tcg_const_i32(con);
2557    gen_helper_madd32_ssov(ret, cpu_env, r1, r2, temp);
2558    tcg_temp_free(temp);
2559}
2560
2561static inline void gen_maddsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
2562{
2563    TCGv temp = tcg_const_i32(con);
2564    gen_helper_madd32_suov(ret, cpu_env, r1, r2, temp);
2565    tcg_temp_free(temp);
2566}
2567
2568static void
2569gen_mul_q(TCGv rl, TCGv rh, TCGv arg1, TCGv arg2, uint32_t n, uint32_t up_shift)
2570{
2571    TCGv temp = tcg_temp_new();
2572    TCGv_i64 temp_64 = tcg_temp_new_i64();
2573    TCGv_i64 temp2_64 = tcg_temp_new_i64();
2574
2575    if (n == 0) {
2576        if (up_shift == 32) {
2577            tcg_gen_muls2_tl(rh, rl, arg1, arg2);
2578        } else if (up_shift == 16) {
2579            tcg_gen_ext_i32_i64(temp_64, arg1);
2580            tcg_gen_ext_i32_i64(temp2_64, arg2);
2581
2582            tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
2583            tcg_gen_shri_i64(temp_64, temp_64, up_shift);
2584            tcg_gen_extr_i64_i32(rl, rh, temp_64);
2585        } else {
2586            tcg_gen_muls2_tl(rl, rh, arg1, arg2);
2587        }
2588        /* reset v bit */
2589        tcg_gen_movi_tl(cpu_PSW_V, 0);
2590    } else { /* n is expected to be 1 */
2591        tcg_gen_ext_i32_i64(temp_64, arg1);
2592        tcg_gen_ext_i32_i64(temp2_64, arg2);
2593
2594        tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
2595
2596        if (up_shift == 0) {
2597            tcg_gen_shli_i64(temp_64, temp_64, 1);
2598        } else {
2599            tcg_gen_shri_i64(temp_64, temp_64, up_shift - 1);
2600        }
2601        tcg_gen_extr_i64_i32(rl, rh, temp_64);
2602        /* overflow only occurs if r1 = r2 = 0x8000 */
2603        if (up_shift == 0) {/* result is 64 bit */
2604            tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, rh,
2605                                0x80000000);
2606        } else { /* result is 32 bit */
2607            tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, rl,
2608                                0x80000000);
2609        }
2610        tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
2611        /* calc sv overflow bit */
2612        tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
2613    }
2614    /* calc av overflow bit */
2615    if (up_shift == 0) {
2616        tcg_gen_add_tl(cpu_PSW_AV, rh, rh);
2617        tcg_gen_xor_tl(cpu_PSW_AV, rh, cpu_PSW_AV);
2618    } else {
2619        tcg_gen_add_tl(cpu_PSW_AV, rl, rl);
2620        tcg_gen_xor_tl(cpu_PSW_AV, rl, cpu_PSW_AV);
2621    }
2622    /* calc sav overflow bit */
2623    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2624    tcg_temp_free(temp);
2625    tcg_temp_free_i64(temp_64);
2626    tcg_temp_free_i64(temp2_64);
2627}
2628
2629static void
2630gen_mul_q_16(TCGv ret, TCGv arg1, TCGv arg2, uint32_t n)
2631{
2632    TCGv temp = tcg_temp_new();
2633    if (n == 0) {
2634        tcg_gen_mul_tl(ret, arg1, arg2);
2635    } else { /* n is expected to be 1 */
2636        tcg_gen_mul_tl(ret, arg1, arg2);
2637        tcg_gen_shli_tl(ret, ret, 1);
2638        /* catch special case r1 = r2 = 0x8000 */
2639        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, ret, 0x80000000);
2640        tcg_gen_sub_tl(ret, ret, temp);
2641    }
2642    /* reset v bit */
2643    tcg_gen_movi_tl(cpu_PSW_V, 0);
2644    /* calc av overflow bit */
2645    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2646    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2647    /* calc sav overflow bit */
2648    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2649
2650    tcg_temp_free(temp);
2651}
2652
2653static void gen_mulr_q(TCGv ret, TCGv arg1, TCGv arg2, uint32_t n)
2654{
2655    TCGv temp = tcg_temp_new();
2656    if (n == 0) {
2657        tcg_gen_mul_tl(ret, arg1, arg2);
2658        tcg_gen_addi_tl(ret, ret, 0x8000);
2659    } else {
2660        tcg_gen_mul_tl(ret, arg1, arg2);
2661        tcg_gen_shli_tl(ret, ret, 1);
2662        tcg_gen_addi_tl(ret, ret, 0x8000);
2663        /* catch special case r1 = r2 = 0x8000 */
2664        tcg_gen_setcondi_tl(TCG_COND_EQ, temp, ret, 0x80008000);
2665        tcg_gen_muli_tl(temp, temp, 0x8001);
2666        tcg_gen_sub_tl(ret, ret, temp);
2667    }
2668    /* reset v bit */
2669    tcg_gen_movi_tl(cpu_PSW_V, 0);
2670    /* calc av overflow bit */
2671    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2672    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2673    /* calc sav overflow bit */
2674    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2675    /* cut halfword off */
2676    tcg_gen_andi_tl(ret, ret, 0xffff0000);
2677
2678    tcg_temp_free(temp);
2679}
2680
2681static inline void
2682gen_madds_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2683             TCGv r3)
2684{
2685    TCGv_i64 temp64 = tcg_temp_new_i64();
2686    tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2687    gen_helper_madd64_ssov(temp64, cpu_env, r1, temp64, r3);
2688    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2689    tcg_temp_free_i64(temp64);
2690}
2691
2692static inline void
2693gen_maddsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2694              int32_t con)
2695{
2696    TCGv temp = tcg_const_i32(con);
2697    gen_madds_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2698    tcg_temp_free(temp);
2699}
2700
2701static inline void
2702gen_maddsu_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2703             TCGv r3)
2704{
2705    TCGv_i64 temp64 = tcg_temp_new_i64();
2706    tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2707    gen_helper_madd64_suov(temp64, cpu_env, r1, temp64, r3);
2708    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2709    tcg_temp_free_i64(temp64);
2710}
2711
2712static inline void
2713gen_maddsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2714               int32_t con)
2715{
2716    TCGv temp = tcg_const_i32(con);
2717    gen_maddsu_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2718    tcg_temp_free(temp);
2719}
2720
2721static inline void gen_msubsi_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
2722{
2723    TCGv temp = tcg_const_i32(con);
2724    gen_helper_msub32_ssov(ret, cpu_env, r1, r2, temp);
2725    tcg_temp_free(temp);
2726}
2727
2728static inline void gen_msubsui_32(TCGv ret, TCGv r1, TCGv r2, int32_t con)
2729{
2730    TCGv temp = tcg_const_i32(con);
2731    gen_helper_msub32_suov(ret, cpu_env, r1, r2, temp);
2732    tcg_temp_free(temp);
2733}
2734
2735static inline void
2736gen_msubs_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2737             TCGv r3)
2738{
2739    TCGv_i64 temp64 = tcg_temp_new_i64();
2740    tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2741    gen_helper_msub64_ssov(temp64, cpu_env, r1, temp64, r3);
2742    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2743    tcg_temp_free_i64(temp64);
2744}
2745
2746static inline void
2747gen_msubsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2748              int32_t con)
2749{
2750    TCGv temp = tcg_const_i32(con);
2751    gen_msubs_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2752    tcg_temp_free(temp);
2753}
2754
2755static inline void
2756gen_msubsu_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2757             TCGv r3)
2758{
2759    TCGv_i64 temp64 = tcg_temp_new_i64();
2760    tcg_gen_concat_i32_i64(temp64, r2_low, r2_high);
2761    gen_helper_msub64_suov(temp64, cpu_env, r1, temp64, r3);
2762    tcg_gen_extr_i64_i32(ret_low, ret_high, temp64);
2763    tcg_temp_free_i64(temp64);
2764}
2765
2766static inline void
2767gen_msubsui_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
2768               int32_t con)
2769{
2770    TCGv temp = tcg_const_i32(con);
2771    gen_msubsu_64(ret_low, ret_high, r1, r2_low, r2_high, temp);
2772    tcg_temp_free(temp);
2773}
2774
2775static void gen_saturate(TCGv ret, TCGv arg, int32_t up, int32_t low)
2776{
2777    TCGv sat_neg = tcg_const_i32(low);
2778    TCGv temp = tcg_const_i32(up);
2779
2780    /* sat_neg = (arg < low ) ? low : arg; */
2781    tcg_gen_movcond_tl(TCG_COND_LT, sat_neg, arg, sat_neg, sat_neg, arg);
2782
2783    /* ret = (sat_neg > up ) ? up  : sat_neg; */
2784    tcg_gen_movcond_tl(TCG_COND_GT, ret, sat_neg, temp, temp, sat_neg);
2785
2786    tcg_temp_free(sat_neg);
2787    tcg_temp_free(temp);
2788}
2789
2790static void gen_saturate_u(TCGv ret, TCGv arg, int32_t up)
2791{
2792    TCGv temp = tcg_const_i32(up);
2793    /* sat_neg = (arg > up ) ? up : arg; */
2794    tcg_gen_movcond_tl(TCG_COND_GTU, ret, arg, temp, temp, arg);
2795    tcg_temp_free(temp);
2796}
2797
2798static void gen_shi(TCGv ret, TCGv r1, int32_t shift_count)
2799{
2800    if (shift_count == -32) {
2801        tcg_gen_movi_tl(ret, 0);
2802    } else if (shift_count >= 0) {
2803        tcg_gen_shli_tl(ret, r1, shift_count);
2804    } else {
2805        tcg_gen_shri_tl(ret, r1, -shift_count);
2806    }
2807}
2808
2809static void gen_sh_hi(TCGv ret, TCGv r1, int32_t shiftcount)
2810{
2811    TCGv temp_low, temp_high;
2812
2813    if (shiftcount == -16) {
2814        tcg_gen_movi_tl(ret, 0);
2815    } else {
2816        temp_high = tcg_temp_new();
2817        temp_low = tcg_temp_new();
2818
2819        tcg_gen_andi_tl(temp_low, r1, 0xffff);
2820        tcg_gen_andi_tl(temp_high, r1, 0xffff0000);
2821        gen_shi(temp_low, temp_low, shiftcount);
2822        gen_shi(ret, temp_high, shiftcount);
2823        tcg_gen_deposit_tl(ret, ret, temp_low, 0, 16);
2824
2825        tcg_temp_free(temp_low);
2826        tcg_temp_free(temp_high);
2827    }
2828}
2829
2830static void gen_shaci(TCGv ret, TCGv r1, int32_t shift_count)
2831{
2832    uint32_t msk, msk_start;
2833    TCGv temp = tcg_temp_new();
2834    TCGv temp2 = tcg_temp_new();
2835    TCGv t_0 = tcg_const_i32(0);
2836
2837    if (shift_count == 0) {
2838        /* Clear PSW.C and PSW.V */
2839        tcg_gen_movi_tl(cpu_PSW_C, 0);
2840        tcg_gen_mov_tl(cpu_PSW_V, cpu_PSW_C);
2841        tcg_gen_mov_tl(ret, r1);
2842    } else if (shift_count == -32) {
2843        /* set PSW.C */
2844        tcg_gen_mov_tl(cpu_PSW_C, r1);
2845        /* fill ret completely with sign bit */
2846        tcg_gen_sari_tl(ret, r1, 31);
2847        /* clear PSW.V */
2848        tcg_gen_movi_tl(cpu_PSW_V, 0);
2849    } else if (shift_count > 0) {
2850        TCGv t_max = tcg_const_i32(0x7FFFFFFF >> shift_count);
2851        TCGv t_min = tcg_const_i32(((int32_t) -0x80000000) >> shift_count);
2852
2853        /* calc carry */
2854        msk_start = 32 - shift_count;
2855        msk = ((1 << shift_count) - 1) << msk_start;
2856        tcg_gen_andi_tl(cpu_PSW_C, r1, msk);
2857        /* calc v/sv bits */
2858        tcg_gen_setcond_tl(TCG_COND_GT, temp, r1, t_max);
2859        tcg_gen_setcond_tl(TCG_COND_LT, temp2, r1, t_min);
2860        tcg_gen_or_tl(cpu_PSW_V, temp, temp2);
2861        tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
2862        /* calc sv */
2863        tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_V, cpu_PSW_SV);
2864        /* do shift */
2865        tcg_gen_shli_tl(ret, r1, shift_count);
2866
2867        tcg_temp_free(t_max);
2868        tcg_temp_free(t_min);
2869    } else {
2870        /* clear PSW.V */
2871        tcg_gen_movi_tl(cpu_PSW_V, 0);
2872        /* calc carry */
2873        msk = (1 << -shift_count) - 1;
2874        tcg_gen_andi_tl(cpu_PSW_C, r1, msk);
2875        /* do shift */
2876        tcg_gen_sari_tl(ret, r1, -shift_count);
2877    }
2878    /* calc av overflow bit */
2879    tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
2880    tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
2881    /* calc sav overflow bit */
2882    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
2883
2884    tcg_temp_free(temp);
2885    tcg_temp_free(temp2);
2886    tcg_temp_free(t_0);
2887}
2888
2889static void gen_shas(TCGv ret, TCGv r1, TCGv r2)
2890{
2891    gen_helper_sha_ssov(ret, cpu_env, r1, r2);
2892}
2893
2894static void gen_shasi(TCGv ret, TCGv r1, int32_t con)
2895{
2896    TCGv temp = tcg_const_i32(con);
2897    gen_shas(ret, r1, temp);
2898    tcg_temp_free(temp);
2899}
2900
2901static void gen_sha_hi(TCGv ret, TCGv r1, int32_t shift_count)
2902{
2903    TCGv low, high;
2904
2905    if (shift_count == 0) {
2906        tcg_gen_mov_tl(ret, r1);
2907    } else if (shift_count > 0) {
2908        low = tcg_temp_new();
2909        high = tcg_temp_new();
2910
2911        tcg_gen_andi_tl(high, r1, 0xffff0000);
2912        tcg_gen_shli_tl(low, r1, shift_count);
2913        tcg_gen_shli_tl(ret, high, shift_count);
2914        tcg_gen_deposit_tl(ret, ret, low, 0, 16);
2915
2916        tcg_temp_free(low);
2917        tcg_temp_free(high);
2918    } else {
2919        low = tcg_temp_new();
2920        high = tcg_temp_new();
2921
2922        tcg_gen_ext16s_tl(low, r1);
2923        tcg_gen_sari_tl(low, low, -shift_count);
2924        tcg_gen_sari_tl(ret, r1, -shift_count);
2925        tcg_gen_deposit_tl(ret, ret, low, 0, 16);
2926
2927        tcg_temp_free(low);
2928        tcg_temp_free(high);
2929    }
2930
2931}
2932
2933/* ret = {ret[30:0], (r1 cond r2)}; */
2934static void gen_sh_cond(int cond, TCGv ret, TCGv r1, TCGv r2)
2935{
2936    TCGv temp = tcg_temp_new();
2937    TCGv temp2 = tcg_temp_new();
2938
2939    tcg_gen_shli_tl(temp, ret, 1);
2940    tcg_gen_setcond_tl(cond, temp2, r1, r2);
2941    tcg_gen_or_tl(ret, temp, temp2);
2942
2943    tcg_temp_free(temp);
2944    tcg_temp_free(temp2);
2945}
2946
2947static void gen_sh_condi(int cond, TCGv ret, TCGv r1, int32_t con)
2948{
2949    TCGv temp = tcg_const_i32(con);
2950    gen_sh_cond(cond, ret, r1, temp);
2951    tcg_temp_free(temp);
2952}
2953
2954static inline void gen_adds(TCGv ret, TCGv r1, TCGv r2)
2955{
2956    gen_helper_add_ssov(ret, cpu_env, r1, r2);
2957}
2958
2959static inline void gen_addsi(TCGv ret, TCGv r1, int32_t con)
2960{
2961    TCGv temp = tcg_const_i32(con);
2962    gen_helper_add_ssov(ret, cpu_env, r1, temp);
2963    tcg_temp_free(temp);
2964}
2965
2966static inline void gen_addsui(TCGv ret, TCGv r1, int32_t con)
2967{
2968    TCGv temp = tcg_const_i32(con);
2969    gen_helper_add_suov(ret, cpu_env, r1, temp);
2970    tcg_temp_free(temp);
2971}
2972
2973static inline void gen_subs(TCGv ret, TCGv r1, TCGv r2)
2974{
2975    gen_helper_sub_ssov(ret, cpu_env, r1, r2);
2976}
2977
2978static inline void gen_subsu(TCGv ret, TCGv r1, TCGv r2)
2979{
2980    gen_helper_sub_suov(ret, cpu_env, r1, r2);
2981}
2982
2983static inline void gen_bit_2op(TCGv ret, TCGv r1, TCGv r2,
2984                               int pos1, int pos2,
2985                               void(*op1)(TCGv, TCGv, TCGv),
2986                               void(*op2)(TCGv, TCGv, TCGv))
2987{
2988    TCGv temp1, temp2;
2989
2990    temp1 = tcg_temp_new();
2991    temp2 = tcg_temp_new();
2992
2993    tcg_gen_shri_tl(temp2, r2, pos2);
2994    tcg_gen_shri_tl(temp1, r1, pos1);
2995
2996    (*op1)(temp1, temp1, temp2);
2997    (*op2)(temp1 , ret, temp1);
2998
2999    tcg_gen_deposit_tl(ret, ret, temp1, 0, 1);
3000
3001    tcg_temp_free(temp1);
3002    tcg_temp_free(temp2);
3003}
3004
3005/* ret = r1[pos1] op1 r2[pos2]; */
3006static inline void gen_bit_1op(TCGv ret, TCGv r1, TCGv r2,
3007                               int pos1, int pos2,
3008                               void(*op1)(TCGv, TCGv, TCGv))
3009{
3010    TCGv temp1, temp2;
3011
3012    temp1 = tcg_temp_new();
3013    temp2 = tcg_temp_new();
3014
3015    tcg_gen_shri_tl(temp2, r2, pos2);
3016    tcg_gen_shri_tl(temp1, r1, pos1);
3017
3018    (*op1)(ret, temp1, temp2);
3019
3020    tcg_gen_andi_tl(ret, ret, 0x1);
3021
3022    tcg_temp_free(temp1);
3023    tcg_temp_free(temp2);
3024}
3025
3026static inline void gen_accumulating_cond(int cond, TCGv ret, TCGv r1, TCGv r2,
3027                                         void(*op)(TCGv, TCGv, TCGv))
3028{
3029    TCGv temp = tcg_temp_new();
3030    TCGv temp2 = tcg_temp_new();
3031    /* temp = (arg1 cond arg2 )*/
3032    tcg_gen_setcond_tl(cond, temp, r1, r2);
3033    /* temp2 = ret[0]*/
3034    tcg_gen_andi_tl(temp2, ret, 0x1);
3035    /* temp = temp insn temp2 */
3036    (*op)(temp, temp, temp2);
3037    /* ret = {ret[31:1], temp} */
3038    tcg_gen_deposit_tl(ret, ret, temp, 0, 1);
3039
3040    tcg_temp_free(temp);
3041    tcg_temp_free(temp2);
3042}
3043
3044static inline void
3045gen_accumulating_condi(int cond, TCGv ret, TCGv r1, int32_t con,
3046                       void(*op)(TCGv, TCGv, TCGv))
3047{
3048    TCGv temp = tcg_const_i32(con);
3049    gen_accumulating_cond(cond, ret, r1, temp, op);
3050    tcg_temp_free(temp);
3051}
3052
3053/* ret = (r1 cond r2) ? 0xFFFFFFFF ? 0x00000000;*/
3054static inline void gen_cond_w(TCGCond cond, TCGv ret, TCGv r1, TCGv r2)
3055{
3056    tcg_gen_setcond_tl(cond, ret, r1, r2);
3057    tcg_gen_neg_tl(ret, ret);
3058}
3059
3060static inline void gen_eqany_bi(TCGv ret, TCGv r1, int32_t con)
3061{
3062    TCGv b0 = tcg_temp_new();
3063    TCGv b1 = tcg_temp_new();
3064    TCGv b2 = tcg_temp_new();
3065    TCGv b3 = tcg_temp_new();
3066
3067    /* byte 0 */
3068    tcg_gen_andi_tl(b0, r1, 0xff);
3069    tcg_gen_setcondi_tl(TCG_COND_EQ, b0, b0, con & 0xff);
3070
3071    /* byte 1 */
3072    tcg_gen_andi_tl(b1, r1, 0xff00);
3073    tcg_gen_setcondi_tl(TCG_COND_EQ, b1, b1, con & 0xff00);
3074
3075    /* byte 2 */
3076    tcg_gen_andi_tl(b2, r1, 0xff0000);
3077    tcg_gen_setcondi_tl(TCG_COND_EQ, b2, b2, con & 0xff0000);
3078
3079    /* byte 3 */
3080    tcg_gen_andi_tl(b3, r1, 0xff000000);
3081    tcg_gen_setcondi_tl(TCG_COND_EQ, b3, b3, con & 0xff000000);
3082
3083    /* combine them */
3084    tcg_gen_or_tl(ret, b0, b1);
3085    tcg_gen_or_tl(ret, ret, b2);
3086    tcg_gen_or_tl(ret, ret, b3);
3087
3088    tcg_temp_free(b0);
3089    tcg_temp_free(b1);
3090    tcg_temp_free(b2);
3091    tcg_temp_free(b3);
3092}
3093
3094static inline void gen_eqany_hi(TCGv ret, TCGv r1, int32_t con)
3095{
3096    TCGv h0 = tcg_temp_new();
3097    TCGv h1 = tcg_temp_new();
3098
3099    /* halfword 0 */
3100    tcg_gen_andi_tl(h0, r1, 0xffff);
3101    tcg_gen_setcondi_tl(TCG_COND_EQ, h0, h0, con & 0xffff);
3102
3103    /* halfword 1 */
3104    tcg_gen_andi_tl(h1, r1, 0xffff0000);
3105    tcg_gen_setcondi_tl(TCG_COND_EQ, h1, h1, con & 0xffff0000);
3106
3107    /* combine them */
3108    tcg_gen_or_tl(ret, h0, h1);
3109
3110    tcg_temp_free(h0);
3111    tcg_temp_free(h1);
3112}
3113/* mask = ((1 << width) -1) << pos;
3114   ret = (r1 & ~mask) | (r2 << pos) & mask); */
3115static inline void gen_insert(TCGv ret, TCGv r1, TCGv r2, TCGv width, TCGv pos)
3116{
3117    TCGv mask = tcg_temp_new();
3118    TCGv temp = tcg_temp_new();
3119    TCGv temp2 = tcg_temp_new();
3120
3121    tcg_gen_movi_tl(mask, 1);
3122    tcg_gen_shl_tl(mask, mask, width);
3123    tcg_gen_subi_tl(mask, mask, 1);
3124    tcg_gen_shl_tl(mask, mask, pos);
3125
3126    tcg_gen_shl_tl(temp, r2, pos);
3127    tcg_gen_and_tl(temp, temp, mask);
3128    tcg_gen_andc_tl(temp2, r1, mask);
3129    tcg_gen_or_tl(ret, temp, temp2);
3130
3131    tcg_temp_free(mask);
3132    tcg_temp_free(temp);
3133    tcg_temp_free(temp2);
3134}
3135
3136static inline void gen_bsplit(TCGv rl, TCGv rh, TCGv r1)
3137{
3138    TCGv_i64 temp = tcg_temp_new_i64();
3139
3140    gen_helper_bsplit(temp, r1);
3141    tcg_gen_extr_i64_i32(rl, rh, temp);
3142
3143    tcg_temp_free_i64(temp);
3144}
3145
3146static inline void gen_unpack(TCGv rl, TCGv rh, TCGv r1)
3147{
3148    TCGv_i64 temp = tcg_temp_new_i64();
3149
3150    gen_helper_unpack(temp, r1);
3151    tcg_gen_extr_i64_i32(rl, rh, temp);
3152
3153    tcg_temp_free_i64(temp);
3154}
3155
3156static inline void
3157gen_dvinit_b(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
3158{
3159    TCGv_i64 ret = tcg_temp_new_i64();
3160
3161    if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
3162        gen_helper_dvinit_b_13(ret, cpu_env, r1, r2);
3163    } else {
3164        gen_helper_dvinit_b_131(ret, cpu_env, r1, r2);
3165    }
3166    tcg_gen_extr_i64_i32(rl, rh, ret);
3167
3168    tcg_temp_free_i64(ret);
3169}
3170
3171static inline void
3172gen_dvinit_h(DisasContext *ctx, TCGv rl, TCGv rh, TCGv r1, TCGv r2)
3173{
3174    TCGv_i64 ret = tcg_temp_new_i64();
3175
3176    if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
3177        gen_helper_dvinit_h_13(ret, cpu_env, r1, r2);
3178    } else {
3179        gen_helper_dvinit_h_131(ret, cpu_env, r1, r2);
3180    }
3181    tcg_gen_extr_i64_i32(rl, rh, ret);
3182
3183    tcg_temp_free_i64(ret);
3184}
3185
3186static void gen_calc_usb_mul_h(TCGv arg_low, TCGv arg_high)
3187{
3188    TCGv temp = tcg_temp_new();
3189    /* calc AV bit */
3190    tcg_gen_add_tl(temp, arg_low, arg_low);
3191    tcg_gen_xor_tl(temp, temp, arg_low);
3192    tcg_gen_add_tl(cpu_PSW_AV, arg_high, arg_high);
3193    tcg_gen_xor_tl(cpu_PSW_AV, cpu_PSW_AV, arg_high);
3194    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
3195    /* calc SAV bit */
3196    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
3197    tcg_gen_movi_tl(cpu_PSW_V, 0);
3198    tcg_temp_free(temp);
3199}
3200
3201static void gen_calc_usb_mulr_h(TCGv arg)
3202{
3203    TCGv temp = tcg_temp_new();
3204    /* calc AV bit */
3205    tcg_gen_add_tl(temp, arg, arg);
3206    tcg_gen_xor_tl(temp, temp, arg);
3207    tcg_gen_shli_tl(cpu_PSW_AV, temp, 16);
3208    tcg_gen_or_tl(cpu_PSW_AV, cpu_PSW_AV, temp);
3209    /* calc SAV bit */
3210    tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
3211    /* clear V bit */
3212    tcg_gen_movi_tl(cpu_PSW_V, 0);
3213    tcg_temp_free(temp);
3214}
3215
3216/* helpers for generating program flow micro-ops */
3217
3218static inline void gen_save_pc(target_ulong pc)
3219{
3220    tcg_gen_movi_tl(cpu_PC, pc);
3221}
3222
3223static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
3224{
3225    if (unlikely(ctx->base.singlestep_enabled)) {
3226        return false;
3227    }
3228
3229#ifndef CONFIG_USER_ONLY
3230    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
3231#else
3232    return true;
3233#endif
3234}
3235
3236static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3237{
3238    if (use_goto_tb(ctx, dest)) {
3239        tcg_gen_goto_tb(n);
3240        gen_save_pc(dest);
3241        tcg_gen_exit_tb(ctx->base.tb, n);
3242    } else {
3243        gen_save_pc(dest);
3244        if (ctx->base.singlestep_enabled) {
3245            /* raise exception debug */
3246        }
3247        tcg_gen_exit_tb(NULL, 0);
3248    }
3249}
3250
3251static void generate_trap(DisasContext *ctx, int class, int tin)
3252{
3253    TCGv_i32 classtemp = tcg_const_i32(class);
3254    TCGv_i32 tintemp = tcg_const_i32(tin);
3255
3256    gen_save_pc(ctx->base.pc_next);
3257    gen_helper_raise_exception_sync(cpu_env, classtemp, tintemp);
3258    ctx->base.is_jmp = DISAS_NORETURN;
3259
3260    tcg_temp_free(classtemp);
3261    tcg_temp_free(tintemp);
3262}
3263
3264static void generate_qemu_excp(DisasContext *ctx, int excp)
3265{
3266    TCGv_i32 tmp = tcg_const_i32(excp);
3267    gen_save_pc(ctx->base.pc_next);
3268    gen_helper_qemu_excp(cpu_env, tmp);
3269    ctx->base.is_jmp = DISAS_NORETURN;
3270    tcg_temp_free(tmp);
3271}
3272
3273static inline void gen_branch_cond(DisasContext *ctx, TCGCond cond, TCGv r1,
3274                                   TCGv r2, int16_t address)
3275{
3276    TCGLabel *jumpLabel = gen_new_label();
3277    tcg_gen_brcond_tl(cond, r1, r2, jumpLabel);
3278
3279    gen_goto_tb(ctx, 1, ctx->pc_succ_insn);
3280
3281    gen_set_label(jumpLabel);
3282    gen_goto_tb(ctx, 0, ctx->base.pc_next + address * 2);
3283}
3284
3285static inline void gen_branch_condi(DisasContext *ctx, TCGCond cond, TCGv r1,
3286                                    int r2, int16_t address)
3287{
3288    TCGv temp = tcg_const_i32(r2);
3289    gen_branch_cond(ctx, cond, r1, temp, address);
3290    tcg_temp_free(temp);
3291}
3292
3293static void gen_loop(DisasContext *ctx, int r1, int32_t offset)
3294{
3295    TCGLabel *l1 = gen_new_label();
3296
3297    tcg_gen_subi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], 1);
3298    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr_a[r1], -1, l1);
3299    gen_goto_tb(ctx, 1, ctx->base.pc_next + offset);
3300    gen_set_label(l1);
3301    gen_goto_tb(ctx, 0, ctx->pc_succ_insn);
3302}
3303
3304static void gen_fcall_save_ctx(DisasContext *ctx)
3305{
3306    TCGv temp = tcg_temp_new();
3307
3308    tcg_gen_addi_tl(temp, cpu_gpr_a[10], -4);
3309    tcg_gen_qemu_st_tl(cpu_gpr_a[11], temp, ctx->mem_idx, MO_LESL);
3310    tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
3311    tcg_gen_mov_tl(cpu_gpr_a[10], temp);
3312
3313    tcg_temp_free(temp);
3314}
3315
3316static void gen_fret(DisasContext *ctx)
3317{
3318    TCGv temp = tcg_temp_new();
3319
3320    tcg_gen_andi_tl(temp, cpu_gpr_a[11], ~0x1);
3321    tcg_gen_qemu_ld_tl(cpu_gpr_a[11], cpu_gpr_a[10], ctx->mem_idx, MO_LESL);
3322    tcg_gen_addi_tl(cpu_gpr_a[10], cpu_gpr_a[10], 4);
3323    tcg_gen_mov_tl(cpu_PC, temp);
3324    tcg_gen_exit_tb(NULL, 0);
3325    ctx->base.is_jmp = DISAS_NORETURN;
3326
3327    tcg_temp_free(temp);
3328}
3329
3330static void gen_compute_branch(DisasContext *ctx, uint32_t opc, int r1,
3331                               int r2 , int32_t constant , int32_t offset)
3332{
3333    TCGv temp, temp2;
3334    int n;
3335
3336    switch (opc) {
3337/* SB-format jumps */
3338    case OPC1_16_SB_J:
3339    case OPC1_32_B_J:
3340        gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3341        break;
3342    case OPC1_32_B_CALL:
3343    case OPC1_16_SB_CALL:
3344        gen_helper_1arg(call, ctx->pc_succ_insn);
3345        gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3346        break;
3347    case OPC1_16_SB_JZ:
3348        gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], 0, offset);
3349        break;
3350    case OPC1_16_SB_JNZ:
3351        gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], 0, offset);
3352        break;
3353/* SBC-format jumps */
3354    case OPC1_16_SBC_JEQ:
3355        gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant, offset);
3356        break;
3357    case OPC1_16_SBC_JEQ2:
3358        gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[15], constant,
3359                         offset + 16);
3360        break;
3361    case OPC1_16_SBC_JNE:
3362        gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15], constant, offset);
3363        break;
3364    case OPC1_16_SBC_JNE2:
3365        gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[15],
3366                         constant, offset + 16);
3367        break;
3368/* SBRN-format jumps */
3369    case OPC1_16_SBRN_JZ_T:
3370        temp = tcg_temp_new();
3371        tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
3372        gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
3373        tcg_temp_free(temp);
3374        break;
3375    case OPC1_16_SBRN_JNZ_T:
3376        temp = tcg_temp_new();
3377        tcg_gen_andi_tl(temp, cpu_gpr_d[15], 0x1u << constant);
3378        gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
3379        tcg_temp_free(temp);
3380        break;
3381/* SBR-format jumps */
3382    case OPC1_16_SBR_JEQ:
3383        gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
3384                        offset);
3385        break;
3386    case OPC1_16_SBR_JEQ2:
3387        gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15],
3388                        offset + 16);
3389        break;
3390    case OPC1_16_SBR_JNE:
3391        gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
3392                        offset);
3393        break;
3394    case OPC1_16_SBR_JNE2:
3395        gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15],
3396                        offset + 16);
3397        break;
3398    case OPC1_16_SBR_JNZ:
3399        gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], 0, offset);
3400        break;
3401    case OPC1_16_SBR_JNZ_A:
3402        gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
3403        break;
3404    case OPC1_16_SBR_JGEZ:
3405        gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], 0, offset);
3406        break;
3407    case OPC1_16_SBR_JGTZ:
3408        gen_branch_condi(ctx, TCG_COND_GT, cpu_gpr_d[r1], 0, offset);
3409        break;
3410    case OPC1_16_SBR_JLEZ:
3411        gen_branch_condi(ctx, TCG_COND_LE, cpu_gpr_d[r1], 0, offset);
3412        break;
3413    case OPC1_16_SBR_JLTZ:
3414        gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], 0, offset);
3415        break;
3416    case OPC1_16_SBR_JZ:
3417        gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], 0, offset);
3418        break;
3419    case OPC1_16_SBR_JZ_A:
3420        gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
3421        break;
3422    case OPC1_16_SBR_LOOP:
3423        gen_loop(ctx, r1, offset * 2 - 32);
3424        break;
3425/* SR-format jumps */
3426    case OPC1_16_SR_JI:
3427        tcg_gen_andi_tl(cpu_PC, cpu_gpr_a[r1], 0xfffffffe);
3428        tcg_gen_exit_tb(NULL, 0);
3429        break;
3430    case OPC2_32_SYS_RET:
3431    case OPC2_16_SR_RET:
3432        gen_helper_ret(cpu_env);
3433        tcg_gen_exit_tb(NULL, 0);
3434        break;
3435/* B-format */
3436    case OPC1_32_B_CALLA:
3437        gen_helper_1arg(call, ctx->pc_succ_insn);
3438        gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3439        break;
3440    case OPC1_32_B_FCALL:
3441        gen_fcall_save_ctx(ctx);
3442        gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3443        break;
3444    case OPC1_32_B_FCALLA:
3445        gen_fcall_save_ctx(ctx);
3446        gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3447        break;
3448    case OPC1_32_B_JLA:
3449        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
3450        /* fall through */
3451    case OPC1_32_B_JA:
3452        gen_goto_tb(ctx, 0, EA_B_ABSOLUT(offset));
3453        break;
3454    case OPC1_32_B_JL:
3455        tcg_gen_movi_tl(cpu_gpr_a[11], ctx->pc_succ_insn);
3456        gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3457        break;
3458/* BOL format */
3459    case OPCM_32_BRC_EQ_NEQ:
3460         if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JEQ) {
3461            gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_d[r1], constant, offset);
3462         } else {
3463            gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_d[r1], constant, offset);
3464         }
3465         break;
3466    case OPCM_32_BRC_GE:
3467         if (MASK_OP_BRC_OP2(ctx->opcode) == OP2_32_BRC_JGE) {
3468            gen_branch_condi(ctx, TCG_COND_GE, cpu_gpr_d[r1], constant, offset);
3469         } else {
3470            constant = MASK_OP_BRC_CONST4(ctx->opcode);
3471            gen_branch_condi(ctx, TCG_COND_GEU, cpu_gpr_d[r1], constant,
3472                             offset);
3473         }
3474         break;
3475    case OPCM_32_BRC_JLT:
3476         if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JLT) {
3477            gen_branch_condi(ctx, TCG_COND_LT, cpu_gpr_d[r1], constant, offset);
3478         } else {
3479            constant = MASK_OP_BRC_CONST4(ctx->opcode);
3480            gen_branch_condi(ctx, TCG_COND_LTU, cpu_gpr_d[r1], constant,
3481                             offset);
3482         }
3483         break;
3484    case OPCM_32_BRC_JNE:
3485        temp = tcg_temp_new();
3486        if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRC_JNED) {
3487            tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3488            /* subi is unconditional */
3489            tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3490            gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
3491        } else {
3492            tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3493            /* addi is unconditional */
3494            tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3495            gen_branch_condi(ctx, TCG_COND_NE, temp, constant, offset);
3496        }
3497        tcg_temp_free(temp);
3498        break;
3499/* BRN format */
3500    case OPCM_32_BRN_JTT:
3501        n = MASK_OP_BRN_N(ctx->opcode);
3502
3503        temp = tcg_temp_new();
3504        tcg_gen_andi_tl(temp, cpu_gpr_d[r1], (1 << n));
3505
3506        if (MASK_OP_BRN_OP2(ctx->opcode) == OPC2_32_BRN_JNZ_T) {
3507            gen_branch_condi(ctx, TCG_COND_NE, temp, 0, offset);
3508        } else {
3509            gen_branch_condi(ctx, TCG_COND_EQ, temp, 0, offset);
3510        }
3511        tcg_temp_free(temp);
3512        break;
3513/* BRR Format */
3514    case OPCM_32_BRR_EQ_NEQ:
3515        if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ) {
3516            gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[r2],
3517                            offset);
3518        } else {
3519            gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[r2],
3520                            offset);
3521        }
3522        break;
3523    case OPCM_32_BRR_ADDR_EQ_NEQ:
3524        if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JEQ_A) {
3525            gen_branch_cond(ctx, TCG_COND_EQ, cpu_gpr_a[r1], cpu_gpr_a[r2],
3526                            offset);
3527        } else {
3528            gen_branch_cond(ctx, TCG_COND_NE, cpu_gpr_a[r1], cpu_gpr_a[r2],
3529                            offset);
3530        }
3531        break;
3532    case OPCM_32_BRR_GE:
3533        if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JGE) {
3534            gen_branch_cond(ctx, TCG_COND_GE, cpu_gpr_d[r1], cpu_gpr_d[r2],
3535                            offset);
3536        } else {
3537            gen_branch_cond(ctx, TCG_COND_GEU, cpu_gpr_d[r1], cpu_gpr_d[r2],
3538                            offset);
3539        }
3540        break;
3541    case OPCM_32_BRR_JLT:
3542        if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JLT) {
3543            gen_branch_cond(ctx, TCG_COND_LT, cpu_gpr_d[r1], cpu_gpr_d[r2],
3544                            offset);
3545        } else {
3546            gen_branch_cond(ctx, TCG_COND_LTU, cpu_gpr_d[r1], cpu_gpr_d[r2],
3547                            offset);
3548        }
3549        break;
3550    case OPCM_32_BRR_LOOP:
3551        if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_LOOP) {
3552            gen_loop(ctx, r2, offset * 2);
3553        } else {
3554            /* OPC2_32_BRR_LOOPU */
3555            gen_goto_tb(ctx, 0, ctx->base.pc_next + offset * 2);
3556        }
3557        break;
3558    case OPCM_32_BRR_JNE:
3559        temp = tcg_temp_new();
3560        temp2 = tcg_temp_new();
3561        if (MASK_OP_BRC_OP2(ctx->opcode) == OPC2_32_BRR_JNED) {
3562            tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3563            /* also save r2, in case of r1 == r2, so r2 is not decremented */
3564            tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
3565            /* subi is unconditional */
3566            tcg_gen_subi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3567            gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
3568        } else {
3569            tcg_gen_mov_tl(temp, cpu_gpr_d[r1]);
3570            /* also save r2, in case of r1 == r2, so r2 is not decremented */
3571            tcg_gen_mov_tl(temp2, cpu_gpr_d[r2]);
3572            /* addi is unconditional */
3573            tcg_gen_addi_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], 1);
3574            gen_branch_cond(ctx, TCG_COND_NE, temp, temp2, offset);
3575        }
3576        tcg_temp_free(temp);
3577        tcg_temp_free(temp2);
3578        break;
3579    case OPCM_32_BRR_JNZ:
3580        if (MASK_OP_BRR_OP2(ctx->opcode) == OPC2_32_BRR_JNZ_A) {
3581            gen_branch_condi(ctx, TCG_COND_NE, cpu_gpr_a[r1], 0, offset);
3582        } else {
3583            gen_branch_condi(ctx, TCG_COND_EQ, cpu_gpr_a[r1], 0, offset);
3584        }
3585        break;
3586    default:
3587        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3588    }
3589    ctx->base.is_jmp = DISAS_NORETURN;
3590}
3591
3592
3593/*
3594 * Functions for decoding instructions
3595 */
3596
3597static void decode_src_opc(DisasContext *ctx, int op1)
3598{
3599    int r1;
3600    int32_t const4;
3601    TCGv temp, temp2;
3602
3603    r1 = MASK_OP_SRC_S1D(ctx->opcode);
3604    const4 = MASK_OP_SRC_CONST4_SEXT(ctx->opcode);
3605
3606    switch (op1) {
3607    case OPC1_16_SRC_ADD:
3608        gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3609        break;
3610    case OPC1_16_SRC_ADD_A15:
3611        gen_addi_d(cpu_gpr_d[r1], cpu_gpr_d[15], const4);
3612        break;
3613    case OPC1_16_SRC_ADD_15A:
3614        gen_addi_d(cpu_gpr_d[15], cpu_gpr_d[r1], const4);
3615        break;
3616    case OPC1_16_SRC_ADD_A:
3617        tcg_gen_addi_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], const4);
3618        break;
3619    case OPC1_16_SRC_CADD:
3620        gen_condi_add(TCG_COND_NE, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
3621                      cpu_gpr_d[15]);
3622        break;
3623    case OPC1_16_SRC_CADDN:
3624        gen_condi_add(TCG_COND_EQ, cpu_gpr_d[r1], const4, cpu_gpr_d[r1],
3625                      cpu_gpr_d[15]);
3626        break;
3627    case OPC1_16_SRC_CMOV:
3628        temp = tcg_const_tl(0);
3629        temp2 = tcg_const_tl(const4);
3630        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3631                           temp2, cpu_gpr_d[r1]);
3632        tcg_temp_free(temp);
3633        tcg_temp_free(temp2);
3634        break;
3635    case OPC1_16_SRC_CMOVN:
3636        temp = tcg_const_tl(0);
3637        temp2 = tcg_const_tl(const4);
3638        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3639                           temp2, cpu_gpr_d[r1]);
3640        tcg_temp_free(temp);
3641        tcg_temp_free(temp2);
3642        break;
3643    case OPC1_16_SRC_EQ:
3644        tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
3645                            const4);
3646        break;
3647    case OPC1_16_SRC_LT:
3648        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
3649                            const4);
3650        break;
3651    case OPC1_16_SRC_MOV:
3652        tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
3653        break;
3654    case OPC1_16_SRC_MOV_A:
3655        const4 = MASK_OP_SRC_CONST4(ctx->opcode);
3656        tcg_gen_movi_tl(cpu_gpr_a[r1], const4);
3657        break;
3658    case OPC1_16_SRC_MOV_E:
3659        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
3660            tcg_gen_movi_tl(cpu_gpr_d[r1], const4);
3661            tcg_gen_sari_tl(cpu_gpr_d[r1+1], cpu_gpr_d[r1], 31);
3662        } else {
3663            generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3664        }
3665        break;
3666    case OPC1_16_SRC_SH:
3667        gen_shi(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3668        break;
3669    case OPC1_16_SRC_SHA:
3670        gen_shaci(cpu_gpr_d[r1], cpu_gpr_d[r1], const4);
3671        break;
3672    default:
3673        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3674    }
3675}
3676
3677static void decode_srr_opc(DisasContext *ctx, int op1)
3678{
3679    int r1, r2;
3680    TCGv temp;
3681
3682    r1 = MASK_OP_SRR_S1D(ctx->opcode);
3683    r2 = MASK_OP_SRR_S2(ctx->opcode);
3684
3685    switch (op1) {
3686    case OPC1_16_SRR_ADD:
3687        gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3688        break;
3689    case OPC1_16_SRR_ADD_A15:
3690        gen_add_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
3691        break;
3692    case OPC1_16_SRR_ADD_15A:
3693        gen_add_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3694        break;
3695    case OPC1_16_SRR_ADD_A:
3696        tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r1], cpu_gpr_a[r2]);
3697        break;
3698    case OPC1_16_SRR_ADDS:
3699        gen_adds(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3700        break;
3701    case OPC1_16_SRR_AND:
3702        tcg_gen_and_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3703        break;
3704    case OPC1_16_SRR_CMOV:
3705        temp = tcg_const_tl(0);
3706        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3707                           cpu_gpr_d[r2], cpu_gpr_d[r1]);
3708        tcg_temp_free(temp);
3709        break;
3710    case OPC1_16_SRR_CMOVN:
3711        temp = tcg_const_tl(0);
3712        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr_d[r1], cpu_gpr_d[15], temp,
3713                           cpu_gpr_d[r2], cpu_gpr_d[r1]);
3714        tcg_temp_free(temp);
3715        break;
3716    case OPC1_16_SRR_EQ:
3717        tcg_gen_setcond_tl(TCG_COND_EQ, cpu_gpr_d[15], cpu_gpr_d[r1],
3718                           cpu_gpr_d[r2]);
3719        break;
3720    case OPC1_16_SRR_LT:
3721        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr_d[15], cpu_gpr_d[r1],
3722                           cpu_gpr_d[r2]);
3723        break;
3724    case OPC1_16_SRR_MOV:
3725        tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_d[r2]);
3726        break;
3727    case OPC1_16_SRR_MOV_A:
3728        tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_d[r2]);
3729        break;
3730    case OPC1_16_SRR_MOV_AA:
3731        tcg_gen_mov_tl(cpu_gpr_a[r1], cpu_gpr_a[r2]);
3732        break;
3733    case OPC1_16_SRR_MOV_D:
3734        tcg_gen_mov_tl(cpu_gpr_d[r1], cpu_gpr_a[r2]);
3735        break;
3736    case OPC1_16_SRR_MUL:
3737        gen_mul_i32s(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3738        break;
3739    case OPC1_16_SRR_OR:
3740        tcg_gen_or_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3741        break;
3742    case OPC1_16_SRR_SUB:
3743        gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3744        break;
3745    case OPC1_16_SRR_SUB_A15B:
3746        gen_sub_d(cpu_gpr_d[r1], cpu_gpr_d[15], cpu_gpr_d[r2]);
3747        break;
3748    case OPC1_16_SRR_SUB_15AB:
3749        gen_sub_d(cpu_gpr_d[15], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3750        break;
3751    case OPC1_16_SRR_SUBS:
3752        gen_subs(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3753        break;
3754    case OPC1_16_SRR_XOR:
3755        tcg_gen_xor_tl(cpu_gpr_d[r1], cpu_gpr_d[r1], cpu_gpr_d[r2]);
3756        break;
3757    default:
3758        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3759    }
3760}
3761
3762static void decode_ssr_opc(DisasContext *ctx, int op1)
3763{
3764    int r1, r2;
3765
3766    r1 = MASK_OP_SSR_S1(ctx->opcode);
3767    r2 = MASK_OP_SSR_S2(ctx->opcode);
3768
3769    switch (op1) {
3770    case OPC1_16_SSR_ST_A:
3771        tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3772        break;
3773    case OPC1_16_SSR_ST_A_POSTINC:
3774        tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3775        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3776        break;
3777    case OPC1_16_SSR_ST_B:
3778        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3779        break;
3780    case OPC1_16_SSR_ST_B_POSTINC:
3781        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3782        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
3783        break;
3784    case OPC1_16_SSR_ST_H:
3785        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
3786        break;
3787    case OPC1_16_SSR_ST_H_POSTINC:
3788        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUW);
3789        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
3790        break;
3791    case OPC1_16_SSR_ST_W:
3792        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3793        break;
3794    case OPC1_16_SSR_ST_W_POSTINC:
3795        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LEUL);
3796        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3797        break;
3798    default:
3799        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3800    }
3801}
3802
3803static void decode_sc_opc(DisasContext *ctx, int op1)
3804{
3805    int32_t const16;
3806
3807    const16 = MASK_OP_SC_CONST8(ctx->opcode);
3808
3809    switch (op1) {
3810    case OPC1_16_SC_AND:
3811        tcg_gen_andi_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
3812        break;
3813    case OPC1_16_SC_BISR:
3814        gen_helper_1arg(bisr, const16 & 0xff);
3815        break;
3816    case OPC1_16_SC_LD_A:
3817        gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3818        break;
3819    case OPC1_16_SC_LD_W:
3820        gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3821        break;
3822    case OPC1_16_SC_MOV:
3823        tcg_gen_movi_tl(cpu_gpr_d[15], const16);
3824        break;
3825    case OPC1_16_SC_OR:
3826        tcg_gen_ori_tl(cpu_gpr_d[15], cpu_gpr_d[15], const16);
3827        break;
3828    case OPC1_16_SC_ST_A:
3829        gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3830        break;
3831    case OPC1_16_SC_ST_W:
3832        gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[10], const16 * 4, MO_LESL);
3833        break;
3834    case OPC1_16_SC_SUB_A:
3835        tcg_gen_subi_tl(cpu_gpr_a[10], cpu_gpr_a[10], const16);
3836        break;
3837    default:
3838        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3839    }
3840}
3841
3842static void decode_slr_opc(DisasContext *ctx, int op1)
3843{
3844    int r1, r2;
3845
3846    r1 = MASK_OP_SLR_D(ctx->opcode);
3847    r2 = MASK_OP_SLR_S2(ctx->opcode);
3848
3849    switch (op1) {
3850/* SLR-format */
3851    case OPC1_16_SLR_LD_A:
3852        tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3853        break;
3854    case OPC1_16_SLR_LD_A_POSTINC:
3855        tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3856        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3857        break;
3858    case OPC1_16_SLR_LD_BU:
3859        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3860        break;
3861    case OPC1_16_SLR_LD_BU_POSTINC:
3862        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_UB);
3863        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 1);
3864        break;
3865    case OPC1_16_SLR_LD_H:
3866        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
3867        break;
3868    case OPC1_16_SLR_LD_H_POSTINC:
3869        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESW);
3870        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 2);
3871        break;
3872    case OPC1_16_SLR_LD_W:
3873        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3874        break;
3875    case OPC1_16_SLR_LD_W_POSTINC:
3876        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx, MO_LESL);
3877        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], 4);
3878        break;
3879    default:
3880        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3881    }
3882}
3883
3884static void decode_sro_opc(DisasContext *ctx, int op1)
3885{
3886    int r2;
3887    int32_t address;
3888
3889    r2 = MASK_OP_SRO_S2(ctx->opcode);
3890    address = MASK_OP_SRO_OFF4(ctx->opcode);
3891
3892/* SRO-format */
3893    switch (op1) {
3894    case OPC1_16_SRO_LD_A:
3895        gen_offset_ld(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3896        break;
3897    case OPC1_16_SRO_LD_BU:
3898        gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
3899        break;
3900    case OPC1_16_SRO_LD_H:
3901        gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_LESW);
3902        break;
3903    case OPC1_16_SRO_LD_W:
3904        gen_offset_ld(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3905        break;
3906    case OPC1_16_SRO_ST_A:
3907        gen_offset_st(ctx, cpu_gpr_a[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3908        break;
3909    case OPC1_16_SRO_ST_B:
3910        gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address, MO_UB);
3911        break;
3912    case OPC1_16_SRO_ST_H:
3913        gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 2, MO_LESW);
3914        break;
3915    case OPC1_16_SRO_ST_W:
3916        gen_offset_st(ctx, cpu_gpr_d[15], cpu_gpr_a[r2], address * 4, MO_LESL);
3917        break;
3918    default:
3919        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3920    }
3921}
3922
3923static void decode_sr_system(DisasContext *ctx)
3924{
3925    uint32_t op2;
3926    op2 = MASK_OP_SR_OP2(ctx->opcode);
3927
3928    switch (op2) {
3929    case OPC2_16_SR_NOP:
3930        break;
3931    case OPC2_16_SR_RET:
3932        gen_compute_branch(ctx, op2, 0, 0, 0, 0);
3933        break;
3934    case OPC2_16_SR_RFE:
3935        gen_helper_rfe(cpu_env);
3936        tcg_gen_exit_tb(NULL, 0);
3937        ctx->base.is_jmp = DISAS_NORETURN;
3938        break;
3939    case OPC2_16_SR_DEBUG:
3940        /* raise EXCP_DEBUG */
3941        break;
3942    case OPC2_16_SR_FRET:
3943        gen_fret(ctx);
3944        break;
3945    default:
3946        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3947    }
3948}
3949
3950static void decode_sr_accu(DisasContext *ctx)
3951{
3952    uint32_t op2;
3953    uint32_t r1;
3954    TCGv temp;
3955
3956    r1 = MASK_OP_SR_S1D(ctx->opcode);
3957    op2 = MASK_OP_SR_OP2(ctx->opcode);
3958
3959    switch (op2) {
3960    case OPC2_16_SR_RSUB:
3961        /* overflow only if r1 = -0x80000000 */
3962        temp = tcg_const_i32(-0x80000000);
3963        /* calc V bit */
3964        tcg_gen_setcond_tl(TCG_COND_EQ, cpu_PSW_V, cpu_gpr_d[r1], temp);
3965        tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
3966        /* calc SV bit */
3967        tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
3968        /* sub */
3969        tcg_gen_neg_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
3970        /* calc av */
3971        tcg_gen_add_tl(cpu_PSW_AV, cpu_gpr_d[r1], cpu_gpr_d[r1]);
3972        tcg_gen_xor_tl(cpu_PSW_AV, cpu_gpr_d[r1], cpu_PSW_AV);
3973        /* calc sav */
3974        tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
3975        tcg_temp_free(temp);
3976        break;
3977    case OPC2_16_SR_SAT_B:
3978        gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7f, -0x80);
3979        break;
3980    case OPC2_16_SR_SAT_BU:
3981        gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xff);
3982        break;
3983    case OPC2_16_SR_SAT_H:
3984        gen_saturate(cpu_gpr_d[r1], cpu_gpr_d[r1], 0x7fff, -0x8000);
3985        break;
3986    case OPC2_16_SR_SAT_HU:
3987        gen_saturate_u(cpu_gpr_d[r1], cpu_gpr_d[r1], 0xffff);
3988        break;
3989    default:
3990        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
3991    }
3992}
3993
3994static void decode_16Bit_opc(DisasContext *ctx)
3995{
3996    int op1;
3997    int r1, r2;
3998    int32_t const16;
3999    int32_t address;
4000    TCGv temp;
4001
4002    op1 = MASK_OP_MAJOR(ctx->opcode);
4003
4004    /* handle ADDSC.A opcode only being 6 bit long */
4005    if (unlikely((op1 & 0x3f) == OPC1_16_SRRS_ADDSC_A)) {
4006        op1 = OPC1_16_SRRS_ADDSC_A;
4007    }
4008
4009    switch (op1) {
4010    case OPC1_16_SRC_ADD:
4011    case OPC1_16_SRC_ADD_A15:
4012    case OPC1_16_SRC_ADD_15A:
4013    case OPC1_16_SRC_ADD_A:
4014    case OPC1_16_SRC_CADD:
4015    case OPC1_16_SRC_CADDN:
4016    case OPC1_16_SRC_CMOV:
4017    case OPC1_16_SRC_CMOVN:
4018    case OPC1_16_SRC_EQ:
4019    case OPC1_16_SRC_LT:
4020    case OPC1_16_SRC_MOV:
4021    case OPC1_16_SRC_MOV_A:
4022    case OPC1_16_SRC_MOV_E:
4023    case OPC1_16_SRC_SH:
4024    case OPC1_16_SRC_SHA:
4025        decode_src_opc(ctx, op1);
4026        break;
4027/* SRR-format */
4028    case OPC1_16_SRR_ADD:
4029    case OPC1_16_SRR_ADD_A15:
4030    case OPC1_16_SRR_ADD_15A:
4031    case OPC1_16_SRR_ADD_A:
4032    case OPC1_16_SRR_ADDS:
4033    case OPC1_16_SRR_AND:
4034    case OPC1_16_SRR_CMOV:
4035    case OPC1_16_SRR_CMOVN:
4036    case OPC1_16_SRR_EQ:
4037    case OPC1_16_SRR_LT:
4038    case OPC1_16_SRR_MOV:
4039    case OPC1_16_SRR_MOV_A:
4040    case OPC1_16_SRR_MOV_AA:
4041    case OPC1_16_SRR_MOV_D:
4042    case OPC1_16_SRR_MUL:
4043    case OPC1_16_SRR_OR:
4044    case OPC1_16_SRR_SUB:
4045    case OPC1_16_SRR_SUB_A15B:
4046    case OPC1_16_SRR_SUB_15AB:
4047    case OPC1_16_SRR_SUBS:
4048    case OPC1_16_SRR_XOR:
4049        decode_srr_opc(ctx, op1);
4050        break;
4051/* SSR-format */
4052    case OPC1_16_SSR_ST_A:
4053    case OPC1_16_SSR_ST_A_POSTINC:
4054    case OPC1_16_SSR_ST_B:
4055    case OPC1_16_SSR_ST_B_POSTINC:
4056    case OPC1_16_SSR_ST_H:
4057    case OPC1_16_SSR_ST_H_POSTINC:
4058    case OPC1_16_SSR_ST_W:
4059    case OPC1_16_SSR_ST_W_POSTINC:
4060        decode_ssr_opc(ctx, op1);
4061        break;
4062/* SRRS-format */
4063    case OPC1_16_SRRS_ADDSC_A:
4064        r2 = MASK_OP_SRRS_S2(ctx->opcode);
4065        r1 = MASK_OP_SRRS_S1D(ctx->opcode);
4066        const16 = MASK_OP_SRRS_N(ctx->opcode);
4067        temp = tcg_temp_new();
4068        tcg_gen_shli_tl(temp, cpu_gpr_d[15], const16);
4069        tcg_gen_add_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], temp);
4070        tcg_temp_free(temp);
4071        break;
4072/* SLRO-format */
4073    case OPC1_16_SLRO_LD_A:
4074        r1 = MASK_OP_SLRO_D(ctx->opcode);
4075        const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
4076        gen_offset_ld(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
4077        break;
4078    case OPC1_16_SLRO_LD_BU:
4079        r1 = MASK_OP_SLRO_D(ctx->opcode);
4080        const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
4081        gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
4082        break;
4083    case OPC1_16_SLRO_LD_H:
4084        r1 = MASK_OP_SLRO_D(ctx->opcode);
4085        const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
4086        gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
4087        break;
4088    case OPC1_16_SLRO_LD_W:
4089        r1 = MASK_OP_SLRO_D(ctx->opcode);
4090        const16 = MASK_OP_SLRO_OFF4(ctx->opcode);
4091        gen_offset_ld(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
4092        break;
4093/* SB-format */
4094    case OPC1_16_SB_CALL:
4095    case OPC1_16_SB_J:
4096    case OPC1_16_SB_JNZ:
4097    case OPC1_16_SB_JZ:
4098        address = MASK_OP_SB_DISP8_SEXT(ctx->opcode);
4099        gen_compute_branch(ctx, op1, 0, 0, 0, address);
4100        break;
4101/* SBC-format */
4102    case OPC1_16_SBC_JEQ:
4103    case OPC1_16_SBC_JNE:
4104        address = MASK_OP_SBC_DISP4(ctx->opcode);
4105        const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
4106        gen_compute_branch(ctx, op1, 0, 0, const16, address);
4107        break;
4108    case OPC1_16_SBC_JEQ2:
4109    case OPC1_16_SBC_JNE2:
4110        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
4111            address = MASK_OP_SBC_DISP4(ctx->opcode);
4112            const16 = MASK_OP_SBC_CONST4_SEXT(ctx->opcode);
4113            gen_compute_branch(ctx, op1, 0, 0, const16, address);
4114        } else {
4115            generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4116        }
4117        break;
4118/* SBRN-format */
4119    case OPC1_16_SBRN_JNZ_T:
4120    case OPC1_16_SBRN_JZ_T:
4121        address = MASK_OP_SBRN_DISP4(ctx->opcode);
4122        const16 = MASK_OP_SBRN_N(ctx->opcode);
4123        gen_compute_branch(ctx, op1, 0, 0, const16, address);
4124        break;
4125/* SBR-format */
4126    case OPC1_16_SBR_JEQ2:
4127    case OPC1_16_SBR_JNE2:
4128        if (tricore_feature(ctx->env, TRICORE_FEATURE_16)) {
4129            r1 = MASK_OP_SBR_S2(ctx->opcode);
4130            address = MASK_OP_SBR_DISP4(ctx->opcode);
4131            gen_compute_branch(ctx, op1, r1, 0, 0, address);
4132        } else {
4133            generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4134        }
4135        break;
4136    case OPC1_16_SBR_JEQ:
4137    case OPC1_16_SBR_JGEZ:
4138    case OPC1_16_SBR_JGTZ:
4139    case OPC1_16_SBR_JLEZ:
4140    case OPC1_16_SBR_JLTZ:
4141    case OPC1_16_SBR_JNE:
4142    case OPC1_16_SBR_JNZ:
4143    case OPC1_16_SBR_JNZ_A:
4144    case OPC1_16_SBR_JZ:
4145    case OPC1_16_SBR_JZ_A:
4146    case OPC1_16_SBR_LOOP:
4147        r1 = MASK_OP_SBR_S2(ctx->opcode);
4148        address = MASK_OP_SBR_DISP4(ctx->opcode);
4149        gen_compute_branch(ctx, op1, r1, 0, 0, address);
4150        break;
4151/* SC-format */
4152    case OPC1_16_SC_AND:
4153    case OPC1_16_SC_BISR:
4154    case OPC1_16_SC_LD_A:
4155    case OPC1_16_SC_LD_W:
4156    case OPC1_16_SC_MOV:
4157    case OPC1_16_SC_OR:
4158    case OPC1_16_SC_ST_A:
4159    case OPC1_16_SC_ST_W:
4160    case OPC1_16_SC_SUB_A:
4161        decode_sc_opc(ctx, op1);
4162        break;
4163/* SLR-format */
4164    case OPC1_16_SLR_LD_A:
4165    case OPC1_16_SLR_LD_A_POSTINC:
4166    case OPC1_16_SLR_LD_BU:
4167    case OPC1_16_SLR_LD_BU_POSTINC:
4168    case OPC1_16_SLR_LD_H:
4169    case OPC1_16_SLR_LD_H_POSTINC:
4170    case OPC1_16_SLR_LD_W:
4171    case OPC1_16_SLR_LD_W_POSTINC:
4172        decode_slr_opc(ctx, op1);
4173        break;
4174/* SRO-format */
4175    case OPC1_16_SRO_LD_A:
4176    case OPC1_16_SRO_LD_BU:
4177    case OPC1_16_SRO_LD_H:
4178    case OPC1_16_SRO_LD_W:
4179    case OPC1_16_SRO_ST_A:
4180    case OPC1_16_SRO_ST_B:
4181    case OPC1_16_SRO_ST_H:
4182    case OPC1_16_SRO_ST_W:
4183        decode_sro_opc(ctx, op1);
4184        break;
4185/* SSRO-format */
4186    case OPC1_16_SSRO_ST_A:
4187        r1 = MASK_OP_SSRO_S1(ctx->opcode);
4188        const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
4189        gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
4190        break;
4191    case OPC1_16_SSRO_ST_B:
4192        r1 = MASK_OP_SSRO_S1(ctx->opcode);
4193        const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
4194        gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16, MO_UB);
4195        break;
4196    case OPC1_16_SSRO_ST_H:
4197        r1 = MASK_OP_SSRO_S1(ctx->opcode);
4198        const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
4199        gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 2, MO_LESW);
4200        break;
4201    case OPC1_16_SSRO_ST_W:
4202        r1 = MASK_OP_SSRO_S1(ctx->opcode);
4203        const16 = MASK_OP_SSRO_OFF4(ctx->opcode);
4204        gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[15], const16 * 4, MO_LESL);
4205        break;
4206/* SR-format */
4207    case OPCM_16_SR_SYSTEM:
4208        decode_sr_system(ctx);
4209        break;
4210    case OPCM_16_SR_ACCU:
4211        decode_sr_accu(ctx);
4212        break;
4213    case OPC1_16_SR_JI:
4214        r1 = MASK_OP_SR_S1D(ctx->opcode);
4215        gen_compute_branch(ctx, op1, r1, 0, 0, 0);
4216        break;
4217    case OPC1_16_SR_NOT:
4218        r1 = MASK_OP_SR_S1D(ctx->opcode);
4219        tcg_gen_not_tl(cpu_gpr_d[r1], cpu_gpr_d[r1]);
4220        break;
4221    default:
4222        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4223    }
4224}
4225
4226/*
4227 * 32 bit instructions
4228 */
4229
4230/* ABS-format */
4231static void decode_abs_ldw(DisasContext *ctx)
4232{
4233    int32_t op2;
4234    int32_t r1;
4235    uint32_t address;
4236    TCGv temp;
4237
4238    r1 = MASK_OP_ABS_S1D(ctx->opcode);
4239    address = MASK_OP_ABS_OFF18(ctx->opcode);
4240    op2 = MASK_OP_ABS_OP2(ctx->opcode);
4241
4242    temp = tcg_const_i32(EA_ABS_FORMAT(address));
4243
4244    switch (op2) {
4245    case OPC2_32_ABS_LD_A:
4246        tcg_gen_qemu_ld_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
4247        break;
4248    case OPC2_32_ABS_LD_D:
4249        CHECK_REG_PAIR(r1);
4250        gen_ld_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
4251        break;
4252    case OPC2_32_ABS_LD_DA:
4253        CHECK_REG_PAIR(r1);
4254        gen_ld_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
4255        break;
4256    case OPC2_32_ABS_LD_W:
4257        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
4258        break;
4259    default:
4260        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4261    }
4262
4263    tcg_temp_free(temp);
4264}
4265
4266static void decode_abs_ldb(DisasContext *ctx)
4267{
4268    int32_t op2;
4269    int32_t r1;
4270    uint32_t address;
4271    TCGv temp;
4272
4273    r1 = MASK_OP_ABS_S1D(ctx->opcode);
4274    address = MASK_OP_ABS_OFF18(ctx->opcode);
4275    op2 = MASK_OP_ABS_OP2(ctx->opcode);
4276
4277    temp = tcg_const_i32(EA_ABS_FORMAT(address));
4278
4279    switch (op2) {
4280    case OPC2_32_ABS_LD_B:
4281        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_SB);
4282        break;
4283    case OPC2_32_ABS_LD_BU:
4284        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
4285        break;
4286    case OPC2_32_ABS_LD_H:
4287        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESW);
4288        break;
4289    case OPC2_32_ABS_LD_HU:
4290        tcg_gen_qemu_ld_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
4291        break;
4292    default:
4293        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4294    }
4295
4296    tcg_temp_free(temp);
4297}
4298
4299static void decode_abs_ldst_swap(DisasContext *ctx)
4300{
4301    int32_t op2;
4302    int32_t r1;
4303    uint32_t address;
4304    TCGv temp;
4305
4306    r1 = MASK_OP_ABS_S1D(ctx->opcode);
4307    address = MASK_OP_ABS_OFF18(ctx->opcode);
4308    op2 = MASK_OP_ABS_OP2(ctx->opcode);
4309
4310    temp = tcg_const_i32(EA_ABS_FORMAT(address));
4311
4312    switch (op2) {
4313    case OPC2_32_ABS_LDMST:
4314        gen_ldmst(ctx, r1, temp);
4315        break;
4316    case OPC2_32_ABS_SWAP_W:
4317        gen_swap(ctx, r1, temp);
4318        break;
4319    default:
4320        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4321    }
4322
4323    tcg_temp_free(temp);
4324}
4325
4326static void decode_abs_ldst_context(DisasContext *ctx)
4327{
4328    uint32_t op2;
4329    int32_t off18;
4330
4331    off18 = MASK_OP_ABS_OFF18(ctx->opcode);
4332    op2   = MASK_OP_ABS_OP2(ctx->opcode);
4333
4334    switch (op2) {
4335    case OPC2_32_ABS_LDLCX:
4336        gen_helper_1arg(ldlcx, EA_ABS_FORMAT(off18));
4337        break;
4338    case OPC2_32_ABS_LDUCX:
4339        gen_helper_1arg(lducx, EA_ABS_FORMAT(off18));
4340        break;
4341    case OPC2_32_ABS_STLCX:
4342        gen_helper_1arg(stlcx, EA_ABS_FORMAT(off18));
4343        break;
4344    case OPC2_32_ABS_STUCX:
4345        gen_helper_1arg(stucx, EA_ABS_FORMAT(off18));
4346        break;
4347    default:
4348        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4349    }
4350}
4351
4352static void decode_abs_store(DisasContext *ctx)
4353{
4354    int32_t op2;
4355    int32_t r1;
4356    uint32_t address;
4357    TCGv temp;
4358
4359    r1 = MASK_OP_ABS_S1D(ctx->opcode);
4360    address = MASK_OP_ABS_OFF18(ctx->opcode);
4361    op2 = MASK_OP_ABS_OP2(ctx->opcode);
4362
4363    temp = tcg_const_i32(EA_ABS_FORMAT(address));
4364
4365    switch (op2) {
4366    case OPC2_32_ABS_ST_A:
4367        tcg_gen_qemu_st_tl(cpu_gpr_a[r1], temp, ctx->mem_idx, MO_LESL);
4368        break;
4369    case OPC2_32_ABS_ST_D:
4370        CHECK_REG_PAIR(r1);
4371        gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
4372        break;
4373    case OPC2_32_ABS_ST_DA:
4374        CHECK_REG_PAIR(r1);
4375        gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
4376        break;
4377    case OPC2_32_ABS_ST_W:
4378        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LESL);
4379        break;
4380    default:
4381        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4382    }
4383    tcg_temp_free(temp);
4384}
4385
4386static void decode_abs_storeb_h(DisasContext *ctx)
4387{
4388    int32_t op2;
4389    int32_t r1;
4390    uint32_t address;
4391    TCGv temp;
4392
4393    r1 = MASK_OP_ABS_S1D(ctx->opcode);
4394    address = MASK_OP_ABS_OFF18(ctx->opcode);
4395    op2 = MASK_OP_ABS_OP2(ctx->opcode);
4396
4397    temp = tcg_const_i32(EA_ABS_FORMAT(address));
4398
4399    switch (op2) {
4400    case OPC2_32_ABS_ST_B:
4401        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_UB);
4402        break;
4403    case OPC2_32_ABS_ST_H:
4404        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], temp, ctx->mem_idx, MO_LEUW);
4405        break;
4406    default:
4407        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4408    }
4409    tcg_temp_free(temp);
4410}
4411
4412/* Bit-format */
4413
4414static void decode_bit_andacc(DisasContext *ctx)
4415{
4416    uint32_t op2;
4417    int r1, r2, r3;
4418    int pos1, pos2;
4419
4420    r1 = MASK_OP_BIT_S1(ctx->opcode);
4421    r2 = MASK_OP_BIT_S2(ctx->opcode);
4422    r3 = MASK_OP_BIT_D(ctx->opcode);
4423    pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4424    pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4425    op2 = MASK_OP_BIT_OP2(ctx->opcode);
4426
4427
4428    switch (op2) {
4429    case OPC2_32_BIT_AND_AND_T:
4430        gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4431                    pos1, pos2, &tcg_gen_and_tl, &tcg_gen_and_tl);
4432        break;
4433    case OPC2_32_BIT_AND_ANDN_T:
4434        gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4435                    pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_and_tl);
4436        break;
4437    case OPC2_32_BIT_AND_NOR_T:
4438        if (TCG_TARGET_HAS_andc_i32) {
4439            gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4440                        pos1, pos2, &tcg_gen_or_tl, &tcg_gen_andc_tl);
4441        } else {
4442            gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4443                        pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_and_tl);
4444        }
4445        break;
4446    case OPC2_32_BIT_AND_OR_T:
4447        gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4448                    pos1, pos2, &tcg_gen_or_tl, &tcg_gen_and_tl);
4449        break;
4450    default:
4451        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4452    }
4453}
4454
4455static void decode_bit_logical_t(DisasContext *ctx)
4456{
4457    uint32_t op2;
4458    int r1, r2, r3;
4459    int pos1, pos2;
4460    r1 = MASK_OP_BIT_S1(ctx->opcode);
4461    r2 = MASK_OP_BIT_S2(ctx->opcode);
4462    r3 = MASK_OP_BIT_D(ctx->opcode);
4463    pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4464    pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4465    op2 = MASK_OP_BIT_OP2(ctx->opcode);
4466
4467    switch (op2) {
4468    case OPC2_32_BIT_AND_T:
4469        gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4470                    pos1, pos2, &tcg_gen_and_tl);
4471        break;
4472    case OPC2_32_BIT_ANDN_T:
4473        gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4474                    pos1, pos2, &tcg_gen_andc_tl);
4475        break;
4476    case OPC2_32_BIT_NOR_T:
4477        gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4478                    pos1, pos2, &tcg_gen_nor_tl);
4479        break;
4480    case OPC2_32_BIT_OR_T:
4481        gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4482                    pos1, pos2, &tcg_gen_or_tl);
4483        break;
4484    default:
4485        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4486    }
4487}
4488
4489static void decode_bit_insert(DisasContext *ctx)
4490{
4491    uint32_t op2;
4492    int r1, r2, r3;
4493    int pos1, pos2;
4494    TCGv temp;
4495    op2 = MASK_OP_BIT_OP2(ctx->opcode);
4496    r1 = MASK_OP_BIT_S1(ctx->opcode);
4497    r2 = MASK_OP_BIT_S2(ctx->opcode);
4498    r3 = MASK_OP_BIT_D(ctx->opcode);
4499    pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4500    pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4501
4502    temp = tcg_temp_new();
4503
4504    tcg_gen_shri_tl(temp, cpu_gpr_d[r2], pos2);
4505    if (op2 == OPC2_32_BIT_INSN_T) {
4506        tcg_gen_not_tl(temp, temp);
4507    }
4508    tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], temp, pos1, 1);
4509    tcg_temp_free(temp);
4510}
4511
4512static void decode_bit_logical_t2(DisasContext *ctx)
4513{
4514    uint32_t op2;
4515
4516    int r1, r2, r3;
4517    int pos1, pos2;
4518
4519    op2 = MASK_OP_BIT_OP2(ctx->opcode);
4520    r1 = MASK_OP_BIT_S1(ctx->opcode);
4521    r2 = MASK_OP_BIT_S2(ctx->opcode);
4522    r3 = MASK_OP_BIT_D(ctx->opcode);
4523    pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4524    pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4525
4526    switch (op2) {
4527    case OPC2_32_BIT_NAND_T:
4528        gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4529                    pos1, pos2, &tcg_gen_nand_tl);
4530        break;
4531    case OPC2_32_BIT_ORN_T:
4532        gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4533                    pos1, pos2, &tcg_gen_orc_tl);
4534        break;
4535    case OPC2_32_BIT_XNOR_T:
4536        gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4537                    pos1, pos2, &tcg_gen_eqv_tl);
4538        break;
4539    case OPC2_32_BIT_XOR_T:
4540        gen_bit_1op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4541                    pos1, pos2, &tcg_gen_xor_tl);
4542        break;
4543    default:
4544        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4545    }
4546}
4547
4548static void decode_bit_orand(DisasContext *ctx)
4549{
4550    uint32_t op2;
4551
4552    int r1, r2, r3;
4553    int pos1, pos2;
4554
4555    op2 = MASK_OP_BIT_OP2(ctx->opcode);
4556    r1 = MASK_OP_BIT_S1(ctx->opcode);
4557    r2 = MASK_OP_BIT_S2(ctx->opcode);
4558    r3 = MASK_OP_BIT_D(ctx->opcode);
4559    pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4560    pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4561
4562    switch (op2) {
4563    case OPC2_32_BIT_OR_AND_T:
4564        gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4565                    pos1, pos2, &tcg_gen_and_tl, &tcg_gen_or_tl);
4566        break;
4567    case OPC2_32_BIT_OR_ANDN_T:
4568        gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4569                    pos1, pos2, &tcg_gen_andc_tl, &tcg_gen_or_tl);
4570        break;
4571    case OPC2_32_BIT_OR_NOR_T:
4572        if (TCG_TARGET_HAS_orc_i32) {
4573            gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4574                        pos1, pos2, &tcg_gen_or_tl, &tcg_gen_orc_tl);
4575        } else {
4576            gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4577                        pos1, pos2, &tcg_gen_nor_tl, &tcg_gen_or_tl);
4578        }
4579        break;
4580    case OPC2_32_BIT_OR_OR_T:
4581        gen_bit_2op(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
4582                    pos1, pos2, &tcg_gen_or_tl, &tcg_gen_or_tl);
4583        break;
4584    default:
4585        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4586    }
4587}
4588
4589static void decode_bit_sh_logic1(DisasContext *ctx)
4590{
4591    uint32_t op2;
4592    int r1, r2, r3;
4593    int pos1, pos2;
4594    TCGv temp;
4595
4596    op2 = MASK_OP_BIT_OP2(ctx->opcode);
4597    r1 = MASK_OP_BIT_S1(ctx->opcode);
4598    r2 = MASK_OP_BIT_S2(ctx->opcode);
4599    r3 = MASK_OP_BIT_D(ctx->opcode);
4600    pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4601    pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4602
4603    temp = tcg_temp_new();
4604
4605    switch (op2) {
4606    case OPC2_32_BIT_SH_AND_T:
4607        gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4608                    pos1, pos2, &tcg_gen_and_tl);
4609        break;
4610    case OPC2_32_BIT_SH_ANDN_T:
4611        gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4612                    pos1, pos2, &tcg_gen_andc_tl);
4613        break;
4614    case OPC2_32_BIT_SH_NOR_T:
4615        gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4616                    pos1, pos2, &tcg_gen_nor_tl);
4617        break;
4618    case OPC2_32_BIT_SH_OR_T:
4619        gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4620                    pos1, pos2, &tcg_gen_or_tl);
4621        break;
4622    default:
4623        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4624    }
4625    tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
4626    tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
4627    tcg_temp_free(temp);
4628}
4629
4630static void decode_bit_sh_logic2(DisasContext *ctx)
4631{
4632    uint32_t op2;
4633    int r1, r2, r3;
4634    int pos1, pos2;
4635    TCGv temp;
4636
4637    op2 = MASK_OP_BIT_OP2(ctx->opcode);
4638    r1 = MASK_OP_BIT_S1(ctx->opcode);
4639    r2 = MASK_OP_BIT_S2(ctx->opcode);
4640    r3 = MASK_OP_BIT_D(ctx->opcode);
4641    pos1 = MASK_OP_BIT_POS1(ctx->opcode);
4642    pos2 = MASK_OP_BIT_POS2(ctx->opcode);
4643
4644    temp = tcg_temp_new();
4645
4646    switch (op2) {
4647    case OPC2_32_BIT_SH_NAND_T:
4648        gen_bit_1op(temp, cpu_gpr_d[r1] , cpu_gpr_d[r2] ,
4649                    pos1, pos2, &tcg_gen_nand_tl);
4650        break;
4651    case OPC2_32_BIT_SH_ORN_T:
4652        gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4653                    pos1, pos2, &tcg_gen_orc_tl);
4654        break;
4655    case OPC2_32_BIT_SH_XNOR_T:
4656        gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4657                    pos1, pos2, &tcg_gen_eqv_tl);
4658        break;
4659    case OPC2_32_BIT_SH_XOR_T:
4660        gen_bit_1op(temp, cpu_gpr_d[r1], cpu_gpr_d[r2],
4661                    pos1, pos2, &tcg_gen_xor_tl);
4662        break;
4663    default:
4664        generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4665    }
4666    tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 1);
4667    tcg_gen_add_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
4668    tcg_temp_free(temp);
4669}
4670
4671/* BO-format */
4672
4673
4674static void decode_bo_addrmode_post_pre_base(DisasContext *ctx)
4675{
4676    uint32_t op2;
4677    uint32_t off10;
4678    int32_t r1, r2;
4679    TCGv temp;
4680
4681    r1 = MASK_OP_BO_S1D(ctx->opcode);
4682    r2  = MASK_OP_BO_S2(ctx->opcode);
4683    off10 = MASK_OP_BO_OFF10_SEXT(ctx->opcode);
4684    op2 = MASK_OP_BO_OP2(ctx->opcode);
4685
4686    switch (op2) {
4687    case OPC2_32_BO_CACHEA_WI_SHORTOFF:
4688    case OPC2_32_BO_CACHEA_W_SHORTOFF:
4689    case OPC2_32_BO_CACHEA_I_SHORTOFF:
4690        /* instruction to access the cache */
4691        break;
4692    case OPC2_32_BO_CACHEA_WI_POSTINC:
4693    case OPC2_32_BO_CACHEA_W_POSTINC:
4694    case OPC2_32_BO_CACHEA_I_POSTINC:
4695        /* instruction to access the cache, but we still need to handle
4696           the addressing mode */
4697        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4698        break;
4699    case OPC2_32_BO_CACHEA_WI_PREINC:
4700    case OPC2_32_BO_CACHEA_W_PREINC:
4701    case OPC2_32_BO_CACHEA_I_PREINC:
4702        /* instruction to access the cache, but we still need to handle
4703           the addressing mode */
4704        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4705        break;
4706    case OPC2_32_BO_CACHEI_WI_SHORTOFF:
4707    case OPC2_32_BO_CACHEI_W_SHORTOFF:
4708        if (!tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
4709            generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4710        }
4711        break;
4712    case OPC2_32_BO_CACHEI_W_POSTINC:
4713    case OPC2_32_BO_CACHEI_WI_POSTINC:
4714        if (tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
4715            tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4716        } else {
4717            generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4718        }
4719        break;
4720    case OPC2_32_BO_CACHEI_W_PREINC:
4721    case OPC2_32_BO_CACHEI_WI_PREINC:
4722        if (tricore_feature(ctx->env, TRICORE_FEATURE_131)) {
4723            tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4724        } else {
4725            generate_trap(ctx, TRAPC_INSN_ERR, TIN2_IOPC);
4726        }
4727        break;
4728    case OPC2_32_BO_ST_A_SHORTOFF:
4729        gen_offset_st(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
4730        break;
4731    case OPC2_32_BO_ST_A_POSTINC:
4732        tcg_gen_qemu_st_tl(cpu_gpr_a[r1], cpu_gpr_a[r2], ctx->mem_idx,
4733                           MO_LESL);
4734        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4735        break;
4736    case OPC2_32_BO_ST_A_PREINC:
4737        gen_st_preincr(ctx, cpu_gpr_a[r1], cpu_gpr_a[r2], off10, MO_LESL);
4738        break;
4739    case OPC2_32_BO_ST_B_SHORTOFF:
4740        gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4741        break;
4742    case OPC2_32_BO_ST_B_POSTINC:
4743        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4744                           MO_UB);
4745        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4746        break;
4747    case OPC2_32_BO_ST_B_PREINC:
4748        gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_UB);
4749        break;
4750    case OPC2_32_BO_ST_D_SHORTOFF:
4751        CHECK_REG_PAIR(r1);
4752        gen_offset_st_2regs(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2],
4753                            off10, ctx);
4754        break;
4755    case OPC2_32_BO_ST_D_POSTINC:
4756        CHECK_REG_PAIR(r1);
4757        gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], cpu_gpr_a[r2], ctx);
4758        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4759        break;
4760    case OPC2_32_BO_ST_D_PREINC:
4761        CHECK_REG_PAIR(r1);
4762        temp = tcg_temp_new();
4763        tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4764        gen_st_2regs_64(cpu_gpr_d[r1+1], cpu_gpr_d[r1], temp, ctx);
4765        tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
4766        tcg_temp_free(temp);
4767        break;
4768    case OPC2_32_BO_ST_DA_SHORTOFF:
4769        CHECK_REG_PAIR(r1);
4770        gen_offset_st_2regs(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2],
4771                            off10, ctx);
4772        break;
4773    case OPC2_32_BO_ST_DA_POSTINC:
4774        CHECK_REG_PAIR(r1);
4775        gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], cpu_gpr_a[r2], ctx);
4776        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4777        break;
4778    case OPC2_32_BO_ST_DA_PREINC:
4779        CHECK_REG_PAIR(r1);
4780        temp = tcg_temp_new();
4781        tcg_gen_addi_tl(temp, cpu_gpr_a[r2], off10);
4782        gen_st_2regs_64(cpu_gpr_a[r1+1], cpu_gpr_a[r1], temp, ctx);
4783        tcg_gen_mov_tl(cpu_gpr_a[r2], temp);
4784        tcg_temp_free(temp);
4785        break;
4786    case OPC2_32_BO_ST_H_SHORTOFF:
4787        gen_offset_st(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4788        break;
4789    case OPC2_32_BO_ST_H_POSTINC:
4790        tcg_gen_qemu_st_tl(cpu_gpr_d[r1], cpu_gpr_a[r2], ctx->mem_idx,
4791                           MO_LEUW);
4792        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4793        break;
4794    case OPC2_32_BO_ST_H_PREINC:
4795        gen_st_preincr(ctx, cpu_gpr_d[r1], cpu_gpr_a[r2], off10, MO_LEUW);
4796        break;
4797    case OPC2_32_BO_ST_Q_SHORTOFF:
4798        temp = tcg_temp_new();
4799        tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4800        gen_offset_st(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW);
4801        tcg_temp_free(temp);
4802        break;
4803    case OPC2_32_BO_ST_Q_POSTINC:
4804        temp = tcg_temp_new();
4805        tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4806        tcg_gen_qemu_st_tl(temp, cpu_gpr_a[r2], ctx->mem_idx,
4807                           MO_LEUW);
4808        tcg_gen_addi_tl(cpu_gpr_a[r2], cpu_gpr_a[r2], off10);
4809        tcg_temp_free(temp);
4810        break;
4811    case OPC2_32_BO_ST_Q_PREINC:
4812        temp = tcg_temp_new();
4813        tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 16);
4814        gen_st_preincr(ctx, temp, cpu_gpr_a[r2], off10, MO_LEUW);
4815        tcg_temp_free(temp);
4816        break;
4817    case