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