qemu/target-tricore/op_helper.c
<<
>>
Prefs
   1/*
   2 *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
   3 *
   4 * This library is free software; you can redistribute it and/or
   5 * modify it under the terms of the GNU Lesser General Public
   6 * License as published by the Free Software Foundation; either
   7 * version 2 of the License, or (at your option) any later version.
   8 *
   9 * This library is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12 * Lesser General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU Lesser General Public
  15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  16 */
  17#include "qemu/osdep.h"
  18#include "cpu.h"
  19#include "qemu/host-utils.h"
  20#include "exec/helper-proto.h"
  21#include "exec/cpu_ldst.h"
  22#include <zlib.h> /* for crc32 */
  23
  24
  25/* Exception helpers */
  26
  27static void QEMU_NORETURN
  28raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin,
  29                              uintptr_t pc, uint32_t fcd_pc)
  30{
  31    CPUState *cs = CPU(tricore_env_get_cpu(env));
  32    /* in case we come from a helper-call we need to restore the PC */
  33    if (pc) {
  34        cpu_restore_state(cs, pc);
  35    }
  36
  37    /* Tin is loaded into d[15] */
  38    env->gpr_d[15] = tin;
  39
  40    if (class == TRAPC_CTX_MNG && tin == TIN3_FCU) {
  41        /* upper context cannot be saved, if the context list is empty */
  42    } else {
  43        helper_svucx(env);
  44    }
  45
  46    /* The return address in a[11] is updated */
  47    if (class == TRAPC_CTX_MNG && tin == TIN3_FCD) {
  48        env->SYSCON |= MASK_SYSCON_FCD_SF;
  49        /* when we run out of CSAs after saving a context a FCD trap is taken
  50           and the return address is the start of the trap handler which used
  51           the last CSA */
  52        env->gpr_a[11] = fcd_pc;
  53    } else if (class == TRAPC_SYSCALL) {
  54        env->gpr_a[11] = env->PC + 4;
  55    } else {
  56        env->gpr_a[11] = env->PC;
  57    }
  58    /* The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP)
  59       when the processor was not previously using the interrupt stack
  60       (in case of PSW.IS = 0). The stack pointer bit is set for using the
  61       interrupt stack: PSW.IS = 1. */
  62    if ((env->PSW & MASK_PSW_IS) == 0) {
  63        env->gpr_a[10] = env->ISP;
  64    }
  65    env->PSW |= MASK_PSW_IS;
  66    /* The I/O mode is set to Supervisor mode, which means all permissions
  67       are enabled: PSW.IO = 10 B .*/
  68    env->PSW |= (2 << 10);
  69
  70    /*The current Protection Register Set is set to 0: PSW.PRS = 00 B .*/
  71    env->PSW &= ~MASK_PSW_PRS;
  72
  73    /* The Call Depth Counter (CDC) is cleared, and the call depth limit is
  74       set for 64: PSW.CDC = 0000000 B .*/
  75    env->PSW &= ~MASK_PSW_CDC;
  76
  77    /* Call Depth Counter is enabled, PSW.CDE = 1. */
  78    env->PSW |= MASK_PSW_CDE;
  79
  80    /* Write permission to global registers A[0], A[1], A[8], A[9] is
  81       disabled: PSW.GW = 0. */
  82    env->PSW &= ~MASK_PSW_GW;
  83
  84    /*The interrupt system is globally disabled: ICR.IE = 0. The ‘old’
  85      ICR.IE and ICR.CCPN are saved */
  86
  87    /* PCXI.PIE = ICR.IE */
  88    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
  89                ((env->ICR & MASK_ICR_IE) << 15));
  90    /* PCXI.PCPN = ICR.CCPN */
  91    env->PCXI = (env->PCXI & 0xffffff) +
  92                ((env->ICR & MASK_ICR_CCPN) << 24);
  93    /* Update PC using the trap vector table */
  94    env->PC = env->BTV | (class << 5);
  95
  96    cpu_loop_exit(cs);
  97}
  98
  99void helper_raise_exception_sync(CPUTriCoreState *env, uint32_t class,
 100                                 uint32_t tin)
 101{
 102    raise_exception_sync_internal(env, class, tin, 0, 0);
 103}
 104
 105static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class,
 106                                        uint32_t tin, uintptr_t pc)
 107{
 108    raise_exception_sync_internal(env, class, tin, pc, 0);
 109}
 110
 111/* Addressing mode helper */
 112
 113static uint16_t reverse16(uint16_t val)
 114{
 115    uint8_t high = (uint8_t)(val >> 8);
 116    uint8_t low  = (uint8_t)(val & 0xff);
 117
 118    uint16_t rh, rl;
 119
 120    rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
 121    rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
 122
 123    return (rh << 8) | rl;
 124}
 125
 126uint32_t helper_br_update(uint32_t reg)
 127{
 128    uint32_t index = reg & 0xffff;
 129    uint32_t incr  = reg >> 16;
 130    uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
 131    return reg - index + new_index;
 132}
 133
 134uint32_t helper_circ_update(uint32_t reg, uint32_t off)
 135{
 136    uint32_t index = reg & 0xffff;
 137    uint32_t length = reg >> 16;
 138    int32_t new_index = index + off;
 139    if (new_index < 0) {
 140        new_index += length;
 141    } else {
 142        new_index %= length;
 143    }
 144    return reg - index + new_index;
 145}
 146
 147static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
 148{
 149    uint32_t ret;
 150    int64_t max_pos = INT32_MAX;
 151    int64_t max_neg = INT32_MIN;
 152    if (arg > max_pos) {
 153        env->PSW_USB_V = (1 << 31);
 154        env->PSW_USB_SV = (1 << 31);
 155        ret = (target_ulong)max_pos;
 156    } else {
 157        if (arg < max_neg) {
 158            env->PSW_USB_V = (1 << 31);
 159            env->PSW_USB_SV = (1 << 31);
 160            ret = (target_ulong)max_neg;
 161        } else {
 162            env->PSW_USB_V = 0;
 163            ret = (target_ulong)arg;
 164        }
 165    }
 166    env->PSW_USB_AV = arg ^ arg * 2u;
 167    env->PSW_USB_SAV |= env->PSW_USB_AV;
 168    return ret;
 169}
 170
 171static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg)
 172{
 173    uint32_t ret;
 174    uint64_t max_pos = UINT32_MAX;
 175    if (arg > max_pos) {
 176        env->PSW_USB_V = (1 << 31);
 177        env->PSW_USB_SV = (1 << 31);
 178        ret = (target_ulong)max_pos;
 179    } else {
 180        env->PSW_USB_V = 0;
 181        ret = (target_ulong)arg;
 182     }
 183    env->PSW_USB_AV = arg ^ arg * 2u;
 184    env->PSW_USB_SAV |= env->PSW_USB_AV;
 185    return ret;
 186}
 187
 188static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg)
 189{
 190    uint32_t ret;
 191
 192    if (arg < 0) {
 193        env->PSW_USB_V = (1 << 31);
 194        env->PSW_USB_SV = (1 << 31);
 195        ret = 0;
 196    } else {
 197        env->PSW_USB_V = 0;
 198        ret = (target_ulong)arg;
 199    }
 200    env->PSW_USB_AV = arg ^ arg * 2u;
 201    env->PSW_USB_SAV |= env->PSW_USB_AV;
 202    return ret;
 203}
 204
 205static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
 206{
 207    int32_t max_pos = INT16_MAX;
 208    int32_t max_neg = INT16_MIN;
 209    int32_t av0, av1;
 210
 211    env->PSW_USB_V = 0;
 212    av0 = hw0 ^ hw0 * 2u;
 213    if (hw0 > max_pos) {
 214        env->PSW_USB_V = (1 << 31);
 215        hw0 = max_pos;
 216    } else if (hw0 < max_neg) {
 217        env->PSW_USB_V = (1 << 31);
 218        hw0 = max_neg;
 219    }
 220
 221    av1 = hw1 ^ hw1 * 2u;
 222    if (hw1 > max_pos) {
 223        env->PSW_USB_V = (1 << 31);
 224        hw1 = max_pos;
 225    } else if (hw1 < max_neg) {
 226        env->PSW_USB_V = (1 << 31);
 227        hw1 = max_neg;
 228    }
 229
 230    env->PSW_USB_SV |= env->PSW_USB_V;
 231    env->PSW_USB_AV = (av0 | av1) << 16;
 232    env->PSW_USB_SAV |= env->PSW_USB_AV;
 233    return (hw0 & 0xffff) | (hw1 << 16);
 234}
 235
 236static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
 237{
 238    int32_t max_pos = UINT16_MAX;
 239    int32_t av0, av1;
 240
 241    env->PSW_USB_V = 0;
 242    av0 = hw0 ^ hw0 * 2u;
 243    if (hw0 > max_pos) {
 244        env->PSW_USB_V = (1 << 31);
 245        hw0 = max_pos;
 246    } else if (hw0 < 0) {
 247        env->PSW_USB_V = (1 << 31);
 248        hw0 = 0;
 249    }
 250
 251    av1 = hw1 ^ hw1 * 2u;
 252    if (hw1 > max_pos) {
 253        env->PSW_USB_V = (1 << 31);
 254        hw1 = max_pos;
 255    } else if (hw1 < 0) {
 256        env->PSW_USB_V = (1 << 31);
 257        hw1 = 0;
 258    }
 259
 260    env->PSW_USB_SV |= env->PSW_USB_V;
 261    env->PSW_USB_AV = (av0 | av1) << 16;
 262    env->PSW_USB_SAV |= env->PSW_USB_AV;
 263    return (hw0 & 0xffff) | (hw1 << 16);
 264}
 265
 266target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
 267                             target_ulong r2)
 268{
 269    int64_t t1 = sextract64(r1, 0, 32);
 270    int64_t t2 = sextract64(r2, 0, 32);
 271    int64_t result = t1 + t2;
 272    return ssov32(env, result);
 273}
 274
 275uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
 276{
 277    uint64_t result;
 278    int64_t ovf;
 279
 280    result = r1 + r2;
 281    ovf = (result ^ r1) & ~(r1 ^ r2);
 282    env->PSW_USB_AV = (result ^ result * 2u) >> 32;
 283    env->PSW_USB_SAV |= env->PSW_USB_AV;
 284    if (ovf < 0) {
 285        env->PSW_USB_V = (1 << 31);
 286        env->PSW_USB_SV = (1 << 31);
 287        /* ext_ret > MAX_INT */
 288        if ((int64_t)r1 >= 0) {
 289            result = INT64_MAX;
 290        /* ext_ret < MIN_INT */
 291        } else {
 292            result = INT64_MIN;
 293        }
 294    } else {
 295        env->PSW_USB_V = 0;
 296    }
 297    return result;
 298}
 299
 300target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
 301                               target_ulong r2)
 302{
 303    int32_t ret_hw0, ret_hw1;
 304
 305    ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
 306    ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
 307    return ssov16(env, ret_hw0, ret_hw1);
 308}
 309
 310uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 311                            uint32_t r2_h)
 312{
 313    int64_t mul_res0 = sextract64(r1, 0, 32);
 314    int64_t mul_res1 = sextract64(r1, 32, 32);
 315    int64_t r2_low = sextract64(r2_l, 0, 32);
 316    int64_t r2_high = sextract64(r2_h, 0, 32);
 317    int64_t result0, result1;
 318    uint32_t ovf0, ovf1;
 319    uint32_t avf0, avf1;
 320
 321    ovf0 = ovf1 = 0;
 322
 323    result0 = r2_low + mul_res0 + 0x8000;
 324    result1 = r2_high + mul_res1 + 0x8000;
 325
 326    avf0 = result0 * 2u;
 327    avf0 = result0 ^ avf0;
 328    avf1 = result1 * 2u;
 329    avf1 = result1 ^ avf1;
 330
 331    if (result0 > INT32_MAX) {
 332        ovf0 = (1 << 31);
 333        result0 = INT32_MAX;
 334    } else if (result0 < INT32_MIN) {
 335        ovf0 = (1 << 31);
 336        result0 = INT32_MIN;
 337    }
 338
 339    if (result1 > INT32_MAX) {
 340        ovf1 = (1 << 31);
 341        result1 = INT32_MAX;
 342    } else if (result1 < INT32_MIN) {
 343        ovf1 = (1 << 31);
 344        result1 = INT32_MIN;
 345    }
 346
 347    env->PSW_USB_V = ovf0 | ovf1;
 348    env->PSW_USB_SV |= env->PSW_USB_V;
 349
 350    env->PSW_USB_AV = avf0 | avf1;
 351    env->PSW_USB_SAV |= env->PSW_USB_AV;
 352
 353    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 354}
 355
 356uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 357                              uint32_t r2_h)
 358{
 359    int64_t mul_res0 = sextract64(r1, 0, 32);
 360    int64_t mul_res1 = sextract64(r1, 32, 32);
 361    int64_t r2_low = sextract64(r2_l, 0, 32);
 362    int64_t r2_high = sextract64(r2_h, 0, 32);
 363    int64_t result0, result1;
 364    uint32_t ovf0, ovf1;
 365    uint32_t avf0, avf1;
 366
 367    ovf0 = ovf1 = 0;
 368
 369    result0 = r2_low - mul_res0 + 0x8000;
 370    result1 = r2_high + mul_res1 + 0x8000;
 371
 372    avf0 = result0 * 2u;
 373    avf0 = result0 ^ avf0;
 374    avf1 = result1 * 2u;
 375    avf1 = result1 ^ avf1;
 376
 377    if (result0 > INT32_MAX) {
 378        ovf0 = (1 << 31);
 379        result0 = INT32_MAX;
 380    } else if (result0 < INT32_MIN) {
 381        ovf0 = (1 << 31);
 382        result0 = INT32_MIN;
 383    }
 384
 385    if (result1 > INT32_MAX) {
 386        ovf1 = (1 << 31);
 387        result1 = INT32_MAX;
 388    } else if (result1 < INT32_MIN) {
 389        ovf1 = (1 << 31);
 390        result1 = INT32_MIN;
 391    }
 392
 393    env->PSW_USB_V = ovf0 | ovf1;
 394    env->PSW_USB_SV |= env->PSW_USB_V;
 395
 396    env->PSW_USB_AV = avf0 | avf1;
 397    env->PSW_USB_SAV |= env->PSW_USB_AV;
 398
 399    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 400}
 401
 402
 403target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
 404                             target_ulong r2)
 405{
 406    int64_t t1 = extract64(r1, 0, 32);
 407    int64_t t2 = extract64(r2, 0, 32);
 408    int64_t result = t1 + t2;
 409    return suov32_pos(env, result);
 410}
 411
 412target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
 413                               target_ulong r2)
 414{
 415    int32_t ret_hw0, ret_hw1;
 416
 417    ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
 418    ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
 419    return suov16(env, ret_hw0, ret_hw1);
 420}
 421
 422target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
 423                             target_ulong r2)
 424{
 425    int64_t t1 = sextract64(r1, 0, 32);
 426    int64_t t2 = sextract64(r2, 0, 32);
 427    int64_t result = t1 - t2;
 428    return ssov32(env, result);
 429}
 430
 431uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
 432{
 433    uint64_t result;
 434    int64_t ovf;
 435
 436    result = r1 - r2;
 437    ovf = (result ^ r1) & (r1 ^ r2);
 438    env->PSW_USB_AV = (result ^ result * 2u) >> 32;
 439    env->PSW_USB_SAV |= env->PSW_USB_AV;
 440    if (ovf < 0) {
 441        env->PSW_USB_V = (1 << 31);
 442        env->PSW_USB_SV = (1 << 31);
 443        /* ext_ret > MAX_INT */
 444        if ((int64_t)r1 >= 0) {
 445            result = INT64_MAX;
 446        /* ext_ret < MIN_INT */
 447        } else {
 448            result = INT64_MIN;
 449        }
 450    } else {
 451        env->PSW_USB_V = 0;
 452    }
 453    return result;
 454}
 455
 456target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
 457                             target_ulong r2)
 458{
 459    int32_t ret_hw0, ret_hw1;
 460
 461    ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
 462    ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
 463    return ssov16(env, ret_hw0, ret_hw1);
 464}
 465
 466uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 467                            uint32_t r2_h)
 468{
 469    int64_t mul_res0 = sextract64(r1, 0, 32);
 470    int64_t mul_res1 = sextract64(r1, 32, 32);
 471    int64_t r2_low = sextract64(r2_l, 0, 32);
 472    int64_t r2_high = sextract64(r2_h, 0, 32);
 473    int64_t result0, result1;
 474    uint32_t ovf0, ovf1;
 475    uint32_t avf0, avf1;
 476
 477    ovf0 = ovf1 = 0;
 478
 479    result0 = r2_low - mul_res0 + 0x8000;
 480    result1 = r2_high - mul_res1 + 0x8000;
 481
 482    avf0 = result0 * 2u;
 483    avf0 = result0 ^ avf0;
 484    avf1 = result1 * 2u;
 485    avf1 = result1 ^ avf1;
 486
 487    if (result0 > INT32_MAX) {
 488        ovf0 = (1 << 31);
 489        result0 = INT32_MAX;
 490    } else if (result0 < INT32_MIN) {
 491        ovf0 = (1 << 31);
 492        result0 = INT32_MIN;
 493    }
 494
 495    if (result1 > INT32_MAX) {
 496        ovf1 = (1 << 31);
 497        result1 = INT32_MAX;
 498    } else if (result1 < INT32_MIN) {
 499        ovf1 = (1 << 31);
 500        result1 = INT32_MIN;
 501    }
 502
 503    env->PSW_USB_V = ovf0 | ovf1;
 504    env->PSW_USB_SV |= env->PSW_USB_V;
 505
 506    env->PSW_USB_AV = avf0 | avf1;
 507    env->PSW_USB_SAV |= env->PSW_USB_AV;
 508
 509    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 510}
 511
 512uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
 513                              uint32_t r2_h)
 514{
 515    int64_t mul_res0 = sextract64(r1, 0, 32);
 516    int64_t mul_res1 = sextract64(r1, 32, 32);
 517    int64_t r2_low = sextract64(r2_l, 0, 32);
 518    int64_t r2_high = sextract64(r2_h, 0, 32);
 519    int64_t result0, result1;
 520    uint32_t ovf0, ovf1;
 521    uint32_t avf0, avf1;
 522
 523    ovf0 = ovf1 = 0;
 524
 525    result0 = r2_low + mul_res0 + 0x8000;
 526    result1 = r2_high - mul_res1 + 0x8000;
 527
 528    avf0 = result0 * 2u;
 529    avf0 = result0 ^ avf0;
 530    avf1 = result1 * 2u;
 531    avf1 = result1 ^ avf1;
 532
 533    if (result0 > INT32_MAX) {
 534        ovf0 = (1 << 31);
 535        result0 = INT32_MAX;
 536    } else if (result0 < INT32_MIN) {
 537        ovf0 = (1 << 31);
 538        result0 = INT32_MIN;
 539    }
 540
 541    if (result1 > INT32_MAX) {
 542        ovf1 = (1 << 31);
 543        result1 = INT32_MAX;
 544    } else if (result1 < INT32_MIN) {
 545        ovf1 = (1 << 31);
 546        result1 = INT32_MIN;
 547    }
 548
 549    env->PSW_USB_V = ovf0 | ovf1;
 550    env->PSW_USB_SV |= env->PSW_USB_V;
 551
 552    env->PSW_USB_AV = avf0 | avf1;
 553    env->PSW_USB_SAV |= env->PSW_USB_AV;
 554
 555    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
 556}
 557
 558target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
 559                             target_ulong r2)
 560{
 561    int64_t t1 = extract64(r1, 0, 32);
 562    int64_t t2 = extract64(r2, 0, 32);
 563    int64_t result = t1 - t2;
 564    return suov32_neg(env, result);
 565}
 566
 567target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
 568                               target_ulong r2)
 569{
 570    int32_t ret_hw0, ret_hw1;
 571
 572    ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
 573    ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
 574    return suov16(env, ret_hw0, ret_hw1);
 575}
 576
 577target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
 578                             target_ulong r2)
 579{
 580    int64_t t1 = sextract64(r1, 0, 32);
 581    int64_t t2 = sextract64(r2, 0, 32);
 582    int64_t result = t1 * t2;
 583    return ssov32(env, result);
 584}
 585
 586target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
 587                             target_ulong r2)
 588{
 589    int64_t t1 = extract64(r1, 0, 32);
 590    int64_t t2 = extract64(r2, 0, 32);
 591    int64_t result = t1 * t2;
 592
 593    return suov32_pos(env, result);
 594}
 595
 596target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
 597                             target_ulong r2)
 598{
 599    int64_t t1 = sextract64(r1, 0, 32);
 600    int32_t t2 = sextract64(r2, 0, 6);
 601    int64_t result;
 602    if (t2 == 0) {
 603        result = t1;
 604    } else if (t2 > 0) {
 605        result = t1 << t2;
 606    } else {
 607        result = t1 >> -t2;
 608    }
 609    return ssov32(env, result);
 610}
 611
 612uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
 613{
 614    target_ulong result;
 615    result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
 616    return ssov32(env, result);
 617}
 618
 619uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
 620{
 621    int32_t ret_h0, ret_h1;
 622
 623    ret_h0 = sextract32(r1, 0, 16);
 624    ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
 625
 626    ret_h1 = sextract32(r1, 16, 16);
 627    ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
 628
 629    return ssov16(env, ret_h0, ret_h1);
 630}
 631
 632target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
 633                                target_ulong r2)
 634{
 635    int64_t t1 = sextract64(r1, 0, 32);
 636    int64_t t2 = sextract64(r2, 0, 32);
 637    int64_t result;
 638
 639    if (t1 > t2) {
 640        result = t1 - t2;
 641    } else {
 642        result = t2 - t1;
 643    }
 644    return ssov32(env, result);
 645}
 646
 647uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
 648                              target_ulong r2)
 649{
 650    int32_t t1, t2;
 651    int32_t ret_h0, ret_h1;
 652
 653    t1 = sextract32(r1, 0, 16);
 654    t2 = sextract32(r2, 0, 16);
 655    if (t1 > t2) {
 656        ret_h0 = t1 - t2;
 657    } else {
 658        ret_h0 = t2 - t1;
 659    }
 660
 661    t1 = sextract32(r1, 16, 16);
 662    t2 = sextract32(r2, 16, 16);
 663    if (t1 > t2) {
 664        ret_h1 = t1 - t2;
 665    } else {
 666        ret_h1 = t2 - t1;
 667    }
 668
 669    return ssov16(env, ret_h0, ret_h1);
 670}
 671
 672target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
 673                                target_ulong r2, target_ulong r3)
 674{
 675    int64_t t1 = sextract64(r1, 0, 32);
 676    int64_t t2 = sextract64(r2, 0, 32);
 677    int64_t t3 = sextract64(r3, 0, 32);
 678    int64_t result;
 679
 680    result = t2 + (t1 * t3);
 681    return ssov32(env, result);
 682}
 683
 684target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
 685                                target_ulong r2, target_ulong r3)
 686{
 687    uint64_t t1 = extract64(r1, 0, 32);
 688    uint64_t t2 = extract64(r2, 0, 32);
 689    uint64_t t3 = extract64(r3, 0, 32);
 690    int64_t result;
 691
 692    result = t2 + (t1 * t3);
 693    return suov32_pos(env, result);
 694}
 695
 696uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
 697                            uint64_t r2, target_ulong r3)
 698{
 699    uint64_t ret, ovf;
 700    int64_t t1 = sextract64(r1, 0, 32);
 701    int64_t t3 = sextract64(r3, 0, 32);
 702    int64_t mul;
 703
 704    mul = t1 * t3;
 705    ret = mul + r2;
 706    ovf = (ret ^ mul) & ~(mul ^ r2);
 707
 708    t1 = ret >> 32;
 709    env->PSW_USB_AV = t1 ^ t1 * 2u;
 710    env->PSW_USB_SAV |= env->PSW_USB_AV;
 711
 712    if ((int64_t)ovf < 0) {
 713        env->PSW_USB_V = (1 << 31);
 714        env->PSW_USB_SV = (1 << 31);
 715        /* ext_ret > MAX_INT */
 716        if (mul >= 0) {
 717            ret = INT64_MAX;
 718        /* ext_ret < MIN_INT */
 719        } else {
 720            ret = INT64_MIN;
 721        }
 722    } else {
 723        env->PSW_USB_V = 0;
 724    }
 725
 726    return ret;
 727}
 728
 729uint32_t
 730helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
 731{
 732    int64_t result;
 733
 734    result = (r1 + r2);
 735
 736    env->PSW_USB_AV = (result ^ result * 2u);
 737    env->PSW_USB_SAV |= env->PSW_USB_AV;
 738
 739    /* we do the saturation by hand, since we produce an overflow on the host
 740       if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
 741       case, we flip the saturated value. */
 742    if (r2 == 0x8000000000000000LL) {
 743        if (result > 0x7fffffffLL) {
 744            env->PSW_USB_V = (1 << 31);
 745            env->PSW_USB_SV = (1 << 31);
 746            result = INT32_MIN;
 747        } else if (result < -0x80000000LL) {
 748            env->PSW_USB_V = (1 << 31);
 749            env->PSW_USB_SV = (1 << 31);
 750            result = INT32_MAX;
 751        } else {
 752            env->PSW_USB_V = 0;
 753        }
 754    } else {
 755        if (result > 0x7fffffffLL) {
 756            env->PSW_USB_V = (1 << 31);
 757            env->PSW_USB_SV = (1 << 31);
 758            result = INT32_MAX;
 759        } else if (result < -0x80000000LL) {
 760            env->PSW_USB_V = (1 << 31);
 761            env->PSW_USB_SV = (1 << 31);
 762            result = INT32_MIN;
 763        } else {
 764            env->PSW_USB_V = 0;
 765        }
 766    }
 767    return (uint32_t)result;
 768}
 769
 770uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
 771                              uint32_t r3, uint32_t n)
 772{
 773    int64_t t1 = (int64_t)r1;
 774    int64_t t2 = sextract64(r2, 0, 32);
 775    int64_t t3 = sextract64(r3, 0, 32);
 776    int64_t result, mul;
 777    int64_t ovf;
 778
 779    mul = (t2 * t3) << n;
 780    result = mul + t1;
 781
 782    env->PSW_USB_AV = (result ^ result * 2u) >> 32;
 783    env->PSW_USB_SAV |= env->PSW_USB_AV;
 784
 785    ovf = (result ^ mul) & ~(mul ^ t1);
 786    /* we do the saturation by hand, since we produce an overflow on the host
 787       if the mul was (0x80000000 * 0x80000000) << 1). If this is the
 788       case, we flip the saturated value. */
 789    if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) {
 790        if (ovf >= 0) {
 791            env->PSW_USB_V = (1 << 31);
 792            env->PSW_USB_SV = (1 << 31);
 793            /* ext_ret > MAX_INT */
 794            if (mul < 0) {
 795                result = INT64_MAX;
 796            /* ext_ret < MIN_INT */
 797            } else {
 798               result = INT64_MIN;
 799            }
 800        } else {
 801            env->PSW_USB_V = 0;
 802        }
 803    } else {
 804        if (ovf < 0) {
 805            env->PSW_USB_V = (1 << 31);
 806            env->PSW_USB_SV = (1 << 31);
 807            /* ext_ret > MAX_INT */
 808            if (mul >= 0) {
 809                result = INT64_MAX;
 810            /* ext_ret < MIN_INT */
 811            } else {
 812               result = INT64_MIN;
 813            }
 814        } else {
 815            env->PSW_USB_V = 0;
 816        }
 817    }
 818    return (uint64_t)result;
 819}
 820
 821uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
 822                             uint32_t r3, uint32_t n)
 823{
 824    int64_t t1 = sextract64(r1, 0, 32);
 825    int64_t t2 = sextract64(r2, 0, 32);
 826    int64_t t3 = sextract64(r3, 0, 32);
 827    int64_t mul, ret;
 828
 829    if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
 830        mul = 0x7fffffff;
 831    } else {
 832        mul = (t2 * t3) << n;
 833    }
 834
 835    ret = t1 + mul + 0x8000;
 836
 837    env->PSW_USB_AV = ret ^ ret * 2u;
 838    env->PSW_USB_SAV |= env->PSW_USB_AV;
 839
 840    if (ret > 0x7fffffffll) {
 841        env->PSW_USB_V = (1 << 31);
 842        env->PSW_USB_SV |= env->PSW_USB_V;
 843        ret = INT32_MAX;
 844    } else if (ret < -0x80000000ll) {
 845        env->PSW_USB_V = (1 << 31);
 846        env->PSW_USB_SV |= env->PSW_USB_V;
 847        ret = INT32_MIN;
 848    } else {
 849        env->PSW_USB_V = 0;
 850    }
 851    return ret & 0xffff0000ll;
 852}
 853
 854uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
 855                            uint64_t r2, target_ulong r3)
 856{
 857    uint64_t ret, mul;
 858    uint64_t t1 = extract64(r1, 0, 32);
 859    uint64_t t3 = extract64(r3, 0, 32);
 860
 861    mul = t1 * t3;
 862    ret = mul + r2;
 863
 864    t1 = ret >> 32;
 865    env->PSW_USB_AV = t1 ^ t1 * 2u;
 866    env->PSW_USB_SAV |= env->PSW_USB_AV;
 867
 868    if (ret < r2) {
 869        env->PSW_USB_V = (1 << 31);
 870        env->PSW_USB_SV = (1 << 31);
 871        /* saturate */
 872        ret = UINT64_MAX;
 873    } else {
 874        env->PSW_USB_V = 0;
 875    }
 876    return ret;
 877}
 878
 879target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
 880                                target_ulong r2, target_ulong r3)
 881{
 882    int64_t t1 = sextract64(r1, 0, 32);
 883    int64_t t2 = sextract64(r2, 0, 32);
 884    int64_t t3 = sextract64(r3, 0, 32);
 885    int64_t result;
 886
 887    result = t2 - (t1 * t3);
 888    return ssov32(env, result);
 889}
 890
 891target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
 892                                target_ulong r2, target_ulong r3)
 893{
 894    uint64_t t1 = extract64(r1, 0, 32);
 895    uint64_t t2 = extract64(r2, 0, 32);
 896    uint64_t t3 = extract64(r3, 0, 32);
 897    uint64_t result;
 898    uint64_t mul;
 899
 900    mul = (t1 * t3);
 901    result = t2 - mul;
 902
 903    env->PSW_USB_AV = result ^ result * 2u;
 904    env->PSW_USB_SAV |= env->PSW_USB_AV;
 905    /* we calculate ovf by hand here, because the multiplication can overflow on
 906       the host, which would give false results if we compare to less than
 907       zero */
 908    if (mul > t2) {
 909        env->PSW_USB_V = (1 << 31);
 910        env->PSW_USB_SV = (1 << 31);
 911        result = 0;
 912    } else {
 913        env->PSW_USB_V = 0;
 914    }
 915    return result;
 916}
 917
 918uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
 919                            uint64_t r2, target_ulong r3)
 920{
 921    uint64_t ret, ovf;
 922    int64_t t1 = sextract64(r1, 0, 32);
 923    int64_t t3 = sextract64(r3, 0, 32);
 924    int64_t mul;
 925
 926    mul = t1 * t3;
 927    ret = r2 - mul;
 928    ovf = (ret ^ r2) & (mul ^ r2);
 929
 930    t1 = ret >> 32;
 931    env->PSW_USB_AV = t1 ^ t1 * 2u;
 932    env->PSW_USB_SAV |= env->PSW_USB_AV;
 933
 934    if ((int64_t)ovf < 0) {
 935        env->PSW_USB_V = (1 << 31);
 936        env->PSW_USB_SV = (1 << 31);
 937        /* ext_ret > MAX_INT */
 938        if (mul < 0) {
 939            ret = INT64_MAX;
 940        /* ext_ret < MIN_INT */
 941        } else {
 942            ret = INT64_MIN;
 943        }
 944    } else {
 945        env->PSW_USB_V = 0;
 946    }
 947    return ret;
 948}
 949
 950uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
 951                            uint64_t r2, target_ulong r3)
 952{
 953    uint64_t ret, mul;
 954    uint64_t t1 = extract64(r1, 0, 32);
 955    uint64_t t3 = extract64(r3, 0, 32);
 956
 957    mul = t1 * t3;
 958    ret = r2 - mul;
 959
 960    t1 = ret >> 32;
 961    env->PSW_USB_AV = t1 ^ t1 * 2u;
 962    env->PSW_USB_SAV |= env->PSW_USB_AV;
 963
 964    if (ret > r2) {
 965        env->PSW_USB_V = (1 << 31);
 966        env->PSW_USB_SV = (1 << 31);
 967        /* saturate */
 968        ret = 0;
 969    } else {
 970        env->PSW_USB_V = 0;
 971    }
 972    return ret;
 973}
 974
 975uint32_t
 976helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
 977{
 978    int64_t result;
 979    int64_t t1 = (int64_t)r1;
 980    int64_t t2 = (int64_t)r2;
 981
 982    result = t1 - t2;
 983
 984    env->PSW_USB_AV = (result ^ result * 2u);
 985    env->PSW_USB_SAV |= env->PSW_USB_AV;
 986
 987    /* we do the saturation by hand, since we produce an overflow on the host
 988       if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
 989       case, we flip the saturated value. */
 990    if (r2 == 0x8000000000000000LL) {
 991        if (result > 0x7fffffffLL) {
 992            env->PSW_USB_V = (1 << 31);
 993            env->PSW_USB_SV = (1 << 31);
 994            result = INT32_MIN;
 995        } else if (result < -0x80000000LL) {
 996            env->PSW_USB_V = (1 << 31);
 997            env->PSW_USB_SV = (1 << 31);
 998            result = INT32_MAX;
 999        } else {
1000            env->PSW_USB_V = 0;
1001        }
1002    } else {
1003        if (result > 0x7fffffffLL) {
1004            env->PSW_USB_V = (1 << 31);
1005            env->PSW_USB_SV = (1 << 31);
1006            result = INT32_MAX;
1007        } else if (result < -0x80000000LL) {
1008            env->PSW_USB_V = (1 << 31);
1009            env->PSW_USB_SV = (1 << 31);
1010            result = INT32_MIN;
1011        } else {
1012            env->PSW_USB_V = 0;
1013        }
1014    }
1015    return (uint32_t)result;
1016}
1017
1018uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
1019                              uint32_t r3, uint32_t n)
1020{
1021    int64_t t1 = (int64_t)r1;
1022    int64_t t2 = sextract64(r2, 0, 32);
1023    int64_t t3 = sextract64(r3, 0, 32);
1024    int64_t result, mul;
1025    int64_t ovf;
1026
1027    mul = (t2 * t3) << n;
1028    result = t1 - mul;
1029
1030    env->PSW_USB_AV = (result ^ result * 2u) >> 32;
1031    env->PSW_USB_SAV |= env->PSW_USB_AV;
1032
1033    ovf = (result ^ t1) & (t1 ^ mul);
1034    /* we do the saturation by hand, since we produce an overflow on the host
1035       if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
1036       case, we flip the saturated value. */
1037    if (mul == 0x8000000000000000LL) {
1038        if (ovf >= 0) {
1039            env->PSW_USB_V = (1 << 31);
1040            env->PSW_USB_SV = (1 << 31);
1041            /* ext_ret > MAX_INT */
1042            if (mul >= 0) {
1043                result = INT64_MAX;
1044            /* ext_ret < MIN_INT */
1045            } else {
1046               result = INT64_MIN;
1047            }
1048        } else {
1049            env->PSW_USB_V = 0;
1050        }
1051    } else {
1052        if (ovf < 0) {
1053            env->PSW_USB_V = (1 << 31);
1054            env->PSW_USB_SV = (1 << 31);
1055            /* ext_ret > MAX_INT */
1056            if (mul < 0) {
1057                result = INT64_MAX;
1058            /* ext_ret < MIN_INT */
1059            } else {
1060               result = INT64_MIN;
1061            }
1062        } else {
1063            env->PSW_USB_V = 0;
1064        }
1065    }
1066
1067    return (uint64_t)result;
1068}
1069
1070uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1071                             uint32_t r3, uint32_t n)
1072{
1073    int64_t t1 = sextract64(r1, 0, 32);
1074    int64_t t2 = sextract64(r2, 0, 32);
1075    int64_t t3 = sextract64(r3, 0, 32);
1076    int64_t mul, ret;
1077
1078    if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1079        mul = 0x7fffffff;
1080    } else {
1081        mul = (t2 * t3) << n;
1082    }
1083
1084    ret = t1 - mul + 0x8000;
1085
1086    env->PSW_USB_AV = ret ^ ret * 2u;
1087    env->PSW_USB_SAV |= env->PSW_USB_AV;
1088
1089    if (ret > 0x7fffffffll) {
1090        env->PSW_USB_V = (1 << 31);
1091        env->PSW_USB_SV |= env->PSW_USB_V;
1092        ret = INT32_MAX;
1093    } else if (ret < -0x80000000ll) {
1094        env->PSW_USB_V = (1 << 31);
1095        env->PSW_USB_SV |= env->PSW_USB_V;
1096        ret = INT32_MIN;
1097    } else {
1098        env->PSW_USB_V = 0;
1099    }
1100    return ret & 0xffff0000ll;
1101}
1102
1103uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
1104{
1105    int32_t b, i;
1106    int32_t ovf = 0;
1107    int32_t avf = 0;
1108    int32_t ret = 0;
1109
1110    for (i = 0; i < 4; i++) {
1111        b = sextract32(arg, i * 8, 8);
1112        b = (b >= 0) ? b : (0 - b);
1113        ovf |= (b > 0x7F) || (b < -0x80);
1114        avf |= b ^ b * 2u;
1115        ret |= (b & 0xff) << (i * 8);
1116    }
1117
1118    env->PSW_USB_V = ovf << 31;
1119    env->PSW_USB_SV |= env->PSW_USB_V;
1120    env->PSW_USB_AV = avf << 24;
1121    env->PSW_USB_SAV |= env->PSW_USB_AV;
1122
1123    return ret;
1124}
1125
1126uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
1127{
1128    int32_t h, i;
1129    int32_t ovf = 0;
1130    int32_t avf = 0;
1131    int32_t ret = 0;
1132
1133    for (i = 0; i < 2; i++) {
1134        h = sextract32(arg, i * 16, 16);
1135        h = (h >= 0) ? h : (0 - h);
1136        ovf |= (h > 0x7FFF) || (h < -0x8000);
1137        avf |= h ^ h * 2u;
1138        ret |= (h & 0xffff) << (i * 16);
1139    }
1140
1141    env->PSW_USB_V = ovf << 31;
1142    env->PSW_USB_SV |= env->PSW_USB_V;
1143    env->PSW_USB_AV = avf << 16;
1144    env->PSW_USB_SAV |= env->PSW_USB_AV;
1145
1146    return ret;
1147}
1148
1149uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1150{
1151    int32_t b, i;
1152    int32_t extr_r2;
1153    int32_t ovf = 0;
1154    int32_t avf = 0;
1155    int32_t ret = 0;
1156
1157    for (i = 0; i < 4; i++) {
1158        extr_r2 = sextract32(r2, i * 8, 8);
1159        b = sextract32(r1, i * 8, 8);
1160        b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
1161        ovf |= (b > 0x7F) || (b < -0x80);
1162        avf |= b ^ b * 2u;
1163        ret |= (b & 0xff) << (i * 8);
1164    }
1165
1166    env->PSW_USB_V = ovf << 31;
1167    env->PSW_USB_SV |= env->PSW_USB_V;
1168    env->PSW_USB_AV = avf << 24;
1169    env->PSW_USB_SAV |= env->PSW_USB_AV;
1170    return ret;
1171}
1172
1173uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1174{
1175    int32_t h, i;
1176    int32_t extr_r2;
1177    int32_t ovf = 0;
1178    int32_t avf = 0;
1179    int32_t ret = 0;
1180
1181    for (i = 0; i < 2; i++) {
1182        extr_r2 = sextract32(r2, i * 16, 16);
1183        h = sextract32(r1, i * 16, 16);
1184        h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
1185        ovf |= (h > 0x7FFF) || (h < -0x8000);
1186        avf |= h ^ h * 2u;
1187        ret |= (h & 0xffff) << (i * 16);
1188    }
1189
1190    env->PSW_USB_V = ovf << 31;
1191    env->PSW_USB_SV |= env->PSW_USB_V;
1192    env->PSW_USB_AV = avf << 16;
1193    env->PSW_USB_SAV |= env->PSW_USB_AV;
1194
1195    return ret;
1196}
1197
1198uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1199                       uint32_t r2_h)
1200{
1201    int64_t mul_res0 = sextract64(r1, 0, 32);
1202    int64_t mul_res1 = sextract64(r1, 32, 32);
1203    int64_t r2_low = sextract64(r2_l, 0, 32);
1204    int64_t r2_high = sextract64(r2_h, 0, 32);
1205    int64_t result0, result1;
1206    uint32_t ovf0, ovf1;
1207    uint32_t avf0, avf1;
1208
1209    ovf0 = ovf1 = 0;
1210
1211    result0 = r2_low + mul_res0 + 0x8000;
1212    result1 = r2_high + mul_res1 + 0x8000;
1213
1214    if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1215        ovf0 = (1 << 31);
1216    }
1217
1218    if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1219        ovf1 = (1 << 31);
1220    }
1221
1222    env->PSW_USB_V = ovf0 | ovf1;
1223    env->PSW_USB_SV |= env->PSW_USB_V;
1224
1225    avf0 = result0 * 2u;
1226    avf0 = result0 ^ avf0;
1227    avf1 = result1 * 2u;
1228    avf1 = result1 ^ avf1;
1229
1230    env->PSW_USB_AV = avf0 | avf1;
1231    env->PSW_USB_SAV |= env->PSW_USB_AV;
1232
1233    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1234}
1235
1236uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1237                         uint32_t r2_h)
1238{
1239    int64_t mul_res0 = sextract64(r1, 0, 32);
1240    int64_t mul_res1 = sextract64(r1, 32, 32);
1241    int64_t r2_low = sextract64(r2_l, 0, 32);
1242    int64_t r2_high = sextract64(r2_h, 0, 32);
1243    int64_t result0, result1;
1244    uint32_t ovf0, ovf1;
1245    uint32_t avf0, avf1;
1246
1247    ovf0 = ovf1 = 0;
1248
1249    result0 = r2_low - mul_res0 + 0x8000;
1250    result1 = r2_high + mul_res1 + 0x8000;
1251
1252    if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1253        ovf0 = (1 << 31);
1254    }
1255
1256    if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1257        ovf1 = (1 << 31);
1258    }
1259
1260    env->PSW_USB_V = ovf0 | ovf1;
1261    env->PSW_USB_SV |= env->PSW_USB_V;
1262
1263    avf0 = result0 * 2u;
1264    avf0 = result0 ^ avf0;
1265    avf1 = result1 * 2u;
1266    avf1 = result1 ^ avf1;
1267
1268    env->PSW_USB_AV = avf0 | avf1;
1269    env->PSW_USB_SAV |= env->PSW_USB_AV;
1270
1271    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1272}
1273
1274uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1275                        uint32_t r3, uint32_t n)
1276{
1277    int64_t t1 = sextract64(r1, 0, 32);
1278    int64_t t2 = sextract64(r2, 0, 32);
1279    int64_t t3 = sextract64(r3, 0, 32);
1280    int64_t mul, ret;
1281
1282    if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1283        mul = 0x7fffffff;
1284    } else {
1285        mul = (t2 * t3) << n;
1286    }
1287
1288    ret = t1 + mul + 0x8000;
1289
1290    if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1291        env->PSW_USB_V = (1 << 31);
1292        env->PSW_USB_SV |= env->PSW_USB_V;
1293    } else {
1294        env->PSW_USB_V = 0;
1295    }
1296    env->PSW_USB_AV = ret ^ ret * 2u;
1297    env->PSW_USB_SAV |= env->PSW_USB_AV;
1298
1299    return ret & 0xffff0000ll;
1300}
1301
1302uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1303{
1304    int32_t b, i;
1305    int32_t extr_r1, extr_r2;
1306    int32_t ovf = 0;
1307    int32_t avf = 0;
1308    uint32_t ret = 0;
1309
1310    for (i = 0; i < 4; i++) {
1311        extr_r1 = sextract32(r1, i * 8, 8);
1312        extr_r2 = sextract32(r2, i * 8, 8);
1313
1314        b = extr_r1 + extr_r2;
1315        ovf |= ((b > 0x7f) || (b < -0x80));
1316        avf |= b ^ b * 2u;
1317        ret |= ((b & 0xff) << (i*8));
1318    }
1319
1320    env->PSW_USB_V = (ovf << 31);
1321    env->PSW_USB_SV |= env->PSW_USB_V;
1322    env->PSW_USB_AV = avf << 24;
1323    env->PSW_USB_SAV |= env->PSW_USB_AV;
1324
1325    return ret;
1326}
1327
1328uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1329{
1330    int32_t h, i;
1331    int32_t extr_r1, extr_r2;
1332    int32_t ovf = 0;
1333    int32_t avf = 0;
1334    int32_t ret = 0;
1335
1336    for (i = 0; i < 2; i++) {
1337        extr_r1 = sextract32(r1, i * 16, 16);
1338        extr_r2 = sextract32(r2, i * 16, 16);
1339        h = extr_r1 + extr_r2;
1340        ovf |= ((h > 0x7fff) || (h < -0x8000));
1341        avf |= h ^ h * 2u;
1342        ret |= (h & 0xffff) << (i * 16);
1343    }
1344
1345    env->PSW_USB_V = (ovf << 31);
1346    env->PSW_USB_SV |= env->PSW_USB_V;
1347    env->PSW_USB_AV = (avf << 16);
1348    env->PSW_USB_SAV |= env->PSW_USB_AV;
1349
1350    return ret;
1351}
1352
1353uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1354                       uint32_t r2_h)
1355{
1356    int64_t mul_res0 = sextract64(r1, 0, 32);
1357    int64_t mul_res1 = sextract64(r1, 32, 32);
1358    int64_t r2_low = sextract64(r2_l, 0, 32);
1359    int64_t r2_high = sextract64(r2_h, 0, 32);
1360    int64_t result0, result1;
1361    uint32_t ovf0, ovf1;
1362    uint32_t avf0, avf1;
1363
1364    ovf0 = ovf1 = 0;
1365
1366    result0 = r2_low - mul_res0 + 0x8000;
1367    result1 = r2_high - mul_res1 + 0x8000;
1368
1369    if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1370        ovf0 = (1 << 31);
1371    }
1372
1373    if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1374        ovf1 = (1 << 31);
1375    }
1376
1377    env->PSW_USB_V = ovf0 | ovf1;
1378    env->PSW_USB_SV |= env->PSW_USB_V;
1379
1380    avf0 = result0 * 2u;
1381    avf0 = result0 ^ avf0;
1382    avf1 = result1 * 2u;
1383    avf1 = result1 ^ avf1;
1384
1385    env->PSW_USB_AV = avf0 | avf1;
1386    env->PSW_USB_SAV |= env->PSW_USB_AV;
1387
1388    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1389}
1390
1391uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1392                         uint32_t r2_h)
1393{
1394    int64_t mul_res0 = sextract64(r1, 0, 32);
1395    int64_t mul_res1 = sextract64(r1, 32, 32);
1396    int64_t r2_low = sextract64(r2_l, 0, 32);
1397    int64_t r2_high = sextract64(r2_h, 0, 32);
1398    int64_t result0, result1;
1399    uint32_t ovf0, ovf1;
1400    uint32_t avf0, avf1;
1401
1402    ovf0 = ovf1 = 0;
1403
1404    result0 = r2_low + mul_res0 + 0x8000;
1405    result1 = r2_high - mul_res1 + 0x8000;
1406
1407    if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1408        ovf0 = (1 << 31);
1409    }
1410
1411    if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1412        ovf1 = (1 << 31);
1413    }
1414
1415    env->PSW_USB_V = ovf0 | ovf1;
1416    env->PSW_USB_SV |= env->PSW_USB_V;
1417
1418    avf0 = result0 * 2u;
1419    avf0 = result0 ^ avf0;
1420    avf1 = result1 * 2u;
1421    avf1 = result1 ^ avf1;
1422
1423    env->PSW_USB_AV = avf0 | avf1;
1424    env->PSW_USB_SAV |= env->PSW_USB_AV;
1425
1426    return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1427}
1428
1429uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1430                        uint32_t r3, uint32_t n)
1431{
1432    int64_t t1 = sextract64(r1, 0, 32);
1433    int64_t t2 = sextract64(r2, 0, 32);
1434    int64_t t3 = sextract64(r3, 0, 32);
1435    int64_t mul, ret;
1436
1437    if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1438        mul = 0x7fffffff;
1439    } else {
1440        mul = (t2 * t3) << n;
1441    }
1442
1443    ret = t1 - mul + 0x8000;
1444
1445    if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1446        env->PSW_USB_V = (1 << 31);
1447        env->PSW_USB_SV |= env->PSW_USB_V;
1448    } else {
1449        env->PSW_USB_V = 0;
1450    }
1451    env->PSW_USB_AV = ret ^ ret * 2u;
1452    env->PSW_USB_SAV |= env->PSW_USB_AV;
1453
1454    return ret & 0xffff0000ll;
1455}
1456
1457uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1458{
1459    int32_t b, i;
1460    int32_t extr_r1, extr_r2;
1461    int32_t ovf = 0;
1462    int32_t avf = 0;
1463    uint32_t ret = 0;
1464
1465    for (i = 0; i < 4; i++) {
1466        extr_r1 = sextract32(r1, i * 8, 8);
1467        extr_r2 = sextract32(r2, i * 8, 8);
1468
1469        b = extr_r1 - extr_r2;
1470        ovf |= ((b > 0x7f) || (b < -0x80));
1471        avf |= b ^ b * 2u;
1472        ret |= ((b & 0xff) << (i*8));
1473    }
1474
1475    env->PSW_USB_V = (ovf << 31);
1476    env->PSW_USB_SV |= env->PSW_USB_V;
1477    env->PSW_USB_AV = avf << 24;
1478    env->PSW_USB_SAV |= env->PSW_USB_AV;
1479
1480    return ret;
1481}
1482
1483uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1484{
1485    int32_t h, i;
1486    int32_t extr_r1, extr_r2;
1487    int32_t ovf = 0;
1488    int32_t avf = 0;
1489    int32_t ret = 0;
1490
1491    for (i = 0; i < 2; i++) {
1492        extr_r1 = sextract32(r1, i * 16, 16);
1493        extr_r2 = sextract32(r2, i * 16, 16);
1494        h = extr_r1 - extr_r2;
1495        ovf |= ((h > 0x7fff) || (h < -0x8000));
1496        avf |= h ^ h * 2u;
1497        ret |= (h & 0xffff) << (i * 16);
1498    }
1499
1500    env->PSW_USB_V = (ovf << 31);
1501    env->PSW_USB_SV |= env->PSW_USB_V;
1502    env->PSW_USB_AV = avf << 16;
1503    env->PSW_USB_SAV |= env->PSW_USB_AV;
1504
1505    return ret;
1506}
1507
1508uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
1509{
1510    int32_t ret;
1511    int32_t i, msk;
1512
1513    ret = 0;
1514    msk = 0xff;
1515    for (i = 0; i < 4; i++) {
1516        if ((r1 & msk) == (r2 & msk)) {
1517            ret |= msk;
1518        }
1519        msk = msk << 8;
1520    }
1521
1522    return ret;
1523}
1524
1525uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1526{
1527    int32_t ret = 0;
1528
1529    if ((r1 & 0xffff) == (r2 & 0xffff)) {
1530        ret = 0xffff;
1531    }
1532
1533    if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1534        ret |= 0xffff0000;
1535    }
1536
1537    return ret;
1538}
1539
1540uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1541{
1542    int32_t i;
1543    uint32_t ret = 0;
1544
1545    for (i = 0; i < 4; i++) {
1546        ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
1547    }
1548
1549    return ret;
1550}
1551
1552uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1553{
1554    uint32_t ret;
1555
1556    ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
1557    ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
1558
1559    return ret;
1560}
1561
1562uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1563{
1564    int32_t i;
1565    uint32_t ret = 0;
1566
1567    for (i = 0; i < 4; i++) {
1568        if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
1569            ret |= (0xff << (i * 8));
1570        }
1571    }
1572
1573    return ret;
1574}
1575
1576uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1577{
1578    int32_t i;
1579    uint32_t ret = 0;
1580
1581    for (i = 0; i < 4; i++) {
1582        if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
1583            ret |= (0xff << (i * 8));
1584        }
1585    }
1586
1587    return ret;
1588}
1589
1590uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1591{
1592    uint32_t ret = 0;
1593
1594    if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
1595        ret |= 0xffff;
1596    }
1597
1598    if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
1599        ret |= 0xffff0000;
1600    }
1601
1602    return ret;
1603}
1604
1605uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1606{
1607    uint32_t ret = 0;
1608
1609    if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
1610        ret |= 0xffff;
1611    }
1612
1613    if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
1614        ret |= 0xffff0000;
1615    }
1616
1617    return ret;
1618}
1619
1620#define EXTREMA_H_B(name, op)                                 \
1621uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1622{                                                             \
1623    int32_t i, extr_r1, extr_r2;                              \
1624    uint32_t ret = 0;                                         \
1625                                                              \
1626    for (i = 0; i < 4; i++) {                                 \
1627        extr_r1 = sextract32(r1, i * 8, 8);                   \
1628        extr_r2 = sextract32(r2, i * 8, 8);                   \
1629        extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1630        ret |= (extr_r1 & 0xff) << (i * 8);                   \
1631    }                                                         \
1632    return ret;                                               \
1633}                                                             \
1634                                                              \
1635uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1636{                                                             \
1637    int32_t i;                                                \
1638    uint32_t extr_r1, extr_r2;                                \
1639    uint32_t ret = 0;                                         \
1640                                                              \
1641    for (i = 0; i < 4; i++) {                                 \
1642        extr_r1 = extract32(r1, i * 8, 8);                    \
1643        extr_r2 = extract32(r2, i * 8, 8);                    \
1644        extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1645        ret |= (extr_r1 & 0xff) << (i * 8);                   \
1646    }                                                         \
1647    return ret;                                               \
1648}                                                             \
1649                                                              \
1650uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1651{                                                             \
1652    int32_t extr_r1, extr_r2;                                 \
1653    uint32_t ret = 0;                                         \
1654                                                              \
1655    extr_r1 = sextract32(r1, 0, 16);                          \
1656    extr_r2 = sextract32(r2, 0, 16);                          \
1657    ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1658    ret = ret & 0xffff;                                       \
1659                                                              \
1660    extr_r1 = sextract32(r1, 16, 16);                         \
1661    extr_r2 = sextract32(r2, 16, 16);                         \
1662    extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1663    ret |= extr_r1 << 16;                                     \
1664                                                              \
1665    return ret;                                               \
1666}                                                             \
1667                                                              \
1668uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1669{                                                             \
1670    uint32_t extr_r1, extr_r2;                                \
1671    uint32_t ret = 0;                                         \
1672                                                              \
1673    extr_r1 = extract32(r1, 0, 16);                           \
1674    extr_r2 = extract32(r2, 0, 16);                           \
1675    ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1676    ret = ret & 0xffff;                                       \
1677                                                              \
1678    extr_r1 = extract32(r1, 16, 16);                          \
1679    extr_r2 = extract32(r2, 16, 16);                          \
1680    extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1681    ret |= extr_r1 << (16);                                   \
1682                                                              \
1683    return ret;                                               \
1684}                                                             \
1685                                                              \
1686uint64_t helper_ix##name(uint64_t r1, uint32_t r2)            \
1687{                                                             \
1688    int64_t r2l, r2h, r1hl;                                   \
1689    uint64_t ret = 0;                                         \
1690                                                              \
1691    ret = ((r1 + 2) & 0xffff);                                \
1692    r2l = sextract64(r2, 0, 16);                              \
1693    r2h = sextract64(r2, 16, 16);                             \
1694    r1hl = sextract64(r1, 32, 16);                            \
1695                                                              \
1696    if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
1697        ret |= (r2l & 0xffff) << 32;                          \
1698        ret |= extract64(r1, 0, 16) << 16;                    \
1699    } else if ((r2h op r2l) && (r2h op r1hl)) {               \
1700        ret |= extract64(r2, 16, 16) << 32;                   \
1701        ret |= extract64(r1 + 1, 0, 16) << 16;                \
1702    } else {                                                  \
1703        ret |= r1 & 0xffffffff0000ull;                        \
1704    }                                                         \
1705    return ret;                                               \
1706}                                                             \
1707                                                              \
1708uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)       \
1709{                                                             \
1710    int64_t r2l, r2h, r1hl;                                   \
1711    uint64_t ret = 0;                                         \
1712                                                              \
1713    ret = ((r1 + 2) & 0xffff);                                \
1714    r2l = extract64(r2, 0, 16);                               \
1715    r2h = extract64(r2, 16, 16);                              \
1716    r1hl = extract64(r1, 32, 16);                             \
1717                                                              \
1718    if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
1719        ret |= (r2l & 0xffff) << 32;                          \
1720        ret |= extract64(r1, 0, 16) << 16;                    \
1721    } else if ((r2h op r2l) && (r2h op r1hl)) {               \
1722        ret |= extract64(r2, 16, 16) << 32;                   \
1723        ret |= extract64(r1 + 1, 0, 16) << 16;                \
1724    } else {                                                  \
1725        ret |= r1 & 0xffffffff0000ull;                        \
1726    }                                                         \
1727    return ret;                                               \
1728}
1729
1730EXTREMA_H_B(max, >)
1731EXTREMA_H_B(min, <)
1732
1733#undef EXTREMA_H_B
1734
1735uint32_t helper_clo(target_ulong r1)
1736{
1737    return clo32(r1);
1738}
1739
1740uint32_t helper_clo_h(target_ulong r1)
1741{
1742    uint32_t ret_hw0 = extract32(r1, 0, 16);
1743    uint32_t ret_hw1 = extract32(r1, 16, 16);
1744
1745    ret_hw0 = clo32(ret_hw0 << 16);
1746    ret_hw1 = clo32(ret_hw1 << 16);
1747
1748    if (ret_hw0 > 16) {
1749        ret_hw0 = 16;
1750    }
1751    if (ret_hw1 > 16) {
1752        ret_hw1 = 16;
1753    }
1754
1755    return ret_hw0 | (ret_hw1 << 16);
1756}
1757
1758uint32_t helper_clz(target_ulong r1)
1759{
1760    return clz32(r1);
1761}
1762
1763uint32_t helper_clz_h(target_ulong r1)
1764{
1765    uint32_t ret_hw0 = extract32(r1, 0, 16);
1766    uint32_t ret_hw1 = extract32(r1, 16, 16);
1767
1768    ret_hw0 = clz32(ret_hw0 << 16);
1769    ret_hw1 = clz32(ret_hw1 << 16);
1770
1771    if (ret_hw0 > 16) {
1772        ret_hw0 = 16;
1773    }
1774    if (ret_hw1 > 16) {
1775        ret_hw1 = 16;
1776    }
1777
1778    return ret_hw0 | (ret_hw1 << 16);
1779}
1780
1781uint32_t helper_cls(target_ulong r1)
1782{
1783    return clrsb32(r1);
1784}
1785
1786uint32_t helper_cls_h(target_ulong r1)
1787{
1788    uint32_t ret_hw0 = extract32(r1, 0, 16);
1789    uint32_t ret_hw1 = extract32(r1, 16, 16);
1790
1791    ret_hw0 = clrsb32(ret_hw0 << 16);
1792    ret_hw1 = clrsb32(ret_hw1 << 16);
1793
1794    if (ret_hw0 > 15) {
1795        ret_hw0 = 15;
1796    }
1797    if (ret_hw1 > 15) {
1798        ret_hw1 = 15;
1799    }
1800
1801    return ret_hw0 | (ret_hw1 << 16);
1802}
1803
1804uint32_t helper_sh(target_ulong r1, target_ulong r2)
1805{
1806    int32_t shift_count = sextract32(r2, 0, 6);
1807
1808    if (shift_count == -32) {
1809        return 0;
1810    } else if (shift_count < 0) {
1811        return r1 >> -shift_count;
1812    } else {
1813        return r1 << shift_count;
1814    }
1815}
1816
1817uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
1818{
1819    int32_t ret_hw0, ret_hw1;
1820    int32_t shift_count;
1821
1822    shift_count = sextract32(r2, 0, 5);
1823
1824    if (shift_count == -16) {
1825        return 0;
1826    } else if (shift_count < 0) {
1827        ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
1828        ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
1829        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1830    } else {
1831        ret_hw0 = extract32(r1, 0, 16) << shift_count;
1832        ret_hw1 = extract32(r1, 16, 16) << shift_count;
1833        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1834    }
1835}
1836
1837uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1838{
1839    int32_t shift_count;
1840    int64_t result, t1;
1841    uint32_t ret;
1842
1843    shift_count = sextract32(r2, 0, 6);
1844    t1 = sextract32(r1, 0, 32);
1845
1846    if (shift_count == 0) {
1847        env->PSW_USB_C = env->PSW_USB_V = 0;
1848        ret = r1;
1849    } else if (shift_count == -32) {
1850        env->PSW_USB_C = r1;
1851        env->PSW_USB_V = 0;
1852        ret = t1 >> 31;
1853    } else if (shift_count > 0) {
1854        result = t1 << shift_count;
1855        /* calc carry */
1856        env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
1857        /* calc v */
1858        env->PSW_USB_V = (((result > 0x7fffffffLL) ||
1859                           (result < -0x80000000LL)) << 31);
1860        /* calc sv */
1861        env->PSW_USB_SV |= env->PSW_USB_V;
1862        ret = (uint32_t)result;
1863    } else {
1864        env->PSW_USB_V = 0;
1865        env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
1866        ret = t1 >> -shift_count;
1867    }
1868
1869    env->PSW_USB_AV = ret ^ ret * 2u;
1870    env->PSW_USB_SAV |= env->PSW_USB_AV;
1871
1872    return ret;
1873}
1874
1875uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
1876{
1877    int32_t shift_count;
1878    int32_t ret_hw0, ret_hw1;
1879
1880    shift_count = sextract32(r2, 0, 5);
1881
1882    if (shift_count == 0) {
1883        return r1;
1884    } else if (shift_count < 0) {
1885        ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
1886        ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
1887        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1888    } else {
1889        ret_hw0 = sextract32(r1, 0, 16) << shift_count;
1890        ret_hw1 = sextract32(r1, 16, 16) << shift_count;
1891        return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1892    }
1893}
1894
1895uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1896{
1897    uint32_t i, ret;
1898
1899    ret = 0;
1900    for (i = 0; i < 16; i++) {
1901        ret |= (r1 & 1) << (2 * i + 1);
1902        ret |= (r2 & 1) << (2 * i);
1903        r1 = r1 >> 1;
1904        r2 = r2 >> 1;
1905    }
1906    return ret;
1907}
1908
1909uint64_t helper_bsplit(uint32_t r1)
1910{
1911    int32_t i;
1912    uint64_t ret;
1913
1914    ret = 0;
1915    for (i = 0; i < 32; i = i + 2) {
1916        /* even */
1917        ret |= (r1 & 1) << (i/2);
1918        r1 = r1 >> 1;
1919        /* odd */
1920        ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1921        r1 = r1 >> 1;
1922    }
1923    return ret;
1924}
1925
1926uint32_t helper_parity(target_ulong r1)
1927{
1928    uint32_t ret;
1929    uint32_t nOnes, i;
1930
1931    ret = 0;
1932    nOnes = 0;
1933    for (i = 0; i < 8; i++) {
1934        ret ^= (r1 & 1);
1935        r1 = r1 >> 1;
1936    }
1937    /* second byte */
1938    nOnes = 0;
1939    for (i = 0; i < 8; i++) {
1940        nOnes ^= (r1 & 1);
1941        r1 = r1 >> 1;
1942    }
1943    ret |= nOnes << 8;
1944    /* third byte */
1945    nOnes = 0;
1946    for (i = 0; i < 8; i++) {
1947        nOnes ^= (r1 & 1);
1948        r1 = r1 >> 1;
1949    }
1950    ret |= nOnes << 16;
1951    /* fourth byte */
1952    nOnes = 0;
1953    for (i = 0; i < 8; i++) {
1954        nOnes ^= (r1 & 1);
1955        r1 = r1 >> 1;
1956    }
1957    ret |= nOnes << 24;
1958
1959    return ret;
1960}
1961
1962uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
1963                     target_ulong r2)
1964{
1965    uint32_t ret;
1966    int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
1967    int32_t int_exp  = r1_high;
1968    int32_t int_mant = r1_low;
1969    uint32_t flag_rnd = (int_mant & (1 << 7)) && (
1970                        (int_mant & (1 << 8)) ||
1971                        (int_mant & 0x7f)     ||
1972                        (carry != 0));
1973    if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
1974        fp_exp = 255;
1975        fp_frac = extract32(int_mant, 8, 23);
1976    } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
1977        fp_exp  = 255;
1978        fp_frac = 0;
1979    } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
1980        fp_exp  = 0;
1981        fp_frac = 0;
1982    } else if (int_mant == 0) {
1983        fp_exp  = 0;
1984        fp_frac = 0;
1985    } else {
1986        if (((int_mant & (1 << 31)) == 0)) {
1987            temp_exp = 0;
1988        } else {
1989            temp_exp = int_exp + 128;
1990        }
1991        fp_exp_frac = (((temp_exp & 0xff) << 23) |
1992                      extract32(int_mant, 8, 23))
1993                      + flag_rnd;
1994        fp_exp  = extract32(fp_exp_frac, 23, 8);
1995        fp_frac = extract32(fp_exp_frac, 0, 23);
1996    }
1997    ret = r2 & (1 << 31);
1998    ret = ret + (fp_exp << 23);
1999    ret = ret + (fp_frac & 0x7fffff);
2000
2001    return ret;
2002}
2003
2004uint64_t helper_unpack(target_ulong arg1)
2005{
2006    int32_t fp_exp  = extract32(arg1, 23, 8);
2007    int32_t fp_frac = extract32(arg1, 0, 23);
2008    uint64_t ret;
2009    int32_t int_exp, int_mant;
2010
2011    if (fp_exp == 255) {
2012        int_exp = 255;
2013        int_mant = (fp_frac << 7);
2014    } else if ((fp_exp == 0) && (fp_frac == 0)) {
2015        int_exp  = -127;
2016        int_mant = 0;
2017    } else if ((fp_exp == 0) && (fp_frac != 0)) {
2018        int_exp  = -126;
2019        int_mant = (fp_frac << 7);
2020    } else {
2021        int_exp  = fp_exp - 127;
2022        int_mant = (fp_frac << 7);
2023        int_mant |= (1 << 30);
2024    }
2025    ret = int_exp;
2026    ret = ret << 32;
2027    ret |= int_mant;
2028
2029    return ret;
2030}
2031
2032uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2033{
2034    uint64_t ret;
2035    int32_t abs_sig_dividend, abs_divisor;
2036
2037    ret = sextract32(r1, 0, 32);
2038    ret = ret << 24;
2039    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2040        ret |= 0xffffff;
2041    }
2042
2043    abs_sig_dividend = abs((int32_t)r1) >> 8;
2044    abs_divisor = abs((int32_t)r2);
2045    /* calc overflow
2046       ofv if (a/b >= 255) <=> (a/255 >= b) */
2047    env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2048    env->PSW_USB_V = env->PSW_USB_V << 31;
2049    env->PSW_USB_SV |= env->PSW_USB_V;
2050    env->PSW_USB_AV = 0;
2051
2052    return ret;
2053}
2054
2055uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2056{
2057    uint64_t ret = sextract32(r1, 0, 32);
2058
2059    ret = ret << 24;
2060    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2061        ret |= 0xffffff;
2062    }
2063    /* calc overflow */
2064    env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
2065    env->PSW_USB_V = env->PSW_USB_V << 31;
2066    env->PSW_USB_SV |= env->PSW_USB_V;
2067    env->PSW_USB_AV = 0;
2068
2069    return ret;
2070}
2071
2072uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2073{
2074    uint64_t ret;
2075    int32_t abs_sig_dividend, abs_divisor;
2076
2077    ret = sextract32(r1, 0, 32);
2078    ret = ret << 16;
2079    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2080        ret |= 0xffff;
2081    }
2082
2083    abs_sig_dividend = abs((int32_t)r1) >> 16;
2084    abs_divisor = abs((int32_t)r2);
2085    /* calc overflow
2086       ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */
2087    env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2088    env->PSW_USB_V = env->PSW_USB_V << 31;
2089    env->PSW_USB_SV |= env->PSW_USB_V;
2090    env->PSW_USB_AV = 0;
2091
2092    return ret;
2093}
2094
2095uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2096{
2097    uint64_t ret = sextract32(r1, 0, 32);
2098
2099    ret = ret << 16;
2100    if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2101        ret |= 0xffff;
2102    }
2103    /* calc overflow */
2104    env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
2105    env->PSW_USB_V = env->PSW_USB_V << 31;
2106    env->PSW_USB_SV |= env->PSW_USB_V;
2107    env->PSW_USB_AV = 0;
2108
2109    return ret;
2110}
2111
2112uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
2113{
2114    int32_t x_sign = (r1 >> 63);
2115    int32_t q_sign = x_sign ^ (r2 >> 31);
2116    int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
2117    int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
2118    uint32_t quotient;
2119    uint64_t ret, remainder;
2120
2121    if ((q_sign & ~eq_neg) | eq_pos) {
2122        quotient = (r1 + 1) & 0xffffffff;
2123    } else {
2124        quotient = r1 & 0xffffffff;
2125    }
2126
2127    if (eq_pos | eq_neg) {
2128        remainder = 0;
2129    } else {
2130        remainder = (r1 & 0xffffffff00000000ull);
2131    }
2132    ret = remainder|quotient;
2133    return ret;
2134}
2135
2136uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
2137{
2138    int32_t dividend_sign = extract64(r1, 63, 1);
2139    int32_t divisor_sign = extract32(r2, 31, 1);
2140    int32_t quotient_sign = (dividend_sign != divisor_sign);
2141    int32_t addend, dividend_quotient, remainder;
2142    int32_t i, temp;
2143
2144    if (quotient_sign) {
2145        addend = r2;
2146    } else {
2147        addend = -r2;
2148    }
2149    dividend_quotient = (int32_t)r1;
2150    remainder = (int32_t)(r1 >> 32);
2151
2152    for (i = 0; i < 8; i++) {
2153        remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2154        dividend_quotient <<= 1;
2155        temp = remainder + addend;
2156        if ((temp < 0) == dividend_sign) {
2157            remainder = temp;
2158        }
2159        if (((temp < 0) == dividend_sign)) {
2160            dividend_quotient = dividend_quotient | !quotient_sign;
2161        } else {
2162            dividend_quotient = dividend_quotient | quotient_sign;
2163        }
2164    }
2165    return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2166}
2167
2168uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
2169{
2170    int32_t dividend_quotient = extract64(r1, 0, 32);
2171    int64_t remainder = extract64(r1, 32, 32);
2172    int32_t i;
2173    int64_t temp;
2174    for (i = 0; i < 8; i++) {
2175        remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2176        dividend_quotient <<= 1;
2177        temp = (remainder & 0xffffffff) - r2;
2178        if (temp >= 0) {
2179            remainder = temp;
2180        }
2181        dividend_quotient = dividend_quotient | !(temp < 0);
2182    }
2183    return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2184}
2185
2186uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2187{
2188    int32_t quotient, remainder;
2189    int32_t dividend = (int32_t)r1;
2190    int32_t divisor = (int32_t)r2;
2191
2192    if (divisor == 0) {
2193        if (dividend >= 0) {
2194            quotient = 0x7fffffff;
2195            remainder = 0;
2196        } else {
2197            quotient = 0x80000000;
2198            remainder = 0;
2199        }
2200        env->PSW_USB_V = (1 << 31);
2201    } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
2202        quotient = 0x7fffffff;
2203        remainder = 0;
2204        env->PSW_USB_V = (1 << 31);
2205    } else {
2206        remainder = dividend % divisor;
2207        quotient = (dividend - remainder)/divisor;
2208        env->PSW_USB_V = 0;
2209    }
2210    env->PSW_USB_SV |= env->PSW_USB_V;
2211    env->PSW_USB_AV = 0;
2212    return ((uint64_t)remainder << 32) | (uint32_t)quotient;
2213}
2214
2215uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2216{
2217    uint32_t quotient, remainder;
2218    uint32_t dividend = r1;
2219    uint32_t divisor = r2;
2220
2221    if (divisor == 0) {
2222        quotient = 0xffffffff;
2223        remainder = 0;
2224        env->PSW_USB_V = (1 << 31);
2225    } else {
2226        remainder = dividend % divisor;
2227        quotient = (dividend - remainder)/divisor;
2228        env->PSW_USB_V = 0;
2229    }
2230    env->PSW_USB_SV |= env->PSW_USB_V;
2231    env->PSW_USB_AV = 0;
2232    return ((uint64_t)remainder << 32) | quotient;
2233}
2234
2235uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
2236                      uint32_t arg10, uint32_t arg11, uint32_t n)
2237{
2238    uint64_t ret;
2239    uint32_t result0, result1;
2240
2241    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2242                  ((arg10 & 0xffff) == 0x8000) && (n == 1);
2243    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2244                  ((arg11 & 0xffff) == 0x8000) && (n == 1);
2245    if (sc1) {
2246        result1 = 0x7fffffff;
2247    } else {
2248        result1 = (((uint32_t)(arg00 * arg10)) << n);
2249    }
2250    if (sc0) {
2251        result0 = 0x7fffffff;
2252    } else {
2253        result0 = (((uint32_t)(arg01 * arg11)) << n);
2254    }
2255    ret = (((uint64_t)result1 << 32)) | result0;
2256    return ret;
2257}
2258
2259uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
2260                       uint32_t arg10, uint32_t arg11, uint32_t n)
2261{
2262    uint64_t ret;
2263    int64_t result0, result1;
2264
2265    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2266                  ((arg10 & 0xffff) == 0x8000) && (n == 1);
2267    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2268                  ((arg11 & 0xffff) == 0x8000) && (n == 1);
2269
2270    if (sc1) {
2271        result1 = 0x7fffffff;
2272    } else {
2273        result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
2274    }
2275    if (sc0) {
2276        result0 = 0x7fffffff;
2277    } else {
2278        result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
2279    }
2280    ret = (result1 + result0);
2281    ret = ret << 16;
2282    return ret;
2283}
2284uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
2285                       uint32_t arg10, uint32_t arg11, uint32_t n)
2286{
2287    uint32_t result0, result1;
2288
2289    int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2290                  ((arg10 & 0xffff) == 0x8000) && (n == 1);
2291    int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2292                  ((arg11 & 0xffff) == 0x8000) && (n == 1);
2293
2294    if (sc1) {
2295        result1 = 0x7fffffff;
2296    } else {
2297        result1 = ((arg00 * arg10) << n) + 0x8000;
2298    }
2299    if (sc0) {
2300        result0 = 0x7fffffff;
2301    } else {
2302        result0 = ((arg01 * arg11) << n) + 0x8000;
2303    }
2304    return (result1 & 0xffff0000) | (result0 >> 16);
2305}
2306
2307uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
2308{
2309    uint8_t buf[4];
2310    uint32_t ret;
2311    stl_be_p(buf, arg0);
2312
2313    ret = crc32(arg1, buf, 4);
2314    return ret;
2315}
2316
2317/* context save area (CSA) related helpers */
2318
2319static int cdc_increment(target_ulong *psw)
2320{
2321    if ((*psw & MASK_PSW_CDC) == 0x7f) {
2322        return 0;
2323    }
2324
2325    (*psw)++;
2326    /* check for overflow */
2327    int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2328    int mask = (1u << (7 - lo)) - 1;
2329    int count = *psw & mask;
2330    if (count == 0) {
2331        (*psw)--;
2332        return 1;
2333    }
2334    return 0;
2335}
2336
2337static int cdc_decrement(target_ulong *psw)
2338{
2339    if ((*psw & MASK_PSW_CDC) == 0x7f) {
2340        return 0;
2341    }
2342    /* check for underflow */
2343    int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2344    int mask = (1u << (7 - lo)) - 1;
2345    int count = *psw & mask;
2346    if (count == 0) {
2347        return 1;
2348    }
2349    (*psw)--;
2350    return 0;
2351}
2352
2353static bool cdc_zero(target_ulong *psw)
2354{
2355    int cdc = *psw & MASK_PSW_CDC;
2356    /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
2357       7'b1111111, otherwise returns FALSE. */
2358    if (cdc == 0x7f) {
2359        return true;
2360    }
2361    /* find CDC.COUNT */
2362    int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2363    int mask = (1u << (7 - lo)) - 1;
2364    int count = *psw & mask;
2365    return count == 0;
2366}
2367
2368static void save_context_upper(CPUTriCoreState *env, int ea)
2369{
2370    cpu_stl_data(env, ea, env->PCXI);
2371    cpu_stl_data(env, ea+4, psw_read(env));
2372    cpu_stl_data(env, ea+8, env->gpr_a[10]);
2373    cpu_stl_data(env, ea+12, env->gpr_a[11]);
2374    cpu_stl_data(env, ea+16, env->gpr_d[8]);
2375    cpu_stl_data(env, ea+20, env->gpr_d[9]);
2376    cpu_stl_data(env, ea+24, env->gpr_d[10]);
2377    cpu_stl_data(env, ea+28, env->gpr_d[11]);
2378    cpu_stl_data(env, ea+32, env->gpr_a[12]);
2379    cpu_stl_data(env, ea+36, env->gpr_a[13]);
2380    cpu_stl_data(env, ea+40, env->gpr_a[14]);
2381    cpu_stl_data(env, ea+44, env->gpr_a[15]);
2382    cpu_stl_data(env, ea+48, env->gpr_d[12]);
2383    cpu_stl_data(env, ea+52, env->gpr_d[13]);
2384    cpu_stl_data(env, ea+56, env->gpr_d[14]);
2385    cpu_stl_data(env, ea+60, env->gpr_d[15]);
2386}
2387
2388static void save_context_lower(CPUTriCoreState *env, int ea)
2389{
2390    cpu_stl_data(env, ea, env->PCXI);
2391    cpu_stl_data(env, ea+4, env->gpr_a[11]);
2392    cpu_stl_data(env, ea+8, env->gpr_a[2]);
2393    cpu_stl_data(env, ea+12, env->gpr_a[3]);
2394    cpu_stl_data(env, ea+16, env->gpr_d[0]);
2395    cpu_stl_data(env, ea+20, env->gpr_d[1]);
2396    cpu_stl_data(env, ea+24, env->gpr_d[2]);
2397    cpu_stl_data(env, ea+28, env->gpr_d[3]);
2398    cpu_stl_data(env, ea+32, env->gpr_a[4]);
2399    cpu_stl_data(env, ea+36, env->gpr_a[5]);
2400    cpu_stl_data(env, ea+40, env->gpr_a[6]);
2401    cpu_stl_data(env, ea+44, env->gpr_a[7]);
2402    cpu_stl_data(env, ea+48, env->gpr_d[4]);
2403    cpu_stl_data(env, ea+52, env->gpr_d[5]);
2404    cpu_stl_data(env, ea+56, env->gpr_d[6]);
2405    cpu_stl_data(env, ea+60, env->gpr_d[7]);
2406}
2407
2408static void restore_context_upper(CPUTriCoreState *env, int ea,
2409                                  target_ulong *new_PCXI, target_ulong *new_PSW)
2410{
2411    *new_PCXI = cpu_ldl_data(env, ea);
2412    *new_PSW = cpu_ldl_data(env, ea+4);
2413    env->gpr_a[10] = cpu_ldl_data(env, ea+8);
2414    env->gpr_a[11] = cpu_ldl_data(env, ea+12);
2415    env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
2416    env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
2417    env->gpr_d[10] = cpu_ldl_data(env, ea+24);
2418    env->gpr_d[11] = cpu_ldl_data(env, ea+28);
2419    env->gpr_a[12] = cpu_ldl_data(env, ea+32);
2420    env->gpr_a[13] = cpu_ldl_data(env, ea+36);
2421    env->gpr_a[14] = cpu_ldl_data(env, ea+40);
2422    env->gpr_a[15] = cpu_ldl_data(env, ea+44);
2423    env->gpr_d[12] = cpu_ldl_data(env, ea+48);
2424    env->gpr_d[13] = cpu_ldl_data(env, ea+52);
2425    env->gpr_d[14] = cpu_ldl_data(env, ea+56);
2426    env->gpr_d[15] = cpu_ldl_data(env, ea+60);
2427}
2428
2429static void restore_context_lower(CPUTriCoreState *env, int ea,
2430                                  target_ulong *ra, target_ulong *pcxi)
2431{
2432    *pcxi = cpu_ldl_data(env, ea);
2433    *ra = cpu_ldl_data(env, ea+4);
2434    env->gpr_a[2] = cpu_ldl_data(env, ea+8);
2435    env->gpr_a[3] = cpu_ldl_data(env, ea+12);
2436    env->gpr_d[0] = cpu_ldl_data(env, ea+16);
2437    env->gpr_d[1] = cpu_ldl_data(env, ea+20);
2438    env->gpr_d[2] = cpu_ldl_data(env, ea+24);
2439    env->gpr_d[3] = cpu_ldl_data(env, ea+28);
2440    env->gpr_a[4] = cpu_ldl_data(env, ea+32);
2441    env->gpr_a[5] = cpu_ldl_data(env, ea+36);
2442    env->gpr_a[6] = cpu_ldl_data(env, ea+40);
2443    env->gpr_a[7] = cpu_ldl_data(env, ea+44);
2444    env->gpr_d[4] = cpu_ldl_data(env, ea+48);
2445    env->gpr_d[5] = cpu_ldl_data(env, ea+52);
2446    env->gpr_d[6] = cpu_ldl_data(env, ea+56);
2447    env->gpr_d[7] = cpu_ldl_data(env, ea+60);
2448}
2449
2450void helper_call(CPUTriCoreState *env, uint32_t next_pc)
2451{
2452    target_ulong tmp_FCX;
2453    target_ulong ea;
2454    target_ulong new_FCX;
2455    target_ulong psw;
2456
2457    psw = psw_read(env);
2458    /* if (FCX == 0) trap(FCU); */
2459    if (env->FCX == 0) {
2460        /* FCU trap */
2461        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2462    }
2463    /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
2464    if (psw & MASK_PSW_CDE) {
2465        if (cdc_increment(&psw)) {
2466            /* CDO trap */
2467            raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC());
2468        }
2469    }
2470    /* PSW.CDE = 1;*/
2471    psw |= MASK_PSW_CDE;
2472    /* tmp_FCX = FCX; */
2473    tmp_FCX = env->FCX;
2474    /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2475    ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2476         ((env->FCX & MASK_FCX_FCXO) << 6);
2477    /* new_FCX = M(EA, word); */
2478    new_FCX = cpu_ldl_data(env, ea);
2479    /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2480                           A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2481                           D[15]}; */
2482    save_context_upper(env, ea);
2483
2484    /* PCXI.PCPN = ICR.CCPN; */
2485    env->PCXI = (env->PCXI & 0xffffff) +
2486                ((env->ICR & MASK_ICR_CCPN) << 24);
2487    /* PCXI.PIE = ICR.IE; */
2488    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2489                ((env->ICR & MASK_ICR_IE) << 15));
2490    /* PCXI.UL = 1; */
2491    env->PCXI |= MASK_PCXI_UL;
2492
2493    /* PCXI[19: 0] = FCX[19: 0]; */
2494    env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2495    /* FCX[19: 0] = new_FCX[19: 0]; */
2496    env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2497    /* A[11] = next_pc[31: 0]; */
2498    env->gpr_a[11] = next_pc;
2499
2500    /* if (tmp_FCX == LCX) trap(FCD);*/
2501    if (tmp_FCX == env->LCX) {
2502        /* FCD trap */
2503        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2504    }
2505    psw_write(env, psw);
2506}
2507
2508void helper_ret(CPUTriCoreState *env)
2509{
2510    target_ulong ea;
2511    target_ulong new_PCXI;
2512    target_ulong new_PSW, psw;
2513
2514    psw = psw_read(env);
2515     /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
2516    if (psw & MASK_PSW_CDE) {
2517        if (cdc_decrement(&psw)) {
2518            /* CDU trap */
2519            psw_write(env, psw);
2520            raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC());
2521        }
2522    }
2523    /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2524    if ((env->PCXI & 0xfffff) == 0) {
2525        /* CSU trap */
2526        psw_write(env, psw);
2527        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2528    }
2529    /* if (PCXI.UL == 0) then trap(CTYP); */
2530    if ((env->PCXI & MASK_PCXI_UL) == 0) {
2531        /* CTYP trap */
2532        cdc_increment(&psw); /* restore to the start of helper */
2533        psw_write(env, psw);
2534        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2535    }
2536    /* PC = {A11 [31: 1], 1’b0}; */
2537    env->PC = env->gpr_a[11] & 0xfffffffe;
2538
2539    /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2540    ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2541         ((env->PCXI & MASK_PCXI_PCXO) << 6);
2542    /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2543        A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2544    restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2545    /* M(EA, word) = FCX; */
2546    cpu_stl_data(env, ea, env->FCX);
2547    /* FCX[19: 0] = PCXI[19: 0]; */
2548    env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2549    /* PCXI = new_PCXI; */
2550    env->PCXI = new_PCXI;
2551
2552    if (tricore_feature(env, TRICORE_FEATURE_13)) {
2553        /* PSW = new_PSW */
2554        psw_write(env, new_PSW);
2555    } else {
2556        /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
2557        psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
2558    }
2559}
2560
2561void helper_bisr(CPUTriCoreState *env, uint32_t const9)
2562{
2563    target_ulong tmp_FCX;
2564    target_ulong ea;
2565    target_ulong new_FCX;
2566
2567    if (env->FCX == 0) {
2568        /* FCU trap */
2569       raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2570    }
2571
2572    tmp_FCX = env->FCX;
2573    ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
2574
2575    /* new_FCX = M(EA, word); */
2576    new_FCX = cpu_ldl_data(env, ea);
2577    /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2578                           , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2579    save_context_lower(env, ea);
2580
2581
2582    /* PCXI.PCPN = ICR.CCPN */
2583    env->PCXI = (env->PCXI & 0xffffff) +
2584                 ((env->ICR & MASK_ICR_CCPN) << 24);
2585    /* PCXI.PIE  = ICR.IE */
2586    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2587                 ((env->ICR & MASK_ICR_IE) << 15));
2588    /* PCXI.UL = 0 */
2589    env->PCXI &= ~(MASK_PCXI_UL);
2590    /* PCXI[19: 0] = FCX[19: 0] */
2591    env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2592    /* FXC[19: 0] = new_FCX[19: 0] */
2593    env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2594    /* ICR.IE = 1 */
2595    env->ICR |= MASK_ICR_IE;
2596
2597    env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
2598
2599    if (tmp_FCX == env->LCX) {
2600        /* FCD trap */
2601        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2602    }
2603}
2604
2605void helper_rfe(CPUTriCoreState *env)
2606{
2607    target_ulong ea;
2608    target_ulong new_PCXI;
2609    target_ulong new_PSW;
2610    /* if (PCXI[19: 0] == 0) then trap(CSU); */
2611    if ((env->PCXI & 0xfffff) == 0) {
2612        /* raise csu trap */
2613        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2614    }
2615    /* if (PCXI.UL == 0) then trap(CTYP); */
2616    if ((env->PCXI & MASK_PCXI_UL) == 0) {
2617        /* raise CTYP trap */
2618        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2619    }
2620    /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
2621    if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
2622        /* raise NEST trap */
2623        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC());
2624    }
2625    env->PC = env->gpr_a[11] & ~0x1;
2626    /* ICR.IE = PCXI.PIE; */
2627    env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
2628    /* ICR.CCPN = PCXI.PCPN; */
2629    env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
2630               ((env->PCXI & MASK_PCXI_PCPN) >> 24);
2631    /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
2632    ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2633         ((env->PCXI & MASK_PCXI_PCXO) << 6);
2634    /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2635      A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2636    restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2637    /* M(EA, word) = FCX;*/
2638    cpu_stl_data(env, ea, env->FCX);
2639    /* FCX[19: 0] = PCXI[19: 0]; */
2640    env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2641    /* PCXI = new_PCXI; */
2642    env->PCXI = new_PCXI;
2643    /* write psw */
2644    psw_write(env, new_PSW);
2645}
2646
2647void helper_rfm(CPUTriCoreState *env)
2648{
2649    env->PC = (env->gpr_a[11] & ~0x1);
2650    /* ICR.IE = PCXI.PIE; */
2651    env->ICR = (env->ICR & ~MASK_ICR_IE) |
2652               ((env->PCXI & MASK_PCXI_PIE) >> 15);
2653    /* ICR.CCPN = PCXI.PCPN; */
2654    env->ICR = (env->ICR & ~MASK_ICR_CCPN) |
2655               ((env->PCXI & MASK_PCXI_PCPN) >> 24);
2656    /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */
2657    env->PCXI = cpu_ldl_data(env, env->DCX);
2658    psw_write(env, cpu_ldl_data(env, env->DCX+4));
2659    env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
2660    env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
2661
2662    if (tricore_feature(env, TRICORE_FEATURE_131)) {
2663        env->DBGTCR = 0;
2664    }
2665}
2666
2667void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
2668{
2669    uint32_t dummy;
2670    /* insn doesn't load PCXI and RA */
2671    restore_context_lower(env, ea, &dummy, &dummy);
2672}
2673
2674void helper_lducx(CPUTriCoreState *env, uint32_t ea)
2675{
2676    uint32_t dummy;
2677    /* insn doesn't load PCXI and PSW */
2678    restore_context_upper(env, ea, &dummy, &dummy);
2679}
2680
2681void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
2682{
2683    save_context_lower(env, ea);
2684}
2685
2686void helper_stucx(CPUTriCoreState *env, uint32_t ea)
2687{
2688    save_context_upper(env, ea);
2689}
2690
2691void helper_svlcx(CPUTriCoreState *env)
2692{
2693    target_ulong tmp_FCX;
2694    target_ulong ea;
2695    target_ulong new_FCX;
2696
2697    if (env->FCX == 0) {
2698        /* FCU trap */
2699        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2700    }
2701    /* tmp_FCX = FCX; */
2702    tmp_FCX = env->FCX;
2703    /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2704    ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2705         ((env->FCX & MASK_FCX_FCXO) << 6);
2706    /* new_FCX = M(EA, word); */
2707    new_FCX = cpu_ldl_data(env, ea);
2708    /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2709                           A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2710                           D[15]}; */
2711    save_context_lower(env, ea);
2712
2713    /* PCXI.PCPN = ICR.CCPN; */
2714    env->PCXI = (env->PCXI & 0xffffff) +
2715                ((env->ICR & MASK_ICR_CCPN) << 24);
2716    /* PCXI.PIE = ICR.IE; */
2717    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2718                ((env->ICR & MASK_ICR_IE) << 15));
2719    /* PCXI.UL = 0; */
2720    env->PCXI &= ~MASK_PCXI_UL;
2721
2722    /* PCXI[19: 0] = FCX[19: 0]; */
2723    env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2724    /* FCX[19: 0] = new_FCX[19: 0]; */
2725    env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2726
2727    /* if (tmp_FCX == LCX) trap(FCD);*/
2728    if (tmp_FCX == env->LCX) {
2729        /* FCD trap */
2730        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2731    }
2732}
2733
2734void helper_svucx(CPUTriCoreState *env)
2735{
2736    target_ulong tmp_FCX;
2737    target_ulong ea;
2738    target_ulong new_FCX;
2739
2740    if (env->FCX == 0) {
2741        /* FCU trap */
2742        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2743    }
2744    /* tmp_FCX = FCX; */
2745    tmp_FCX = env->FCX;
2746    /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2747    ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2748         ((env->FCX & MASK_FCX_FCXO) << 6);
2749    /* new_FCX = M(EA, word); */
2750    new_FCX = cpu_ldl_data(env, ea);
2751    /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2752                           A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2753                           D[15]}; */
2754    save_context_upper(env, ea);
2755
2756    /* PCXI.PCPN = ICR.CCPN; */
2757    env->PCXI = (env->PCXI & 0xffffff) +
2758                ((env->ICR & MASK_ICR_CCPN) << 24);
2759    /* PCXI.PIE = ICR.IE; */
2760    env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2761                ((env->ICR & MASK_ICR_IE) << 15));
2762    /* PCXI.UL = 1; */
2763    env->PCXI |= MASK_PCXI_UL;
2764
2765    /* PCXI[19: 0] = FCX[19: 0]; */
2766    env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2767    /* FCX[19: 0] = new_FCX[19: 0]; */
2768    env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2769
2770    /* if (tmp_FCX == LCX) trap(FCD);*/
2771    if (tmp_FCX == env->LCX) {
2772        /* FCD trap */
2773        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2774    }
2775}
2776
2777void helper_rslcx(CPUTriCoreState *env)
2778{
2779    target_ulong ea;
2780    target_ulong new_PCXI;
2781    /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2782    if ((env->PCXI & 0xfffff) == 0) {
2783        /* CSU trap */
2784        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2785    }
2786    /* if (PCXI.UL == 1) then trap(CTYP); */
2787    if ((env->PCXI & MASK_PCXI_UL) != 0) {
2788        /* CTYP trap */
2789        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2790    }
2791    /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2792    ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2793         ((env->PCXI & MASK_PCXI_PCXO) << 6);
2794    /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2795        A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2796    restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI);
2797    /* M(EA, word) = FCX; */
2798    cpu_stl_data(env, ea, env->FCX);
2799    /* M(EA, word) = FCX; */
2800    cpu_stl_data(env, ea, env->FCX);
2801    /* FCX[19: 0] = PCXI[19: 0]; */
2802    env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2803    /* PCXI = new_PCXI; */
2804    env->PCXI = new_PCXI;
2805}
2806
2807void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
2808{
2809    psw_write(env, arg);
2810}
2811
2812uint32_t helper_psw_read(CPUTriCoreState *env)
2813{
2814    return psw_read(env);
2815}
2816
2817
2818static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
2819                                                        uint32_t exception,
2820                                                        int error_code,
2821                                                        uintptr_t pc)
2822{
2823    CPUState *cs = CPU(tricore_env_get_cpu(env));
2824    cs->exception_index = exception;
2825    env->error_code = error_code;
2826
2827    if (pc) {
2828        /* now we have a real cpu fault */
2829        cpu_restore_state(cs, pc);
2830    }
2831
2832    cpu_loop_exit(cs);
2833}
2834
2835void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
2836              uintptr_t retaddr)
2837{
2838    int ret;
2839    ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
2840    if (ret) {
2841        TriCoreCPU *cpu = TRICORE_CPU(cs);
2842        CPUTriCoreState *env = &cpu->env;
2843        do_raise_exception_err(env, cs->exception_index,
2844                               env->error_code, retaddr);
2845    }
2846}
2847