qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

op_helper.c (80824B)


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