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