148e06fe0SBastian Koppelmann /* 248e06fe0SBastian Koppelmann * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn 348e06fe0SBastian Koppelmann * 448e06fe0SBastian Koppelmann * This library is free software; you can redistribute it and/or 548e06fe0SBastian Koppelmann * modify it under the terms of the GNU Lesser General Public 648e06fe0SBastian Koppelmann * License as published by the Free Software Foundation; either 748e06fe0SBastian Koppelmann * version 2 of the License, or (at your option) any later version. 848e06fe0SBastian Koppelmann * 948e06fe0SBastian Koppelmann * This library is distributed in the hope that it will be useful, 1048e06fe0SBastian Koppelmann * but WITHOUT ANY WARRANTY; without even the implied warranty of 1148e06fe0SBastian Koppelmann * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1248e06fe0SBastian Koppelmann * Lesser General Public License for more details. 1348e06fe0SBastian Koppelmann * 1448e06fe0SBastian Koppelmann * You should have received a copy of the GNU Lesser General Public 1548e06fe0SBastian Koppelmann * License along with this library; if not, see <http://www.gnu.org/licenses/>. 1648e06fe0SBastian Koppelmann */ 1748e06fe0SBastian Koppelmann #include <stdlib.h> 1848e06fe0SBastian Koppelmann #include "cpu.h" 1948e06fe0SBastian Koppelmann #include "qemu/host-utils.h" 2048e06fe0SBastian Koppelmann #include "exec/helper-proto.h" 2148e06fe0SBastian Koppelmann #include "exec/cpu_ldst.h" 22e5c96c82SBastian Koppelmann #include <zlib.h> /* for crc32 */ 2348e06fe0SBastian Koppelmann 243a16ecb0SBastian Koppelmann /* Addressing mode helper */ 253a16ecb0SBastian Koppelmann 263a16ecb0SBastian Koppelmann static uint16_t reverse16(uint16_t val) 273a16ecb0SBastian Koppelmann { 283a16ecb0SBastian Koppelmann uint8_t high = (uint8_t)(val >> 8); 293a16ecb0SBastian Koppelmann uint8_t low = (uint8_t)(val & 0xff); 303a16ecb0SBastian Koppelmann 313a16ecb0SBastian Koppelmann uint16_t rh, rl; 323a16ecb0SBastian Koppelmann 333a16ecb0SBastian Koppelmann rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023); 343a16ecb0SBastian Koppelmann rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023); 353a16ecb0SBastian Koppelmann 363a16ecb0SBastian Koppelmann return (rh << 8) | rl; 373a16ecb0SBastian Koppelmann } 383a16ecb0SBastian Koppelmann 393a16ecb0SBastian Koppelmann uint32_t helper_br_update(uint32_t reg) 403a16ecb0SBastian Koppelmann { 413a16ecb0SBastian Koppelmann uint32_t index = reg & 0xffff; 423a16ecb0SBastian Koppelmann uint32_t incr = reg >> 16; 433a16ecb0SBastian Koppelmann uint32_t new_index = reverse16(reverse16(index) + reverse16(incr)); 443a16ecb0SBastian Koppelmann return reg - index + new_index; 453a16ecb0SBastian Koppelmann } 463a16ecb0SBastian Koppelmann 473a16ecb0SBastian Koppelmann uint32_t helper_circ_update(uint32_t reg, uint32_t off) 483a16ecb0SBastian Koppelmann { 493a16ecb0SBastian Koppelmann uint32_t index = reg & 0xffff; 503a16ecb0SBastian Koppelmann uint32_t length = reg >> 16; 513a16ecb0SBastian Koppelmann int32_t new_index = index + off; 523a16ecb0SBastian Koppelmann if (new_index < 0) { 533a16ecb0SBastian Koppelmann new_index += length; 543a16ecb0SBastian Koppelmann } else { 553a16ecb0SBastian Koppelmann new_index %= length; 563a16ecb0SBastian Koppelmann } 573a16ecb0SBastian Koppelmann return reg - index + new_index; 583a16ecb0SBastian Koppelmann } 593a16ecb0SBastian Koppelmann 60e4e39176SBastian Koppelmann static uint32_t ssov32(CPUTriCoreState *env, int64_t arg) 61e4e39176SBastian Koppelmann { 62e4e39176SBastian Koppelmann uint32_t ret; 63e4e39176SBastian Koppelmann int64_t max_pos = INT32_MAX; 64e4e39176SBastian Koppelmann int64_t max_neg = INT32_MIN; 65e4e39176SBastian Koppelmann if (arg > max_pos) { 66e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 67e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 68e4e39176SBastian Koppelmann ret = (target_ulong)max_pos; 69e4e39176SBastian Koppelmann } else { 70e4e39176SBastian Koppelmann if (arg < max_neg) { 71e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 72e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 73e4e39176SBastian Koppelmann ret = (target_ulong)max_neg; 74e4e39176SBastian Koppelmann } else { 75e4e39176SBastian Koppelmann env->PSW_USB_V = 0; 76e4e39176SBastian Koppelmann ret = (target_ulong)arg; 77e4e39176SBastian Koppelmann } 78e4e39176SBastian Koppelmann } 79e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 80e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 81e4e39176SBastian Koppelmann return ret; 82e4e39176SBastian Koppelmann } 832692802aSBastian Koppelmann 8485d604afSBastian Koppelmann static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg) 85e4e39176SBastian Koppelmann { 86e4e39176SBastian Koppelmann uint32_t ret; 8785d604afSBastian Koppelmann uint64_t max_pos = UINT32_MAX; 88e4e39176SBastian Koppelmann if (arg > max_pos) { 89e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 90e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 91e4e39176SBastian Koppelmann ret = (target_ulong)max_pos; 92e4e39176SBastian Koppelmann } else { 9385d604afSBastian Koppelmann env->PSW_USB_V = 0; 9485d604afSBastian Koppelmann ret = (target_ulong)arg; 9585d604afSBastian Koppelmann } 9685d604afSBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 9785d604afSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 9885d604afSBastian Koppelmann return ret; 9985d604afSBastian Koppelmann } 10085d604afSBastian Koppelmann 10185d604afSBastian Koppelmann static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg) 10285d604afSBastian Koppelmann { 10385d604afSBastian Koppelmann uint32_t ret; 10485d604afSBastian Koppelmann 105e4e39176SBastian Koppelmann if (arg < 0) { 106e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 107e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 108e4e39176SBastian Koppelmann ret = 0; 109e4e39176SBastian Koppelmann } else { 110e4e39176SBastian Koppelmann env->PSW_USB_V = 0; 111e4e39176SBastian Koppelmann ret = (target_ulong)arg; 112e4e39176SBastian Koppelmann } 113e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 114e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 115e4e39176SBastian Koppelmann return ret; 116e4e39176SBastian Koppelmann } 1170974257eSBastian Koppelmann 118d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 119d5de7839SBastian Koppelmann { 120d5de7839SBastian Koppelmann int32_t max_pos = INT16_MAX; 121d5de7839SBastian Koppelmann int32_t max_neg = INT16_MIN; 122d5de7839SBastian Koppelmann int32_t av0, av1; 123d5de7839SBastian Koppelmann 124d5de7839SBastian Koppelmann env->PSW_USB_V = 0; 125d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u; 126d5de7839SBastian Koppelmann if (hw0 > max_pos) { 127d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 128d5de7839SBastian Koppelmann hw0 = max_pos; 129d5de7839SBastian Koppelmann } else if (hw0 < max_neg) { 130d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 131d5de7839SBastian Koppelmann hw0 = max_neg; 132d5de7839SBastian Koppelmann } 133d5de7839SBastian Koppelmann 134d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u; 135d5de7839SBastian Koppelmann if (hw1 > max_pos) { 136d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 137d5de7839SBastian Koppelmann hw1 = max_pos; 138d5de7839SBastian Koppelmann } else if (hw1 < max_neg) { 139d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 140d5de7839SBastian Koppelmann hw1 = max_neg; 141d5de7839SBastian Koppelmann } 142d5de7839SBastian Koppelmann 143d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 144d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16; 145d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 146d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16); 147d5de7839SBastian Koppelmann } 148d5de7839SBastian Koppelmann 149d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 150d5de7839SBastian Koppelmann { 151d5de7839SBastian Koppelmann int32_t max_pos = UINT16_MAX; 152d5de7839SBastian Koppelmann int32_t av0, av1; 153d5de7839SBastian Koppelmann 154d5de7839SBastian Koppelmann env->PSW_USB_V = 0; 155d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u; 156d5de7839SBastian Koppelmann if (hw0 > max_pos) { 157d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 158d5de7839SBastian Koppelmann hw0 = max_pos; 159d5de7839SBastian Koppelmann } else if (hw0 < 0) { 160d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 161d5de7839SBastian Koppelmann hw0 = 0; 162d5de7839SBastian Koppelmann } 163d5de7839SBastian Koppelmann 164d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u; 165d5de7839SBastian Koppelmann if (hw1 > max_pos) { 166d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 167d5de7839SBastian Koppelmann hw1 = max_pos; 168d5de7839SBastian Koppelmann } else if (hw1 < 0) { 169d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 170d5de7839SBastian Koppelmann hw1 = 0; 171d5de7839SBastian Koppelmann } 172d5de7839SBastian Koppelmann 173d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 174d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16; 175d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 176d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16); 177d5de7839SBastian Koppelmann } 1780974257eSBastian Koppelmann 1792692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1, 1802692802aSBastian Koppelmann target_ulong r2) 1812692802aSBastian Koppelmann { 1822692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 1832692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 1842692802aSBastian Koppelmann int64_t result = t1 + t2; 185e4e39176SBastian Koppelmann return ssov32(env, result); 1862692802aSBastian Koppelmann } 1872692802aSBastian Koppelmann 1882e430e1cSBastian Koppelmann uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 1892e430e1cSBastian Koppelmann { 1902e430e1cSBastian Koppelmann uint64_t result; 1912e430e1cSBastian Koppelmann int64_t ovf; 1922e430e1cSBastian Koppelmann 1932e430e1cSBastian Koppelmann result = r1 + r2; 1942e430e1cSBastian Koppelmann ovf = (result ^ r1) & ~(r1 ^ r2); 1952e430e1cSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 1962e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1972e430e1cSBastian Koppelmann if (ovf < 0) { 1982e430e1cSBastian Koppelmann env->PSW_USB_V = (1 << 31); 1992e430e1cSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 2002e430e1cSBastian Koppelmann /* ext_ret > MAX_INT */ 2012e430e1cSBastian Koppelmann if ((int64_t)r1 >= 0) { 2022e430e1cSBastian Koppelmann result = INT64_MAX; 2032e430e1cSBastian Koppelmann /* ext_ret < MIN_INT */ 2042e430e1cSBastian Koppelmann } else { 2052e430e1cSBastian Koppelmann result = INT64_MIN; 2062e430e1cSBastian Koppelmann } 2072e430e1cSBastian Koppelmann } else { 2082e430e1cSBastian Koppelmann env->PSW_USB_V = 0; 2092e430e1cSBastian Koppelmann } 2102e430e1cSBastian Koppelmann return result; 2112e430e1cSBastian Koppelmann } 2122e430e1cSBastian Koppelmann 213d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1, 214d5de7839SBastian Koppelmann target_ulong r2) 215d5de7839SBastian Koppelmann { 216d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 217d5de7839SBastian Koppelmann 218d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16); 219d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16); 220d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 221d5de7839SBastian Koppelmann } 222d5de7839SBastian Koppelmann 2232e430e1cSBastian Koppelmann uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 2242e430e1cSBastian Koppelmann uint32_t r2_h) 2252e430e1cSBastian Koppelmann { 2262e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 2272e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 2282e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 2292e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 2302e430e1cSBastian Koppelmann int64_t result0, result1; 2312e430e1cSBastian Koppelmann uint32_t ovf0, ovf1; 2322e430e1cSBastian Koppelmann uint32_t avf0, avf1; 2332e430e1cSBastian Koppelmann 2342e430e1cSBastian Koppelmann ovf0 = ovf1 = 0; 2352e430e1cSBastian Koppelmann 2362e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 2372e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 2382e430e1cSBastian Koppelmann 2392e430e1cSBastian Koppelmann avf0 = result0 * 2u; 2402e430e1cSBastian Koppelmann avf0 = result0 ^ avf0; 2412e430e1cSBastian Koppelmann avf1 = result1 * 2u; 2422e430e1cSBastian Koppelmann avf1 = result1 ^ avf1; 2432e430e1cSBastian Koppelmann 2442e430e1cSBastian Koppelmann if (result0 > INT32_MAX) { 2452e430e1cSBastian Koppelmann ovf0 = (1 << 31); 2462e430e1cSBastian Koppelmann result0 = INT32_MAX; 2472e430e1cSBastian Koppelmann } else if (result0 < INT32_MIN) { 2482e430e1cSBastian Koppelmann ovf0 = (1 << 31); 2492e430e1cSBastian Koppelmann result0 = INT32_MIN; 2502e430e1cSBastian Koppelmann } 2512e430e1cSBastian Koppelmann 2522e430e1cSBastian Koppelmann if (result1 > INT32_MAX) { 2532e430e1cSBastian Koppelmann ovf1 = (1 << 31); 2542e430e1cSBastian Koppelmann result1 = INT32_MAX; 2552e430e1cSBastian Koppelmann } else if (result1 < INT32_MIN) { 2562e430e1cSBastian Koppelmann ovf1 = (1 << 31); 2572e430e1cSBastian Koppelmann result1 = INT32_MIN; 2582e430e1cSBastian Koppelmann } 2592e430e1cSBastian Koppelmann 2602e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 2612e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2622e430e1cSBastian Koppelmann 2632e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 2642e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 2652e430e1cSBastian Koppelmann 2662e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 2672e430e1cSBastian Koppelmann } 2682e430e1cSBastian Koppelmann 269bebe80fcSBastian Koppelmann uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 270bebe80fcSBastian Koppelmann uint32_t r2_h) 271bebe80fcSBastian Koppelmann { 272bebe80fcSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 273bebe80fcSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 274bebe80fcSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 275bebe80fcSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 276bebe80fcSBastian Koppelmann int64_t result0, result1; 277bebe80fcSBastian Koppelmann uint32_t ovf0, ovf1; 278bebe80fcSBastian Koppelmann uint32_t avf0, avf1; 279bebe80fcSBastian Koppelmann 280bebe80fcSBastian Koppelmann ovf0 = ovf1 = 0; 281bebe80fcSBastian Koppelmann 282bebe80fcSBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 283bebe80fcSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 284bebe80fcSBastian Koppelmann 285bebe80fcSBastian Koppelmann avf0 = result0 * 2u; 286bebe80fcSBastian Koppelmann avf0 = result0 ^ avf0; 287bebe80fcSBastian Koppelmann avf1 = result1 * 2u; 288bebe80fcSBastian Koppelmann avf1 = result1 ^ avf1; 289bebe80fcSBastian Koppelmann 290bebe80fcSBastian Koppelmann if (result0 > INT32_MAX) { 291bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 292bebe80fcSBastian Koppelmann result0 = INT32_MAX; 293bebe80fcSBastian Koppelmann } else if (result0 < INT32_MIN) { 294bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 295bebe80fcSBastian Koppelmann result0 = INT32_MIN; 296bebe80fcSBastian Koppelmann } 297bebe80fcSBastian Koppelmann 298bebe80fcSBastian Koppelmann if (result1 > INT32_MAX) { 299bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 300bebe80fcSBastian Koppelmann result1 = INT32_MAX; 301bebe80fcSBastian Koppelmann } else if (result1 < INT32_MIN) { 302bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 303bebe80fcSBastian Koppelmann result1 = INT32_MIN; 304bebe80fcSBastian Koppelmann } 305bebe80fcSBastian Koppelmann 306bebe80fcSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 307bebe80fcSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 308bebe80fcSBastian Koppelmann 309bebe80fcSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 310bebe80fcSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 311bebe80fcSBastian Koppelmann 312bebe80fcSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 313bebe80fcSBastian Koppelmann } 314bebe80fcSBastian Koppelmann 3152e430e1cSBastian Koppelmann 3160974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1, 3170974257eSBastian Koppelmann target_ulong r2) 3180974257eSBastian Koppelmann { 3190974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 3200974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 3210974257eSBastian Koppelmann int64_t result = t1 + t2; 32285d604afSBastian Koppelmann return suov32_pos(env, result); 3230974257eSBastian Koppelmann } 3240974257eSBastian Koppelmann 325d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1, 326d5de7839SBastian Koppelmann target_ulong r2) 327d5de7839SBastian Koppelmann { 328d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 329d5de7839SBastian Koppelmann 330d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16); 331d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16); 332d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 333d5de7839SBastian Koppelmann } 334d5de7839SBastian Koppelmann 3352692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1, 3362692802aSBastian Koppelmann target_ulong r2) 3372692802aSBastian Koppelmann { 3382692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 3392692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 3402692802aSBastian Koppelmann int64_t result = t1 - t2; 341e4e39176SBastian Koppelmann return ssov32(env, result); 3422692802aSBastian Koppelmann } 3432692802aSBastian Koppelmann 344f4aef476SBastian Koppelmann uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 345f4aef476SBastian Koppelmann { 346f4aef476SBastian Koppelmann uint64_t result; 347f4aef476SBastian Koppelmann int64_t ovf; 348f4aef476SBastian Koppelmann 349f4aef476SBastian Koppelmann result = r1 - r2; 350f4aef476SBastian Koppelmann ovf = (result ^ r1) & (r1 ^ r2); 351f4aef476SBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 352f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 353f4aef476SBastian Koppelmann if (ovf < 0) { 354f4aef476SBastian Koppelmann env->PSW_USB_V = (1 << 31); 355f4aef476SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 356f4aef476SBastian Koppelmann /* ext_ret > MAX_INT */ 357f4aef476SBastian Koppelmann if ((int64_t)r1 >= 0) { 358f4aef476SBastian Koppelmann result = INT64_MAX; 359f4aef476SBastian Koppelmann /* ext_ret < MIN_INT */ 360f4aef476SBastian Koppelmann } else { 361f4aef476SBastian Koppelmann result = INT64_MIN; 362f4aef476SBastian Koppelmann } 363f4aef476SBastian Koppelmann } else { 364f4aef476SBastian Koppelmann env->PSW_USB_V = 0; 365f4aef476SBastian Koppelmann } 366f4aef476SBastian Koppelmann return result; 367f4aef476SBastian Koppelmann } 368f4aef476SBastian Koppelmann 369d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1, 370d5de7839SBastian Koppelmann target_ulong r2) 371d5de7839SBastian Koppelmann { 372d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 373d5de7839SBastian Koppelmann 374d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16); 375d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16); 376d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 377d5de7839SBastian Koppelmann } 378d5de7839SBastian Koppelmann 379f4aef476SBastian Koppelmann uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 380f4aef476SBastian Koppelmann uint32_t r2_h) 381f4aef476SBastian Koppelmann { 382f4aef476SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 383f4aef476SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 384f4aef476SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 385f4aef476SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 386f4aef476SBastian Koppelmann int64_t result0, result1; 387f4aef476SBastian Koppelmann uint32_t ovf0, ovf1; 388f4aef476SBastian Koppelmann uint32_t avf0, avf1; 389f4aef476SBastian Koppelmann 390f4aef476SBastian Koppelmann ovf0 = ovf1 = 0; 391f4aef476SBastian Koppelmann 392f4aef476SBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 393f4aef476SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 394f4aef476SBastian Koppelmann 395f4aef476SBastian Koppelmann avf0 = result0 * 2u; 396f4aef476SBastian Koppelmann avf0 = result0 ^ avf0; 397f4aef476SBastian Koppelmann avf1 = result1 * 2u; 398f4aef476SBastian Koppelmann avf1 = result1 ^ avf1; 399f4aef476SBastian Koppelmann 400f4aef476SBastian Koppelmann if (result0 > INT32_MAX) { 401f4aef476SBastian Koppelmann ovf0 = (1 << 31); 402f4aef476SBastian Koppelmann result0 = INT32_MAX; 403f4aef476SBastian Koppelmann } else if (result0 < INT32_MIN) { 404f4aef476SBastian Koppelmann ovf0 = (1 << 31); 405f4aef476SBastian Koppelmann result0 = INT32_MIN; 406f4aef476SBastian Koppelmann } 407f4aef476SBastian Koppelmann 408f4aef476SBastian Koppelmann if (result1 > INT32_MAX) { 409f4aef476SBastian Koppelmann ovf1 = (1 << 31); 410f4aef476SBastian Koppelmann result1 = INT32_MAX; 411f4aef476SBastian Koppelmann } else if (result1 < INT32_MIN) { 412f4aef476SBastian Koppelmann ovf1 = (1 << 31); 413f4aef476SBastian Koppelmann result1 = INT32_MIN; 414f4aef476SBastian Koppelmann } 415f4aef476SBastian Koppelmann 416f4aef476SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 417f4aef476SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 418f4aef476SBastian Koppelmann 419f4aef476SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 420f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 421f4aef476SBastian Koppelmann 422f4aef476SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 423f4aef476SBastian Koppelmann } 424f4aef476SBastian Koppelmann 425068fac77SBastian Koppelmann uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 426068fac77SBastian Koppelmann uint32_t r2_h) 427068fac77SBastian Koppelmann { 428068fac77SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 429068fac77SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 430068fac77SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 431068fac77SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 432068fac77SBastian Koppelmann int64_t result0, result1; 433068fac77SBastian Koppelmann uint32_t ovf0, ovf1; 434068fac77SBastian Koppelmann uint32_t avf0, avf1; 435068fac77SBastian Koppelmann 436068fac77SBastian Koppelmann ovf0 = ovf1 = 0; 437068fac77SBastian Koppelmann 438068fac77SBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 439068fac77SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 440068fac77SBastian Koppelmann 441068fac77SBastian Koppelmann avf0 = result0 * 2u; 442068fac77SBastian Koppelmann avf0 = result0 ^ avf0; 443068fac77SBastian Koppelmann avf1 = result1 * 2u; 444068fac77SBastian Koppelmann avf1 = result1 ^ avf1; 445068fac77SBastian Koppelmann 446068fac77SBastian Koppelmann if (result0 > INT32_MAX) { 447068fac77SBastian Koppelmann ovf0 = (1 << 31); 448068fac77SBastian Koppelmann result0 = INT32_MAX; 449068fac77SBastian Koppelmann } else if (result0 < INT32_MIN) { 450068fac77SBastian Koppelmann ovf0 = (1 << 31); 451068fac77SBastian Koppelmann result0 = INT32_MIN; 452068fac77SBastian Koppelmann } 453068fac77SBastian Koppelmann 454068fac77SBastian Koppelmann if (result1 > INT32_MAX) { 455068fac77SBastian Koppelmann ovf1 = (1 << 31); 456068fac77SBastian Koppelmann result1 = INT32_MAX; 457068fac77SBastian Koppelmann } else if (result1 < INT32_MIN) { 458068fac77SBastian Koppelmann ovf1 = (1 << 31); 459068fac77SBastian Koppelmann result1 = INT32_MIN; 460068fac77SBastian Koppelmann } 461068fac77SBastian Koppelmann 462068fac77SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 463068fac77SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 464068fac77SBastian Koppelmann 465068fac77SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 466068fac77SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 467068fac77SBastian Koppelmann 468068fac77SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 469068fac77SBastian Koppelmann } 470068fac77SBastian Koppelmann 4710974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1, 4720974257eSBastian Koppelmann target_ulong r2) 4730974257eSBastian Koppelmann { 4740974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 4750974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 4760974257eSBastian Koppelmann int64_t result = t1 - t2; 47785d604afSBastian Koppelmann return suov32_neg(env, result); 4780974257eSBastian Koppelmann } 4790974257eSBastian Koppelmann 480d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1, 481d5de7839SBastian Koppelmann target_ulong r2) 482d5de7839SBastian Koppelmann { 483d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 484d5de7839SBastian Koppelmann 485d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16); 486d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16); 487d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 488d5de7839SBastian Koppelmann } 489d5de7839SBastian Koppelmann 4900974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1, 4910974257eSBastian Koppelmann target_ulong r2) 4920974257eSBastian Koppelmann { 4930974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 4940974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 4950974257eSBastian Koppelmann int64_t result = t1 * t2; 496e4e39176SBastian Koppelmann return ssov32(env, result); 4970974257eSBastian Koppelmann } 4980974257eSBastian Koppelmann 4990974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1, 5000974257eSBastian Koppelmann target_ulong r2) 5010974257eSBastian Koppelmann { 5020974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 5030974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 5040974257eSBastian Koppelmann int64_t result = t1 * t2; 5055f30046fSBastian Koppelmann 50685d604afSBastian Koppelmann return suov32_pos(env, result); 5070974257eSBastian Koppelmann } 5080974257eSBastian Koppelmann 5090974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1, 5100974257eSBastian Koppelmann target_ulong r2) 5110974257eSBastian Koppelmann { 5120974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 5130974257eSBastian Koppelmann int32_t t2 = sextract64(r2, 0, 6); 5140974257eSBastian Koppelmann int64_t result; 5150974257eSBastian Koppelmann if (t2 == 0) { 5160974257eSBastian Koppelmann result = t1; 5170974257eSBastian Koppelmann } else if (t2 > 0) { 5180974257eSBastian Koppelmann result = t1 << t2; 5190974257eSBastian Koppelmann } else { 5200974257eSBastian Koppelmann result = t1 >> -t2; 5210974257eSBastian Koppelmann } 522e4e39176SBastian Koppelmann return ssov32(env, result); 5230974257eSBastian Koppelmann } 5240974257eSBastian Koppelmann 525d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1) 526d5de7839SBastian Koppelmann { 527d5de7839SBastian Koppelmann target_ulong result; 528d5de7839SBastian Koppelmann result = ((int32_t)r1 >= 0) ? r1 : (0 - r1); 529d5de7839SBastian Koppelmann return ssov32(env, result); 530d5de7839SBastian Koppelmann } 531d5de7839SBastian Koppelmann 532d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1) 533d5de7839SBastian Koppelmann { 534d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 535d5de7839SBastian Koppelmann 536d5de7839SBastian Koppelmann ret_h0 = sextract32(r1, 0, 16); 537d5de7839SBastian Koppelmann ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0); 538d5de7839SBastian Koppelmann 539d5de7839SBastian Koppelmann ret_h1 = sextract32(r1, 16, 16); 540d5de7839SBastian Koppelmann ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1); 541d5de7839SBastian Koppelmann 542d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 543d5de7839SBastian Koppelmann } 544d5de7839SBastian Koppelmann 5450974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1, 5460974257eSBastian Koppelmann target_ulong r2) 5470974257eSBastian Koppelmann { 5480974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 5490974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 5500974257eSBastian Koppelmann int64_t result; 5510974257eSBastian Koppelmann 5520974257eSBastian Koppelmann if (t1 > t2) { 5530974257eSBastian Koppelmann result = t1 - t2; 5540974257eSBastian Koppelmann } else { 5550974257eSBastian Koppelmann result = t2 - t1; 5560974257eSBastian Koppelmann } 557e4e39176SBastian Koppelmann return ssov32(env, result); 5580974257eSBastian Koppelmann } 559328f1f0fSBastian Koppelmann 560d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1, 561d5de7839SBastian Koppelmann target_ulong r2) 562d5de7839SBastian Koppelmann { 563d5de7839SBastian Koppelmann int32_t t1, t2; 564d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 565d5de7839SBastian Koppelmann 566d5de7839SBastian Koppelmann t1 = sextract32(r1, 0, 16); 567d5de7839SBastian Koppelmann t2 = sextract32(r2, 0, 16); 568d5de7839SBastian Koppelmann if (t1 > t2) { 569d5de7839SBastian Koppelmann ret_h0 = t1 - t2; 570d5de7839SBastian Koppelmann } else { 571d5de7839SBastian Koppelmann ret_h0 = t2 - t1; 572d5de7839SBastian Koppelmann } 573d5de7839SBastian Koppelmann 574d5de7839SBastian Koppelmann t1 = sextract32(r1, 16, 16); 575d5de7839SBastian Koppelmann t2 = sextract32(r2, 16, 16); 576d5de7839SBastian Koppelmann if (t1 > t2) { 577d5de7839SBastian Koppelmann ret_h1 = t1 - t2; 578d5de7839SBastian Koppelmann } else { 579d5de7839SBastian Koppelmann ret_h1 = t2 - t1; 580d5de7839SBastian Koppelmann } 581d5de7839SBastian Koppelmann 582d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 583d5de7839SBastian Koppelmann } 584d5de7839SBastian Koppelmann 585328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1, 586328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 587328f1f0fSBastian Koppelmann { 588328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 589328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 590328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 591328f1f0fSBastian Koppelmann int64_t result; 592328f1f0fSBastian Koppelmann 593328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 594e4e39176SBastian Koppelmann return ssov32(env, result); 595328f1f0fSBastian Koppelmann } 596328f1f0fSBastian Koppelmann 597328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1, 598328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 599328f1f0fSBastian Koppelmann { 600328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 601328f1f0fSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 602328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 603328f1f0fSBastian Koppelmann int64_t result; 604328f1f0fSBastian Koppelmann 605328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 60685d604afSBastian Koppelmann return suov32_pos(env, result); 607328f1f0fSBastian Koppelmann } 608328f1f0fSBastian Koppelmann 609328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1, 610328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 611328f1f0fSBastian Koppelmann { 612328f1f0fSBastian Koppelmann uint64_t ret, ovf; 613328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 614328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 615328f1f0fSBastian Koppelmann int64_t mul; 616328f1f0fSBastian Koppelmann 617328f1f0fSBastian Koppelmann mul = t1 * t3; 618328f1f0fSBastian Koppelmann ret = mul + r2; 619328f1f0fSBastian Koppelmann ovf = (ret ^ mul) & ~(mul ^ r2); 620328f1f0fSBastian Koppelmann 621811ea608SBastian Koppelmann t1 = ret >> 32; 622811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 623811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 624811ea608SBastian Koppelmann 625328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 626328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 627328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 628328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 629328f1f0fSBastian Koppelmann if (mul >= 0) { 630328f1f0fSBastian Koppelmann ret = INT64_MAX; 631328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 632328f1f0fSBastian Koppelmann } else { 633328f1f0fSBastian Koppelmann ret = INT64_MIN; 634328f1f0fSBastian Koppelmann } 635328f1f0fSBastian Koppelmann } else { 636328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 637328f1f0fSBastian Koppelmann } 638328f1f0fSBastian Koppelmann 639328f1f0fSBastian Koppelmann return ret; 640328f1f0fSBastian Koppelmann } 641328f1f0fSBastian Koppelmann 642b00aa8ecSBastian Koppelmann uint32_t 643b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 644b00aa8ecSBastian Koppelmann { 645b00aa8ecSBastian Koppelmann int64_t result; 646b00aa8ecSBastian Koppelmann 647b00aa8ecSBastian Koppelmann result = (r1 + r2); 648b00aa8ecSBastian Koppelmann 649b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u); 650b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 651b00aa8ecSBastian Koppelmann 652b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 653b00aa8ecSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 654b00aa8ecSBastian Koppelmann case, we flip the saturated value. */ 655b00aa8ecSBastian Koppelmann if (r2 == 0x8000000000000000LL) { 656b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) { 657b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 658b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 659b00aa8ecSBastian Koppelmann result = INT32_MIN; 660b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) { 661b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 662b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 663b00aa8ecSBastian Koppelmann result = INT32_MAX; 664b00aa8ecSBastian Koppelmann } else { 665b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 666b00aa8ecSBastian Koppelmann } 667b00aa8ecSBastian Koppelmann } else { 668b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) { 669b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 670b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 671b00aa8ecSBastian Koppelmann result = INT32_MAX; 672b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) { 673b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 674b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 675b00aa8ecSBastian Koppelmann result = INT32_MIN; 676b00aa8ecSBastian Koppelmann } else { 677b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 678b00aa8ecSBastian Koppelmann } 679b00aa8ecSBastian Koppelmann } 680b00aa8ecSBastian Koppelmann return (uint32_t)result; 681b00aa8ecSBastian Koppelmann } 682b00aa8ecSBastian Koppelmann 683b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 684b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 685b00aa8ecSBastian Koppelmann { 686b00aa8ecSBastian Koppelmann int64_t t1 = (int64_t)r1; 687b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 688b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 689b00aa8ecSBastian Koppelmann int64_t result, mul; 690b00aa8ecSBastian Koppelmann int64_t ovf; 691b00aa8ecSBastian Koppelmann 692b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 693b00aa8ecSBastian Koppelmann result = mul + t1; 694b00aa8ecSBastian Koppelmann 695b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 696b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 697b00aa8ecSBastian Koppelmann 698b00aa8ecSBastian Koppelmann ovf = (result ^ mul) & ~(mul ^ t1); 699b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 700b00aa8ecSBastian Koppelmann if the mul was (0x80000000 * 0x80000000) << 1). If this is the 701b00aa8ecSBastian Koppelmann case, we flip the saturated value. */ 702b00aa8ecSBastian Koppelmann if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) { 703b00aa8ecSBastian Koppelmann if (ovf >= 0) { 704b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 705b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 706b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */ 707b00aa8ecSBastian Koppelmann if (mul < 0) { 708b00aa8ecSBastian Koppelmann result = INT64_MAX; 709b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */ 710b00aa8ecSBastian Koppelmann } else { 711b00aa8ecSBastian Koppelmann result = INT64_MIN; 712b00aa8ecSBastian Koppelmann } 713b00aa8ecSBastian Koppelmann } else { 714b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 715b00aa8ecSBastian Koppelmann } 716b00aa8ecSBastian Koppelmann } else { 717b00aa8ecSBastian Koppelmann if (ovf < 0) { 718b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 719b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 720b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */ 721b00aa8ecSBastian Koppelmann if (mul >= 0) { 722b00aa8ecSBastian Koppelmann result = INT64_MAX; 723b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */ 724b00aa8ecSBastian Koppelmann } else { 725b00aa8ecSBastian Koppelmann result = INT64_MIN; 726b00aa8ecSBastian Koppelmann } 727b00aa8ecSBastian Koppelmann } else { 728b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 729b00aa8ecSBastian Koppelmann } 730b00aa8ecSBastian Koppelmann } 731b00aa8ecSBastian Koppelmann return (uint64_t)result; 732b00aa8ecSBastian Koppelmann } 733b00aa8ecSBastian Koppelmann 734b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 735b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 736b00aa8ecSBastian Koppelmann { 737b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 738b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 739b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 740b00aa8ecSBastian Koppelmann int64_t mul, ret; 741b00aa8ecSBastian Koppelmann 742b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 743b00aa8ecSBastian Koppelmann mul = 0x7fffffff; 744b00aa8ecSBastian Koppelmann } else { 745b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 746b00aa8ecSBastian Koppelmann } 747b00aa8ecSBastian Koppelmann 748b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000; 749b00aa8ecSBastian Koppelmann 750b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 751b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 752b00aa8ecSBastian Koppelmann 753b00aa8ecSBastian Koppelmann if (ret > 0x7fffffffll) { 754b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 755b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 756b00aa8ecSBastian Koppelmann ret = INT32_MAX; 757b00aa8ecSBastian Koppelmann } else if (ret < -0x80000000ll) { 758b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 759b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 760b00aa8ecSBastian Koppelmann ret = INT32_MIN; 761b00aa8ecSBastian Koppelmann } else { 762b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 763b00aa8ecSBastian Koppelmann } 764b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll; 765b00aa8ecSBastian Koppelmann } 766b00aa8ecSBastian Koppelmann 767328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1, 768328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 769328f1f0fSBastian Koppelmann { 770328f1f0fSBastian Koppelmann uint64_t ret, mul; 771328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 772328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 773328f1f0fSBastian Koppelmann 774328f1f0fSBastian Koppelmann mul = t1 * t3; 775328f1f0fSBastian Koppelmann ret = mul + r2; 776328f1f0fSBastian Koppelmann 777811ea608SBastian Koppelmann t1 = ret >> 32; 778811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 779811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 780811ea608SBastian Koppelmann 781328f1f0fSBastian Koppelmann if (ret < r2) { 782328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 783328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 784328f1f0fSBastian Koppelmann /* saturate */ 785328f1f0fSBastian Koppelmann ret = UINT64_MAX; 786328f1f0fSBastian Koppelmann } else { 787328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 788328f1f0fSBastian Koppelmann } 789328f1f0fSBastian Koppelmann return ret; 790328f1f0fSBastian Koppelmann } 791328f1f0fSBastian Koppelmann 792328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1, 793328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 794328f1f0fSBastian Koppelmann { 795328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 796328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 797328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 798328f1f0fSBastian Koppelmann int64_t result; 799328f1f0fSBastian Koppelmann 800328f1f0fSBastian Koppelmann result = t2 - (t1 * t3); 801e4e39176SBastian Koppelmann return ssov32(env, result); 802328f1f0fSBastian Koppelmann } 803328f1f0fSBastian Koppelmann 804328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1, 805328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 806328f1f0fSBastian Koppelmann { 8073debbb5aSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 8083debbb5aSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 8093debbb5aSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 8103debbb5aSBastian Koppelmann uint64_t result; 8113debbb5aSBastian Koppelmann uint64_t mul; 812328f1f0fSBastian Koppelmann 8133debbb5aSBastian Koppelmann mul = (t1 * t3); 8143debbb5aSBastian Koppelmann result = t2 - mul; 8153debbb5aSBastian Koppelmann 8163debbb5aSBastian Koppelmann env->PSW_USB_AV = result ^ result * 2u; 8173debbb5aSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 8183debbb5aSBastian Koppelmann /* we calculate ovf by hand here, because the multiplication can overflow on 8193debbb5aSBastian Koppelmann the host, which would give false results if we compare to less than 8203debbb5aSBastian Koppelmann zero */ 8213debbb5aSBastian Koppelmann if (mul > t2) { 8223debbb5aSBastian Koppelmann env->PSW_USB_V = (1 << 31); 8233debbb5aSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 8243debbb5aSBastian Koppelmann result = 0; 8253debbb5aSBastian Koppelmann } else { 8263debbb5aSBastian Koppelmann env->PSW_USB_V = 0; 8273debbb5aSBastian Koppelmann } 8283debbb5aSBastian Koppelmann return result; 829328f1f0fSBastian Koppelmann } 830328f1f0fSBastian Koppelmann 831328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1, 832328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 833328f1f0fSBastian Koppelmann { 834328f1f0fSBastian Koppelmann uint64_t ret, ovf; 835328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 836328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 837328f1f0fSBastian Koppelmann int64_t mul; 838328f1f0fSBastian Koppelmann 839328f1f0fSBastian Koppelmann mul = t1 * t3; 840328f1f0fSBastian Koppelmann ret = r2 - mul; 841328f1f0fSBastian Koppelmann ovf = (ret ^ r2) & (mul ^ r2); 842328f1f0fSBastian Koppelmann 843811ea608SBastian Koppelmann t1 = ret >> 32; 844811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 845811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 846811ea608SBastian Koppelmann 847328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 848328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 849328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 850328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 851328f1f0fSBastian Koppelmann if (mul < 0) { 852328f1f0fSBastian Koppelmann ret = INT64_MAX; 853328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 854328f1f0fSBastian Koppelmann } else { 855328f1f0fSBastian Koppelmann ret = INT64_MIN; 856328f1f0fSBastian Koppelmann } 857328f1f0fSBastian Koppelmann } else { 858328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 859328f1f0fSBastian Koppelmann } 860328f1f0fSBastian Koppelmann return ret; 861328f1f0fSBastian Koppelmann } 862328f1f0fSBastian Koppelmann 863328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1, 864328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 865328f1f0fSBastian Koppelmann { 866328f1f0fSBastian Koppelmann uint64_t ret, mul; 867328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 868328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 869328f1f0fSBastian Koppelmann 870328f1f0fSBastian Koppelmann mul = t1 * t3; 871328f1f0fSBastian Koppelmann ret = r2 - mul; 872328f1f0fSBastian Koppelmann 873811ea608SBastian Koppelmann t1 = ret >> 32; 874811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 875811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 876811ea608SBastian Koppelmann 877328f1f0fSBastian Koppelmann if (ret > r2) { 878328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 879328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 880328f1f0fSBastian Koppelmann /* saturate */ 881328f1f0fSBastian Koppelmann ret = 0; 882328f1f0fSBastian Koppelmann } else { 883328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 884328f1f0fSBastian Koppelmann } 885328f1f0fSBastian Koppelmann return ret; 886328f1f0fSBastian Koppelmann } 887328f1f0fSBastian Koppelmann 88862e47b2eSBastian Koppelmann uint32_t 88962e47b2eSBastian Koppelmann helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 89062e47b2eSBastian Koppelmann { 89162e47b2eSBastian Koppelmann int64_t result; 89262e47b2eSBastian Koppelmann int64_t t1 = (int64_t)r1; 89362e47b2eSBastian Koppelmann int64_t t2 = (int64_t)r2; 89462e47b2eSBastian Koppelmann 89562e47b2eSBastian Koppelmann result = t1 - t2; 89662e47b2eSBastian Koppelmann 89762e47b2eSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u); 89862e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 89962e47b2eSBastian Koppelmann 90062e47b2eSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 90162e47b2eSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 90262e47b2eSBastian Koppelmann case, we flip the saturated value. */ 90362e47b2eSBastian Koppelmann if (r2 == 0x8000000000000000LL) { 90462e47b2eSBastian Koppelmann if (result > 0x7fffffffLL) { 90562e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 90662e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 90762e47b2eSBastian Koppelmann result = INT32_MIN; 90862e47b2eSBastian Koppelmann } else if (result < -0x80000000LL) { 90962e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 91062e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 91162e47b2eSBastian Koppelmann result = INT32_MAX; 91262e47b2eSBastian Koppelmann } else { 91362e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 91462e47b2eSBastian Koppelmann } 91562e47b2eSBastian Koppelmann } else { 91662e47b2eSBastian Koppelmann if (result > 0x7fffffffLL) { 91762e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 91862e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 91962e47b2eSBastian Koppelmann result = INT32_MAX; 92062e47b2eSBastian Koppelmann } else if (result < -0x80000000LL) { 92162e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 92262e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 92362e47b2eSBastian Koppelmann result = INT32_MIN; 92462e47b2eSBastian Koppelmann } else { 92562e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 92662e47b2eSBastian Koppelmann } 92762e47b2eSBastian Koppelmann } 92862e47b2eSBastian Koppelmann return (uint32_t)result; 92962e47b2eSBastian Koppelmann } 93062e47b2eSBastian Koppelmann 93162e47b2eSBastian Koppelmann uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 93262e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 93362e47b2eSBastian Koppelmann { 93462e47b2eSBastian Koppelmann int64_t t1 = (int64_t)r1; 93562e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 93662e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 93762e47b2eSBastian Koppelmann int64_t result, mul; 93862e47b2eSBastian Koppelmann int64_t ovf; 93962e47b2eSBastian Koppelmann 94062e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 94162e47b2eSBastian Koppelmann result = t1 - mul; 94262e47b2eSBastian Koppelmann 94362e47b2eSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 94462e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 94562e47b2eSBastian Koppelmann 94662e47b2eSBastian Koppelmann ovf = (result ^ t1) & (t1 ^ mul); 94762e47b2eSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 94862e47b2eSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 94962e47b2eSBastian Koppelmann case, we flip the saturated value. */ 95062e47b2eSBastian Koppelmann if (mul == 0x8000000000000000LL) { 95162e47b2eSBastian Koppelmann if (ovf >= 0) { 95262e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 95362e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 95462e47b2eSBastian Koppelmann /* ext_ret > MAX_INT */ 95562e47b2eSBastian Koppelmann if (mul >= 0) { 95662e47b2eSBastian Koppelmann result = INT64_MAX; 95762e47b2eSBastian Koppelmann /* ext_ret < MIN_INT */ 95862e47b2eSBastian Koppelmann } else { 95962e47b2eSBastian Koppelmann result = INT64_MIN; 96062e47b2eSBastian Koppelmann } 96162e47b2eSBastian Koppelmann } 96262e47b2eSBastian Koppelmann } else { 96362e47b2eSBastian Koppelmann if (ovf < 0) { 96462e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 96562e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 96662e47b2eSBastian Koppelmann /* ext_ret > MAX_INT */ 96762e47b2eSBastian Koppelmann if (mul < 0) { 96862e47b2eSBastian Koppelmann result = INT64_MAX; 96962e47b2eSBastian Koppelmann /* ext_ret < MIN_INT */ 97062e47b2eSBastian Koppelmann } else { 97162e47b2eSBastian Koppelmann result = INT64_MIN; 97262e47b2eSBastian Koppelmann } 97362e47b2eSBastian Koppelmann } else { 97462e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 97562e47b2eSBastian Koppelmann } 97662e47b2eSBastian Koppelmann } 97762e47b2eSBastian Koppelmann 97862e47b2eSBastian Koppelmann return (uint64_t)result; 97962e47b2eSBastian Koppelmann } 98062e47b2eSBastian Koppelmann 98162e47b2eSBastian Koppelmann uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 98262e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 98362e47b2eSBastian Koppelmann { 98462e47b2eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 98562e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 98662e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 98762e47b2eSBastian Koppelmann int64_t mul, ret; 98862e47b2eSBastian Koppelmann 98962e47b2eSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 99062e47b2eSBastian Koppelmann mul = 0x7fffffff; 99162e47b2eSBastian Koppelmann } else { 99262e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 99362e47b2eSBastian Koppelmann } 99462e47b2eSBastian Koppelmann 99562e47b2eSBastian Koppelmann ret = t1 - mul + 0x8000; 99662e47b2eSBastian Koppelmann 99762e47b2eSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 99862e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 99962e47b2eSBastian Koppelmann 100062e47b2eSBastian Koppelmann if (ret > 0x7fffffffll) { 100162e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 100262e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 100362e47b2eSBastian Koppelmann ret = INT32_MAX; 100462e47b2eSBastian Koppelmann } else if (ret < -0x80000000ll) { 100562e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 100662e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 100762e47b2eSBastian Koppelmann ret = INT32_MIN; 100862e47b2eSBastian Koppelmann } else { 100962e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 101062e47b2eSBastian Koppelmann } 101162e47b2eSBastian Koppelmann return ret & 0xffff0000ll; 101262e47b2eSBastian Koppelmann } 101362e47b2eSBastian Koppelmann 1014d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg) 1015d5de7839SBastian Koppelmann { 1016d5de7839SBastian Koppelmann int32_t b, i; 1017d5de7839SBastian Koppelmann int32_t ovf = 0; 1018d5de7839SBastian Koppelmann int32_t avf = 0; 1019d5de7839SBastian Koppelmann int32_t ret = 0; 1020d5de7839SBastian Koppelmann 1021d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1022d5de7839SBastian Koppelmann b = sextract32(arg, i * 8, 8); 1023d5de7839SBastian Koppelmann b = (b >= 0) ? b : (0 - b); 1024d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 1025d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1026d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 1027d5de7839SBastian Koppelmann } 1028d5de7839SBastian Koppelmann 1029d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1030d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1031d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1032d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1033d5de7839SBastian Koppelmann 1034d5de7839SBastian Koppelmann return ret; 1035d5de7839SBastian Koppelmann } 1036d5de7839SBastian Koppelmann 1037d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg) 1038d5de7839SBastian Koppelmann { 1039d5de7839SBastian Koppelmann int32_t h, i; 1040d5de7839SBastian Koppelmann int32_t ovf = 0; 1041d5de7839SBastian Koppelmann int32_t avf = 0; 1042d5de7839SBastian Koppelmann int32_t ret = 0; 1043d5de7839SBastian Koppelmann 1044d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1045d5de7839SBastian Koppelmann h = sextract32(arg, i * 16, 16); 1046d5de7839SBastian Koppelmann h = (h >= 0) ? h : (0 - h); 1047d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 1048d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1049d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1050d5de7839SBastian Koppelmann } 1051d5de7839SBastian Koppelmann 1052d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1053d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1054d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1055d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1056d5de7839SBastian Koppelmann 1057d5de7839SBastian Koppelmann return ret; 1058d5de7839SBastian Koppelmann } 1059d5de7839SBastian Koppelmann 1060d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1061d5de7839SBastian Koppelmann { 1062d5de7839SBastian Koppelmann int32_t b, i; 1063d5de7839SBastian Koppelmann int32_t extr_r2; 1064d5de7839SBastian Koppelmann int32_t ovf = 0; 1065d5de7839SBastian Koppelmann int32_t avf = 0; 1066d5de7839SBastian Koppelmann int32_t ret = 0; 1067d5de7839SBastian Koppelmann 1068d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1069d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1070d5de7839SBastian Koppelmann b = sextract32(r1, i * 8, 8); 1071d5de7839SBastian Koppelmann b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b); 1072d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 1073d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1074d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 1075d5de7839SBastian Koppelmann } 1076d5de7839SBastian Koppelmann 1077d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1078d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1079d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1080d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1081d5de7839SBastian Koppelmann return ret; 1082d5de7839SBastian Koppelmann } 1083d5de7839SBastian Koppelmann 1084d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1085d5de7839SBastian Koppelmann { 1086d5de7839SBastian Koppelmann int32_t h, i; 1087d5de7839SBastian Koppelmann int32_t extr_r2; 1088d5de7839SBastian Koppelmann int32_t ovf = 0; 1089d5de7839SBastian Koppelmann int32_t avf = 0; 1090d5de7839SBastian Koppelmann int32_t ret = 0; 1091d5de7839SBastian Koppelmann 1092d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1093d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1094d5de7839SBastian Koppelmann h = sextract32(r1, i * 16, 16); 1095d5de7839SBastian Koppelmann h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h); 1096d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 1097d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1098d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1099d5de7839SBastian Koppelmann } 1100d5de7839SBastian Koppelmann 1101d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1102d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1103d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1104d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1105d5de7839SBastian Koppelmann 1106d5de7839SBastian Koppelmann return ret; 1107d5de7839SBastian Koppelmann } 1108d5de7839SBastian Koppelmann 11092e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 11102e430e1cSBastian Koppelmann uint32_t r2_h) 11112e430e1cSBastian Koppelmann { 11122e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 11132e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 11142e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 11152e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 11162e430e1cSBastian Koppelmann int64_t result0, result1; 11172e430e1cSBastian Koppelmann uint32_t ovf0, ovf1; 11182e430e1cSBastian Koppelmann uint32_t avf0, avf1; 11192e430e1cSBastian Koppelmann 11202e430e1cSBastian Koppelmann ovf0 = ovf1 = 0; 11212e430e1cSBastian Koppelmann 11222e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 11232e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 11242e430e1cSBastian Koppelmann 11252e430e1cSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 11262e430e1cSBastian Koppelmann ovf0 = (1 << 31); 11272e430e1cSBastian Koppelmann } 11282e430e1cSBastian Koppelmann 11292e430e1cSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 11302e430e1cSBastian Koppelmann ovf1 = (1 << 31); 11312e430e1cSBastian Koppelmann } 11322e430e1cSBastian Koppelmann 11332e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 11342e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 11352e430e1cSBastian Koppelmann 11362e430e1cSBastian Koppelmann avf0 = result0 * 2u; 11372e430e1cSBastian Koppelmann avf0 = result0 ^ avf0; 11382e430e1cSBastian Koppelmann avf1 = result1 * 2u; 11392e430e1cSBastian Koppelmann avf1 = result1 ^ avf1; 11402e430e1cSBastian Koppelmann 11412e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 11422e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 11432e430e1cSBastian Koppelmann 11442e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 11452e430e1cSBastian Koppelmann } 11462e430e1cSBastian Koppelmann 1147bebe80fcSBastian Koppelmann uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1148bebe80fcSBastian Koppelmann uint32_t r2_h) 1149bebe80fcSBastian Koppelmann { 1150bebe80fcSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1151bebe80fcSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1152bebe80fcSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1153bebe80fcSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1154bebe80fcSBastian Koppelmann int64_t result0, result1; 1155bebe80fcSBastian Koppelmann uint32_t ovf0, ovf1; 1156bebe80fcSBastian Koppelmann uint32_t avf0, avf1; 1157bebe80fcSBastian Koppelmann 1158bebe80fcSBastian Koppelmann ovf0 = ovf1 = 0; 1159bebe80fcSBastian Koppelmann 1160bebe80fcSBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 1161bebe80fcSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 1162bebe80fcSBastian Koppelmann 1163bebe80fcSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1164bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 1165bebe80fcSBastian Koppelmann } 1166bebe80fcSBastian Koppelmann 1167bebe80fcSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1168bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 1169bebe80fcSBastian Koppelmann } 1170bebe80fcSBastian Koppelmann 1171bebe80fcSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1172bebe80fcSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1173bebe80fcSBastian Koppelmann 1174bebe80fcSBastian Koppelmann avf0 = result0 * 2u; 1175bebe80fcSBastian Koppelmann avf0 = result0 ^ avf0; 1176bebe80fcSBastian Koppelmann avf1 = result1 * 2u; 1177bebe80fcSBastian Koppelmann avf1 = result1 ^ avf1; 1178bebe80fcSBastian Koppelmann 1179bebe80fcSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1180bebe80fcSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1181bebe80fcSBastian Koppelmann 1182bebe80fcSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1183bebe80fcSBastian Koppelmann } 1184bebe80fcSBastian Koppelmann 1185b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 1186b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 1187b00aa8ecSBastian Koppelmann { 1188b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 1189b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 1190b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 1191b00aa8ecSBastian Koppelmann int64_t mul, ret; 1192b00aa8ecSBastian Koppelmann 1193b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 1194b00aa8ecSBastian Koppelmann mul = 0x7fffffff; 1195b00aa8ecSBastian Koppelmann } else { 1196b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 1197b00aa8ecSBastian Koppelmann } 1198b00aa8ecSBastian Koppelmann 1199b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000; 1200b00aa8ecSBastian Koppelmann 1201b00aa8ecSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 1202b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 1203b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1204b00aa8ecSBastian Koppelmann } else { 1205b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 1206b00aa8ecSBastian Koppelmann } 1207b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 1208b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1209b00aa8ecSBastian Koppelmann 1210b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll; 1211b00aa8ecSBastian Koppelmann } 1212b00aa8ecSBastian Koppelmann 1213d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1214d5de7839SBastian Koppelmann { 1215d5de7839SBastian Koppelmann int32_t b, i; 1216d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1217d5de7839SBastian Koppelmann int32_t ovf = 0; 1218d5de7839SBastian Koppelmann int32_t avf = 0; 1219d5de7839SBastian Koppelmann uint32_t ret = 0; 1220d5de7839SBastian Koppelmann 1221d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1222d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 1223d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1224d5de7839SBastian Koppelmann 1225d5de7839SBastian Koppelmann b = extr_r1 + extr_r2; 1226d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 1227d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1228d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 1229d5de7839SBastian Koppelmann } 1230d5de7839SBastian Koppelmann 1231d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1232d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1233d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1234d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1235d5de7839SBastian Koppelmann 1236d5de7839SBastian Koppelmann return ret; 1237d5de7839SBastian Koppelmann } 1238d5de7839SBastian Koppelmann 1239d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1240d5de7839SBastian Koppelmann { 1241d5de7839SBastian Koppelmann int32_t h, i; 1242d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1243d5de7839SBastian Koppelmann int32_t ovf = 0; 1244d5de7839SBastian Koppelmann int32_t avf = 0; 1245d5de7839SBastian Koppelmann int32_t ret = 0; 1246d5de7839SBastian Koppelmann 1247d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1248d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 1249d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1250d5de7839SBastian Koppelmann h = extr_r1 + extr_r2; 1251d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 1252d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1253d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1254d5de7839SBastian Koppelmann } 1255d5de7839SBastian Koppelmann 1256d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1257d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1258d5de7839SBastian Koppelmann env->PSW_USB_AV = (avf << 16); 1259d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1260d5de7839SBastian Koppelmann 1261d5de7839SBastian Koppelmann return ret; 1262d5de7839SBastian Koppelmann } 1263d5de7839SBastian Koppelmann 1264f4aef476SBastian Koppelmann uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1265f4aef476SBastian Koppelmann uint32_t r2_h) 1266f4aef476SBastian Koppelmann { 1267f4aef476SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1268f4aef476SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1269f4aef476SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1270f4aef476SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1271f4aef476SBastian Koppelmann int64_t result0, result1; 1272f4aef476SBastian Koppelmann uint32_t ovf0, ovf1; 1273f4aef476SBastian Koppelmann uint32_t avf0, avf1; 1274f4aef476SBastian Koppelmann 1275f4aef476SBastian Koppelmann ovf0 = ovf1 = 0; 1276f4aef476SBastian Koppelmann 1277f4aef476SBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 1278f4aef476SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 1279f4aef476SBastian Koppelmann 1280f4aef476SBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1281f4aef476SBastian Koppelmann ovf0 = (1 << 31); 1282f4aef476SBastian Koppelmann } 1283f4aef476SBastian Koppelmann 1284f4aef476SBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1285f4aef476SBastian Koppelmann ovf1 = (1 << 31); 1286f4aef476SBastian Koppelmann } 1287f4aef476SBastian Koppelmann 1288f4aef476SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1289f4aef476SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1290f4aef476SBastian Koppelmann 1291f4aef476SBastian Koppelmann avf0 = result0 * 2u; 1292f4aef476SBastian Koppelmann avf0 = result0 ^ avf0; 1293f4aef476SBastian Koppelmann avf1 = result1 * 2u; 1294f4aef476SBastian Koppelmann avf1 = result1 ^ avf1; 1295f4aef476SBastian Koppelmann 1296f4aef476SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1297f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1298f4aef476SBastian Koppelmann 1299f4aef476SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1300f4aef476SBastian Koppelmann } 1301f4aef476SBastian Koppelmann 1302068fac77SBastian Koppelmann uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1303068fac77SBastian Koppelmann uint32_t r2_h) 1304068fac77SBastian Koppelmann { 1305068fac77SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1306068fac77SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1307068fac77SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1308068fac77SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1309068fac77SBastian Koppelmann int64_t result0, result1; 1310068fac77SBastian Koppelmann uint32_t ovf0, ovf1; 1311068fac77SBastian Koppelmann uint32_t avf0, avf1; 1312068fac77SBastian Koppelmann 1313068fac77SBastian Koppelmann ovf0 = ovf1 = 0; 1314068fac77SBastian Koppelmann 1315068fac77SBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 1316068fac77SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 1317068fac77SBastian Koppelmann 1318068fac77SBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1319068fac77SBastian Koppelmann ovf0 = (1 << 31); 1320068fac77SBastian Koppelmann } 1321068fac77SBastian Koppelmann 1322068fac77SBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1323068fac77SBastian Koppelmann ovf1 = (1 << 31); 1324068fac77SBastian Koppelmann } 1325068fac77SBastian Koppelmann 1326068fac77SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1327068fac77SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1328068fac77SBastian Koppelmann 1329068fac77SBastian Koppelmann avf0 = result0 * 2u; 1330068fac77SBastian Koppelmann avf0 = result0 ^ avf0; 1331068fac77SBastian Koppelmann avf1 = result1 * 2u; 1332068fac77SBastian Koppelmann avf1 = result1 ^ avf1; 1333068fac77SBastian Koppelmann 1334068fac77SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1335068fac77SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1336068fac77SBastian Koppelmann 1337068fac77SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1338068fac77SBastian Koppelmann } 1339068fac77SBastian Koppelmann 134062e47b2eSBastian Koppelmann uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 134162e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 134262e47b2eSBastian Koppelmann { 134362e47b2eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 134462e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 134562e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 134662e47b2eSBastian Koppelmann int64_t mul, ret; 134762e47b2eSBastian Koppelmann 134862e47b2eSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 134962e47b2eSBastian Koppelmann mul = 0x7fffffff; 135062e47b2eSBastian Koppelmann } else { 135162e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 135262e47b2eSBastian Koppelmann } 135362e47b2eSBastian Koppelmann 135462e47b2eSBastian Koppelmann ret = t1 - mul + 0x8000; 135562e47b2eSBastian Koppelmann 135662e47b2eSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 135762e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 135862e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 135962e47b2eSBastian Koppelmann } else { 136062e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 136162e47b2eSBastian Koppelmann } 136262e47b2eSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 136362e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 136462e47b2eSBastian Koppelmann 136562e47b2eSBastian Koppelmann return ret & 0xffff0000ll; 136662e47b2eSBastian Koppelmann } 136762e47b2eSBastian Koppelmann 1368d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1369d5de7839SBastian Koppelmann { 1370d5de7839SBastian Koppelmann int32_t b, i; 1371d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1372d5de7839SBastian Koppelmann int32_t ovf = 0; 1373d5de7839SBastian Koppelmann int32_t avf = 0; 1374d5de7839SBastian Koppelmann uint32_t ret = 0; 1375d5de7839SBastian Koppelmann 1376d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1377d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 1378d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1379d5de7839SBastian Koppelmann 1380d5de7839SBastian Koppelmann b = extr_r1 - extr_r2; 1381d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 1382d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1383d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 1384d5de7839SBastian Koppelmann } 1385d5de7839SBastian Koppelmann 1386d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1387d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1388d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1389d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1390d5de7839SBastian Koppelmann 1391d5de7839SBastian Koppelmann return ret; 1392d5de7839SBastian Koppelmann } 1393d5de7839SBastian Koppelmann 1394d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1395d5de7839SBastian Koppelmann { 1396d5de7839SBastian Koppelmann int32_t h, i; 1397d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1398d5de7839SBastian Koppelmann int32_t ovf = 0; 1399d5de7839SBastian Koppelmann int32_t avf = 0; 1400d5de7839SBastian Koppelmann int32_t ret = 0; 1401d5de7839SBastian Koppelmann 1402d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1403d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 1404d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1405d5de7839SBastian Koppelmann h = extr_r1 - extr_r2; 1406d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 1407d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1408d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1409d5de7839SBastian Koppelmann } 1410d5de7839SBastian Koppelmann 1411d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1412d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1413d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1414d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1415d5de7839SBastian Koppelmann 1416d5de7839SBastian Koppelmann return ret; 1417d5de7839SBastian Koppelmann } 1418d5de7839SBastian Koppelmann 1419d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2) 1420d5de7839SBastian Koppelmann { 1421d5de7839SBastian Koppelmann int32_t ret; 1422d5de7839SBastian Koppelmann int32_t i, msk; 1423d5de7839SBastian Koppelmann 1424d5de7839SBastian Koppelmann ret = 0; 1425d5de7839SBastian Koppelmann msk = 0xff; 1426d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1427d5de7839SBastian Koppelmann if ((r1 & msk) == (r2 & msk)) { 1428d5de7839SBastian Koppelmann ret |= msk; 1429d5de7839SBastian Koppelmann } 1430d5de7839SBastian Koppelmann msk = msk << 8; 1431d5de7839SBastian Koppelmann } 1432d5de7839SBastian Koppelmann 1433d5de7839SBastian Koppelmann return ret; 1434d5de7839SBastian Koppelmann } 1435d5de7839SBastian Koppelmann 1436d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2) 1437d5de7839SBastian Koppelmann { 1438d5de7839SBastian Koppelmann int32_t ret = 0; 1439d5de7839SBastian Koppelmann 1440d5de7839SBastian Koppelmann if ((r1 & 0xffff) == (r2 & 0xffff)) { 1441d5de7839SBastian Koppelmann ret = 0xffff; 1442d5de7839SBastian Koppelmann } 1443d5de7839SBastian Koppelmann 1444d5de7839SBastian Koppelmann if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) { 1445d5de7839SBastian Koppelmann ret |= 0xffff0000; 1446d5de7839SBastian Koppelmann } 1447d5de7839SBastian Koppelmann 1448d5de7839SBastian Koppelmann return ret; 1449d5de7839SBastian Koppelmann } 1450d5de7839SBastian Koppelmann 1451d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2) 1452d5de7839SBastian Koppelmann { 1453d5de7839SBastian Koppelmann int32_t i; 1454d5de7839SBastian Koppelmann uint32_t ret = 0; 1455d5de7839SBastian Koppelmann 1456d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1457d5de7839SBastian Koppelmann ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8)); 1458d5de7839SBastian Koppelmann } 1459d5de7839SBastian Koppelmann 1460d5de7839SBastian Koppelmann return ret; 1461d5de7839SBastian Koppelmann } 1462d5de7839SBastian Koppelmann 1463d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2) 1464d5de7839SBastian Koppelmann { 1465d5de7839SBastian Koppelmann uint32_t ret; 1466d5de7839SBastian Koppelmann 1467d5de7839SBastian Koppelmann ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16)); 1468d5de7839SBastian Koppelmann ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16)); 1469d5de7839SBastian Koppelmann 1470d5de7839SBastian Koppelmann return ret; 1471d5de7839SBastian Koppelmann } 1472d5de7839SBastian Koppelmann 1473d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2) 1474d5de7839SBastian Koppelmann { 1475d5de7839SBastian Koppelmann int32_t i; 1476d5de7839SBastian Koppelmann uint32_t ret = 0; 1477d5de7839SBastian Koppelmann 1478d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1479d5de7839SBastian Koppelmann if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) { 1480d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 1481d5de7839SBastian Koppelmann } 1482d5de7839SBastian Koppelmann } 1483d5de7839SBastian Koppelmann 1484d5de7839SBastian Koppelmann return ret; 1485d5de7839SBastian Koppelmann } 1486d5de7839SBastian Koppelmann 1487d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2) 1488d5de7839SBastian Koppelmann { 1489d5de7839SBastian Koppelmann int32_t i; 1490d5de7839SBastian Koppelmann uint32_t ret = 0; 1491d5de7839SBastian Koppelmann 1492d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1493d5de7839SBastian Koppelmann if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) { 1494d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 1495d5de7839SBastian Koppelmann } 1496d5de7839SBastian Koppelmann } 1497d5de7839SBastian Koppelmann 1498d5de7839SBastian Koppelmann return ret; 1499d5de7839SBastian Koppelmann } 1500d5de7839SBastian Koppelmann 1501d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2) 1502d5de7839SBastian Koppelmann { 1503d5de7839SBastian Koppelmann uint32_t ret = 0; 1504d5de7839SBastian Koppelmann 1505d5de7839SBastian Koppelmann if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) { 1506d5de7839SBastian Koppelmann ret |= 0xffff; 1507d5de7839SBastian Koppelmann } 1508d5de7839SBastian Koppelmann 1509d5de7839SBastian Koppelmann if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) { 1510d5de7839SBastian Koppelmann ret |= 0xffff0000; 1511d5de7839SBastian Koppelmann } 1512d5de7839SBastian Koppelmann 1513d5de7839SBastian Koppelmann return ret; 1514d5de7839SBastian Koppelmann } 1515d5de7839SBastian Koppelmann 1516d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2) 1517d5de7839SBastian Koppelmann { 1518d5de7839SBastian Koppelmann uint32_t ret = 0; 1519d5de7839SBastian Koppelmann 1520d5de7839SBastian Koppelmann if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) { 1521d5de7839SBastian Koppelmann ret |= 0xffff; 1522d5de7839SBastian Koppelmann } 1523d5de7839SBastian Koppelmann 1524d5de7839SBastian Koppelmann if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) { 1525d5de7839SBastian Koppelmann ret |= 0xffff0000; 1526d5de7839SBastian Koppelmann } 1527d5de7839SBastian Koppelmann 1528d5de7839SBastian Koppelmann return ret; 1529d5de7839SBastian Koppelmann } 1530d5de7839SBastian Koppelmann 1531d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op) \ 1532d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \ 1533d5de7839SBastian Koppelmann { \ 1534d5de7839SBastian Koppelmann int32_t i, extr_r1, extr_r2; \ 1535d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1536d5de7839SBastian Koppelmann \ 1537d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 1538d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); \ 1539d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); \ 1540d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1541d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 1542d5de7839SBastian Koppelmann } \ 1543d5de7839SBastian Koppelmann return ret; \ 1544d5de7839SBastian Koppelmann } \ 1545d5de7839SBastian Koppelmann \ 1546d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\ 1547d5de7839SBastian Koppelmann { \ 1548d5de7839SBastian Koppelmann int32_t i; \ 1549d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 1550d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1551d5de7839SBastian Koppelmann \ 1552d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 1553d5de7839SBastian Koppelmann extr_r1 = extract32(r1, i * 8, 8); \ 1554d5de7839SBastian Koppelmann extr_r2 = extract32(r2, i * 8, 8); \ 1555d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1556d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 1557d5de7839SBastian Koppelmann } \ 1558d5de7839SBastian Koppelmann return ret; \ 1559d5de7839SBastian Koppelmann } \ 1560d5de7839SBastian Koppelmann \ 1561d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \ 1562d5de7839SBastian Koppelmann { \ 1563d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; \ 1564d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1565d5de7839SBastian Koppelmann \ 1566d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 0, 16); \ 1567d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 0, 16); \ 1568d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1569d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 1570d5de7839SBastian Koppelmann \ 1571d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 16, 16); \ 1572d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 16, 16); \ 1573d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1574d5de7839SBastian Koppelmann ret |= extr_r1 << 16; \ 1575d5de7839SBastian Koppelmann \ 1576d5de7839SBastian Koppelmann return ret; \ 1577d5de7839SBastian Koppelmann } \ 1578d5de7839SBastian Koppelmann \ 1579d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\ 1580d5de7839SBastian Koppelmann { \ 1581d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 1582d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1583d5de7839SBastian Koppelmann \ 1584d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 0, 16); \ 1585d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 0, 16); \ 1586d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1587d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 1588d5de7839SBastian Koppelmann \ 1589d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 16, 16); \ 1590d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 16, 16); \ 1591d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1592d5de7839SBastian Koppelmann ret |= extr_r1 << (16); \ 1593d5de7839SBastian Koppelmann \ 1594d5de7839SBastian Koppelmann return ret; \ 1595d5de7839SBastian Koppelmann } \ 159609532255SBastian Koppelmann \ 159709532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2) \ 159809532255SBastian Koppelmann { \ 159909532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \ 160009532255SBastian Koppelmann uint64_t ret = 0; \ 160109532255SBastian Koppelmann \ 160209532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \ 160309532255SBastian Koppelmann r2l = sextract64(r2, 0, 16); \ 160409532255SBastian Koppelmann r2h = sextract64(r2, 16, 16); \ 160509532255SBastian Koppelmann r1hl = sextract64(r1, 32, 16); \ 160609532255SBastian Koppelmann \ 160709532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 160809532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \ 160909532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \ 161009532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \ 161109532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \ 161209532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \ 161309532255SBastian Koppelmann } else { \ 161409532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \ 161509532255SBastian Koppelmann } \ 161609532255SBastian Koppelmann return ret; \ 161709532255SBastian Koppelmann } \ 161809532255SBastian Koppelmann \ 161909532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2) \ 162009532255SBastian Koppelmann { \ 162109532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \ 162209532255SBastian Koppelmann uint64_t ret = 0; \ 162309532255SBastian Koppelmann \ 162409532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \ 162509532255SBastian Koppelmann r2l = extract64(r2, 0, 16); \ 162609532255SBastian Koppelmann r2h = extract64(r2, 16, 16); \ 162709532255SBastian Koppelmann r1hl = extract64(r1, 32, 16); \ 162809532255SBastian Koppelmann \ 162909532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 163009532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \ 163109532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \ 163209532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \ 163309532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \ 163409532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \ 163509532255SBastian Koppelmann } else { \ 163609532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \ 163709532255SBastian Koppelmann } \ 163809532255SBastian Koppelmann return ret; \ 163909532255SBastian Koppelmann } 1640d5de7839SBastian Koppelmann 1641d5de7839SBastian Koppelmann EXTREMA_H_B(max, >) 1642d5de7839SBastian Koppelmann EXTREMA_H_B(min, <) 1643d5de7839SBastian Koppelmann 1644d5de7839SBastian Koppelmann #undef EXTREMA_H_B 1645d5de7839SBastian Koppelmann 16460b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1) 16470b79a781SBastian Koppelmann { 16480b79a781SBastian Koppelmann return clo32(r1); 16490b79a781SBastian Koppelmann } 16500b79a781SBastian Koppelmann 16510b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1) 16520b79a781SBastian Koppelmann { 16530b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 16540b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 16550b79a781SBastian Koppelmann 16560b79a781SBastian Koppelmann ret_hw0 = clo32(ret_hw0 << 16); 16570b79a781SBastian Koppelmann ret_hw1 = clo32(ret_hw1 << 16); 16580b79a781SBastian Koppelmann 16590b79a781SBastian Koppelmann if (ret_hw0 > 16) { 16600b79a781SBastian Koppelmann ret_hw0 = 16; 16610b79a781SBastian Koppelmann } 16620b79a781SBastian Koppelmann if (ret_hw1 > 16) { 16630b79a781SBastian Koppelmann ret_hw1 = 16; 16640b79a781SBastian Koppelmann } 16650b79a781SBastian Koppelmann 16660b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 16670b79a781SBastian Koppelmann } 16680b79a781SBastian Koppelmann 16690b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1) 16700b79a781SBastian Koppelmann { 16710b79a781SBastian Koppelmann return clz32(r1); 16720b79a781SBastian Koppelmann } 16730b79a781SBastian Koppelmann 16740b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1) 16750b79a781SBastian Koppelmann { 16760b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 16770b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 16780b79a781SBastian Koppelmann 16790b79a781SBastian Koppelmann ret_hw0 = clz32(ret_hw0 << 16); 16800b79a781SBastian Koppelmann ret_hw1 = clz32(ret_hw1 << 16); 16810b79a781SBastian Koppelmann 16820b79a781SBastian Koppelmann if (ret_hw0 > 16) { 16830b79a781SBastian Koppelmann ret_hw0 = 16; 16840b79a781SBastian Koppelmann } 16850b79a781SBastian Koppelmann if (ret_hw1 > 16) { 16860b79a781SBastian Koppelmann ret_hw1 = 16; 16870b79a781SBastian Koppelmann } 16880b79a781SBastian Koppelmann 16890b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 16900b79a781SBastian Koppelmann } 16910b79a781SBastian Koppelmann 16920b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1) 16930b79a781SBastian Koppelmann { 16940b79a781SBastian Koppelmann return clrsb32(r1); 16950b79a781SBastian Koppelmann } 16960b79a781SBastian Koppelmann 16970b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1) 16980b79a781SBastian Koppelmann { 16990b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 17000b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 17010b79a781SBastian Koppelmann 17020b79a781SBastian Koppelmann ret_hw0 = clrsb32(ret_hw0 << 16); 17030b79a781SBastian Koppelmann ret_hw1 = clrsb32(ret_hw1 << 16); 17040b79a781SBastian Koppelmann 17050b79a781SBastian Koppelmann if (ret_hw0 > 15) { 17060b79a781SBastian Koppelmann ret_hw0 = 15; 17070b79a781SBastian Koppelmann } 17080b79a781SBastian Koppelmann if (ret_hw1 > 15) { 17090b79a781SBastian Koppelmann ret_hw1 = 15; 17100b79a781SBastian Koppelmann } 17110b79a781SBastian Koppelmann 17120b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 17130b79a781SBastian Koppelmann } 17140b79a781SBastian Koppelmann 17150b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2) 17160b79a781SBastian Koppelmann { 17170b79a781SBastian Koppelmann int32_t shift_count = sextract32(r2, 0, 6); 17180b79a781SBastian Koppelmann 17190b79a781SBastian Koppelmann if (shift_count == -32) { 17200b79a781SBastian Koppelmann return 0; 17210b79a781SBastian Koppelmann } else if (shift_count < 0) { 17220b79a781SBastian Koppelmann return r1 >> -shift_count; 17230b79a781SBastian Koppelmann } else { 17240b79a781SBastian Koppelmann return r1 << shift_count; 17250b79a781SBastian Koppelmann } 17260b79a781SBastian Koppelmann } 17270b79a781SBastian Koppelmann 17280b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2) 17290b79a781SBastian Koppelmann { 17300b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 17310b79a781SBastian Koppelmann int32_t shift_count; 17320b79a781SBastian Koppelmann 17330b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 17340b79a781SBastian Koppelmann 17350b79a781SBastian Koppelmann if (shift_count == -16) { 17360b79a781SBastian Koppelmann return 0; 17370b79a781SBastian Koppelmann } else if (shift_count < 0) { 17380b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) >> -shift_count; 17390b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) >> -shift_count; 17400b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 17410b79a781SBastian Koppelmann } else { 17420b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) << shift_count; 17430b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) << shift_count; 17440b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 17450b79a781SBastian Koppelmann } 17460b79a781SBastian Koppelmann } 17470b79a781SBastian Koppelmann 17480b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 17490b79a781SBastian Koppelmann { 17500b79a781SBastian Koppelmann int32_t shift_count; 17510b79a781SBastian Koppelmann int64_t result, t1; 17520b79a781SBastian Koppelmann uint32_t ret; 17530b79a781SBastian Koppelmann 17540b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 6); 17550b79a781SBastian Koppelmann t1 = sextract32(r1, 0, 32); 17560b79a781SBastian Koppelmann 17570b79a781SBastian Koppelmann if (shift_count == 0) { 17580b79a781SBastian Koppelmann env->PSW_USB_C = env->PSW_USB_V = 0; 17590b79a781SBastian Koppelmann ret = r1; 17600b79a781SBastian Koppelmann } else if (shift_count == -32) { 17610b79a781SBastian Koppelmann env->PSW_USB_C = r1; 17620b79a781SBastian Koppelmann env->PSW_USB_V = 0; 17630b79a781SBastian Koppelmann ret = t1 >> 31; 17640b79a781SBastian Koppelmann } else if (shift_count > 0) { 17650b79a781SBastian Koppelmann result = t1 << shift_count; 17660b79a781SBastian Koppelmann /* calc carry */ 1767452e3d49SPeter Maydell env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0); 17680b79a781SBastian Koppelmann /* calc v */ 17690b79a781SBastian Koppelmann env->PSW_USB_V = (((result > 0x7fffffffLL) || 17700b79a781SBastian Koppelmann (result < -0x80000000LL)) << 31); 17710b79a781SBastian Koppelmann /* calc sv */ 17720b79a781SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 17730b79a781SBastian Koppelmann ret = (uint32_t)result; 17740b79a781SBastian Koppelmann } else { 17750b79a781SBastian Koppelmann env->PSW_USB_V = 0; 17760b79a781SBastian Koppelmann env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1)); 17770b79a781SBastian Koppelmann ret = t1 >> -shift_count; 17780b79a781SBastian Koppelmann } 17790b79a781SBastian Koppelmann 17800b79a781SBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 17810b79a781SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 17820b79a781SBastian Koppelmann 17830b79a781SBastian Koppelmann return ret; 17840b79a781SBastian Koppelmann } 17850b79a781SBastian Koppelmann 17860b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2) 17870b79a781SBastian Koppelmann { 17880b79a781SBastian Koppelmann int32_t shift_count; 17890b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 17900b79a781SBastian Koppelmann 17910b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 17920b79a781SBastian Koppelmann 17930b79a781SBastian Koppelmann if (shift_count == 0) { 17940b79a781SBastian Koppelmann return r1; 17950b79a781SBastian Koppelmann } else if (shift_count < 0) { 17960b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) >> -shift_count; 17970b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) >> -shift_count; 17980b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 17990b79a781SBastian Koppelmann } else { 18000b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) << shift_count; 18010b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) << shift_count; 18020b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 18030b79a781SBastian Koppelmann } 18040b79a781SBastian Koppelmann } 18050b79a781SBastian Koppelmann 1806e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2) 1807e2bed107SBastian Koppelmann { 1808e2bed107SBastian Koppelmann uint32_t i, ret; 1809e2bed107SBastian Koppelmann 1810e2bed107SBastian Koppelmann ret = 0; 1811e2bed107SBastian Koppelmann for (i = 0; i < 16; i++) { 1812e2bed107SBastian Koppelmann ret |= (r1 & 1) << (2 * i + 1); 1813e2bed107SBastian Koppelmann ret |= (r2 & 1) << (2 * i); 1814e2bed107SBastian Koppelmann r1 = r1 >> 1; 1815e2bed107SBastian Koppelmann r2 = r2 >> 1; 1816e2bed107SBastian Koppelmann } 1817e2bed107SBastian Koppelmann return ret; 1818e2bed107SBastian Koppelmann } 1819e2bed107SBastian Koppelmann 1820e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1) 1821e2bed107SBastian Koppelmann { 1822e2bed107SBastian Koppelmann int32_t i; 1823e2bed107SBastian Koppelmann uint64_t ret; 1824e2bed107SBastian Koppelmann 1825e2bed107SBastian Koppelmann ret = 0; 1826e2bed107SBastian Koppelmann for (i = 0; i < 32; i = i + 2) { 1827e2bed107SBastian Koppelmann /* even */ 1828e2bed107SBastian Koppelmann ret |= (r1 & 1) << (i/2); 1829e2bed107SBastian Koppelmann r1 = r1 >> 1; 1830e2bed107SBastian Koppelmann /* odd */ 1831e2bed107SBastian Koppelmann ret |= (uint64_t)(r1 & 1) << (i/2 + 32); 1832e2bed107SBastian Koppelmann r1 = r1 >> 1; 1833e2bed107SBastian Koppelmann } 1834e2bed107SBastian Koppelmann return ret; 1835e2bed107SBastian Koppelmann } 1836e2bed107SBastian Koppelmann 1837e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1) 1838e2bed107SBastian Koppelmann { 1839e2bed107SBastian Koppelmann uint32_t ret; 1840e2bed107SBastian Koppelmann uint32_t nOnes, i; 1841e2bed107SBastian Koppelmann 1842e2bed107SBastian Koppelmann ret = 0; 1843e2bed107SBastian Koppelmann nOnes = 0; 1844e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1845e2bed107SBastian Koppelmann ret ^= (r1 & 1); 1846e2bed107SBastian Koppelmann r1 = r1 >> 1; 1847e2bed107SBastian Koppelmann } 1848e2bed107SBastian Koppelmann /* second byte */ 1849e2bed107SBastian Koppelmann nOnes = 0; 1850e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1851e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1852e2bed107SBastian Koppelmann r1 = r1 >> 1; 1853e2bed107SBastian Koppelmann } 1854e2bed107SBastian Koppelmann ret |= nOnes << 8; 1855e2bed107SBastian Koppelmann /* third byte */ 1856e2bed107SBastian Koppelmann nOnes = 0; 1857e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1858e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1859e2bed107SBastian Koppelmann r1 = r1 >> 1; 1860e2bed107SBastian Koppelmann } 1861e2bed107SBastian Koppelmann ret |= nOnes << 16; 1862e2bed107SBastian Koppelmann /* fourth byte */ 1863e2bed107SBastian Koppelmann nOnes = 0; 1864e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1865e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1866e2bed107SBastian Koppelmann r1 = r1 >> 1; 1867e2bed107SBastian Koppelmann } 1868e2bed107SBastian Koppelmann ret |= nOnes << 24; 1869e2bed107SBastian Koppelmann 1870e2bed107SBastian Koppelmann return ret; 1871e2bed107SBastian Koppelmann } 1872e2bed107SBastian Koppelmann 187309532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high, 187409532255SBastian Koppelmann target_ulong r2) 187509532255SBastian Koppelmann { 187609532255SBastian Koppelmann uint32_t ret; 187709532255SBastian Koppelmann int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac; 187809532255SBastian Koppelmann int32_t int_exp = r1_high; 187909532255SBastian Koppelmann int32_t int_mant = r1_low; 188009532255SBastian Koppelmann uint32_t flag_rnd = (int_mant & (1 << 7)) && ( 188109532255SBastian Koppelmann (int_mant & (1 << 8)) || 188209532255SBastian Koppelmann (int_mant & 0x7f) || 188309532255SBastian Koppelmann (carry != 0)); 188409532255SBastian Koppelmann if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) { 188509532255SBastian Koppelmann fp_exp = 255; 188609532255SBastian Koppelmann fp_frac = extract32(int_mant, 8, 23); 188709532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp >= 127)) { 188809532255SBastian Koppelmann fp_exp = 255; 188909532255SBastian Koppelmann fp_frac = 0; 189009532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp <= -128)) { 189109532255SBastian Koppelmann fp_exp = 0; 189209532255SBastian Koppelmann fp_frac = 0; 189309532255SBastian Koppelmann } else if (int_mant == 0) { 189409532255SBastian Koppelmann fp_exp = 0; 189509532255SBastian Koppelmann fp_frac = 0; 189609532255SBastian Koppelmann } else { 189709532255SBastian Koppelmann if (((int_mant & (1 << 31)) == 0)) { 189809532255SBastian Koppelmann temp_exp = 0; 189909532255SBastian Koppelmann } else { 190009532255SBastian Koppelmann temp_exp = int_exp + 128; 190109532255SBastian Koppelmann } 190209532255SBastian Koppelmann fp_exp_frac = (((temp_exp & 0xff) << 23) | 190309532255SBastian Koppelmann extract32(int_mant, 8, 23)) 190409532255SBastian Koppelmann + flag_rnd; 190509532255SBastian Koppelmann fp_exp = extract32(fp_exp_frac, 23, 8); 190609532255SBastian Koppelmann fp_frac = extract32(fp_exp_frac, 0, 23); 190709532255SBastian Koppelmann } 190809532255SBastian Koppelmann ret = r2 & (1 << 31); 190909532255SBastian Koppelmann ret = ret + (fp_exp << 23); 191009532255SBastian Koppelmann ret = ret + (fp_frac & 0x7fffff); 191109532255SBastian Koppelmann 191209532255SBastian Koppelmann return ret; 191309532255SBastian Koppelmann } 191409532255SBastian Koppelmann 1915e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1) 1916e2bed107SBastian Koppelmann { 1917e2bed107SBastian Koppelmann int32_t fp_exp = extract32(arg1, 23, 8); 1918e2bed107SBastian Koppelmann int32_t fp_frac = extract32(arg1, 0, 23); 1919e2bed107SBastian Koppelmann uint64_t ret; 1920e2bed107SBastian Koppelmann int32_t int_exp, int_mant; 1921e2bed107SBastian Koppelmann 1922e2bed107SBastian Koppelmann if (fp_exp == 255) { 1923e2bed107SBastian Koppelmann int_exp = 255; 1924e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1925e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac == 0)) { 1926e2bed107SBastian Koppelmann int_exp = -127; 1927e2bed107SBastian Koppelmann int_mant = 0; 1928e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac != 0)) { 1929e2bed107SBastian Koppelmann int_exp = -126; 1930e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1931e2bed107SBastian Koppelmann } else { 1932e2bed107SBastian Koppelmann int_exp = fp_exp - 127; 1933e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1934e2bed107SBastian Koppelmann int_mant |= (1 << 30); 1935e2bed107SBastian Koppelmann } 1936e2bed107SBastian Koppelmann ret = int_exp; 1937e2bed107SBastian Koppelmann ret = ret << 32; 1938e2bed107SBastian Koppelmann ret |= int_mant; 1939e2bed107SBastian Koppelmann 1940e2bed107SBastian Koppelmann return ret; 1941e2bed107SBastian Koppelmann } 1942e2bed107SBastian Koppelmann 1943e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1944e2bed107SBastian Koppelmann { 1945e2bed107SBastian Koppelmann uint64_t ret; 1946f69c24e4SBastian Koppelmann int32_t abs_sig_dividend, abs_divisor; 1947e2bed107SBastian Koppelmann 1948e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 1949e2bed107SBastian Koppelmann ret = ret << 24; 1950e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1951e2bed107SBastian Koppelmann ret |= 0xffffff; 1952e2bed107SBastian Koppelmann } 1953e2bed107SBastian Koppelmann 1954f69c24e4SBastian Koppelmann abs_sig_dividend = abs((int32_t)r1) >> 8; 195530a0d72fSStefan Weil abs_divisor = abs((int32_t)r2); 1956f69c24e4SBastian Koppelmann /* calc overflow 1957f69c24e4SBastian Koppelmann ofv if (a/b >= 255) <=> (a/255 >= b) */ 1958f69c24e4SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; 1959e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1960e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1961e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1962e2bed107SBastian Koppelmann 1963e2bed107SBastian Koppelmann return ret; 1964e2bed107SBastian Koppelmann } 1965e2bed107SBastian Koppelmann 1966e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1967e2bed107SBastian Koppelmann { 1968e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 1969e2bed107SBastian Koppelmann 1970e2bed107SBastian Koppelmann ret = ret << 24; 1971e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1972e2bed107SBastian Koppelmann ret |= 0xffffff; 1973e2bed107SBastian Koppelmann } 1974e2bed107SBastian Koppelmann /* calc overflow */ 1975e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80))); 1976e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1977e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1978e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1979e2bed107SBastian Koppelmann 1980e2bed107SBastian Koppelmann return ret; 1981e2bed107SBastian Koppelmann } 1982e2bed107SBastian Koppelmann 1983e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1984e2bed107SBastian Koppelmann { 1985e2bed107SBastian Koppelmann uint64_t ret; 1986f69c24e4SBastian Koppelmann int32_t abs_sig_dividend, abs_divisor; 1987e2bed107SBastian Koppelmann 1988e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 1989e2bed107SBastian Koppelmann ret = ret << 16; 1990e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1991e2bed107SBastian Koppelmann ret |= 0xffff; 1992e2bed107SBastian Koppelmann } 1993e2bed107SBastian Koppelmann 1994f69c24e4SBastian Koppelmann abs_sig_dividend = abs((int32_t)r1) >> 16; 199530a0d72fSStefan Weil abs_divisor = abs((int32_t)r2); 1996f69c24e4SBastian Koppelmann /* calc overflow 1997f69c24e4SBastian Koppelmann ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */ 1998f69c24e4SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; 1999e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 2000e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2001e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 2002e2bed107SBastian Koppelmann 2003e2bed107SBastian Koppelmann return ret; 2004e2bed107SBastian Koppelmann } 2005e2bed107SBastian Koppelmann 2006e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2007e2bed107SBastian Koppelmann { 2008e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 2009e2bed107SBastian Koppelmann 2010e2bed107SBastian Koppelmann ret = ret << 16; 2011e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2012e2bed107SBastian Koppelmann ret |= 0xffff; 2013e2bed107SBastian Koppelmann } 2014e2bed107SBastian Koppelmann /* calc overflow */ 2015e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000))); 2016e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 2017e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2018e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 2019e2bed107SBastian Koppelmann 2020e2bed107SBastian Koppelmann return ret; 2021e2bed107SBastian Koppelmann } 2022e2bed107SBastian Koppelmann 202309532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2) 202409532255SBastian Koppelmann { 202509532255SBastian Koppelmann int32_t x_sign = (r1 >> 63); 202609532255SBastian Koppelmann int32_t q_sign = x_sign ^ (r2 >> 31); 202709532255SBastian Koppelmann int32_t eq_pos = x_sign & ((r1 >> 32) == r2); 202809532255SBastian Koppelmann int32_t eq_neg = x_sign & ((r1 >> 32) == -r2); 202909532255SBastian Koppelmann uint32_t quotient; 203009532255SBastian Koppelmann uint64_t ret, remainder; 203109532255SBastian Koppelmann 203209532255SBastian Koppelmann if ((q_sign & ~eq_neg) | eq_pos) { 203309532255SBastian Koppelmann quotient = (r1 + 1) & 0xffffffff; 203409532255SBastian Koppelmann } else { 203509532255SBastian Koppelmann quotient = r1 & 0xffffffff; 203609532255SBastian Koppelmann } 203709532255SBastian Koppelmann 203809532255SBastian Koppelmann if (eq_pos | eq_neg) { 203909532255SBastian Koppelmann remainder = 0; 204009532255SBastian Koppelmann } else { 204109532255SBastian Koppelmann remainder = (r1 & 0xffffffff00000000ull); 204209532255SBastian Koppelmann } 204309532255SBastian Koppelmann ret = remainder|quotient; 204409532255SBastian Koppelmann return ret; 204509532255SBastian Koppelmann } 204609532255SBastian Koppelmann 204709532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2) 204809532255SBastian Koppelmann { 204909532255SBastian Koppelmann int32_t dividend_sign = extract64(r1, 63, 1); 205009532255SBastian Koppelmann int32_t divisor_sign = extract32(r2, 31, 1); 205109532255SBastian Koppelmann int32_t quotient_sign = (dividend_sign != divisor_sign); 205209532255SBastian Koppelmann int32_t addend, dividend_quotient, remainder; 205309532255SBastian Koppelmann int32_t i, temp; 205409532255SBastian Koppelmann 205509532255SBastian Koppelmann if (quotient_sign) { 205609532255SBastian Koppelmann addend = r2; 205709532255SBastian Koppelmann } else { 205809532255SBastian Koppelmann addend = -r2; 205909532255SBastian Koppelmann } 206009532255SBastian Koppelmann dividend_quotient = (int32_t)r1; 206109532255SBastian Koppelmann remainder = (int32_t)(r1 >> 32); 206209532255SBastian Koppelmann 206309532255SBastian Koppelmann for (i = 0; i < 8; i++) { 206409532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 206509532255SBastian Koppelmann dividend_quotient <<= 1; 206609532255SBastian Koppelmann temp = remainder + addend; 206709532255SBastian Koppelmann if ((temp < 0) == dividend_sign) { 206809532255SBastian Koppelmann remainder = temp; 206909532255SBastian Koppelmann } 207009532255SBastian Koppelmann if (((temp < 0) == dividend_sign)) { 207109532255SBastian Koppelmann dividend_quotient = dividend_quotient | !quotient_sign; 207209532255SBastian Koppelmann } else { 207309532255SBastian Koppelmann dividend_quotient = dividend_quotient | quotient_sign; 207409532255SBastian Koppelmann } 207509532255SBastian Koppelmann } 207609532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 207709532255SBastian Koppelmann } 207809532255SBastian Koppelmann 207909532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2) 208009532255SBastian Koppelmann { 208109532255SBastian Koppelmann int32_t dividend_quotient = extract64(r1, 0, 32); 208209532255SBastian Koppelmann int64_t remainder = extract64(r1, 32, 32); 208309532255SBastian Koppelmann int32_t i; 208409532255SBastian Koppelmann int64_t temp; 208509532255SBastian Koppelmann for (i = 0; i < 8; i++) { 208609532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 208709532255SBastian Koppelmann dividend_quotient <<= 1; 208809532255SBastian Koppelmann temp = (remainder & 0xffffffff) - r2; 208909532255SBastian Koppelmann if (temp >= 0) { 209009532255SBastian Koppelmann remainder = temp; 209109532255SBastian Koppelmann } 209209532255SBastian Koppelmann dividend_quotient = dividend_quotient | !(temp < 0); 209309532255SBastian Koppelmann } 209409532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 209509532255SBastian Koppelmann } 209609532255SBastian Koppelmann 209793715571SBastian Koppelmann uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 209893715571SBastian Koppelmann { 209993715571SBastian Koppelmann int32_t quotient, remainder; 210093715571SBastian Koppelmann int32_t dividend = (int32_t)r1; 210193715571SBastian Koppelmann int32_t divisor = (int32_t)r2; 210293715571SBastian Koppelmann 210393715571SBastian Koppelmann if (divisor == 0) { 210493715571SBastian Koppelmann if (dividend >= 0) { 210593715571SBastian Koppelmann quotient = 0x7fffffff; 210693715571SBastian Koppelmann remainder = 0; 210793715571SBastian Koppelmann } else { 210893715571SBastian Koppelmann quotient = 0x80000000; 210993715571SBastian Koppelmann remainder = 0; 211093715571SBastian Koppelmann } 211193715571SBastian Koppelmann env->PSW_USB_V = (1 << 31); 211293715571SBastian Koppelmann } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) { 211393715571SBastian Koppelmann quotient = 0x7fffffff; 211493715571SBastian Koppelmann remainder = 0; 211593715571SBastian Koppelmann env->PSW_USB_V = (1 << 31); 211693715571SBastian Koppelmann } else { 211793715571SBastian Koppelmann remainder = dividend % divisor; 211893715571SBastian Koppelmann quotient = (dividend - remainder)/divisor; 211993715571SBastian Koppelmann env->PSW_USB_V = 0; 212093715571SBastian Koppelmann } 212193715571SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 212293715571SBastian Koppelmann env->PSW_USB_AV = 0; 212393715571SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)quotient; 212493715571SBastian Koppelmann } 212593715571SBastian Koppelmann 212693715571SBastian Koppelmann uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 212793715571SBastian Koppelmann { 212893715571SBastian Koppelmann uint32_t quotient, remainder; 212993715571SBastian Koppelmann uint32_t dividend = r1; 213093715571SBastian Koppelmann uint32_t divisor = r2; 213193715571SBastian Koppelmann 213293715571SBastian Koppelmann if (divisor == 0) { 213393715571SBastian Koppelmann quotient = 0xffffffff; 213493715571SBastian Koppelmann remainder = 0; 213593715571SBastian Koppelmann env->PSW_USB_V = (1 << 31); 213693715571SBastian Koppelmann } else { 213793715571SBastian Koppelmann remainder = dividend % divisor; 213893715571SBastian Koppelmann quotient = (dividend - remainder)/divisor; 213993715571SBastian Koppelmann env->PSW_USB_V = 0; 214093715571SBastian Koppelmann } 214193715571SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 214293715571SBastian Koppelmann env->PSW_USB_AV = 0; 214393715571SBastian Koppelmann return ((uint64_t)remainder << 32) | quotient; 214493715571SBastian Koppelmann } 214593715571SBastian Koppelmann 21469655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01, 21479655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 21489655b932SBastian Koppelmann { 21499655b932SBastian Koppelmann uint64_t ret; 21509655b932SBastian Koppelmann uint32_t result0, result1; 21519655b932SBastian Koppelmann 21529655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 21539655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 21549655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 21559655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 21569655b932SBastian Koppelmann if (sc1) { 21579655b932SBastian Koppelmann result1 = 0x7fffffff; 21589655b932SBastian Koppelmann } else { 21599655b932SBastian Koppelmann result1 = (((uint32_t)(arg00 * arg10)) << n); 21609655b932SBastian Koppelmann } 21619655b932SBastian Koppelmann if (sc0) { 21629655b932SBastian Koppelmann result0 = 0x7fffffff; 21639655b932SBastian Koppelmann } else { 21649655b932SBastian Koppelmann result0 = (((uint32_t)(arg01 * arg11)) << n); 21659655b932SBastian Koppelmann } 21669655b932SBastian Koppelmann ret = (((uint64_t)result1 << 32)) | result0; 21679655b932SBastian Koppelmann return ret; 21689655b932SBastian Koppelmann } 21699655b932SBastian Koppelmann 21709655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01, 21719655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 21729655b932SBastian Koppelmann { 21739655b932SBastian Koppelmann uint64_t ret; 21749655b932SBastian Koppelmann int64_t result0, result1; 21759655b932SBastian Koppelmann 21769655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 21779655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 21789655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 21799655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 21809655b932SBastian Koppelmann 21819655b932SBastian Koppelmann if (sc1) { 21829655b932SBastian Koppelmann result1 = 0x7fffffff; 21839655b932SBastian Koppelmann } else { 21849655b932SBastian Koppelmann result1 = (((int32_t)arg00 * (int32_t)arg10) << n); 21859655b932SBastian Koppelmann } 21869655b932SBastian Koppelmann if (sc0) { 21879655b932SBastian Koppelmann result0 = 0x7fffffff; 21889655b932SBastian Koppelmann } else { 21899655b932SBastian Koppelmann result0 = (((int32_t)arg01 * (int32_t)arg11) << n); 21909655b932SBastian Koppelmann } 21919655b932SBastian Koppelmann ret = (result1 + result0); 21929655b932SBastian Koppelmann ret = ret << 16; 21939655b932SBastian Koppelmann return ret; 21949655b932SBastian Koppelmann } 21959655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01, 21969655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 21979655b932SBastian Koppelmann { 21989655b932SBastian Koppelmann uint32_t result0, result1; 21999655b932SBastian Koppelmann 22009655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 22019655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 22029655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 22039655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 22049655b932SBastian Koppelmann 22059655b932SBastian Koppelmann if (sc1) { 22069655b932SBastian Koppelmann result1 = 0x7fffffff; 22079655b932SBastian Koppelmann } else { 22089655b932SBastian Koppelmann result1 = ((arg00 * arg10) << n) + 0x8000; 22099655b932SBastian Koppelmann } 22109655b932SBastian Koppelmann if (sc0) { 22119655b932SBastian Koppelmann result0 = 0x7fffffff; 22129655b932SBastian Koppelmann } else { 22139655b932SBastian Koppelmann result0 = ((arg01 * arg11) << n) + 0x8000; 22149655b932SBastian Koppelmann } 22159655b932SBastian Koppelmann return (result1 & 0xffff0000) | (result0 >> 16); 22169655b932SBastian Koppelmann } 22179655b932SBastian Koppelmann 2218e5c96c82SBastian Koppelmann uint32_t helper_crc32(uint32_t arg0, uint32_t arg1) 2219e5c96c82SBastian Koppelmann { 2220e5c96c82SBastian Koppelmann uint8_t buf[4]; 2221e5c96c82SBastian Koppelmann uint32_t ret; 2222e5c96c82SBastian Koppelmann stl_be_p(buf, arg0); 2223e5c96c82SBastian Koppelmann 2224e5c96c82SBastian Koppelmann ret = crc32(arg1, buf, 4); 2225e5c96c82SBastian Koppelmann return ret; 2226e5c96c82SBastian Koppelmann } 2227e5c96c82SBastian Koppelmann 22289a31922bSBastian Koppelmann /* context save area (CSA) related helpers */ 22299a31922bSBastian Koppelmann 22309a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw) 22319a31922bSBastian Koppelmann { 22329a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 22339a31922bSBastian Koppelmann return 0; 22349a31922bSBastian Koppelmann } 22359a31922bSBastian Koppelmann 22369a31922bSBastian Koppelmann (*psw)++; 22379a31922bSBastian Koppelmann /* check for overflow */ 22389a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 22399a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 22409a31922bSBastian Koppelmann int count = *psw & mask; 22419a31922bSBastian Koppelmann if (count == 0) { 22429a31922bSBastian Koppelmann (*psw)--; 22439a31922bSBastian Koppelmann return 1; 22449a31922bSBastian Koppelmann } 22459a31922bSBastian Koppelmann return 0; 22469a31922bSBastian Koppelmann } 22479a31922bSBastian Koppelmann 22489a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw) 22499a31922bSBastian Koppelmann { 22509a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 22519a31922bSBastian Koppelmann return 0; 22529a31922bSBastian Koppelmann } 22539a31922bSBastian Koppelmann /* check for underflow */ 22549a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 22559a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 22569a31922bSBastian Koppelmann int count = *psw & mask; 22579a31922bSBastian Koppelmann if (count == 0) { 22589a31922bSBastian Koppelmann return 1; 22599a31922bSBastian Koppelmann } 22609a31922bSBastian Koppelmann (*psw)--; 22619a31922bSBastian Koppelmann return 0; 22629a31922bSBastian Koppelmann } 22639a31922bSBastian Koppelmann 226444ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw) 226544ea3430SBastian Koppelmann { 226644ea3430SBastian Koppelmann int cdc = *psw & MASK_PSW_CDC; 226744ea3430SBastian Koppelmann /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC == 226844ea3430SBastian Koppelmann 7'b1111111, otherwise returns FALSE. */ 226944ea3430SBastian Koppelmann if (cdc == 0x7f) { 227044ea3430SBastian Koppelmann return true; 227144ea3430SBastian Koppelmann } 227244ea3430SBastian Koppelmann /* find CDC.COUNT */ 227344ea3430SBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 227444ea3430SBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 227544ea3430SBastian Koppelmann int count = *psw & mask; 227644ea3430SBastian Koppelmann return count == 0; 227744ea3430SBastian Koppelmann } 227844ea3430SBastian Koppelmann 2279030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea) 22809a31922bSBastian Koppelmann { 22819a31922bSBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 22829a31922bSBastian Koppelmann cpu_stl_data(env, ea+4, env->PSW); 22839a31922bSBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[10]); 22849a31922bSBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[11]); 22859a31922bSBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[8]); 22869a31922bSBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[9]); 22879a31922bSBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[10]); 22889a31922bSBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[11]); 22899a31922bSBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[12]); 22909a31922bSBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[13]); 22919a31922bSBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[14]); 22929a31922bSBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[15]); 22939a31922bSBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[12]); 22949a31922bSBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[13]); 22959a31922bSBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[14]); 22969a31922bSBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[15]); 22979a31922bSBastian Koppelmann } 22989a31922bSBastian Koppelmann 2299030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea) 23005de93515SBastian Koppelmann { 23015de93515SBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 2302030c58dfSBastian Koppelmann cpu_stl_data(env, ea+4, env->gpr_a[11]); 23035de93515SBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[2]); 23045de93515SBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[3]); 23055de93515SBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[0]); 23065de93515SBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[1]); 23075de93515SBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[2]); 23085de93515SBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[3]); 23095de93515SBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[4]); 23105de93515SBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[5]); 23115de93515SBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[6]); 23125de93515SBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[7]); 23135de93515SBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[4]); 23145de93515SBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[5]); 23155de93515SBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[6]); 23165de93515SBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[7]); 23175de93515SBastian Koppelmann } 23185de93515SBastian Koppelmann 23199a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea, 23209a31922bSBastian Koppelmann target_ulong *new_PCXI, target_ulong *new_PSW) 23219a31922bSBastian Koppelmann { 23229a31922bSBastian Koppelmann *new_PCXI = cpu_ldl_data(env, ea); 23239a31922bSBastian Koppelmann *new_PSW = cpu_ldl_data(env, ea+4); 23249a31922bSBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, ea+8); 23259a31922bSBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, ea+12); 23269a31922bSBastian Koppelmann env->gpr_d[8] = cpu_ldl_data(env, ea+16); 23279a31922bSBastian Koppelmann env->gpr_d[9] = cpu_ldl_data(env, ea+20); 23289a31922bSBastian Koppelmann env->gpr_d[10] = cpu_ldl_data(env, ea+24); 23299a31922bSBastian Koppelmann env->gpr_d[11] = cpu_ldl_data(env, ea+28); 23309a31922bSBastian Koppelmann env->gpr_a[12] = cpu_ldl_data(env, ea+32); 23319a31922bSBastian Koppelmann env->gpr_a[13] = cpu_ldl_data(env, ea+36); 23329a31922bSBastian Koppelmann env->gpr_a[14] = cpu_ldl_data(env, ea+40); 23339a31922bSBastian Koppelmann env->gpr_a[15] = cpu_ldl_data(env, ea+44); 23349a31922bSBastian Koppelmann env->gpr_d[12] = cpu_ldl_data(env, ea+48); 23359a31922bSBastian Koppelmann env->gpr_d[13] = cpu_ldl_data(env, ea+52); 23369a31922bSBastian Koppelmann env->gpr_d[14] = cpu_ldl_data(env, ea+56); 23379a31922bSBastian Koppelmann env->gpr_d[15] = cpu_ldl_data(env, ea+60); 23389a31922bSBastian Koppelmann } 23399a31922bSBastian Koppelmann 234059543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea, 234159543d4eSBastian Koppelmann target_ulong *ra, target_ulong *pcxi) 234259543d4eSBastian Koppelmann { 234359543d4eSBastian Koppelmann *pcxi = cpu_ldl_data(env, ea); 234459543d4eSBastian Koppelmann *ra = cpu_ldl_data(env, ea+4); 234559543d4eSBastian Koppelmann env->gpr_a[2] = cpu_ldl_data(env, ea+8); 234659543d4eSBastian Koppelmann env->gpr_a[3] = cpu_ldl_data(env, ea+12); 234759543d4eSBastian Koppelmann env->gpr_d[0] = cpu_ldl_data(env, ea+16); 234859543d4eSBastian Koppelmann env->gpr_d[1] = cpu_ldl_data(env, ea+20); 234959543d4eSBastian Koppelmann env->gpr_d[2] = cpu_ldl_data(env, ea+24); 235059543d4eSBastian Koppelmann env->gpr_d[3] = cpu_ldl_data(env, ea+28); 235159543d4eSBastian Koppelmann env->gpr_a[4] = cpu_ldl_data(env, ea+32); 235259543d4eSBastian Koppelmann env->gpr_a[5] = cpu_ldl_data(env, ea+36); 235359543d4eSBastian Koppelmann env->gpr_a[6] = cpu_ldl_data(env, ea+40); 235459543d4eSBastian Koppelmann env->gpr_a[7] = cpu_ldl_data(env, ea+44); 235559543d4eSBastian Koppelmann env->gpr_d[4] = cpu_ldl_data(env, ea+48); 235659543d4eSBastian Koppelmann env->gpr_d[5] = cpu_ldl_data(env, ea+52); 235759543d4eSBastian Koppelmann env->gpr_d[6] = cpu_ldl_data(env, ea+56); 235859543d4eSBastian Koppelmann env->gpr_d[7] = cpu_ldl_data(env, ea+60); 235959543d4eSBastian Koppelmann } 236059543d4eSBastian Koppelmann 23619a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc) 23629a31922bSBastian Koppelmann { 23639a31922bSBastian Koppelmann target_ulong tmp_FCX; 23649a31922bSBastian Koppelmann target_ulong ea; 23659a31922bSBastian Koppelmann target_ulong new_FCX; 23669a31922bSBastian Koppelmann target_ulong psw; 23679a31922bSBastian Koppelmann 23689a31922bSBastian Koppelmann psw = psw_read(env); 23699a31922bSBastian Koppelmann /* if (FCX == 0) trap(FCU); */ 23709a31922bSBastian Koppelmann if (env->FCX == 0) { 23719a31922bSBastian Koppelmann /* FCU trap */ 23729a31922bSBastian Koppelmann } 23739a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */ 23749a31922bSBastian Koppelmann if (psw & MASK_PSW_CDE) { 23759a31922bSBastian Koppelmann if (cdc_increment(&psw)) { 23769a31922bSBastian Koppelmann /* CDO trap */ 23779a31922bSBastian Koppelmann } 23789a31922bSBastian Koppelmann } 23799a31922bSBastian Koppelmann /* PSW.CDE = 1;*/ 23809a31922bSBastian Koppelmann psw |= MASK_PSW_CDE; 23819a31922bSBastian Koppelmann /* tmp_FCX = FCX; */ 23829a31922bSBastian Koppelmann tmp_FCX = env->FCX; 23839a31922bSBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 23849a31922bSBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 23859a31922bSBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 2386030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 2387030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2388030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 23899a31922bSBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 23909a31922bSBastian Koppelmann D[15]}; */ 2391030c58dfSBastian Koppelmann save_context_upper(env, ea); 23929a31922bSBastian Koppelmann 23939a31922bSBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 23949a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 23959a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 23969a31922bSBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 23979a31922bSBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 23989a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 23999a31922bSBastian Koppelmann /* PCXI.UL = 1; */ 24009a31922bSBastian Koppelmann env->PCXI |= MASK_PCXI_UL; 24019a31922bSBastian Koppelmann 24029a31922bSBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 24039a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 24049a31922bSBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 24059a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 24069a31922bSBastian Koppelmann /* A[11] = next_pc[31: 0]; */ 24079a31922bSBastian Koppelmann env->gpr_a[11] = next_pc; 24089a31922bSBastian Koppelmann 24099a31922bSBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 24109a31922bSBastian Koppelmann if (tmp_FCX == env->LCX) { 24119a31922bSBastian Koppelmann /* FCD trap */ 24129a31922bSBastian Koppelmann } 24139a31922bSBastian Koppelmann psw_write(env, psw); 24149a31922bSBastian Koppelmann } 24159a31922bSBastian Koppelmann 24169a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env) 24179a31922bSBastian Koppelmann { 24189a31922bSBastian Koppelmann target_ulong ea; 24199a31922bSBastian Koppelmann target_ulong new_PCXI; 24209a31922bSBastian Koppelmann target_ulong new_PSW, psw; 24219a31922bSBastian Koppelmann 24229a31922bSBastian Koppelmann psw = psw_read(env); 24239a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/ 24249a31922bSBastian Koppelmann if (env->PSW & MASK_PSW_CDE) { 24259a31922bSBastian Koppelmann if (cdc_decrement(&(env->PSW))) { 24269a31922bSBastian Koppelmann /* CDU trap */ 24279a31922bSBastian Koppelmann } 24289a31922bSBastian Koppelmann } 24299a31922bSBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 24309a31922bSBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 24319a31922bSBastian Koppelmann /* CSU trap */ 24329a31922bSBastian Koppelmann } 24339a31922bSBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 24349a31922bSBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 24359a31922bSBastian Koppelmann /* CTYP trap */ 24369a31922bSBastian Koppelmann } 24379a31922bSBastian Koppelmann /* PC = {A11 [31: 1], 1’b0}; */ 24389a31922bSBastian Koppelmann env->PC = env->gpr_a[11] & 0xfffffffe; 24399a31922bSBastian Koppelmann 24409a31922bSBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 24419a31922bSBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 24429a31922bSBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 24439a31922bSBastian Koppelmann /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2444030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 24459a31922bSBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2446030c58dfSBastian Koppelmann /* M(EA, word) = FCX; */ 2447030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 24489a31922bSBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 24499a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 24509a31922bSBastian Koppelmann /* PCXI = new_PCXI; */ 24519a31922bSBastian Koppelmann env->PCXI = new_PCXI; 24529a31922bSBastian Koppelmann 24539a31922bSBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_13)) { 24549a31922bSBastian Koppelmann /* PSW = new_PSW */ 24559a31922bSBastian Koppelmann psw_write(env, new_PSW); 24569a31922bSBastian Koppelmann } else { 24579a31922bSBastian Koppelmann /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */ 24589a31922bSBastian Koppelmann psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000))); 24599a31922bSBastian Koppelmann } 24609a31922bSBastian Koppelmann } 24619a31922bSBastian Koppelmann 24625de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9) 24635de93515SBastian Koppelmann { 24645de93515SBastian Koppelmann target_ulong tmp_FCX; 24655de93515SBastian Koppelmann target_ulong ea; 24665de93515SBastian Koppelmann target_ulong new_FCX; 24675de93515SBastian Koppelmann 24685de93515SBastian Koppelmann if (env->FCX == 0) { 24695de93515SBastian Koppelmann /* FCU trap */ 24705de93515SBastian Koppelmann } 24715de93515SBastian Koppelmann 24725de93515SBastian Koppelmann tmp_FCX = env->FCX; 24735de93515SBastian Koppelmann ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6); 24745de93515SBastian Koppelmann 2475030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 2476030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2477030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4] 2478030c58dfSBastian Koppelmann , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */ 2479030c58dfSBastian Koppelmann save_context_lower(env, ea); 2480030c58dfSBastian Koppelmann 24815de93515SBastian Koppelmann 24825de93515SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */ 24835de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 24845de93515SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 24855de93515SBastian Koppelmann /* PCXI.PIE = ICR.IE */ 24865de93515SBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 24875de93515SBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 24885de93515SBastian Koppelmann /* PCXI.UL = 0 */ 24895de93515SBastian Koppelmann env->PCXI &= ~(MASK_PCXI_UL); 24905de93515SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0] */ 24915de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 24925de93515SBastian Koppelmann /* FXC[19: 0] = new_FCX[19: 0] */ 24935de93515SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 24945de93515SBastian Koppelmann /* ICR.IE = 1 */ 24955de93515SBastian Koppelmann env->ICR |= MASK_ICR_IE; 24965de93515SBastian Koppelmann 24975de93515SBastian Koppelmann env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/ 24985de93515SBastian Koppelmann 24995de93515SBastian Koppelmann if (tmp_FCX == env->LCX) { 25005de93515SBastian Koppelmann /* FCD trap */ 25015de93515SBastian Koppelmann } 25025de93515SBastian Koppelmann } 25035de93515SBastian Koppelmann 250444ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env) 250544ea3430SBastian Koppelmann { 250644ea3430SBastian Koppelmann target_ulong ea; 250744ea3430SBastian Koppelmann target_ulong new_PCXI; 250844ea3430SBastian Koppelmann target_ulong new_PSW; 250944ea3430SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 251044ea3430SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 251144ea3430SBastian Koppelmann /* raise csu trap */ 251244ea3430SBastian Koppelmann } 251344ea3430SBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 251444ea3430SBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 251544ea3430SBastian Koppelmann /* raise CTYP trap */ 251644ea3430SBastian Koppelmann } 251744ea3430SBastian Koppelmann /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */ 251844ea3430SBastian Koppelmann if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) { 251944ea3430SBastian Koppelmann /* raise MNG trap */ 252044ea3430SBastian Koppelmann } 25213446a111SBastian Koppelmann env->PC = env->gpr_a[11] & ~0x1; 252244ea3430SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 252344ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15); 252444ea3430SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 252544ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) + 252644ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCPN) >> 24); 252744ea3430SBastian Koppelmann /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/ 252844ea3430SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 252944ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 253044ea3430SBastian Koppelmann /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2531030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 253244ea3430SBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2533030c58dfSBastian Koppelmann /* M(EA, word) = FCX;*/ 2534030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 253544ea3430SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 253644ea3430SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 253744ea3430SBastian Koppelmann /* PCXI = new_PCXI; */ 253844ea3430SBastian Koppelmann env->PCXI = new_PCXI; 253944ea3430SBastian Koppelmann /* write psw */ 254044ea3430SBastian Koppelmann psw_write(env, new_PSW); 254144ea3430SBastian Koppelmann } 254244ea3430SBastian Koppelmann 2543b724b012SBastian Koppelmann void helper_rfm(CPUTriCoreState *env) 2544b724b012SBastian Koppelmann { 2545b724b012SBastian Koppelmann env->PC = (env->gpr_a[11] & ~0x1); 2546b724b012SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 2547b724b012SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_IE) | 2548b724b012SBastian Koppelmann ((env->PCXI & ~MASK_PCXI_PIE) >> 15); 2549b724b012SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 2550b724b012SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) | 2551b724b012SBastian Koppelmann ((env->PCXI & ~MASK_PCXI_PCPN) >> 24); 2552b724b012SBastian Koppelmann /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */ 2553b724b012SBastian Koppelmann env->PCXI = cpu_ldl_data(env, env->DCX); 2554b724b012SBastian Koppelmann psw_write(env, cpu_ldl_data(env, env->DCX+4)); 2555b724b012SBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8); 2556b724b012SBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12); 2557b724b012SBastian Koppelmann 2558b724b012SBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_131)) { 2559b724b012SBastian Koppelmann env->DBGTCR = 0; 2560b724b012SBastian Koppelmann } 2561b724b012SBastian Koppelmann } 2562b724b012SBastian Koppelmann 256359543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) 256459543d4eSBastian Koppelmann { 256559543d4eSBastian Koppelmann uint32_t dummy; 256659543d4eSBastian Koppelmann /* insn doesn't load PCXI and RA */ 256759543d4eSBastian Koppelmann restore_context_lower(env, ea, &dummy, &dummy); 256859543d4eSBastian Koppelmann } 256959543d4eSBastian Koppelmann 257059543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea) 257159543d4eSBastian Koppelmann { 257259543d4eSBastian Koppelmann uint32_t dummy; 257359543d4eSBastian Koppelmann /* insn doesn't load PCXI and PSW */ 257459543d4eSBastian Koppelmann restore_context_upper(env, ea, &dummy, &dummy); 257559543d4eSBastian Koppelmann } 257659543d4eSBastian Koppelmann 257759543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea) 257859543d4eSBastian Koppelmann { 257959543d4eSBastian Koppelmann save_context_lower(env, ea); 258059543d4eSBastian Koppelmann } 258159543d4eSBastian Koppelmann 258259543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea) 258359543d4eSBastian Koppelmann { 258459543d4eSBastian Koppelmann save_context_upper(env, ea); 258559543d4eSBastian Koppelmann } 258659543d4eSBastian Koppelmann 2587b724b012SBastian Koppelmann void helper_svlcx(CPUTriCoreState *env) 2588b724b012SBastian Koppelmann { 2589b724b012SBastian Koppelmann target_ulong tmp_FCX; 2590b724b012SBastian Koppelmann target_ulong ea; 2591b724b012SBastian Koppelmann target_ulong new_FCX; 2592b724b012SBastian Koppelmann 2593b724b012SBastian Koppelmann if (env->FCX == 0) { 2594b724b012SBastian Koppelmann /* FCU trap */ 2595b724b012SBastian Koppelmann } 2596b724b012SBastian Koppelmann /* tmp_FCX = FCX; */ 2597b724b012SBastian Koppelmann tmp_FCX = env->FCX; 2598b724b012SBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 2599b724b012SBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 2600b724b012SBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 2601b724b012SBastian Koppelmann /* new_FCX = M(EA, word); */ 2602b724b012SBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2603b724b012SBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 2604b724b012SBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 2605b724b012SBastian Koppelmann D[15]}; */ 2606b724b012SBastian Koppelmann save_context_lower(env, ea); 2607b724b012SBastian Koppelmann 2608b724b012SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 2609b724b012SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 2610b724b012SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 2611b724b012SBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 2612b724b012SBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 2613b724b012SBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 2614b724b012SBastian Koppelmann /* PCXI.UL = 0; */ 2615b724b012SBastian Koppelmann env->PCXI &= ~MASK_PCXI_UL; 2616b724b012SBastian Koppelmann 2617b724b012SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 2618b724b012SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 2619b724b012SBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 2620b724b012SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 2621b724b012SBastian Koppelmann 2622b724b012SBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 2623b724b012SBastian Koppelmann if (tmp_FCX == env->LCX) { 2624b724b012SBastian Koppelmann /* FCD trap */ 2625b724b012SBastian Koppelmann } 2626b724b012SBastian Koppelmann } 2627b724b012SBastian Koppelmann 2628b724b012SBastian Koppelmann void helper_rslcx(CPUTriCoreState *env) 2629b724b012SBastian Koppelmann { 2630b724b012SBastian Koppelmann target_ulong ea; 2631b724b012SBastian Koppelmann target_ulong new_PCXI; 2632b724b012SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 2633b724b012SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 2634b724b012SBastian Koppelmann /* CSU trap */ 2635b724b012SBastian Koppelmann } 2636b724b012SBastian Koppelmann /* if (PCXI.UL == 1) then trap(CTYP); */ 26377b4b0b57SStefan Weil if ((env->PCXI & MASK_PCXI_UL) != 0) { 2638b724b012SBastian Koppelmann /* CTYP trap */ 2639b724b012SBastian Koppelmann } 2640b724b012SBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 2641b724b012SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 2642b724b012SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 2643b724b012SBastian Koppelmann /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2644b724b012SBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 2645bc72f8aaSBastian Koppelmann restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI); 2646b724b012SBastian Koppelmann /* M(EA, word) = FCX; */ 2647b724b012SBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 2648b724b012SBastian Koppelmann /* M(EA, word) = FCX; */ 2649b724b012SBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 2650b724b012SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 2651b724b012SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 2652b724b012SBastian Koppelmann /* PCXI = new_PCXI; */ 2653b724b012SBastian Koppelmann env->PCXI = new_PCXI; 2654b724b012SBastian Koppelmann } 2655b724b012SBastian Koppelmann 26562b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg) 26572b2f7d97SBastian Koppelmann { 26582b2f7d97SBastian Koppelmann psw_write(env, arg); 26592b2f7d97SBastian Koppelmann } 26602b2f7d97SBastian Koppelmann 26612b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env) 26622b2f7d97SBastian Koppelmann { 26632b2f7d97SBastian Koppelmann return psw_read(env); 26642b2f7d97SBastian Koppelmann } 26652b2f7d97SBastian Koppelmann 26662b2f7d97SBastian Koppelmann 26672d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env, 26682d30267eSBastian Koppelmann uint32_t exception, 26692d30267eSBastian Koppelmann int error_code, 26702d30267eSBastian Koppelmann uintptr_t pc) 26712d30267eSBastian Koppelmann { 26722d30267eSBastian Koppelmann CPUState *cs = CPU(tricore_env_get_cpu(env)); 26732d30267eSBastian Koppelmann cs->exception_index = exception; 26742d30267eSBastian Koppelmann env->error_code = error_code; 26752d30267eSBastian Koppelmann 26762d30267eSBastian Koppelmann if (pc) { 26772d30267eSBastian Koppelmann /* now we have a real cpu fault */ 26782d30267eSBastian Koppelmann cpu_restore_state(cs, pc); 26792d30267eSBastian Koppelmann } 26802d30267eSBastian Koppelmann 26812d30267eSBastian Koppelmann cpu_loop_exit(cs); 26822d30267eSBastian Koppelmann } 26832d30267eSBastian Koppelmann 268448e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, 268548e06fe0SBastian Koppelmann uintptr_t retaddr) 268648e06fe0SBastian Koppelmann { 26872d30267eSBastian Koppelmann int ret; 26882d30267eSBastian Koppelmann ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx); 26892d30267eSBastian Koppelmann if (ret) { 26902d30267eSBastian Koppelmann TriCoreCPU *cpu = TRICORE_CPU(cs); 26912d30267eSBastian Koppelmann CPUTriCoreState *env = &cpu->env; 26922d30267eSBastian Koppelmann do_raise_exception_err(env, cs->exception_index, 26932d30267eSBastian Koppelmann env->error_code, retaddr); 269448e06fe0SBastian Koppelmann } 26952d30267eSBastian Koppelmann } 2696