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" 2248e06fe0SBastian Koppelmann 233a16ecb0SBastian Koppelmann /* Addressing mode helper */ 243a16ecb0SBastian Koppelmann 253a16ecb0SBastian Koppelmann static uint16_t reverse16(uint16_t val) 263a16ecb0SBastian Koppelmann { 273a16ecb0SBastian Koppelmann uint8_t high = (uint8_t)(val >> 8); 283a16ecb0SBastian Koppelmann uint8_t low = (uint8_t)(val & 0xff); 293a16ecb0SBastian Koppelmann 303a16ecb0SBastian Koppelmann uint16_t rh, rl; 313a16ecb0SBastian Koppelmann 323a16ecb0SBastian Koppelmann rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023); 333a16ecb0SBastian Koppelmann rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023); 343a16ecb0SBastian Koppelmann 353a16ecb0SBastian Koppelmann return (rh << 8) | rl; 363a16ecb0SBastian Koppelmann } 373a16ecb0SBastian Koppelmann 383a16ecb0SBastian Koppelmann uint32_t helper_br_update(uint32_t reg) 393a16ecb0SBastian Koppelmann { 403a16ecb0SBastian Koppelmann uint32_t index = reg & 0xffff; 413a16ecb0SBastian Koppelmann uint32_t incr = reg >> 16; 423a16ecb0SBastian Koppelmann uint32_t new_index = reverse16(reverse16(index) + reverse16(incr)); 433a16ecb0SBastian Koppelmann return reg - index + new_index; 443a16ecb0SBastian Koppelmann } 453a16ecb0SBastian Koppelmann 463a16ecb0SBastian Koppelmann uint32_t helper_circ_update(uint32_t reg, uint32_t off) 473a16ecb0SBastian Koppelmann { 483a16ecb0SBastian Koppelmann uint32_t index = reg & 0xffff; 493a16ecb0SBastian Koppelmann uint32_t length = reg >> 16; 503a16ecb0SBastian Koppelmann int32_t new_index = index + off; 513a16ecb0SBastian Koppelmann if (new_index < 0) { 523a16ecb0SBastian Koppelmann new_index += length; 533a16ecb0SBastian Koppelmann } else { 543a16ecb0SBastian Koppelmann new_index %= length; 553a16ecb0SBastian Koppelmann } 563a16ecb0SBastian Koppelmann return reg - index + new_index; 573a16ecb0SBastian Koppelmann } 583a16ecb0SBastian Koppelmann 59e4e39176SBastian Koppelmann static uint32_t ssov32(CPUTriCoreState *env, int64_t arg) 60e4e39176SBastian Koppelmann { 61e4e39176SBastian Koppelmann uint32_t ret; 62e4e39176SBastian Koppelmann int64_t max_pos = INT32_MAX; 63e4e39176SBastian Koppelmann int64_t max_neg = INT32_MIN; 64e4e39176SBastian Koppelmann if (arg > max_pos) { 65e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 66e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 67e4e39176SBastian Koppelmann ret = (target_ulong)max_pos; 68e4e39176SBastian Koppelmann } else { 69e4e39176SBastian Koppelmann if (arg < max_neg) { 70e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 71e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 72e4e39176SBastian Koppelmann ret = (target_ulong)max_neg; 73e4e39176SBastian Koppelmann } else { 74e4e39176SBastian Koppelmann env->PSW_USB_V = 0; 75e4e39176SBastian Koppelmann ret = (target_ulong)arg; 76e4e39176SBastian Koppelmann } 77e4e39176SBastian Koppelmann } 78e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 79e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 80e4e39176SBastian Koppelmann return ret; 81e4e39176SBastian Koppelmann } 822692802aSBastian Koppelmann 8385d604afSBastian Koppelmann static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg) 84e4e39176SBastian Koppelmann { 85e4e39176SBastian Koppelmann uint32_t ret; 8685d604afSBastian Koppelmann uint64_t max_pos = UINT32_MAX; 87e4e39176SBastian Koppelmann if (arg > max_pos) { 88e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 89e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 90e4e39176SBastian Koppelmann ret = (target_ulong)max_pos; 91e4e39176SBastian Koppelmann } else { 9285d604afSBastian Koppelmann env->PSW_USB_V = 0; 9385d604afSBastian Koppelmann ret = (target_ulong)arg; 9485d604afSBastian Koppelmann } 9585d604afSBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 9685d604afSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 9785d604afSBastian Koppelmann return ret; 9885d604afSBastian Koppelmann } 9985d604afSBastian Koppelmann 10085d604afSBastian Koppelmann static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg) 10185d604afSBastian Koppelmann { 10285d604afSBastian Koppelmann uint32_t ret; 10385d604afSBastian Koppelmann 104e4e39176SBastian Koppelmann if (arg < 0) { 105e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 106e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 107e4e39176SBastian Koppelmann ret = 0; 108e4e39176SBastian Koppelmann } else { 109e4e39176SBastian Koppelmann env->PSW_USB_V = 0; 110e4e39176SBastian Koppelmann ret = (target_ulong)arg; 111e4e39176SBastian Koppelmann } 112e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 113e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 114e4e39176SBastian Koppelmann return ret; 115e4e39176SBastian Koppelmann } 1160974257eSBastian Koppelmann 117d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 118d5de7839SBastian Koppelmann { 119d5de7839SBastian Koppelmann int32_t max_pos = INT16_MAX; 120d5de7839SBastian Koppelmann int32_t max_neg = INT16_MIN; 121d5de7839SBastian Koppelmann int32_t av0, av1; 122d5de7839SBastian Koppelmann 123d5de7839SBastian Koppelmann env->PSW_USB_V = 0; 124d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u; 125d5de7839SBastian Koppelmann if (hw0 > max_pos) { 126d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 127d5de7839SBastian Koppelmann hw0 = max_pos; 128d5de7839SBastian Koppelmann } else if (hw0 < max_neg) { 129d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 130d5de7839SBastian Koppelmann hw0 = max_neg; 131d5de7839SBastian Koppelmann } 132d5de7839SBastian Koppelmann 133d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u; 134d5de7839SBastian Koppelmann if (hw1 > max_pos) { 135d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 136d5de7839SBastian Koppelmann hw1 = max_pos; 137d5de7839SBastian Koppelmann } else if (hw1 < max_neg) { 138d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 139d5de7839SBastian Koppelmann hw1 = max_neg; 140d5de7839SBastian Koppelmann } 141d5de7839SBastian Koppelmann 142d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 143d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16; 144d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 145d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16); 146d5de7839SBastian Koppelmann } 147d5de7839SBastian Koppelmann 148d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 149d5de7839SBastian Koppelmann { 150d5de7839SBastian Koppelmann int32_t max_pos = UINT16_MAX; 151d5de7839SBastian Koppelmann int32_t av0, av1; 152d5de7839SBastian Koppelmann 153d5de7839SBastian Koppelmann env->PSW_USB_V = 0; 154d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u; 155d5de7839SBastian Koppelmann if (hw0 > max_pos) { 156d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 157d5de7839SBastian Koppelmann hw0 = max_pos; 158d5de7839SBastian Koppelmann } else if (hw0 < 0) { 159d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 160d5de7839SBastian Koppelmann hw0 = 0; 161d5de7839SBastian Koppelmann } 162d5de7839SBastian Koppelmann 163d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u; 164d5de7839SBastian Koppelmann if (hw1 > max_pos) { 165d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 166d5de7839SBastian Koppelmann hw1 = max_pos; 167d5de7839SBastian Koppelmann } else if (hw1 < 0) { 168d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 169d5de7839SBastian Koppelmann hw1 = 0; 170d5de7839SBastian Koppelmann } 171d5de7839SBastian Koppelmann 172d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 173d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16; 174d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 175d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16); 176d5de7839SBastian Koppelmann } 1770974257eSBastian Koppelmann 1782692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1, 1792692802aSBastian Koppelmann target_ulong r2) 1802692802aSBastian Koppelmann { 1812692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 1822692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 1832692802aSBastian Koppelmann int64_t result = t1 + t2; 184e4e39176SBastian Koppelmann return ssov32(env, result); 1852692802aSBastian Koppelmann } 1862692802aSBastian Koppelmann 1872e430e1cSBastian Koppelmann uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 1882e430e1cSBastian Koppelmann { 1892e430e1cSBastian Koppelmann uint64_t result; 1902e430e1cSBastian Koppelmann int64_t ovf; 1912e430e1cSBastian Koppelmann 1922e430e1cSBastian Koppelmann result = r1 + r2; 1932e430e1cSBastian Koppelmann ovf = (result ^ r1) & ~(r1 ^ r2); 1942e430e1cSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 1952e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1962e430e1cSBastian Koppelmann if (ovf < 0) { 1972e430e1cSBastian Koppelmann env->PSW_USB_V = (1 << 31); 1982e430e1cSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 1992e430e1cSBastian Koppelmann /* ext_ret > MAX_INT */ 2002e430e1cSBastian Koppelmann if ((int64_t)r1 >= 0) { 2012e430e1cSBastian Koppelmann result = INT64_MAX; 2022e430e1cSBastian Koppelmann /* ext_ret < MIN_INT */ 2032e430e1cSBastian Koppelmann } else { 2042e430e1cSBastian Koppelmann result = INT64_MIN; 2052e430e1cSBastian Koppelmann } 2062e430e1cSBastian Koppelmann } else { 2072e430e1cSBastian Koppelmann env->PSW_USB_V = 0; 2082e430e1cSBastian Koppelmann } 2092e430e1cSBastian Koppelmann return result; 2102e430e1cSBastian Koppelmann } 2112e430e1cSBastian Koppelmann 212d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1, 213d5de7839SBastian Koppelmann target_ulong r2) 214d5de7839SBastian Koppelmann { 215d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 216d5de7839SBastian Koppelmann 217d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16); 218d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16); 219d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 220d5de7839SBastian Koppelmann } 221d5de7839SBastian Koppelmann 2222e430e1cSBastian Koppelmann uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 2232e430e1cSBastian Koppelmann uint32_t r2_h) 2242e430e1cSBastian Koppelmann { 2252e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 2262e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 2272e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 2282e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 2292e430e1cSBastian Koppelmann int64_t result0, result1; 2302e430e1cSBastian Koppelmann uint32_t ovf0, ovf1; 2312e430e1cSBastian Koppelmann uint32_t avf0, avf1; 2322e430e1cSBastian Koppelmann 2332e430e1cSBastian Koppelmann ovf0 = ovf1 = 0; 2342e430e1cSBastian Koppelmann 2352e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 2362e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 2372e430e1cSBastian Koppelmann 2382e430e1cSBastian Koppelmann avf0 = result0 * 2u; 2392e430e1cSBastian Koppelmann avf0 = result0 ^ avf0; 2402e430e1cSBastian Koppelmann avf1 = result1 * 2u; 2412e430e1cSBastian Koppelmann avf1 = result1 ^ avf1; 2422e430e1cSBastian Koppelmann 2432e430e1cSBastian Koppelmann if (result0 > INT32_MAX) { 2442e430e1cSBastian Koppelmann ovf0 = (1 << 31); 2452e430e1cSBastian Koppelmann result0 = INT32_MAX; 2462e430e1cSBastian Koppelmann } else if (result0 < INT32_MIN) { 2472e430e1cSBastian Koppelmann ovf0 = (1 << 31); 2482e430e1cSBastian Koppelmann result0 = INT32_MIN; 2492e430e1cSBastian Koppelmann } 2502e430e1cSBastian Koppelmann 2512e430e1cSBastian Koppelmann if (result1 > INT32_MAX) { 2522e430e1cSBastian Koppelmann ovf1 = (1 << 31); 2532e430e1cSBastian Koppelmann result1 = INT32_MAX; 2542e430e1cSBastian Koppelmann } else if (result1 < INT32_MIN) { 2552e430e1cSBastian Koppelmann ovf1 = (1 << 31); 2562e430e1cSBastian Koppelmann result1 = INT32_MIN; 2572e430e1cSBastian Koppelmann } 2582e430e1cSBastian Koppelmann 2592e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 2602e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2612e430e1cSBastian Koppelmann 2622e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 2632e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 2642e430e1cSBastian Koppelmann 2652e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 2662e430e1cSBastian Koppelmann } 2672e430e1cSBastian Koppelmann 268bebe80fcSBastian Koppelmann uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 269bebe80fcSBastian Koppelmann uint32_t r2_h) 270bebe80fcSBastian Koppelmann { 271bebe80fcSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 272bebe80fcSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 273bebe80fcSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 274bebe80fcSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 275bebe80fcSBastian Koppelmann int64_t result0, result1; 276bebe80fcSBastian Koppelmann uint32_t ovf0, ovf1; 277bebe80fcSBastian Koppelmann uint32_t avf0, avf1; 278bebe80fcSBastian Koppelmann 279bebe80fcSBastian Koppelmann ovf0 = ovf1 = 0; 280bebe80fcSBastian Koppelmann 281bebe80fcSBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 282bebe80fcSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 283bebe80fcSBastian Koppelmann 284bebe80fcSBastian Koppelmann avf0 = result0 * 2u; 285bebe80fcSBastian Koppelmann avf0 = result0 ^ avf0; 286bebe80fcSBastian Koppelmann avf1 = result1 * 2u; 287bebe80fcSBastian Koppelmann avf1 = result1 ^ avf1; 288bebe80fcSBastian Koppelmann 289bebe80fcSBastian Koppelmann if (result0 > INT32_MAX) { 290bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 291bebe80fcSBastian Koppelmann result0 = INT32_MAX; 292bebe80fcSBastian Koppelmann } else if (result0 < INT32_MIN) { 293bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 294bebe80fcSBastian Koppelmann result0 = INT32_MIN; 295bebe80fcSBastian Koppelmann } 296bebe80fcSBastian Koppelmann 297bebe80fcSBastian Koppelmann if (result1 > INT32_MAX) { 298bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 299bebe80fcSBastian Koppelmann result1 = INT32_MAX; 300bebe80fcSBastian Koppelmann } else if (result1 < INT32_MIN) { 301bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 302bebe80fcSBastian Koppelmann result1 = INT32_MIN; 303bebe80fcSBastian Koppelmann } 304bebe80fcSBastian Koppelmann 305bebe80fcSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 306bebe80fcSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 307bebe80fcSBastian Koppelmann 308bebe80fcSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 309bebe80fcSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 310bebe80fcSBastian Koppelmann 311bebe80fcSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 312bebe80fcSBastian Koppelmann } 313bebe80fcSBastian Koppelmann 3142e430e1cSBastian Koppelmann 3150974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1, 3160974257eSBastian Koppelmann target_ulong r2) 3170974257eSBastian Koppelmann { 3180974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 3190974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 3200974257eSBastian Koppelmann int64_t result = t1 + t2; 32185d604afSBastian Koppelmann return suov32_pos(env, result); 3220974257eSBastian Koppelmann } 3230974257eSBastian Koppelmann 324d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1, 325d5de7839SBastian Koppelmann target_ulong r2) 326d5de7839SBastian Koppelmann { 327d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 328d5de7839SBastian Koppelmann 329d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16); 330d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16); 331d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 332d5de7839SBastian Koppelmann } 333d5de7839SBastian Koppelmann 3342692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1, 3352692802aSBastian Koppelmann target_ulong r2) 3362692802aSBastian Koppelmann { 3372692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 3382692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 3392692802aSBastian Koppelmann int64_t result = t1 - t2; 340e4e39176SBastian Koppelmann return ssov32(env, result); 3412692802aSBastian Koppelmann } 3422692802aSBastian Koppelmann 343f4aef476SBastian Koppelmann uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 344f4aef476SBastian Koppelmann { 345f4aef476SBastian Koppelmann uint64_t result; 346f4aef476SBastian Koppelmann int64_t ovf; 347f4aef476SBastian Koppelmann 348f4aef476SBastian Koppelmann result = r1 - r2; 349f4aef476SBastian Koppelmann ovf = (result ^ r1) & (r1 ^ r2); 350f4aef476SBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 351f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 352f4aef476SBastian Koppelmann if (ovf < 0) { 353f4aef476SBastian Koppelmann env->PSW_USB_V = (1 << 31); 354f4aef476SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 355f4aef476SBastian Koppelmann /* ext_ret > MAX_INT */ 356f4aef476SBastian Koppelmann if ((int64_t)r1 >= 0) { 357f4aef476SBastian Koppelmann result = INT64_MAX; 358f4aef476SBastian Koppelmann /* ext_ret < MIN_INT */ 359f4aef476SBastian Koppelmann } else { 360f4aef476SBastian Koppelmann result = INT64_MIN; 361f4aef476SBastian Koppelmann } 362f4aef476SBastian Koppelmann } else { 363f4aef476SBastian Koppelmann env->PSW_USB_V = 0; 364f4aef476SBastian Koppelmann } 365f4aef476SBastian Koppelmann return result; 366f4aef476SBastian Koppelmann } 367f4aef476SBastian Koppelmann 368d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1, 369d5de7839SBastian Koppelmann target_ulong r2) 370d5de7839SBastian Koppelmann { 371d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 372d5de7839SBastian Koppelmann 373d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16); 374d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16); 375d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 376d5de7839SBastian Koppelmann } 377d5de7839SBastian Koppelmann 378f4aef476SBastian Koppelmann uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 379f4aef476SBastian Koppelmann uint32_t r2_h) 380f4aef476SBastian Koppelmann { 381f4aef476SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 382f4aef476SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 383f4aef476SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 384f4aef476SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 385f4aef476SBastian Koppelmann int64_t result0, result1; 386f4aef476SBastian Koppelmann uint32_t ovf0, ovf1; 387f4aef476SBastian Koppelmann uint32_t avf0, avf1; 388f4aef476SBastian Koppelmann 389f4aef476SBastian Koppelmann ovf0 = ovf1 = 0; 390f4aef476SBastian Koppelmann 391f4aef476SBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 392f4aef476SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 393f4aef476SBastian Koppelmann 394f4aef476SBastian Koppelmann avf0 = result0 * 2u; 395f4aef476SBastian Koppelmann avf0 = result0 ^ avf0; 396f4aef476SBastian Koppelmann avf1 = result1 * 2u; 397f4aef476SBastian Koppelmann avf1 = result1 ^ avf1; 398f4aef476SBastian Koppelmann 399f4aef476SBastian Koppelmann if (result0 > INT32_MAX) { 400f4aef476SBastian Koppelmann ovf0 = (1 << 31); 401f4aef476SBastian Koppelmann result0 = INT32_MAX; 402f4aef476SBastian Koppelmann } else if (result0 < INT32_MIN) { 403f4aef476SBastian Koppelmann ovf0 = (1 << 31); 404f4aef476SBastian Koppelmann result0 = INT32_MIN; 405f4aef476SBastian Koppelmann } 406f4aef476SBastian Koppelmann 407f4aef476SBastian Koppelmann if (result1 > INT32_MAX) { 408f4aef476SBastian Koppelmann ovf1 = (1 << 31); 409f4aef476SBastian Koppelmann result1 = INT32_MAX; 410f4aef476SBastian Koppelmann } else if (result1 < INT32_MIN) { 411f4aef476SBastian Koppelmann ovf1 = (1 << 31); 412f4aef476SBastian Koppelmann result1 = INT32_MIN; 413f4aef476SBastian Koppelmann } 414f4aef476SBastian Koppelmann 415f4aef476SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 416f4aef476SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 417f4aef476SBastian Koppelmann 418f4aef476SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 419f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 420f4aef476SBastian Koppelmann 421f4aef476SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 422f4aef476SBastian Koppelmann } 423f4aef476SBastian Koppelmann 424068fac77SBastian Koppelmann uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 425068fac77SBastian Koppelmann uint32_t r2_h) 426068fac77SBastian Koppelmann { 427068fac77SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 428068fac77SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 429068fac77SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 430068fac77SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 431068fac77SBastian Koppelmann int64_t result0, result1; 432068fac77SBastian Koppelmann uint32_t ovf0, ovf1; 433068fac77SBastian Koppelmann uint32_t avf0, avf1; 434068fac77SBastian Koppelmann 435068fac77SBastian Koppelmann ovf0 = ovf1 = 0; 436068fac77SBastian Koppelmann 437068fac77SBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 438068fac77SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 439068fac77SBastian Koppelmann 440068fac77SBastian Koppelmann avf0 = result0 * 2u; 441068fac77SBastian Koppelmann avf0 = result0 ^ avf0; 442068fac77SBastian Koppelmann avf1 = result1 * 2u; 443068fac77SBastian Koppelmann avf1 = result1 ^ avf1; 444068fac77SBastian Koppelmann 445068fac77SBastian Koppelmann if (result0 > INT32_MAX) { 446068fac77SBastian Koppelmann ovf0 = (1 << 31); 447068fac77SBastian Koppelmann result0 = INT32_MAX; 448068fac77SBastian Koppelmann } else if (result0 < INT32_MIN) { 449068fac77SBastian Koppelmann ovf0 = (1 << 31); 450068fac77SBastian Koppelmann result0 = INT32_MIN; 451068fac77SBastian Koppelmann } 452068fac77SBastian Koppelmann 453068fac77SBastian Koppelmann if (result1 > INT32_MAX) { 454068fac77SBastian Koppelmann ovf1 = (1 << 31); 455068fac77SBastian Koppelmann result1 = INT32_MAX; 456068fac77SBastian Koppelmann } else if (result1 < INT32_MIN) { 457068fac77SBastian Koppelmann ovf1 = (1 << 31); 458068fac77SBastian Koppelmann result1 = INT32_MIN; 459068fac77SBastian Koppelmann } 460068fac77SBastian Koppelmann 461068fac77SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 462068fac77SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 463068fac77SBastian Koppelmann 464068fac77SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 465068fac77SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 466068fac77SBastian Koppelmann 467068fac77SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 468068fac77SBastian Koppelmann } 469068fac77SBastian Koppelmann 4700974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1, 4710974257eSBastian Koppelmann target_ulong r2) 4720974257eSBastian Koppelmann { 4730974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 4740974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 4750974257eSBastian Koppelmann int64_t result = t1 - t2; 47685d604afSBastian Koppelmann return suov32_neg(env, result); 4770974257eSBastian Koppelmann } 4780974257eSBastian Koppelmann 479d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1, 480d5de7839SBastian Koppelmann target_ulong r2) 481d5de7839SBastian Koppelmann { 482d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 483d5de7839SBastian Koppelmann 484d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16); 485d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16); 486d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 487d5de7839SBastian Koppelmann } 488d5de7839SBastian Koppelmann 4890974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1, 4900974257eSBastian Koppelmann target_ulong r2) 4910974257eSBastian Koppelmann { 4920974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 4930974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 4940974257eSBastian Koppelmann int64_t result = t1 * t2; 495e4e39176SBastian Koppelmann return ssov32(env, result); 4960974257eSBastian Koppelmann } 4970974257eSBastian Koppelmann 4980974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1, 4990974257eSBastian Koppelmann target_ulong r2) 5000974257eSBastian Koppelmann { 5010974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 5020974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 5030974257eSBastian Koppelmann int64_t result = t1 * t2; 5045f30046fSBastian Koppelmann 50585d604afSBastian Koppelmann return suov32_pos(env, result); 5060974257eSBastian Koppelmann } 5070974257eSBastian Koppelmann 5080974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1, 5090974257eSBastian Koppelmann target_ulong r2) 5100974257eSBastian Koppelmann { 5110974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 5120974257eSBastian Koppelmann int32_t t2 = sextract64(r2, 0, 6); 5130974257eSBastian Koppelmann int64_t result; 5140974257eSBastian Koppelmann if (t2 == 0) { 5150974257eSBastian Koppelmann result = t1; 5160974257eSBastian Koppelmann } else if (t2 > 0) { 5170974257eSBastian Koppelmann result = t1 << t2; 5180974257eSBastian Koppelmann } else { 5190974257eSBastian Koppelmann result = t1 >> -t2; 5200974257eSBastian Koppelmann } 521e4e39176SBastian Koppelmann return ssov32(env, result); 5220974257eSBastian Koppelmann } 5230974257eSBastian Koppelmann 524d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1) 525d5de7839SBastian Koppelmann { 526d5de7839SBastian Koppelmann target_ulong result; 527d5de7839SBastian Koppelmann result = ((int32_t)r1 >= 0) ? r1 : (0 - r1); 528d5de7839SBastian Koppelmann return ssov32(env, result); 529d5de7839SBastian Koppelmann } 530d5de7839SBastian Koppelmann 531d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1) 532d5de7839SBastian Koppelmann { 533d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 534d5de7839SBastian Koppelmann 535d5de7839SBastian Koppelmann ret_h0 = sextract32(r1, 0, 16); 536d5de7839SBastian Koppelmann ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0); 537d5de7839SBastian Koppelmann 538d5de7839SBastian Koppelmann ret_h1 = sextract32(r1, 16, 16); 539d5de7839SBastian Koppelmann ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1); 540d5de7839SBastian Koppelmann 541d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 542d5de7839SBastian Koppelmann } 543d5de7839SBastian Koppelmann 5440974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1, 5450974257eSBastian Koppelmann target_ulong r2) 5460974257eSBastian Koppelmann { 5470974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 5480974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 5490974257eSBastian Koppelmann int64_t result; 5500974257eSBastian Koppelmann 5510974257eSBastian Koppelmann if (t1 > t2) { 5520974257eSBastian Koppelmann result = t1 - t2; 5530974257eSBastian Koppelmann } else { 5540974257eSBastian Koppelmann result = t2 - t1; 5550974257eSBastian Koppelmann } 556e4e39176SBastian Koppelmann return ssov32(env, result); 5570974257eSBastian Koppelmann } 558328f1f0fSBastian Koppelmann 559d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1, 560d5de7839SBastian Koppelmann target_ulong r2) 561d5de7839SBastian Koppelmann { 562d5de7839SBastian Koppelmann int32_t t1, t2; 563d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 564d5de7839SBastian Koppelmann 565d5de7839SBastian Koppelmann t1 = sextract32(r1, 0, 16); 566d5de7839SBastian Koppelmann t2 = sextract32(r2, 0, 16); 567d5de7839SBastian Koppelmann if (t1 > t2) { 568d5de7839SBastian Koppelmann ret_h0 = t1 - t2; 569d5de7839SBastian Koppelmann } else { 570d5de7839SBastian Koppelmann ret_h0 = t2 - t1; 571d5de7839SBastian Koppelmann } 572d5de7839SBastian Koppelmann 573d5de7839SBastian Koppelmann t1 = sextract32(r1, 16, 16); 574d5de7839SBastian Koppelmann t2 = sextract32(r2, 16, 16); 575d5de7839SBastian Koppelmann if (t1 > t2) { 576d5de7839SBastian Koppelmann ret_h1 = t1 - t2; 577d5de7839SBastian Koppelmann } else { 578d5de7839SBastian Koppelmann ret_h1 = t2 - t1; 579d5de7839SBastian Koppelmann } 580d5de7839SBastian Koppelmann 581d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 582d5de7839SBastian Koppelmann } 583d5de7839SBastian Koppelmann 584328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1, 585328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 586328f1f0fSBastian Koppelmann { 587328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 588328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 589328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 590328f1f0fSBastian Koppelmann int64_t result; 591328f1f0fSBastian Koppelmann 592328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 593e4e39176SBastian Koppelmann return ssov32(env, result); 594328f1f0fSBastian Koppelmann } 595328f1f0fSBastian Koppelmann 596328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1, 597328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 598328f1f0fSBastian Koppelmann { 599328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 600328f1f0fSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 601328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 602328f1f0fSBastian Koppelmann int64_t result; 603328f1f0fSBastian Koppelmann 604328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 60585d604afSBastian Koppelmann return suov32_pos(env, result); 606328f1f0fSBastian Koppelmann } 607328f1f0fSBastian Koppelmann 608328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1, 609328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 610328f1f0fSBastian Koppelmann { 611328f1f0fSBastian Koppelmann uint64_t ret, ovf; 612328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 613328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 614328f1f0fSBastian Koppelmann int64_t mul; 615328f1f0fSBastian Koppelmann 616328f1f0fSBastian Koppelmann mul = t1 * t3; 617328f1f0fSBastian Koppelmann ret = mul + r2; 618328f1f0fSBastian Koppelmann ovf = (ret ^ mul) & ~(mul ^ r2); 619328f1f0fSBastian Koppelmann 620811ea608SBastian Koppelmann t1 = ret >> 32; 621811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 622811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 623811ea608SBastian Koppelmann 624328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 625328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 626328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 627328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 628328f1f0fSBastian Koppelmann if (mul >= 0) { 629328f1f0fSBastian Koppelmann ret = INT64_MAX; 630328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 631328f1f0fSBastian Koppelmann } else { 632328f1f0fSBastian Koppelmann ret = INT64_MIN; 633328f1f0fSBastian Koppelmann } 634328f1f0fSBastian Koppelmann } else { 635328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 636328f1f0fSBastian Koppelmann } 637328f1f0fSBastian Koppelmann 638328f1f0fSBastian Koppelmann return ret; 639328f1f0fSBastian Koppelmann } 640328f1f0fSBastian Koppelmann 641b00aa8ecSBastian Koppelmann uint32_t 642b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 643b00aa8ecSBastian Koppelmann { 644b00aa8ecSBastian Koppelmann int64_t result; 645b00aa8ecSBastian Koppelmann 646b00aa8ecSBastian Koppelmann result = (r1 + r2); 647b00aa8ecSBastian Koppelmann 648b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u); 649b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 650b00aa8ecSBastian Koppelmann 651b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 652b00aa8ecSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 653b00aa8ecSBastian Koppelmann case, we flip the saturated value. */ 654b00aa8ecSBastian Koppelmann if (r2 == 0x8000000000000000LL) { 655b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) { 656b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 657b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 658b00aa8ecSBastian Koppelmann result = INT32_MIN; 659b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) { 660b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 661b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 662b00aa8ecSBastian Koppelmann result = INT32_MAX; 663b00aa8ecSBastian Koppelmann } else { 664b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 665b00aa8ecSBastian Koppelmann } 666b00aa8ecSBastian Koppelmann } else { 667b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) { 668b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 669b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 670b00aa8ecSBastian Koppelmann result = INT32_MAX; 671b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) { 672b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 673b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 674b00aa8ecSBastian Koppelmann result = INT32_MIN; 675b00aa8ecSBastian Koppelmann } else { 676b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 677b00aa8ecSBastian Koppelmann } 678b00aa8ecSBastian Koppelmann } 679b00aa8ecSBastian Koppelmann return (uint32_t)result; 680b00aa8ecSBastian Koppelmann } 681b00aa8ecSBastian Koppelmann 682b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 683b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 684b00aa8ecSBastian Koppelmann { 685b00aa8ecSBastian Koppelmann int64_t t1 = (int64_t)r1; 686b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 687b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 688b00aa8ecSBastian Koppelmann int64_t result, mul; 689b00aa8ecSBastian Koppelmann int64_t ovf; 690b00aa8ecSBastian Koppelmann 691b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 692b00aa8ecSBastian Koppelmann result = mul + t1; 693b00aa8ecSBastian Koppelmann 694b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 695b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 696b00aa8ecSBastian Koppelmann 697b00aa8ecSBastian Koppelmann ovf = (result ^ mul) & ~(mul ^ t1); 698b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 699b00aa8ecSBastian Koppelmann if the mul was (0x80000000 * 0x80000000) << 1). If this is the 700b00aa8ecSBastian Koppelmann case, we flip the saturated value. */ 701b00aa8ecSBastian Koppelmann if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) { 702b00aa8ecSBastian Koppelmann if (ovf >= 0) { 703b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 704b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 705b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */ 706b00aa8ecSBastian Koppelmann if (mul < 0) { 707b00aa8ecSBastian Koppelmann result = INT64_MAX; 708b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */ 709b00aa8ecSBastian Koppelmann } else { 710b00aa8ecSBastian Koppelmann result = INT64_MIN; 711b00aa8ecSBastian Koppelmann } 712b00aa8ecSBastian Koppelmann } else { 713b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 714b00aa8ecSBastian Koppelmann } 715b00aa8ecSBastian Koppelmann } else { 716b00aa8ecSBastian Koppelmann if (ovf < 0) { 717b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 718b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 719b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */ 720b00aa8ecSBastian Koppelmann if (mul >= 0) { 721b00aa8ecSBastian Koppelmann result = INT64_MAX; 722b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */ 723b00aa8ecSBastian Koppelmann } else { 724b00aa8ecSBastian Koppelmann result = INT64_MIN; 725b00aa8ecSBastian Koppelmann } 726b00aa8ecSBastian Koppelmann } else { 727b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 728b00aa8ecSBastian Koppelmann } 729b00aa8ecSBastian Koppelmann } 730b00aa8ecSBastian Koppelmann return (uint64_t)result; 731b00aa8ecSBastian Koppelmann } 732b00aa8ecSBastian Koppelmann 733b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 734b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 735b00aa8ecSBastian Koppelmann { 736b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 737b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 738b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 739b00aa8ecSBastian Koppelmann int64_t mul, ret; 740b00aa8ecSBastian Koppelmann 741b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 742b00aa8ecSBastian Koppelmann mul = 0x7fffffff; 743b00aa8ecSBastian Koppelmann } else { 744b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 745b00aa8ecSBastian Koppelmann } 746b00aa8ecSBastian Koppelmann 747b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000; 748b00aa8ecSBastian Koppelmann 749b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 750b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 751b00aa8ecSBastian Koppelmann 752b00aa8ecSBastian Koppelmann if (ret > 0x7fffffffll) { 753b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 754b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 755b00aa8ecSBastian Koppelmann ret = INT32_MAX; 756b00aa8ecSBastian Koppelmann } else if (ret < -0x80000000ll) { 757b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 758b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 759b00aa8ecSBastian Koppelmann ret = INT32_MIN; 760b00aa8ecSBastian Koppelmann } else { 761b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 762b00aa8ecSBastian Koppelmann } 763b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll; 764b00aa8ecSBastian Koppelmann } 765b00aa8ecSBastian Koppelmann 766328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1, 767328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 768328f1f0fSBastian Koppelmann { 769328f1f0fSBastian Koppelmann uint64_t ret, mul; 770328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 771328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 772328f1f0fSBastian Koppelmann 773328f1f0fSBastian Koppelmann mul = t1 * t3; 774328f1f0fSBastian Koppelmann ret = mul + r2; 775328f1f0fSBastian Koppelmann 776811ea608SBastian Koppelmann t1 = ret >> 32; 777811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 778811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 779811ea608SBastian Koppelmann 780328f1f0fSBastian Koppelmann if (ret < r2) { 781328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 782328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 783328f1f0fSBastian Koppelmann /* saturate */ 784328f1f0fSBastian Koppelmann ret = UINT64_MAX; 785328f1f0fSBastian Koppelmann } else { 786328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 787328f1f0fSBastian Koppelmann } 788328f1f0fSBastian Koppelmann return ret; 789328f1f0fSBastian Koppelmann } 790328f1f0fSBastian Koppelmann 791328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1, 792328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 793328f1f0fSBastian Koppelmann { 794328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 795328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 796328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 797328f1f0fSBastian Koppelmann int64_t result; 798328f1f0fSBastian Koppelmann 799328f1f0fSBastian Koppelmann result = t2 - (t1 * t3); 800e4e39176SBastian Koppelmann return ssov32(env, result); 801328f1f0fSBastian Koppelmann } 802328f1f0fSBastian Koppelmann 803328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1, 804328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 805328f1f0fSBastian Koppelmann { 8063debbb5aSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 8073debbb5aSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 8083debbb5aSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 8093debbb5aSBastian Koppelmann uint64_t result; 8103debbb5aSBastian Koppelmann uint64_t mul; 811328f1f0fSBastian Koppelmann 8123debbb5aSBastian Koppelmann mul = (t1 * t3); 8133debbb5aSBastian Koppelmann result = t2 - mul; 8143debbb5aSBastian Koppelmann 8153debbb5aSBastian Koppelmann env->PSW_USB_AV = result ^ result * 2u; 8163debbb5aSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 8173debbb5aSBastian Koppelmann /* we calculate ovf by hand here, because the multiplication can overflow on 8183debbb5aSBastian Koppelmann the host, which would give false results if we compare to less than 8193debbb5aSBastian Koppelmann zero */ 8203debbb5aSBastian Koppelmann if (mul > t2) { 8213debbb5aSBastian Koppelmann env->PSW_USB_V = (1 << 31); 8223debbb5aSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 8233debbb5aSBastian Koppelmann result = 0; 8243debbb5aSBastian Koppelmann } else { 8253debbb5aSBastian Koppelmann env->PSW_USB_V = 0; 8263debbb5aSBastian Koppelmann } 8273debbb5aSBastian Koppelmann return result; 828328f1f0fSBastian Koppelmann } 829328f1f0fSBastian Koppelmann 830328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1, 831328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 832328f1f0fSBastian Koppelmann { 833328f1f0fSBastian Koppelmann uint64_t ret, ovf; 834328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 835328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 836328f1f0fSBastian Koppelmann int64_t mul; 837328f1f0fSBastian Koppelmann 838328f1f0fSBastian Koppelmann mul = t1 * t3; 839328f1f0fSBastian Koppelmann ret = r2 - mul; 840328f1f0fSBastian Koppelmann ovf = (ret ^ r2) & (mul ^ r2); 841328f1f0fSBastian Koppelmann 842811ea608SBastian Koppelmann t1 = ret >> 32; 843811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 844811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 845811ea608SBastian Koppelmann 846328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 847328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 848328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 849328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 850328f1f0fSBastian Koppelmann if (mul < 0) { 851328f1f0fSBastian Koppelmann ret = INT64_MAX; 852328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 853328f1f0fSBastian Koppelmann } else { 854328f1f0fSBastian Koppelmann ret = INT64_MIN; 855328f1f0fSBastian Koppelmann } 856328f1f0fSBastian Koppelmann } else { 857328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 858328f1f0fSBastian Koppelmann } 859328f1f0fSBastian Koppelmann return ret; 860328f1f0fSBastian Koppelmann } 861328f1f0fSBastian Koppelmann 862328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1, 863328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 864328f1f0fSBastian Koppelmann { 865328f1f0fSBastian Koppelmann uint64_t ret, mul; 866328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 867328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 868328f1f0fSBastian Koppelmann 869328f1f0fSBastian Koppelmann mul = t1 * t3; 870328f1f0fSBastian Koppelmann ret = r2 - mul; 871328f1f0fSBastian Koppelmann 872811ea608SBastian Koppelmann t1 = ret >> 32; 873811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 874811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 875811ea608SBastian Koppelmann 876328f1f0fSBastian Koppelmann if (ret > r2) { 877328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 878328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 879328f1f0fSBastian Koppelmann /* saturate */ 880328f1f0fSBastian Koppelmann ret = 0; 881328f1f0fSBastian Koppelmann } else { 882328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 883328f1f0fSBastian Koppelmann } 884328f1f0fSBastian Koppelmann return ret; 885328f1f0fSBastian Koppelmann } 886328f1f0fSBastian Koppelmann 88762e47b2eSBastian Koppelmann uint32_t 88862e47b2eSBastian Koppelmann helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 88962e47b2eSBastian Koppelmann { 89062e47b2eSBastian Koppelmann int64_t result; 89162e47b2eSBastian Koppelmann int64_t t1 = (int64_t)r1; 89262e47b2eSBastian Koppelmann int64_t t2 = (int64_t)r2; 89362e47b2eSBastian Koppelmann 89462e47b2eSBastian Koppelmann result = t1 - t2; 89562e47b2eSBastian Koppelmann 89662e47b2eSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u); 89762e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 89862e47b2eSBastian Koppelmann 89962e47b2eSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 90062e47b2eSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 90162e47b2eSBastian Koppelmann case, we flip the saturated value. */ 90262e47b2eSBastian Koppelmann if (r2 == 0x8000000000000000LL) { 90362e47b2eSBastian Koppelmann if (result > 0x7fffffffLL) { 90462e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 90562e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 90662e47b2eSBastian Koppelmann result = INT32_MIN; 90762e47b2eSBastian Koppelmann } else if (result < -0x80000000LL) { 90862e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 90962e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 91062e47b2eSBastian Koppelmann result = INT32_MAX; 91162e47b2eSBastian Koppelmann } else { 91262e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 91362e47b2eSBastian Koppelmann } 91462e47b2eSBastian Koppelmann } else { 91562e47b2eSBastian Koppelmann if (result > 0x7fffffffLL) { 91662e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 91762e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 91862e47b2eSBastian Koppelmann result = INT32_MAX; 91962e47b2eSBastian Koppelmann } else if (result < -0x80000000LL) { 92062e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 92162e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 92262e47b2eSBastian Koppelmann result = INT32_MIN; 92362e47b2eSBastian Koppelmann } else { 92462e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 92562e47b2eSBastian Koppelmann } 92662e47b2eSBastian Koppelmann } 92762e47b2eSBastian Koppelmann return (uint32_t)result; 92862e47b2eSBastian Koppelmann } 92962e47b2eSBastian Koppelmann 93062e47b2eSBastian Koppelmann uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 93162e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 93262e47b2eSBastian Koppelmann { 93362e47b2eSBastian Koppelmann int64_t t1 = (int64_t)r1; 93462e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 93562e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 93662e47b2eSBastian Koppelmann int64_t result, mul; 93762e47b2eSBastian Koppelmann int64_t ovf; 93862e47b2eSBastian Koppelmann 93962e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 94062e47b2eSBastian Koppelmann result = t1 - mul; 94162e47b2eSBastian Koppelmann 94262e47b2eSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 94362e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 94462e47b2eSBastian Koppelmann 94562e47b2eSBastian Koppelmann ovf = (result ^ t1) & (t1 ^ mul); 94662e47b2eSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 94762e47b2eSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 94862e47b2eSBastian Koppelmann case, we flip the saturated value. */ 94962e47b2eSBastian Koppelmann if (mul == 0x8000000000000000LL) { 95062e47b2eSBastian Koppelmann if (ovf >= 0) { 95162e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 95262e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 95362e47b2eSBastian Koppelmann /* ext_ret > MAX_INT */ 95462e47b2eSBastian Koppelmann if (mul >= 0) { 95562e47b2eSBastian Koppelmann result = INT64_MAX; 95662e47b2eSBastian Koppelmann /* ext_ret < MIN_INT */ 95762e47b2eSBastian Koppelmann } else { 95862e47b2eSBastian Koppelmann result = INT64_MIN; 95962e47b2eSBastian Koppelmann } 96062e47b2eSBastian Koppelmann } 96162e47b2eSBastian Koppelmann } else { 96262e47b2eSBastian Koppelmann if (ovf < 0) { 96362e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 96462e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 96562e47b2eSBastian Koppelmann /* ext_ret > MAX_INT */ 96662e47b2eSBastian Koppelmann if (mul < 0) { 96762e47b2eSBastian Koppelmann result = INT64_MAX; 96862e47b2eSBastian Koppelmann /* ext_ret < MIN_INT */ 96962e47b2eSBastian Koppelmann } else { 97062e47b2eSBastian Koppelmann result = INT64_MIN; 97162e47b2eSBastian Koppelmann } 97262e47b2eSBastian Koppelmann } else { 97362e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 97462e47b2eSBastian Koppelmann } 97562e47b2eSBastian Koppelmann } 97662e47b2eSBastian Koppelmann 97762e47b2eSBastian Koppelmann return (uint64_t)result; 97862e47b2eSBastian Koppelmann } 97962e47b2eSBastian Koppelmann 98062e47b2eSBastian Koppelmann uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 98162e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 98262e47b2eSBastian Koppelmann { 98362e47b2eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 98462e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 98562e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 98662e47b2eSBastian Koppelmann int64_t mul, ret; 98762e47b2eSBastian Koppelmann 98862e47b2eSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 98962e47b2eSBastian Koppelmann mul = 0x7fffffff; 99062e47b2eSBastian Koppelmann } else { 99162e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 99262e47b2eSBastian Koppelmann } 99362e47b2eSBastian Koppelmann 99462e47b2eSBastian Koppelmann ret = t1 - mul + 0x8000; 99562e47b2eSBastian Koppelmann 99662e47b2eSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 99762e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 99862e47b2eSBastian Koppelmann 99962e47b2eSBastian Koppelmann if (ret > 0x7fffffffll) { 100062e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 100162e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 100262e47b2eSBastian Koppelmann ret = INT32_MAX; 100362e47b2eSBastian Koppelmann } else if (ret < -0x80000000ll) { 100462e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 100562e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 100662e47b2eSBastian Koppelmann ret = INT32_MIN; 100762e47b2eSBastian Koppelmann } else { 100862e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 100962e47b2eSBastian Koppelmann } 101062e47b2eSBastian Koppelmann return ret & 0xffff0000ll; 101162e47b2eSBastian Koppelmann } 101262e47b2eSBastian Koppelmann 1013d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg) 1014d5de7839SBastian Koppelmann { 1015d5de7839SBastian Koppelmann int32_t b, i; 1016d5de7839SBastian Koppelmann int32_t ovf = 0; 1017d5de7839SBastian Koppelmann int32_t avf = 0; 1018d5de7839SBastian Koppelmann int32_t ret = 0; 1019d5de7839SBastian Koppelmann 1020d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1021d5de7839SBastian Koppelmann b = sextract32(arg, i * 8, 8); 1022d5de7839SBastian Koppelmann b = (b >= 0) ? b : (0 - b); 1023d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 1024d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1025d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 1026d5de7839SBastian Koppelmann } 1027d5de7839SBastian Koppelmann 1028d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1029d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1030d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1031d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1032d5de7839SBastian Koppelmann 1033d5de7839SBastian Koppelmann return ret; 1034d5de7839SBastian Koppelmann } 1035d5de7839SBastian Koppelmann 1036d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg) 1037d5de7839SBastian Koppelmann { 1038d5de7839SBastian Koppelmann int32_t h, i; 1039d5de7839SBastian Koppelmann int32_t ovf = 0; 1040d5de7839SBastian Koppelmann int32_t avf = 0; 1041d5de7839SBastian Koppelmann int32_t ret = 0; 1042d5de7839SBastian Koppelmann 1043d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1044d5de7839SBastian Koppelmann h = sextract32(arg, i * 16, 16); 1045d5de7839SBastian Koppelmann h = (h >= 0) ? h : (0 - h); 1046d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 1047d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1048d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1049d5de7839SBastian Koppelmann } 1050d5de7839SBastian Koppelmann 1051d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1052d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1053d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1054d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1055d5de7839SBastian Koppelmann 1056d5de7839SBastian Koppelmann return ret; 1057d5de7839SBastian Koppelmann } 1058d5de7839SBastian Koppelmann 1059d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1060d5de7839SBastian Koppelmann { 1061d5de7839SBastian Koppelmann int32_t b, i; 1062d5de7839SBastian Koppelmann int32_t extr_r2; 1063d5de7839SBastian Koppelmann int32_t ovf = 0; 1064d5de7839SBastian Koppelmann int32_t avf = 0; 1065d5de7839SBastian Koppelmann int32_t ret = 0; 1066d5de7839SBastian Koppelmann 1067d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1068d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1069d5de7839SBastian Koppelmann b = sextract32(r1, i * 8, 8); 1070d5de7839SBastian Koppelmann b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b); 1071d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 1072d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1073d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 1074d5de7839SBastian Koppelmann } 1075d5de7839SBastian Koppelmann 1076d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1077d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1078d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1079d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1080d5de7839SBastian Koppelmann return ret; 1081d5de7839SBastian Koppelmann } 1082d5de7839SBastian Koppelmann 1083d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1084d5de7839SBastian Koppelmann { 1085d5de7839SBastian Koppelmann int32_t h, i; 1086d5de7839SBastian Koppelmann int32_t extr_r2; 1087d5de7839SBastian Koppelmann int32_t ovf = 0; 1088d5de7839SBastian Koppelmann int32_t avf = 0; 1089d5de7839SBastian Koppelmann int32_t ret = 0; 1090d5de7839SBastian Koppelmann 1091d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1092d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1093d5de7839SBastian Koppelmann h = sextract32(r1, i * 16, 16); 1094d5de7839SBastian Koppelmann h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h); 1095d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 1096d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1097d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1098d5de7839SBastian Koppelmann } 1099d5de7839SBastian Koppelmann 1100d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1101d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1102d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1103d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1104d5de7839SBastian Koppelmann 1105d5de7839SBastian Koppelmann return ret; 1106d5de7839SBastian Koppelmann } 1107d5de7839SBastian Koppelmann 11082e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 11092e430e1cSBastian Koppelmann uint32_t r2_h) 11102e430e1cSBastian Koppelmann { 11112e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 11122e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 11132e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 11142e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 11152e430e1cSBastian Koppelmann int64_t result0, result1; 11162e430e1cSBastian Koppelmann uint32_t ovf0, ovf1; 11172e430e1cSBastian Koppelmann uint32_t avf0, avf1; 11182e430e1cSBastian Koppelmann 11192e430e1cSBastian Koppelmann ovf0 = ovf1 = 0; 11202e430e1cSBastian Koppelmann 11212e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 11222e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 11232e430e1cSBastian Koppelmann 11242e430e1cSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 11252e430e1cSBastian Koppelmann ovf0 = (1 << 31); 11262e430e1cSBastian Koppelmann } 11272e430e1cSBastian Koppelmann 11282e430e1cSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 11292e430e1cSBastian Koppelmann ovf1 = (1 << 31); 11302e430e1cSBastian Koppelmann } 11312e430e1cSBastian Koppelmann 11322e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 11332e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 11342e430e1cSBastian Koppelmann 11352e430e1cSBastian Koppelmann avf0 = result0 * 2u; 11362e430e1cSBastian Koppelmann avf0 = result0 ^ avf0; 11372e430e1cSBastian Koppelmann avf1 = result1 * 2u; 11382e430e1cSBastian Koppelmann avf1 = result1 ^ avf1; 11392e430e1cSBastian Koppelmann 11402e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 11412e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 11422e430e1cSBastian Koppelmann 11432e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 11442e430e1cSBastian Koppelmann } 11452e430e1cSBastian Koppelmann 1146bebe80fcSBastian Koppelmann uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1147bebe80fcSBastian Koppelmann uint32_t r2_h) 1148bebe80fcSBastian Koppelmann { 1149bebe80fcSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1150bebe80fcSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1151bebe80fcSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1152bebe80fcSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1153bebe80fcSBastian Koppelmann int64_t result0, result1; 1154bebe80fcSBastian Koppelmann uint32_t ovf0, ovf1; 1155bebe80fcSBastian Koppelmann uint32_t avf0, avf1; 1156bebe80fcSBastian Koppelmann 1157bebe80fcSBastian Koppelmann ovf0 = ovf1 = 0; 1158bebe80fcSBastian Koppelmann 1159bebe80fcSBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 1160bebe80fcSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 1161bebe80fcSBastian Koppelmann 1162bebe80fcSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1163bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 1164bebe80fcSBastian Koppelmann } 1165bebe80fcSBastian Koppelmann 1166bebe80fcSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1167bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 1168bebe80fcSBastian Koppelmann } 1169bebe80fcSBastian Koppelmann 1170bebe80fcSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1171bebe80fcSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1172bebe80fcSBastian Koppelmann 1173bebe80fcSBastian Koppelmann avf0 = result0 * 2u; 1174bebe80fcSBastian Koppelmann avf0 = result0 ^ avf0; 1175bebe80fcSBastian Koppelmann avf1 = result1 * 2u; 1176bebe80fcSBastian Koppelmann avf1 = result1 ^ avf1; 1177bebe80fcSBastian Koppelmann 1178bebe80fcSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1179bebe80fcSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1180bebe80fcSBastian Koppelmann 1181bebe80fcSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1182bebe80fcSBastian Koppelmann } 1183bebe80fcSBastian Koppelmann 1184b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 1185b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 1186b00aa8ecSBastian Koppelmann { 1187b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 1188b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 1189b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 1190b00aa8ecSBastian Koppelmann int64_t mul, ret; 1191b00aa8ecSBastian Koppelmann 1192b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 1193b00aa8ecSBastian Koppelmann mul = 0x7fffffff; 1194b00aa8ecSBastian Koppelmann } else { 1195b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 1196b00aa8ecSBastian Koppelmann } 1197b00aa8ecSBastian Koppelmann 1198b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000; 1199b00aa8ecSBastian Koppelmann 1200b00aa8ecSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 1201b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 1202b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1203b00aa8ecSBastian Koppelmann } else { 1204b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 1205b00aa8ecSBastian Koppelmann } 1206b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 1207b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1208b00aa8ecSBastian Koppelmann 1209b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll; 1210b00aa8ecSBastian Koppelmann } 1211b00aa8ecSBastian Koppelmann 1212d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1213d5de7839SBastian Koppelmann { 1214d5de7839SBastian Koppelmann int32_t b, i; 1215d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1216d5de7839SBastian Koppelmann int32_t ovf = 0; 1217d5de7839SBastian Koppelmann int32_t avf = 0; 1218d5de7839SBastian Koppelmann uint32_t ret = 0; 1219d5de7839SBastian Koppelmann 1220d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1221d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 1222d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1223d5de7839SBastian Koppelmann 1224d5de7839SBastian Koppelmann b = extr_r1 + extr_r2; 1225d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 1226d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1227d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 1228d5de7839SBastian Koppelmann } 1229d5de7839SBastian Koppelmann 1230d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1231d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1232d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1233d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1234d5de7839SBastian Koppelmann 1235d5de7839SBastian Koppelmann return ret; 1236d5de7839SBastian Koppelmann } 1237d5de7839SBastian Koppelmann 1238d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1239d5de7839SBastian Koppelmann { 1240d5de7839SBastian Koppelmann int32_t h, i; 1241d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1242d5de7839SBastian Koppelmann int32_t ovf = 0; 1243d5de7839SBastian Koppelmann int32_t avf = 0; 1244d5de7839SBastian Koppelmann int32_t ret = 0; 1245d5de7839SBastian Koppelmann 1246d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1247d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 1248d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1249d5de7839SBastian Koppelmann h = extr_r1 + extr_r2; 1250d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 1251d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1252d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1253d5de7839SBastian Koppelmann } 1254d5de7839SBastian Koppelmann 1255d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1256d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1257d5de7839SBastian Koppelmann env->PSW_USB_AV = (avf << 16); 1258d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1259d5de7839SBastian Koppelmann 1260d5de7839SBastian Koppelmann return ret; 1261d5de7839SBastian Koppelmann } 1262d5de7839SBastian Koppelmann 1263f4aef476SBastian Koppelmann uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1264f4aef476SBastian Koppelmann uint32_t r2_h) 1265f4aef476SBastian Koppelmann { 1266f4aef476SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1267f4aef476SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1268f4aef476SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1269f4aef476SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1270f4aef476SBastian Koppelmann int64_t result0, result1; 1271f4aef476SBastian Koppelmann uint32_t ovf0, ovf1; 1272f4aef476SBastian Koppelmann uint32_t avf0, avf1; 1273f4aef476SBastian Koppelmann 1274f4aef476SBastian Koppelmann ovf0 = ovf1 = 0; 1275f4aef476SBastian Koppelmann 1276f4aef476SBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 1277f4aef476SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 1278f4aef476SBastian Koppelmann 1279f4aef476SBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1280f4aef476SBastian Koppelmann ovf0 = (1 << 31); 1281f4aef476SBastian Koppelmann } 1282f4aef476SBastian Koppelmann 1283f4aef476SBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1284f4aef476SBastian Koppelmann ovf1 = (1 << 31); 1285f4aef476SBastian Koppelmann } 1286f4aef476SBastian Koppelmann 1287f4aef476SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1288f4aef476SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1289f4aef476SBastian Koppelmann 1290f4aef476SBastian Koppelmann avf0 = result0 * 2u; 1291f4aef476SBastian Koppelmann avf0 = result0 ^ avf0; 1292f4aef476SBastian Koppelmann avf1 = result1 * 2u; 1293f4aef476SBastian Koppelmann avf1 = result1 ^ avf1; 1294f4aef476SBastian Koppelmann 1295f4aef476SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1296f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1297f4aef476SBastian Koppelmann 1298f4aef476SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1299f4aef476SBastian Koppelmann } 1300f4aef476SBastian Koppelmann 1301068fac77SBastian Koppelmann uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1302068fac77SBastian Koppelmann uint32_t r2_h) 1303068fac77SBastian Koppelmann { 1304068fac77SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1305068fac77SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1306068fac77SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1307068fac77SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1308068fac77SBastian Koppelmann int64_t result0, result1; 1309068fac77SBastian Koppelmann uint32_t ovf0, ovf1; 1310068fac77SBastian Koppelmann uint32_t avf0, avf1; 1311068fac77SBastian Koppelmann 1312068fac77SBastian Koppelmann ovf0 = ovf1 = 0; 1313068fac77SBastian Koppelmann 1314068fac77SBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 1315068fac77SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 1316068fac77SBastian Koppelmann 1317068fac77SBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1318068fac77SBastian Koppelmann ovf0 = (1 << 31); 1319068fac77SBastian Koppelmann } 1320068fac77SBastian Koppelmann 1321068fac77SBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1322068fac77SBastian Koppelmann ovf1 = (1 << 31); 1323068fac77SBastian Koppelmann } 1324068fac77SBastian Koppelmann 1325068fac77SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1326068fac77SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1327068fac77SBastian Koppelmann 1328068fac77SBastian Koppelmann avf0 = result0 * 2u; 1329068fac77SBastian Koppelmann avf0 = result0 ^ avf0; 1330068fac77SBastian Koppelmann avf1 = result1 * 2u; 1331068fac77SBastian Koppelmann avf1 = result1 ^ avf1; 1332068fac77SBastian Koppelmann 1333068fac77SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1334068fac77SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1335068fac77SBastian Koppelmann 1336068fac77SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1337068fac77SBastian Koppelmann } 1338068fac77SBastian Koppelmann 133962e47b2eSBastian Koppelmann uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 134062e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 134162e47b2eSBastian Koppelmann { 134262e47b2eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 134362e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 134462e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 134562e47b2eSBastian Koppelmann int64_t mul, ret; 134662e47b2eSBastian Koppelmann 134762e47b2eSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 134862e47b2eSBastian Koppelmann mul = 0x7fffffff; 134962e47b2eSBastian Koppelmann } else { 135062e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 135162e47b2eSBastian Koppelmann } 135262e47b2eSBastian Koppelmann 135362e47b2eSBastian Koppelmann ret = t1 - mul + 0x8000; 135462e47b2eSBastian Koppelmann 135562e47b2eSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 135662e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 135762e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 135862e47b2eSBastian Koppelmann } else { 135962e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 136062e47b2eSBastian Koppelmann } 136162e47b2eSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 136262e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 136362e47b2eSBastian Koppelmann 136462e47b2eSBastian Koppelmann return ret & 0xffff0000ll; 136562e47b2eSBastian Koppelmann } 136662e47b2eSBastian Koppelmann 1367d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1368d5de7839SBastian Koppelmann { 1369d5de7839SBastian Koppelmann int32_t b, i; 1370d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1371d5de7839SBastian Koppelmann int32_t ovf = 0; 1372d5de7839SBastian Koppelmann int32_t avf = 0; 1373d5de7839SBastian Koppelmann uint32_t ret = 0; 1374d5de7839SBastian Koppelmann 1375d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1376d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 1377d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1378d5de7839SBastian Koppelmann 1379d5de7839SBastian Koppelmann b = extr_r1 - extr_r2; 1380d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 1381d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1382d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 1383d5de7839SBastian Koppelmann } 1384d5de7839SBastian Koppelmann 1385d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1386d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1387d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1388d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1389d5de7839SBastian Koppelmann 1390d5de7839SBastian Koppelmann return ret; 1391d5de7839SBastian Koppelmann } 1392d5de7839SBastian Koppelmann 1393d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1394d5de7839SBastian Koppelmann { 1395d5de7839SBastian Koppelmann int32_t h, i; 1396d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1397d5de7839SBastian Koppelmann int32_t ovf = 0; 1398d5de7839SBastian Koppelmann int32_t avf = 0; 1399d5de7839SBastian Koppelmann int32_t ret = 0; 1400d5de7839SBastian Koppelmann 1401d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1402d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 1403d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1404d5de7839SBastian Koppelmann h = extr_r1 - extr_r2; 1405d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 1406d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1407d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1408d5de7839SBastian Koppelmann } 1409d5de7839SBastian Koppelmann 1410d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1411d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1412d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1413d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1414d5de7839SBastian Koppelmann 1415d5de7839SBastian Koppelmann return ret; 1416d5de7839SBastian Koppelmann } 1417d5de7839SBastian Koppelmann 1418d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2) 1419d5de7839SBastian Koppelmann { 1420d5de7839SBastian Koppelmann int32_t ret; 1421d5de7839SBastian Koppelmann int32_t i, msk; 1422d5de7839SBastian Koppelmann 1423d5de7839SBastian Koppelmann ret = 0; 1424d5de7839SBastian Koppelmann msk = 0xff; 1425d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1426d5de7839SBastian Koppelmann if ((r1 & msk) == (r2 & msk)) { 1427d5de7839SBastian Koppelmann ret |= msk; 1428d5de7839SBastian Koppelmann } 1429d5de7839SBastian Koppelmann msk = msk << 8; 1430d5de7839SBastian Koppelmann } 1431d5de7839SBastian Koppelmann 1432d5de7839SBastian Koppelmann return ret; 1433d5de7839SBastian Koppelmann } 1434d5de7839SBastian Koppelmann 1435d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2) 1436d5de7839SBastian Koppelmann { 1437d5de7839SBastian Koppelmann int32_t ret = 0; 1438d5de7839SBastian Koppelmann 1439d5de7839SBastian Koppelmann if ((r1 & 0xffff) == (r2 & 0xffff)) { 1440d5de7839SBastian Koppelmann ret = 0xffff; 1441d5de7839SBastian Koppelmann } 1442d5de7839SBastian Koppelmann 1443d5de7839SBastian Koppelmann if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) { 1444d5de7839SBastian Koppelmann ret |= 0xffff0000; 1445d5de7839SBastian Koppelmann } 1446d5de7839SBastian Koppelmann 1447d5de7839SBastian Koppelmann return ret; 1448d5de7839SBastian Koppelmann } 1449d5de7839SBastian Koppelmann 1450d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2) 1451d5de7839SBastian Koppelmann { 1452d5de7839SBastian Koppelmann int32_t i; 1453d5de7839SBastian Koppelmann uint32_t ret = 0; 1454d5de7839SBastian Koppelmann 1455d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1456d5de7839SBastian Koppelmann ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8)); 1457d5de7839SBastian Koppelmann } 1458d5de7839SBastian Koppelmann 1459d5de7839SBastian Koppelmann return ret; 1460d5de7839SBastian Koppelmann } 1461d5de7839SBastian Koppelmann 1462d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2) 1463d5de7839SBastian Koppelmann { 1464d5de7839SBastian Koppelmann uint32_t ret; 1465d5de7839SBastian Koppelmann 1466d5de7839SBastian Koppelmann ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16)); 1467d5de7839SBastian Koppelmann ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16)); 1468d5de7839SBastian Koppelmann 1469d5de7839SBastian Koppelmann return ret; 1470d5de7839SBastian Koppelmann } 1471d5de7839SBastian Koppelmann 1472d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2) 1473d5de7839SBastian Koppelmann { 1474d5de7839SBastian Koppelmann int32_t i; 1475d5de7839SBastian Koppelmann uint32_t ret = 0; 1476d5de7839SBastian Koppelmann 1477d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1478d5de7839SBastian Koppelmann if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) { 1479d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 1480d5de7839SBastian Koppelmann } 1481d5de7839SBastian Koppelmann } 1482d5de7839SBastian Koppelmann 1483d5de7839SBastian Koppelmann return ret; 1484d5de7839SBastian Koppelmann } 1485d5de7839SBastian Koppelmann 1486d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2) 1487d5de7839SBastian Koppelmann { 1488d5de7839SBastian Koppelmann int32_t i; 1489d5de7839SBastian Koppelmann uint32_t ret = 0; 1490d5de7839SBastian Koppelmann 1491d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1492d5de7839SBastian Koppelmann if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) { 1493d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 1494d5de7839SBastian Koppelmann } 1495d5de7839SBastian Koppelmann } 1496d5de7839SBastian Koppelmann 1497d5de7839SBastian Koppelmann return ret; 1498d5de7839SBastian Koppelmann } 1499d5de7839SBastian Koppelmann 1500d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2) 1501d5de7839SBastian Koppelmann { 1502d5de7839SBastian Koppelmann uint32_t ret = 0; 1503d5de7839SBastian Koppelmann 1504d5de7839SBastian Koppelmann if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) { 1505d5de7839SBastian Koppelmann ret |= 0xffff; 1506d5de7839SBastian Koppelmann } 1507d5de7839SBastian Koppelmann 1508d5de7839SBastian Koppelmann if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) { 1509d5de7839SBastian Koppelmann ret |= 0xffff0000; 1510d5de7839SBastian Koppelmann } 1511d5de7839SBastian Koppelmann 1512d5de7839SBastian Koppelmann return ret; 1513d5de7839SBastian Koppelmann } 1514d5de7839SBastian Koppelmann 1515d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2) 1516d5de7839SBastian Koppelmann { 1517d5de7839SBastian Koppelmann uint32_t ret = 0; 1518d5de7839SBastian Koppelmann 1519d5de7839SBastian Koppelmann if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) { 1520d5de7839SBastian Koppelmann ret |= 0xffff; 1521d5de7839SBastian Koppelmann } 1522d5de7839SBastian Koppelmann 1523d5de7839SBastian Koppelmann if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) { 1524d5de7839SBastian Koppelmann ret |= 0xffff0000; 1525d5de7839SBastian Koppelmann } 1526d5de7839SBastian Koppelmann 1527d5de7839SBastian Koppelmann return ret; 1528d5de7839SBastian Koppelmann } 1529d5de7839SBastian Koppelmann 1530d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op) \ 1531d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \ 1532d5de7839SBastian Koppelmann { \ 1533d5de7839SBastian Koppelmann int32_t i, extr_r1, extr_r2; \ 1534d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1535d5de7839SBastian Koppelmann \ 1536d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 1537d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); \ 1538d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); \ 1539d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1540d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 1541d5de7839SBastian Koppelmann } \ 1542d5de7839SBastian Koppelmann return ret; \ 1543d5de7839SBastian Koppelmann } \ 1544d5de7839SBastian Koppelmann \ 1545d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\ 1546d5de7839SBastian Koppelmann { \ 1547d5de7839SBastian Koppelmann int32_t i; \ 1548d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 1549d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1550d5de7839SBastian Koppelmann \ 1551d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 1552d5de7839SBastian Koppelmann extr_r1 = extract32(r1, i * 8, 8); \ 1553d5de7839SBastian Koppelmann extr_r2 = extract32(r2, i * 8, 8); \ 1554d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1555d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 1556d5de7839SBastian Koppelmann } \ 1557d5de7839SBastian Koppelmann return ret; \ 1558d5de7839SBastian Koppelmann } \ 1559d5de7839SBastian Koppelmann \ 1560d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \ 1561d5de7839SBastian Koppelmann { \ 1562d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; \ 1563d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1564d5de7839SBastian Koppelmann \ 1565d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 0, 16); \ 1566d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 0, 16); \ 1567d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1568d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 1569d5de7839SBastian Koppelmann \ 1570d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 16, 16); \ 1571d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 16, 16); \ 1572d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1573d5de7839SBastian Koppelmann ret |= extr_r1 << 16; \ 1574d5de7839SBastian Koppelmann \ 1575d5de7839SBastian Koppelmann return ret; \ 1576d5de7839SBastian Koppelmann } \ 1577d5de7839SBastian Koppelmann \ 1578d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\ 1579d5de7839SBastian Koppelmann { \ 1580d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 1581d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1582d5de7839SBastian Koppelmann \ 1583d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 0, 16); \ 1584d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 0, 16); \ 1585d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1586d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 1587d5de7839SBastian Koppelmann \ 1588d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 16, 16); \ 1589d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 16, 16); \ 1590d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1591d5de7839SBastian Koppelmann ret |= extr_r1 << (16); \ 1592d5de7839SBastian Koppelmann \ 1593d5de7839SBastian Koppelmann return ret; \ 1594d5de7839SBastian Koppelmann } \ 159509532255SBastian Koppelmann \ 159609532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2) \ 159709532255SBastian Koppelmann { \ 159809532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \ 159909532255SBastian Koppelmann uint64_t ret = 0; \ 160009532255SBastian Koppelmann \ 160109532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \ 160209532255SBastian Koppelmann r2l = sextract64(r2, 0, 16); \ 160309532255SBastian Koppelmann r2h = sextract64(r2, 16, 16); \ 160409532255SBastian Koppelmann r1hl = sextract64(r1, 32, 16); \ 160509532255SBastian Koppelmann \ 160609532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 160709532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \ 160809532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \ 160909532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \ 161009532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \ 161109532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \ 161209532255SBastian Koppelmann } else { \ 161309532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \ 161409532255SBastian Koppelmann } \ 161509532255SBastian Koppelmann return ret; \ 161609532255SBastian Koppelmann } \ 161709532255SBastian Koppelmann \ 161809532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2) \ 161909532255SBastian Koppelmann { \ 162009532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \ 162109532255SBastian Koppelmann uint64_t ret = 0; \ 162209532255SBastian Koppelmann \ 162309532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \ 162409532255SBastian Koppelmann r2l = extract64(r2, 0, 16); \ 162509532255SBastian Koppelmann r2h = extract64(r2, 16, 16); \ 162609532255SBastian Koppelmann r1hl = extract64(r1, 32, 16); \ 162709532255SBastian Koppelmann \ 162809532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 162909532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \ 163009532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \ 163109532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \ 163209532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \ 163309532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \ 163409532255SBastian Koppelmann } else { \ 163509532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \ 163609532255SBastian Koppelmann } \ 163709532255SBastian Koppelmann return ret; \ 163809532255SBastian Koppelmann } 1639d5de7839SBastian Koppelmann 1640d5de7839SBastian Koppelmann EXTREMA_H_B(max, >) 1641d5de7839SBastian Koppelmann EXTREMA_H_B(min, <) 1642d5de7839SBastian Koppelmann 1643d5de7839SBastian Koppelmann #undef EXTREMA_H_B 1644d5de7839SBastian Koppelmann 16450b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1) 16460b79a781SBastian Koppelmann { 16470b79a781SBastian Koppelmann return clo32(r1); 16480b79a781SBastian Koppelmann } 16490b79a781SBastian Koppelmann 16500b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1) 16510b79a781SBastian Koppelmann { 16520b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 16530b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 16540b79a781SBastian Koppelmann 16550b79a781SBastian Koppelmann ret_hw0 = clo32(ret_hw0 << 16); 16560b79a781SBastian Koppelmann ret_hw1 = clo32(ret_hw1 << 16); 16570b79a781SBastian Koppelmann 16580b79a781SBastian Koppelmann if (ret_hw0 > 16) { 16590b79a781SBastian Koppelmann ret_hw0 = 16; 16600b79a781SBastian Koppelmann } 16610b79a781SBastian Koppelmann if (ret_hw1 > 16) { 16620b79a781SBastian Koppelmann ret_hw1 = 16; 16630b79a781SBastian Koppelmann } 16640b79a781SBastian Koppelmann 16650b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 16660b79a781SBastian Koppelmann } 16670b79a781SBastian Koppelmann 16680b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1) 16690b79a781SBastian Koppelmann { 16700b79a781SBastian Koppelmann return clz32(r1); 16710b79a781SBastian Koppelmann } 16720b79a781SBastian Koppelmann 16730b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1) 16740b79a781SBastian Koppelmann { 16750b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 16760b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 16770b79a781SBastian Koppelmann 16780b79a781SBastian Koppelmann ret_hw0 = clz32(ret_hw0 << 16); 16790b79a781SBastian Koppelmann ret_hw1 = clz32(ret_hw1 << 16); 16800b79a781SBastian Koppelmann 16810b79a781SBastian Koppelmann if (ret_hw0 > 16) { 16820b79a781SBastian Koppelmann ret_hw0 = 16; 16830b79a781SBastian Koppelmann } 16840b79a781SBastian Koppelmann if (ret_hw1 > 16) { 16850b79a781SBastian Koppelmann ret_hw1 = 16; 16860b79a781SBastian Koppelmann } 16870b79a781SBastian Koppelmann 16880b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 16890b79a781SBastian Koppelmann } 16900b79a781SBastian Koppelmann 16910b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1) 16920b79a781SBastian Koppelmann { 16930b79a781SBastian Koppelmann return clrsb32(r1); 16940b79a781SBastian Koppelmann } 16950b79a781SBastian Koppelmann 16960b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1) 16970b79a781SBastian Koppelmann { 16980b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 16990b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 17000b79a781SBastian Koppelmann 17010b79a781SBastian Koppelmann ret_hw0 = clrsb32(ret_hw0 << 16); 17020b79a781SBastian Koppelmann ret_hw1 = clrsb32(ret_hw1 << 16); 17030b79a781SBastian Koppelmann 17040b79a781SBastian Koppelmann if (ret_hw0 > 15) { 17050b79a781SBastian Koppelmann ret_hw0 = 15; 17060b79a781SBastian Koppelmann } 17070b79a781SBastian Koppelmann if (ret_hw1 > 15) { 17080b79a781SBastian Koppelmann ret_hw1 = 15; 17090b79a781SBastian Koppelmann } 17100b79a781SBastian Koppelmann 17110b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 17120b79a781SBastian Koppelmann } 17130b79a781SBastian Koppelmann 17140b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2) 17150b79a781SBastian Koppelmann { 17160b79a781SBastian Koppelmann int32_t shift_count = sextract32(r2, 0, 6); 17170b79a781SBastian Koppelmann 17180b79a781SBastian Koppelmann if (shift_count == -32) { 17190b79a781SBastian Koppelmann return 0; 17200b79a781SBastian Koppelmann } else if (shift_count < 0) { 17210b79a781SBastian Koppelmann return r1 >> -shift_count; 17220b79a781SBastian Koppelmann } else { 17230b79a781SBastian Koppelmann return r1 << shift_count; 17240b79a781SBastian Koppelmann } 17250b79a781SBastian Koppelmann } 17260b79a781SBastian Koppelmann 17270b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2) 17280b79a781SBastian Koppelmann { 17290b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 17300b79a781SBastian Koppelmann int32_t shift_count; 17310b79a781SBastian Koppelmann 17320b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 17330b79a781SBastian Koppelmann 17340b79a781SBastian Koppelmann if (shift_count == -16) { 17350b79a781SBastian Koppelmann return 0; 17360b79a781SBastian Koppelmann } else if (shift_count < 0) { 17370b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) >> -shift_count; 17380b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) >> -shift_count; 17390b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 17400b79a781SBastian Koppelmann } else { 17410b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) << shift_count; 17420b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) << shift_count; 17430b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 17440b79a781SBastian Koppelmann } 17450b79a781SBastian Koppelmann } 17460b79a781SBastian Koppelmann 17470b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 17480b79a781SBastian Koppelmann { 17490b79a781SBastian Koppelmann int32_t shift_count; 17500b79a781SBastian Koppelmann int64_t result, t1; 17510b79a781SBastian Koppelmann uint32_t ret; 17520b79a781SBastian Koppelmann 17530b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 6); 17540b79a781SBastian Koppelmann t1 = sextract32(r1, 0, 32); 17550b79a781SBastian Koppelmann 17560b79a781SBastian Koppelmann if (shift_count == 0) { 17570b79a781SBastian Koppelmann env->PSW_USB_C = env->PSW_USB_V = 0; 17580b79a781SBastian Koppelmann ret = r1; 17590b79a781SBastian Koppelmann } else if (shift_count == -32) { 17600b79a781SBastian Koppelmann env->PSW_USB_C = r1; 17610b79a781SBastian Koppelmann env->PSW_USB_V = 0; 17620b79a781SBastian Koppelmann ret = t1 >> 31; 17630b79a781SBastian Koppelmann } else if (shift_count > 0) { 17640b79a781SBastian Koppelmann result = t1 << shift_count; 17650b79a781SBastian Koppelmann /* calc carry */ 1766452e3d49SPeter Maydell env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0); 17670b79a781SBastian Koppelmann /* calc v */ 17680b79a781SBastian Koppelmann env->PSW_USB_V = (((result > 0x7fffffffLL) || 17690b79a781SBastian Koppelmann (result < -0x80000000LL)) << 31); 17700b79a781SBastian Koppelmann /* calc sv */ 17710b79a781SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 17720b79a781SBastian Koppelmann ret = (uint32_t)result; 17730b79a781SBastian Koppelmann } else { 17740b79a781SBastian Koppelmann env->PSW_USB_V = 0; 17750b79a781SBastian Koppelmann env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1)); 17760b79a781SBastian Koppelmann ret = t1 >> -shift_count; 17770b79a781SBastian Koppelmann } 17780b79a781SBastian Koppelmann 17790b79a781SBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 17800b79a781SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 17810b79a781SBastian Koppelmann 17820b79a781SBastian Koppelmann return ret; 17830b79a781SBastian Koppelmann } 17840b79a781SBastian Koppelmann 17850b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2) 17860b79a781SBastian Koppelmann { 17870b79a781SBastian Koppelmann int32_t shift_count; 17880b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 17890b79a781SBastian Koppelmann 17900b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 17910b79a781SBastian Koppelmann 17920b79a781SBastian Koppelmann if (shift_count == 0) { 17930b79a781SBastian Koppelmann return r1; 17940b79a781SBastian Koppelmann } else if (shift_count < 0) { 17950b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) >> -shift_count; 17960b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) >> -shift_count; 17970b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 17980b79a781SBastian Koppelmann } else { 17990b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) << shift_count; 18000b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) << shift_count; 18010b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 18020b79a781SBastian Koppelmann } 18030b79a781SBastian Koppelmann } 18040b79a781SBastian Koppelmann 1805e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2) 1806e2bed107SBastian Koppelmann { 1807e2bed107SBastian Koppelmann uint32_t i, ret; 1808e2bed107SBastian Koppelmann 1809e2bed107SBastian Koppelmann ret = 0; 1810e2bed107SBastian Koppelmann for (i = 0; i < 16; i++) { 1811e2bed107SBastian Koppelmann ret |= (r1 & 1) << (2 * i + 1); 1812e2bed107SBastian Koppelmann ret |= (r2 & 1) << (2 * i); 1813e2bed107SBastian Koppelmann r1 = r1 >> 1; 1814e2bed107SBastian Koppelmann r2 = r2 >> 1; 1815e2bed107SBastian Koppelmann } 1816e2bed107SBastian Koppelmann return ret; 1817e2bed107SBastian Koppelmann } 1818e2bed107SBastian Koppelmann 1819e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1) 1820e2bed107SBastian Koppelmann { 1821e2bed107SBastian Koppelmann int32_t i; 1822e2bed107SBastian Koppelmann uint64_t ret; 1823e2bed107SBastian Koppelmann 1824e2bed107SBastian Koppelmann ret = 0; 1825e2bed107SBastian Koppelmann for (i = 0; i < 32; i = i + 2) { 1826e2bed107SBastian Koppelmann /* even */ 1827e2bed107SBastian Koppelmann ret |= (r1 & 1) << (i/2); 1828e2bed107SBastian Koppelmann r1 = r1 >> 1; 1829e2bed107SBastian Koppelmann /* odd */ 1830e2bed107SBastian Koppelmann ret |= (uint64_t)(r1 & 1) << (i/2 + 32); 1831e2bed107SBastian Koppelmann r1 = r1 >> 1; 1832e2bed107SBastian Koppelmann } 1833e2bed107SBastian Koppelmann return ret; 1834e2bed107SBastian Koppelmann } 1835e2bed107SBastian Koppelmann 1836e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1) 1837e2bed107SBastian Koppelmann { 1838e2bed107SBastian Koppelmann uint32_t ret; 1839e2bed107SBastian Koppelmann uint32_t nOnes, i; 1840e2bed107SBastian Koppelmann 1841e2bed107SBastian Koppelmann ret = 0; 1842e2bed107SBastian Koppelmann nOnes = 0; 1843e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1844e2bed107SBastian Koppelmann ret ^= (r1 & 1); 1845e2bed107SBastian Koppelmann r1 = r1 >> 1; 1846e2bed107SBastian Koppelmann } 1847e2bed107SBastian Koppelmann /* second byte */ 1848e2bed107SBastian Koppelmann nOnes = 0; 1849e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1850e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1851e2bed107SBastian Koppelmann r1 = r1 >> 1; 1852e2bed107SBastian Koppelmann } 1853e2bed107SBastian Koppelmann ret |= nOnes << 8; 1854e2bed107SBastian Koppelmann /* third byte */ 1855e2bed107SBastian Koppelmann nOnes = 0; 1856e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1857e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1858e2bed107SBastian Koppelmann r1 = r1 >> 1; 1859e2bed107SBastian Koppelmann } 1860e2bed107SBastian Koppelmann ret |= nOnes << 16; 1861e2bed107SBastian Koppelmann /* fourth byte */ 1862e2bed107SBastian Koppelmann nOnes = 0; 1863e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1864e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1865e2bed107SBastian Koppelmann r1 = r1 >> 1; 1866e2bed107SBastian Koppelmann } 1867e2bed107SBastian Koppelmann ret |= nOnes << 24; 1868e2bed107SBastian Koppelmann 1869e2bed107SBastian Koppelmann return ret; 1870e2bed107SBastian Koppelmann } 1871e2bed107SBastian Koppelmann 187209532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high, 187309532255SBastian Koppelmann target_ulong r2) 187409532255SBastian Koppelmann { 187509532255SBastian Koppelmann uint32_t ret; 187609532255SBastian Koppelmann int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac; 187709532255SBastian Koppelmann int32_t int_exp = r1_high; 187809532255SBastian Koppelmann int32_t int_mant = r1_low; 187909532255SBastian Koppelmann uint32_t flag_rnd = (int_mant & (1 << 7)) && ( 188009532255SBastian Koppelmann (int_mant & (1 << 8)) || 188109532255SBastian Koppelmann (int_mant & 0x7f) || 188209532255SBastian Koppelmann (carry != 0)); 188309532255SBastian Koppelmann if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) { 188409532255SBastian Koppelmann fp_exp = 255; 188509532255SBastian Koppelmann fp_frac = extract32(int_mant, 8, 23); 188609532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp >= 127)) { 188709532255SBastian Koppelmann fp_exp = 255; 188809532255SBastian Koppelmann fp_frac = 0; 188909532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp <= -128)) { 189009532255SBastian Koppelmann fp_exp = 0; 189109532255SBastian Koppelmann fp_frac = 0; 189209532255SBastian Koppelmann } else if (int_mant == 0) { 189309532255SBastian Koppelmann fp_exp = 0; 189409532255SBastian Koppelmann fp_frac = 0; 189509532255SBastian Koppelmann } else { 189609532255SBastian Koppelmann if (((int_mant & (1 << 31)) == 0)) { 189709532255SBastian Koppelmann temp_exp = 0; 189809532255SBastian Koppelmann } else { 189909532255SBastian Koppelmann temp_exp = int_exp + 128; 190009532255SBastian Koppelmann } 190109532255SBastian Koppelmann fp_exp_frac = (((temp_exp & 0xff) << 23) | 190209532255SBastian Koppelmann extract32(int_mant, 8, 23)) 190309532255SBastian Koppelmann + flag_rnd; 190409532255SBastian Koppelmann fp_exp = extract32(fp_exp_frac, 23, 8); 190509532255SBastian Koppelmann fp_frac = extract32(fp_exp_frac, 0, 23); 190609532255SBastian Koppelmann } 190709532255SBastian Koppelmann ret = r2 & (1 << 31); 190809532255SBastian Koppelmann ret = ret + (fp_exp << 23); 190909532255SBastian Koppelmann ret = ret + (fp_frac & 0x7fffff); 191009532255SBastian Koppelmann 191109532255SBastian Koppelmann return ret; 191209532255SBastian Koppelmann } 191309532255SBastian Koppelmann 1914e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1) 1915e2bed107SBastian Koppelmann { 1916e2bed107SBastian Koppelmann int32_t fp_exp = extract32(arg1, 23, 8); 1917e2bed107SBastian Koppelmann int32_t fp_frac = extract32(arg1, 0, 23); 1918e2bed107SBastian Koppelmann uint64_t ret; 1919e2bed107SBastian Koppelmann int32_t int_exp, int_mant; 1920e2bed107SBastian Koppelmann 1921e2bed107SBastian Koppelmann if (fp_exp == 255) { 1922e2bed107SBastian Koppelmann int_exp = 255; 1923e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1924e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac == 0)) { 1925e2bed107SBastian Koppelmann int_exp = -127; 1926e2bed107SBastian Koppelmann int_mant = 0; 1927e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac != 0)) { 1928e2bed107SBastian Koppelmann int_exp = -126; 1929e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1930e2bed107SBastian Koppelmann } else { 1931e2bed107SBastian Koppelmann int_exp = fp_exp - 127; 1932e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1933e2bed107SBastian Koppelmann int_mant |= (1 << 30); 1934e2bed107SBastian Koppelmann } 1935e2bed107SBastian Koppelmann ret = int_exp; 1936e2bed107SBastian Koppelmann ret = ret << 32; 1937e2bed107SBastian Koppelmann ret |= int_mant; 1938e2bed107SBastian Koppelmann 1939e2bed107SBastian Koppelmann return ret; 1940e2bed107SBastian Koppelmann } 1941e2bed107SBastian Koppelmann 1942e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1943e2bed107SBastian Koppelmann { 1944e2bed107SBastian Koppelmann uint64_t ret; 1945f69c24e4SBastian Koppelmann int32_t abs_sig_dividend, abs_divisor; 1946e2bed107SBastian Koppelmann 1947e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 1948e2bed107SBastian Koppelmann ret = ret << 24; 1949e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1950e2bed107SBastian Koppelmann ret |= 0xffffff; 1951e2bed107SBastian Koppelmann } 1952e2bed107SBastian Koppelmann 1953f69c24e4SBastian Koppelmann abs_sig_dividend = abs((int32_t)r1) >> 8; 195430a0d72fSStefan Weil abs_divisor = abs((int32_t)r2); 1955f69c24e4SBastian Koppelmann /* calc overflow 1956f69c24e4SBastian Koppelmann ofv if (a/b >= 255) <=> (a/255 >= b) */ 1957f69c24e4SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; 1958e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1959e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1960e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1961e2bed107SBastian Koppelmann 1962e2bed107SBastian Koppelmann return ret; 1963e2bed107SBastian Koppelmann } 1964e2bed107SBastian Koppelmann 1965e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1966e2bed107SBastian Koppelmann { 1967e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 1968e2bed107SBastian Koppelmann 1969e2bed107SBastian Koppelmann ret = ret << 24; 1970e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1971e2bed107SBastian Koppelmann ret |= 0xffffff; 1972e2bed107SBastian Koppelmann } 1973e2bed107SBastian Koppelmann /* calc overflow */ 1974e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80))); 1975e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1976e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1977e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1978e2bed107SBastian Koppelmann 1979e2bed107SBastian Koppelmann return ret; 1980e2bed107SBastian Koppelmann } 1981e2bed107SBastian Koppelmann 1982e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1983e2bed107SBastian Koppelmann { 1984e2bed107SBastian Koppelmann uint64_t ret; 1985f69c24e4SBastian Koppelmann int32_t abs_sig_dividend, abs_divisor; 1986e2bed107SBastian Koppelmann 1987e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 1988e2bed107SBastian Koppelmann ret = ret << 16; 1989e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1990e2bed107SBastian Koppelmann ret |= 0xffff; 1991e2bed107SBastian Koppelmann } 1992e2bed107SBastian Koppelmann 1993f69c24e4SBastian Koppelmann abs_sig_dividend = abs((int32_t)r1) >> 16; 199430a0d72fSStefan Weil abs_divisor = abs((int32_t)r2); 1995f69c24e4SBastian Koppelmann /* calc overflow 1996f69c24e4SBastian Koppelmann ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */ 1997f69c24e4SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; 1998e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1999e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2000e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 2001e2bed107SBastian Koppelmann 2002e2bed107SBastian Koppelmann return ret; 2003e2bed107SBastian Koppelmann } 2004e2bed107SBastian Koppelmann 2005e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2006e2bed107SBastian Koppelmann { 2007e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 2008e2bed107SBastian Koppelmann 2009e2bed107SBastian Koppelmann ret = ret << 16; 2010e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2011e2bed107SBastian Koppelmann ret |= 0xffff; 2012e2bed107SBastian Koppelmann } 2013e2bed107SBastian Koppelmann /* calc overflow */ 2014e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000))); 2015e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 2016e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2017e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 2018e2bed107SBastian Koppelmann 2019e2bed107SBastian Koppelmann return ret; 2020e2bed107SBastian Koppelmann } 2021e2bed107SBastian Koppelmann 202209532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2) 202309532255SBastian Koppelmann { 202409532255SBastian Koppelmann int32_t x_sign = (r1 >> 63); 202509532255SBastian Koppelmann int32_t q_sign = x_sign ^ (r2 >> 31); 202609532255SBastian Koppelmann int32_t eq_pos = x_sign & ((r1 >> 32) == r2); 202709532255SBastian Koppelmann int32_t eq_neg = x_sign & ((r1 >> 32) == -r2); 202809532255SBastian Koppelmann uint32_t quotient; 202909532255SBastian Koppelmann uint64_t ret, remainder; 203009532255SBastian Koppelmann 203109532255SBastian Koppelmann if ((q_sign & ~eq_neg) | eq_pos) { 203209532255SBastian Koppelmann quotient = (r1 + 1) & 0xffffffff; 203309532255SBastian Koppelmann } else { 203409532255SBastian Koppelmann quotient = r1 & 0xffffffff; 203509532255SBastian Koppelmann } 203609532255SBastian Koppelmann 203709532255SBastian Koppelmann if (eq_pos | eq_neg) { 203809532255SBastian Koppelmann remainder = 0; 203909532255SBastian Koppelmann } else { 204009532255SBastian Koppelmann remainder = (r1 & 0xffffffff00000000ull); 204109532255SBastian Koppelmann } 204209532255SBastian Koppelmann ret = remainder|quotient; 204309532255SBastian Koppelmann return ret; 204409532255SBastian Koppelmann } 204509532255SBastian Koppelmann 204609532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2) 204709532255SBastian Koppelmann { 204809532255SBastian Koppelmann int32_t dividend_sign = extract64(r1, 63, 1); 204909532255SBastian Koppelmann int32_t divisor_sign = extract32(r2, 31, 1); 205009532255SBastian Koppelmann int32_t quotient_sign = (dividend_sign != divisor_sign); 205109532255SBastian Koppelmann int32_t addend, dividend_quotient, remainder; 205209532255SBastian Koppelmann int32_t i, temp; 205309532255SBastian Koppelmann 205409532255SBastian Koppelmann if (quotient_sign) { 205509532255SBastian Koppelmann addend = r2; 205609532255SBastian Koppelmann } else { 205709532255SBastian Koppelmann addend = -r2; 205809532255SBastian Koppelmann } 205909532255SBastian Koppelmann dividend_quotient = (int32_t)r1; 206009532255SBastian Koppelmann remainder = (int32_t)(r1 >> 32); 206109532255SBastian Koppelmann 206209532255SBastian Koppelmann for (i = 0; i < 8; i++) { 206309532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 206409532255SBastian Koppelmann dividend_quotient <<= 1; 206509532255SBastian Koppelmann temp = remainder + addend; 206609532255SBastian Koppelmann if ((temp < 0) == dividend_sign) { 206709532255SBastian Koppelmann remainder = temp; 206809532255SBastian Koppelmann } 206909532255SBastian Koppelmann if (((temp < 0) == dividend_sign)) { 207009532255SBastian Koppelmann dividend_quotient = dividend_quotient | !quotient_sign; 207109532255SBastian Koppelmann } else { 207209532255SBastian Koppelmann dividend_quotient = dividend_quotient | quotient_sign; 207309532255SBastian Koppelmann } 207409532255SBastian Koppelmann } 207509532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 207609532255SBastian Koppelmann } 207709532255SBastian Koppelmann 207809532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2) 207909532255SBastian Koppelmann { 208009532255SBastian Koppelmann int32_t dividend_quotient = extract64(r1, 0, 32); 208109532255SBastian Koppelmann int64_t remainder = extract64(r1, 32, 32); 208209532255SBastian Koppelmann int32_t i; 208309532255SBastian Koppelmann int64_t temp; 208409532255SBastian Koppelmann for (i = 0; i < 8; i++) { 208509532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 208609532255SBastian Koppelmann dividend_quotient <<= 1; 208709532255SBastian Koppelmann temp = (remainder & 0xffffffff) - r2; 208809532255SBastian Koppelmann if (temp >= 0) { 208909532255SBastian Koppelmann remainder = temp; 209009532255SBastian Koppelmann } 209109532255SBastian Koppelmann dividend_quotient = dividend_quotient | !(temp < 0); 209209532255SBastian Koppelmann } 209309532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 209409532255SBastian Koppelmann } 209509532255SBastian Koppelmann 20969655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01, 20979655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 20989655b932SBastian Koppelmann { 20999655b932SBastian Koppelmann uint64_t ret; 21009655b932SBastian Koppelmann uint32_t result0, result1; 21019655b932SBastian Koppelmann 21029655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 21039655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 21049655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 21059655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 21069655b932SBastian Koppelmann if (sc1) { 21079655b932SBastian Koppelmann result1 = 0x7fffffff; 21089655b932SBastian Koppelmann } else { 21099655b932SBastian Koppelmann result1 = (((uint32_t)(arg00 * arg10)) << n); 21109655b932SBastian Koppelmann } 21119655b932SBastian Koppelmann if (sc0) { 21129655b932SBastian Koppelmann result0 = 0x7fffffff; 21139655b932SBastian Koppelmann } else { 21149655b932SBastian Koppelmann result0 = (((uint32_t)(arg01 * arg11)) << n); 21159655b932SBastian Koppelmann } 21169655b932SBastian Koppelmann ret = (((uint64_t)result1 << 32)) | result0; 21179655b932SBastian Koppelmann return ret; 21189655b932SBastian Koppelmann } 21199655b932SBastian Koppelmann 21209655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01, 21219655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 21229655b932SBastian Koppelmann { 21239655b932SBastian Koppelmann uint64_t ret; 21249655b932SBastian Koppelmann int64_t result0, result1; 21259655b932SBastian Koppelmann 21269655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 21279655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 21289655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 21299655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 21309655b932SBastian Koppelmann 21319655b932SBastian Koppelmann if (sc1) { 21329655b932SBastian Koppelmann result1 = 0x7fffffff; 21339655b932SBastian Koppelmann } else { 21349655b932SBastian Koppelmann result1 = (((int32_t)arg00 * (int32_t)arg10) << n); 21359655b932SBastian Koppelmann } 21369655b932SBastian Koppelmann if (sc0) { 21379655b932SBastian Koppelmann result0 = 0x7fffffff; 21389655b932SBastian Koppelmann } else { 21399655b932SBastian Koppelmann result0 = (((int32_t)arg01 * (int32_t)arg11) << n); 21409655b932SBastian Koppelmann } 21419655b932SBastian Koppelmann ret = (result1 + result0); 21429655b932SBastian Koppelmann ret = ret << 16; 21439655b932SBastian Koppelmann return ret; 21449655b932SBastian Koppelmann } 21459655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01, 21469655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 21479655b932SBastian Koppelmann { 21489655b932SBastian Koppelmann uint32_t result0, result1; 21499655b932SBastian Koppelmann 21509655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 21519655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 21529655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 21539655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 21549655b932SBastian Koppelmann 21559655b932SBastian Koppelmann if (sc1) { 21569655b932SBastian Koppelmann result1 = 0x7fffffff; 21579655b932SBastian Koppelmann } else { 21589655b932SBastian Koppelmann result1 = ((arg00 * arg10) << n) + 0x8000; 21599655b932SBastian Koppelmann } 21609655b932SBastian Koppelmann if (sc0) { 21619655b932SBastian Koppelmann result0 = 0x7fffffff; 21629655b932SBastian Koppelmann } else { 21639655b932SBastian Koppelmann result0 = ((arg01 * arg11) << n) + 0x8000; 21649655b932SBastian Koppelmann } 21659655b932SBastian Koppelmann return (result1 & 0xffff0000) | (result0 >> 16); 21669655b932SBastian Koppelmann } 21679655b932SBastian Koppelmann 21689a31922bSBastian Koppelmann /* context save area (CSA) related helpers */ 21699a31922bSBastian Koppelmann 21709a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw) 21719a31922bSBastian Koppelmann { 21729a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 21739a31922bSBastian Koppelmann return 0; 21749a31922bSBastian Koppelmann } 21759a31922bSBastian Koppelmann 21769a31922bSBastian Koppelmann (*psw)++; 21779a31922bSBastian Koppelmann /* check for overflow */ 21789a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 21799a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 21809a31922bSBastian Koppelmann int count = *psw & mask; 21819a31922bSBastian Koppelmann if (count == 0) { 21829a31922bSBastian Koppelmann (*psw)--; 21839a31922bSBastian Koppelmann return 1; 21849a31922bSBastian Koppelmann } 21859a31922bSBastian Koppelmann return 0; 21869a31922bSBastian Koppelmann } 21879a31922bSBastian Koppelmann 21889a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw) 21899a31922bSBastian Koppelmann { 21909a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 21919a31922bSBastian Koppelmann return 0; 21929a31922bSBastian Koppelmann } 21939a31922bSBastian Koppelmann /* check for underflow */ 21949a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 21959a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 21969a31922bSBastian Koppelmann int count = *psw & mask; 21979a31922bSBastian Koppelmann if (count == 0) { 21989a31922bSBastian Koppelmann return 1; 21999a31922bSBastian Koppelmann } 22009a31922bSBastian Koppelmann (*psw)--; 22019a31922bSBastian Koppelmann return 0; 22029a31922bSBastian Koppelmann } 22039a31922bSBastian Koppelmann 220444ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw) 220544ea3430SBastian Koppelmann { 220644ea3430SBastian Koppelmann int cdc = *psw & MASK_PSW_CDC; 220744ea3430SBastian Koppelmann /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC == 220844ea3430SBastian Koppelmann 7'b1111111, otherwise returns FALSE. */ 220944ea3430SBastian Koppelmann if (cdc == 0x7f) { 221044ea3430SBastian Koppelmann return true; 221144ea3430SBastian Koppelmann } 221244ea3430SBastian Koppelmann /* find CDC.COUNT */ 221344ea3430SBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 221444ea3430SBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 221544ea3430SBastian Koppelmann int count = *psw & mask; 221644ea3430SBastian Koppelmann return count == 0; 221744ea3430SBastian Koppelmann } 221844ea3430SBastian Koppelmann 2219030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea) 22209a31922bSBastian Koppelmann { 22219a31922bSBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 22229a31922bSBastian Koppelmann cpu_stl_data(env, ea+4, env->PSW); 22239a31922bSBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[10]); 22249a31922bSBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[11]); 22259a31922bSBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[8]); 22269a31922bSBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[9]); 22279a31922bSBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[10]); 22289a31922bSBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[11]); 22299a31922bSBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[12]); 22309a31922bSBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[13]); 22319a31922bSBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[14]); 22329a31922bSBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[15]); 22339a31922bSBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[12]); 22349a31922bSBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[13]); 22359a31922bSBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[14]); 22369a31922bSBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[15]); 22379a31922bSBastian Koppelmann } 22389a31922bSBastian Koppelmann 2239030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea) 22405de93515SBastian Koppelmann { 22415de93515SBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 2242030c58dfSBastian Koppelmann cpu_stl_data(env, ea+4, env->gpr_a[11]); 22435de93515SBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[2]); 22445de93515SBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[3]); 22455de93515SBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[0]); 22465de93515SBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[1]); 22475de93515SBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[2]); 22485de93515SBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[3]); 22495de93515SBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[4]); 22505de93515SBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[5]); 22515de93515SBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[6]); 22525de93515SBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[7]); 22535de93515SBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[4]); 22545de93515SBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[5]); 22555de93515SBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[6]); 22565de93515SBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[7]); 22575de93515SBastian Koppelmann } 22585de93515SBastian Koppelmann 22599a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea, 22609a31922bSBastian Koppelmann target_ulong *new_PCXI, target_ulong *new_PSW) 22619a31922bSBastian Koppelmann { 22629a31922bSBastian Koppelmann *new_PCXI = cpu_ldl_data(env, ea); 22639a31922bSBastian Koppelmann *new_PSW = cpu_ldl_data(env, ea+4); 22649a31922bSBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, ea+8); 22659a31922bSBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, ea+12); 22669a31922bSBastian Koppelmann env->gpr_d[8] = cpu_ldl_data(env, ea+16); 22679a31922bSBastian Koppelmann env->gpr_d[9] = cpu_ldl_data(env, ea+20); 22689a31922bSBastian Koppelmann env->gpr_d[10] = cpu_ldl_data(env, ea+24); 22699a31922bSBastian Koppelmann env->gpr_d[11] = cpu_ldl_data(env, ea+28); 22709a31922bSBastian Koppelmann env->gpr_a[12] = cpu_ldl_data(env, ea+32); 22719a31922bSBastian Koppelmann env->gpr_a[13] = cpu_ldl_data(env, ea+36); 22729a31922bSBastian Koppelmann env->gpr_a[14] = cpu_ldl_data(env, ea+40); 22739a31922bSBastian Koppelmann env->gpr_a[15] = cpu_ldl_data(env, ea+44); 22749a31922bSBastian Koppelmann env->gpr_d[12] = cpu_ldl_data(env, ea+48); 22759a31922bSBastian Koppelmann env->gpr_d[13] = cpu_ldl_data(env, ea+52); 22769a31922bSBastian Koppelmann env->gpr_d[14] = cpu_ldl_data(env, ea+56); 22779a31922bSBastian Koppelmann env->gpr_d[15] = cpu_ldl_data(env, ea+60); 22789a31922bSBastian Koppelmann } 22799a31922bSBastian Koppelmann 228059543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea, 228159543d4eSBastian Koppelmann target_ulong *ra, target_ulong *pcxi) 228259543d4eSBastian Koppelmann { 228359543d4eSBastian Koppelmann *pcxi = cpu_ldl_data(env, ea); 228459543d4eSBastian Koppelmann *ra = cpu_ldl_data(env, ea+4); 228559543d4eSBastian Koppelmann env->gpr_a[2] = cpu_ldl_data(env, ea+8); 228659543d4eSBastian Koppelmann env->gpr_a[3] = cpu_ldl_data(env, ea+12); 228759543d4eSBastian Koppelmann env->gpr_d[0] = cpu_ldl_data(env, ea+16); 228859543d4eSBastian Koppelmann env->gpr_d[1] = cpu_ldl_data(env, ea+20); 228959543d4eSBastian Koppelmann env->gpr_d[2] = cpu_ldl_data(env, ea+24); 229059543d4eSBastian Koppelmann env->gpr_d[3] = cpu_ldl_data(env, ea+28); 229159543d4eSBastian Koppelmann env->gpr_a[4] = cpu_ldl_data(env, ea+32); 229259543d4eSBastian Koppelmann env->gpr_a[5] = cpu_ldl_data(env, ea+36); 229359543d4eSBastian Koppelmann env->gpr_a[6] = cpu_ldl_data(env, ea+40); 229459543d4eSBastian Koppelmann env->gpr_a[7] = cpu_ldl_data(env, ea+44); 229559543d4eSBastian Koppelmann env->gpr_d[4] = cpu_ldl_data(env, ea+48); 229659543d4eSBastian Koppelmann env->gpr_d[5] = cpu_ldl_data(env, ea+52); 229759543d4eSBastian Koppelmann env->gpr_d[6] = cpu_ldl_data(env, ea+56); 229859543d4eSBastian Koppelmann env->gpr_d[7] = cpu_ldl_data(env, ea+60); 229959543d4eSBastian Koppelmann } 230059543d4eSBastian Koppelmann 23019a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc) 23029a31922bSBastian Koppelmann { 23039a31922bSBastian Koppelmann target_ulong tmp_FCX; 23049a31922bSBastian Koppelmann target_ulong ea; 23059a31922bSBastian Koppelmann target_ulong new_FCX; 23069a31922bSBastian Koppelmann target_ulong psw; 23079a31922bSBastian Koppelmann 23089a31922bSBastian Koppelmann psw = psw_read(env); 23099a31922bSBastian Koppelmann /* if (FCX == 0) trap(FCU); */ 23109a31922bSBastian Koppelmann if (env->FCX == 0) { 23119a31922bSBastian Koppelmann /* FCU trap */ 23129a31922bSBastian Koppelmann } 23139a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */ 23149a31922bSBastian Koppelmann if (psw & MASK_PSW_CDE) { 23159a31922bSBastian Koppelmann if (cdc_increment(&psw)) { 23169a31922bSBastian Koppelmann /* CDO trap */ 23179a31922bSBastian Koppelmann } 23189a31922bSBastian Koppelmann } 23199a31922bSBastian Koppelmann /* PSW.CDE = 1;*/ 23209a31922bSBastian Koppelmann psw |= MASK_PSW_CDE; 23219a31922bSBastian Koppelmann /* tmp_FCX = FCX; */ 23229a31922bSBastian Koppelmann tmp_FCX = env->FCX; 23239a31922bSBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 23249a31922bSBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 23259a31922bSBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 2326030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 2327030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2328030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 23299a31922bSBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 23309a31922bSBastian Koppelmann D[15]}; */ 2331030c58dfSBastian Koppelmann save_context_upper(env, ea); 23329a31922bSBastian Koppelmann 23339a31922bSBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 23349a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 23359a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 23369a31922bSBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 23379a31922bSBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 23389a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 23399a31922bSBastian Koppelmann /* PCXI.UL = 1; */ 23409a31922bSBastian Koppelmann env->PCXI |= MASK_PCXI_UL; 23419a31922bSBastian Koppelmann 23429a31922bSBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 23439a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 23449a31922bSBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 23459a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 23469a31922bSBastian Koppelmann /* A[11] = next_pc[31: 0]; */ 23479a31922bSBastian Koppelmann env->gpr_a[11] = next_pc; 23489a31922bSBastian Koppelmann 23499a31922bSBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 23509a31922bSBastian Koppelmann if (tmp_FCX == env->LCX) { 23519a31922bSBastian Koppelmann /* FCD trap */ 23529a31922bSBastian Koppelmann } 23539a31922bSBastian Koppelmann psw_write(env, psw); 23549a31922bSBastian Koppelmann } 23559a31922bSBastian Koppelmann 23569a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env) 23579a31922bSBastian Koppelmann { 23589a31922bSBastian Koppelmann target_ulong ea; 23599a31922bSBastian Koppelmann target_ulong new_PCXI; 23609a31922bSBastian Koppelmann target_ulong new_PSW, psw; 23619a31922bSBastian Koppelmann 23629a31922bSBastian Koppelmann psw = psw_read(env); 23639a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/ 23649a31922bSBastian Koppelmann if (env->PSW & MASK_PSW_CDE) { 23659a31922bSBastian Koppelmann if (cdc_decrement(&(env->PSW))) { 23669a31922bSBastian Koppelmann /* CDU trap */ 23679a31922bSBastian Koppelmann } 23689a31922bSBastian Koppelmann } 23699a31922bSBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 23709a31922bSBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 23719a31922bSBastian Koppelmann /* CSU trap */ 23729a31922bSBastian Koppelmann } 23739a31922bSBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 23749a31922bSBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 23759a31922bSBastian Koppelmann /* CTYP trap */ 23769a31922bSBastian Koppelmann } 23779a31922bSBastian Koppelmann /* PC = {A11 [31: 1], 1’b0}; */ 23789a31922bSBastian Koppelmann env->PC = env->gpr_a[11] & 0xfffffffe; 23799a31922bSBastian Koppelmann 23809a31922bSBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 23819a31922bSBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 23829a31922bSBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 23839a31922bSBastian Koppelmann /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2384030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 23859a31922bSBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2386030c58dfSBastian Koppelmann /* M(EA, word) = FCX; */ 2387030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 23889a31922bSBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 23899a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 23909a31922bSBastian Koppelmann /* PCXI = new_PCXI; */ 23919a31922bSBastian Koppelmann env->PCXI = new_PCXI; 23929a31922bSBastian Koppelmann 23939a31922bSBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_13)) { 23949a31922bSBastian Koppelmann /* PSW = new_PSW */ 23959a31922bSBastian Koppelmann psw_write(env, new_PSW); 23969a31922bSBastian Koppelmann } else { 23979a31922bSBastian Koppelmann /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */ 23989a31922bSBastian Koppelmann psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000))); 23999a31922bSBastian Koppelmann } 24009a31922bSBastian Koppelmann } 24019a31922bSBastian Koppelmann 24025de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9) 24035de93515SBastian Koppelmann { 24045de93515SBastian Koppelmann target_ulong tmp_FCX; 24055de93515SBastian Koppelmann target_ulong ea; 24065de93515SBastian Koppelmann target_ulong new_FCX; 24075de93515SBastian Koppelmann 24085de93515SBastian Koppelmann if (env->FCX == 0) { 24095de93515SBastian Koppelmann /* FCU trap */ 24105de93515SBastian Koppelmann } 24115de93515SBastian Koppelmann 24125de93515SBastian Koppelmann tmp_FCX = env->FCX; 24135de93515SBastian Koppelmann ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6); 24145de93515SBastian Koppelmann 2415030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 2416030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2417030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4] 2418030c58dfSBastian Koppelmann , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */ 2419030c58dfSBastian Koppelmann save_context_lower(env, ea); 2420030c58dfSBastian Koppelmann 24215de93515SBastian Koppelmann 24225de93515SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */ 24235de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 24245de93515SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 24255de93515SBastian Koppelmann /* PCXI.PIE = ICR.IE */ 24265de93515SBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 24275de93515SBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 24285de93515SBastian Koppelmann /* PCXI.UL = 0 */ 24295de93515SBastian Koppelmann env->PCXI &= ~(MASK_PCXI_UL); 24305de93515SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0] */ 24315de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 24325de93515SBastian Koppelmann /* FXC[19: 0] = new_FCX[19: 0] */ 24335de93515SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 24345de93515SBastian Koppelmann /* ICR.IE = 1 */ 24355de93515SBastian Koppelmann env->ICR |= MASK_ICR_IE; 24365de93515SBastian Koppelmann 24375de93515SBastian Koppelmann env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/ 24385de93515SBastian Koppelmann 24395de93515SBastian Koppelmann if (tmp_FCX == env->LCX) { 24405de93515SBastian Koppelmann /* FCD trap */ 24415de93515SBastian Koppelmann } 24425de93515SBastian Koppelmann } 24435de93515SBastian Koppelmann 244444ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env) 244544ea3430SBastian Koppelmann { 244644ea3430SBastian Koppelmann target_ulong ea; 244744ea3430SBastian Koppelmann target_ulong new_PCXI; 244844ea3430SBastian Koppelmann target_ulong new_PSW; 244944ea3430SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 245044ea3430SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 245144ea3430SBastian Koppelmann /* raise csu trap */ 245244ea3430SBastian Koppelmann } 245344ea3430SBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 245444ea3430SBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 245544ea3430SBastian Koppelmann /* raise CTYP trap */ 245644ea3430SBastian Koppelmann } 245744ea3430SBastian Koppelmann /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */ 245844ea3430SBastian Koppelmann if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) { 245944ea3430SBastian Koppelmann /* raise MNG trap */ 246044ea3430SBastian Koppelmann } 246144ea3430SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 246244ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15); 246344ea3430SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 246444ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) + 246544ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCPN) >> 24); 246644ea3430SBastian Koppelmann /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/ 246744ea3430SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 246844ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 246944ea3430SBastian Koppelmann /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2470030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 247144ea3430SBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2472030c58dfSBastian Koppelmann /* M(EA, word) = FCX;*/ 2473030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 247444ea3430SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 247544ea3430SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 247644ea3430SBastian Koppelmann /* PCXI = new_PCXI; */ 247744ea3430SBastian Koppelmann env->PCXI = new_PCXI; 247844ea3430SBastian Koppelmann /* write psw */ 247944ea3430SBastian Koppelmann psw_write(env, new_PSW); 248044ea3430SBastian Koppelmann } 248144ea3430SBastian Koppelmann 2482b724b012SBastian Koppelmann void helper_rfm(CPUTriCoreState *env) 2483b724b012SBastian Koppelmann { 2484b724b012SBastian Koppelmann env->PC = (env->gpr_a[11] & ~0x1); 2485b724b012SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 2486b724b012SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_IE) | 2487b724b012SBastian Koppelmann ((env->PCXI & ~MASK_PCXI_PIE) >> 15); 2488b724b012SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 2489b724b012SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) | 2490b724b012SBastian Koppelmann ((env->PCXI & ~MASK_PCXI_PCPN) >> 24); 2491b724b012SBastian Koppelmann /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */ 2492b724b012SBastian Koppelmann env->PCXI = cpu_ldl_data(env, env->DCX); 2493b724b012SBastian Koppelmann psw_write(env, cpu_ldl_data(env, env->DCX+4)); 2494b724b012SBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8); 2495b724b012SBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12); 2496b724b012SBastian Koppelmann 2497b724b012SBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_131)) { 2498b724b012SBastian Koppelmann env->DBGTCR = 0; 2499b724b012SBastian Koppelmann } 2500b724b012SBastian Koppelmann } 2501b724b012SBastian Koppelmann 250259543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) 250359543d4eSBastian Koppelmann { 250459543d4eSBastian Koppelmann uint32_t dummy; 250559543d4eSBastian Koppelmann /* insn doesn't load PCXI and RA */ 250659543d4eSBastian Koppelmann restore_context_lower(env, ea, &dummy, &dummy); 250759543d4eSBastian Koppelmann } 250859543d4eSBastian Koppelmann 250959543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea) 251059543d4eSBastian Koppelmann { 251159543d4eSBastian Koppelmann uint32_t dummy; 251259543d4eSBastian Koppelmann /* insn doesn't load PCXI and PSW */ 251359543d4eSBastian Koppelmann restore_context_upper(env, ea, &dummy, &dummy); 251459543d4eSBastian Koppelmann } 251559543d4eSBastian Koppelmann 251659543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea) 251759543d4eSBastian Koppelmann { 251859543d4eSBastian Koppelmann save_context_lower(env, ea); 251959543d4eSBastian Koppelmann } 252059543d4eSBastian Koppelmann 252159543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea) 252259543d4eSBastian Koppelmann { 252359543d4eSBastian Koppelmann save_context_upper(env, ea); 252459543d4eSBastian Koppelmann } 252559543d4eSBastian Koppelmann 2526b724b012SBastian Koppelmann void helper_svlcx(CPUTriCoreState *env) 2527b724b012SBastian Koppelmann { 2528b724b012SBastian Koppelmann target_ulong tmp_FCX; 2529b724b012SBastian Koppelmann target_ulong ea; 2530b724b012SBastian Koppelmann target_ulong new_FCX; 2531b724b012SBastian Koppelmann 2532b724b012SBastian Koppelmann if (env->FCX == 0) { 2533b724b012SBastian Koppelmann /* FCU trap */ 2534b724b012SBastian Koppelmann } 2535b724b012SBastian Koppelmann /* tmp_FCX = FCX; */ 2536b724b012SBastian Koppelmann tmp_FCX = env->FCX; 2537b724b012SBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 2538b724b012SBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 2539b724b012SBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 2540b724b012SBastian Koppelmann /* new_FCX = M(EA, word); */ 2541b724b012SBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2542b724b012SBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 2543b724b012SBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 2544b724b012SBastian Koppelmann D[15]}; */ 2545b724b012SBastian Koppelmann save_context_lower(env, ea); 2546b724b012SBastian Koppelmann 2547b724b012SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 2548b724b012SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 2549b724b012SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 2550b724b012SBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 2551b724b012SBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 2552b724b012SBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 2553b724b012SBastian Koppelmann /* PCXI.UL = 0; */ 2554b724b012SBastian Koppelmann env->PCXI &= ~MASK_PCXI_UL; 2555b724b012SBastian Koppelmann 2556b724b012SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 2557b724b012SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 2558b724b012SBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 2559b724b012SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 2560b724b012SBastian Koppelmann 2561b724b012SBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 2562b724b012SBastian Koppelmann if (tmp_FCX == env->LCX) { 2563b724b012SBastian Koppelmann /* FCD trap */ 2564b724b012SBastian Koppelmann } 2565b724b012SBastian Koppelmann } 2566b724b012SBastian Koppelmann 2567b724b012SBastian Koppelmann void helper_rslcx(CPUTriCoreState *env) 2568b724b012SBastian Koppelmann { 2569b724b012SBastian Koppelmann target_ulong ea; 2570b724b012SBastian Koppelmann target_ulong new_PCXI; 2571b724b012SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 2572b724b012SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 2573b724b012SBastian Koppelmann /* CSU trap */ 2574b724b012SBastian Koppelmann } 2575b724b012SBastian Koppelmann /* if (PCXI.UL == 1) then trap(CTYP); */ 2576b724b012SBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 1) { 2577b724b012SBastian Koppelmann /* CTYP trap */ 2578b724b012SBastian Koppelmann } 2579b724b012SBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 2580b724b012SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 2581b724b012SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 2582b724b012SBastian Koppelmann /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2583b724b012SBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 2584b724b012SBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &env->gpr_a[11]); 2585b724b012SBastian Koppelmann /* M(EA, word) = FCX; */ 2586b724b012SBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 2587b724b012SBastian Koppelmann /* M(EA, word) = FCX; */ 2588b724b012SBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 2589b724b012SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 2590b724b012SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 2591b724b012SBastian Koppelmann /* PCXI = new_PCXI; */ 2592b724b012SBastian Koppelmann env->PCXI = new_PCXI; 2593b724b012SBastian Koppelmann } 2594b724b012SBastian Koppelmann 25952b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg) 25962b2f7d97SBastian Koppelmann { 25972b2f7d97SBastian Koppelmann psw_write(env, arg); 25982b2f7d97SBastian Koppelmann } 25992b2f7d97SBastian Koppelmann 26002b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env) 26012b2f7d97SBastian Koppelmann { 26022b2f7d97SBastian Koppelmann return psw_read(env); 26032b2f7d97SBastian Koppelmann } 26042b2f7d97SBastian Koppelmann 26052b2f7d97SBastian Koppelmann 26062d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env, 26072d30267eSBastian Koppelmann uint32_t exception, 26082d30267eSBastian Koppelmann int error_code, 26092d30267eSBastian Koppelmann uintptr_t pc) 26102d30267eSBastian Koppelmann { 26112d30267eSBastian Koppelmann CPUState *cs = CPU(tricore_env_get_cpu(env)); 26122d30267eSBastian Koppelmann cs->exception_index = exception; 26132d30267eSBastian Koppelmann env->error_code = error_code; 26142d30267eSBastian Koppelmann 26152d30267eSBastian Koppelmann if (pc) { 26162d30267eSBastian Koppelmann /* now we have a real cpu fault */ 26172d30267eSBastian Koppelmann cpu_restore_state(cs, pc); 26182d30267eSBastian Koppelmann } 26192d30267eSBastian Koppelmann 26202d30267eSBastian Koppelmann cpu_loop_exit(cs); 26212d30267eSBastian Koppelmann } 26222d30267eSBastian Koppelmann 262348e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, 262448e06fe0SBastian Koppelmann uintptr_t retaddr) 262548e06fe0SBastian Koppelmann { 26262d30267eSBastian Koppelmann int ret; 26272d30267eSBastian Koppelmann ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx); 26282d30267eSBastian Koppelmann if (ret) { 26292d30267eSBastian Koppelmann TriCoreCPU *cpu = TRICORE_CPU(cs); 26302d30267eSBastian Koppelmann CPUTriCoreState *env = &cpu->env; 26312d30267eSBastian Koppelmann do_raise_exception_err(env, cs->exception_index, 26322d30267eSBastian Koppelmann env->error_code, retaddr); 263348e06fe0SBastian Koppelmann } 26342d30267eSBastian Koppelmann } 2635