cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

op_helper.c (80980B)


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