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