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 2682e430e1cSBastian Koppelmann 2690974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1, 2700974257eSBastian Koppelmann target_ulong r2) 2710974257eSBastian Koppelmann { 2720974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 2730974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 2740974257eSBastian Koppelmann int64_t result = t1 + t2; 27585d604afSBastian Koppelmann return suov32_pos(env, result); 2760974257eSBastian Koppelmann } 2770974257eSBastian Koppelmann 278d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1, 279d5de7839SBastian Koppelmann target_ulong r2) 280d5de7839SBastian Koppelmann { 281d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 282d5de7839SBastian Koppelmann 283d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16); 284d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16); 285d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 286d5de7839SBastian Koppelmann } 287d5de7839SBastian Koppelmann 2882692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1, 2892692802aSBastian Koppelmann target_ulong r2) 2902692802aSBastian Koppelmann { 2912692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 2922692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 2932692802aSBastian Koppelmann int64_t result = t1 - t2; 294e4e39176SBastian Koppelmann return ssov32(env, result); 2952692802aSBastian Koppelmann } 2962692802aSBastian Koppelmann 297d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1, 298d5de7839SBastian Koppelmann target_ulong r2) 299d5de7839SBastian Koppelmann { 300d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 301d5de7839SBastian Koppelmann 302d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16); 303d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16); 304d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 305d5de7839SBastian Koppelmann } 306d5de7839SBastian Koppelmann 3070974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1, 3080974257eSBastian Koppelmann target_ulong r2) 3090974257eSBastian Koppelmann { 3100974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 3110974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 3120974257eSBastian Koppelmann int64_t result = t1 - t2; 31385d604afSBastian Koppelmann return suov32_neg(env, result); 3140974257eSBastian Koppelmann } 3150974257eSBastian Koppelmann 316d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1, 317d5de7839SBastian Koppelmann target_ulong r2) 318d5de7839SBastian Koppelmann { 319d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 320d5de7839SBastian Koppelmann 321d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16); 322d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16); 323d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 324d5de7839SBastian Koppelmann } 325d5de7839SBastian Koppelmann 3260974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1, 3270974257eSBastian Koppelmann target_ulong r2) 3280974257eSBastian Koppelmann { 3290974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 3300974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 3310974257eSBastian Koppelmann int64_t result = t1 * t2; 332e4e39176SBastian Koppelmann return ssov32(env, result); 3330974257eSBastian Koppelmann } 3340974257eSBastian Koppelmann 3350974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1, 3360974257eSBastian Koppelmann target_ulong r2) 3370974257eSBastian Koppelmann { 3380974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 3390974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 3400974257eSBastian Koppelmann int64_t result = t1 * t2; 3415f30046fSBastian Koppelmann 34285d604afSBastian Koppelmann return suov32_pos(env, result); 3430974257eSBastian Koppelmann } 3440974257eSBastian Koppelmann 3450974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1, 3460974257eSBastian Koppelmann target_ulong r2) 3470974257eSBastian Koppelmann { 3480974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 3490974257eSBastian Koppelmann int32_t t2 = sextract64(r2, 0, 6); 3500974257eSBastian Koppelmann int64_t result; 3510974257eSBastian Koppelmann if (t2 == 0) { 3520974257eSBastian Koppelmann result = t1; 3530974257eSBastian Koppelmann } else if (t2 > 0) { 3540974257eSBastian Koppelmann result = t1 << t2; 3550974257eSBastian Koppelmann } else { 3560974257eSBastian Koppelmann result = t1 >> -t2; 3570974257eSBastian Koppelmann } 358e4e39176SBastian Koppelmann return ssov32(env, result); 3590974257eSBastian Koppelmann } 3600974257eSBastian Koppelmann 361d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1) 362d5de7839SBastian Koppelmann { 363d5de7839SBastian Koppelmann target_ulong result; 364d5de7839SBastian Koppelmann result = ((int32_t)r1 >= 0) ? r1 : (0 - r1); 365d5de7839SBastian Koppelmann return ssov32(env, result); 366d5de7839SBastian Koppelmann } 367d5de7839SBastian Koppelmann 368d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1) 369d5de7839SBastian Koppelmann { 370d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 371d5de7839SBastian Koppelmann 372d5de7839SBastian Koppelmann ret_h0 = sextract32(r1, 0, 16); 373d5de7839SBastian Koppelmann ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0); 374d5de7839SBastian Koppelmann 375d5de7839SBastian Koppelmann ret_h1 = sextract32(r1, 16, 16); 376d5de7839SBastian Koppelmann ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1); 377d5de7839SBastian Koppelmann 378d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 379d5de7839SBastian Koppelmann } 380d5de7839SBastian Koppelmann 3810974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1, 3820974257eSBastian Koppelmann target_ulong r2) 3830974257eSBastian Koppelmann { 3840974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 3850974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 3860974257eSBastian Koppelmann int64_t result; 3870974257eSBastian Koppelmann 3880974257eSBastian Koppelmann if (t1 > t2) { 3890974257eSBastian Koppelmann result = t1 - t2; 3900974257eSBastian Koppelmann } else { 3910974257eSBastian Koppelmann result = t2 - t1; 3920974257eSBastian Koppelmann } 393e4e39176SBastian Koppelmann return ssov32(env, result); 3940974257eSBastian Koppelmann } 395328f1f0fSBastian Koppelmann 396d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1, 397d5de7839SBastian Koppelmann target_ulong r2) 398d5de7839SBastian Koppelmann { 399d5de7839SBastian Koppelmann int32_t t1, t2; 400d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 401d5de7839SBastian Koppelmann 402d5de7839SBastian Koppelmann t1 = sextract32(r1, 0, 16); 403d5de7839SBastian Koppelmann t2 = sextract32(r2, 0, 16); 404d5de7839SBastian Koppelmann if (t1 > t2) { 405d5de7839SBastian Koppelmann ret_h0 = t1 - t2; 406d5de7839SBastian Koppelmann } else { 407d5de7839SBastian Koppelmann ret_h0 = t2 - t1; 408d5de7839SBastian Koppelmann } 409d5de7839SBastian Koppelmann 410d5de7839SBastian Koppelmann t1 = sextract32(r1, 16, 16); 411d5de7839SBastian Koppelmann t2 = sextract32(r2, 16, 16); 412d5de7839SBastian Koppelmann if (t1 > t2) { 413d5de7839SBastian Koppelmann ret_h1 = t1 - t2; 414d5de7839SBastian Koppelmann } else { 415d5de7839SBastian Koppelmann ret_h1 = t2 - t1; 416d5de7839SBastian Koppelmann } 417d5de7839SBastian Koppelmann 418d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 419d5de7839SBastian Koppelmann } 420d5de7839SBastian Koppelmann 421328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1, 422328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 423328f1f0fSBastian Koppelmann { 424328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 425328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 426328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 427328f1f0fSBastian Koppelmann int64_t result; 428328f1f0fSBastian Koppelmann 429328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 430e4e39176SBastian Koppelmann return ssov32(env, result); 431328f1f0fSBastian Koppelmann } 432328f1f0fSBastian Koppelmann 433328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1, 434328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 435328f1f0fSBastian Koppelmann { 436328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 437328f1f0fSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 438328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 439328f1f0fSBastian Koppelmann int64_t result; 440328f1f0fSBastian Koppelmann 441328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 44285d604afSBastian Koppelmann return suov32_pos(env, result); 443328f1f0fSBastian Koppelmann } 444328f1f0fSBastian Koppelmann 445328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1, 446328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 447328f1f0fSBastian Koppelmann { 448328f1f0fSBastian Koppelmann uint64_t ret, ovf; 449328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 450328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 451328f1f0fSBastian Koppelmann int64_t mul; 452328f1f0fSBastian Koppelmann 453328f1f0fSBastian Koppelmann mul = t1 * t3; 454328f1f0fSBastian Koppelmann ret = mul + r2; 455328f1f0fSBastian Koppelmann ovf = (ret ^ mul) & ~(mul ^ r2); 456328f1f0fSBastian Koppelmann 457811ea608SBastian Koppelmann t1 = ret >> 32; 458811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 459811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 460811ea608SBastian Koppelmann 461328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 462328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 463328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 464328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 465328f1f0fSBastian Koppelmann if (mul >= 0) { 466328f1f0fSBastian Koppelmann ret = INT64_MAX; 467328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 468328f1f0fSBastian Koppelmann } else { 469328f1f0fSBastian Koppelmann ret = INT64_MIN; 470328f1f0fSBastian Koppelmann } 471328f1f0fSBastian Koppelmann } else { 472328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 473328f1f0fSBastian Koppelmann } 474328f1f0fSBastian Koppelmann 475328f1f0fSBastian Koppelmann return ret; 476328f1f0fSBastian Koppelmann } 477328f1f0fSBastian Koppelmann 478b00aa8ecSBastian Koppelmann uint32_t 479b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 480b00aa8ecSBastian Koppelmann { 481b00aa8ecSBastian Koppelmann int64_t result; 482b00aa8ecSBastian Koppelmann 483b00aa8ecSBastian Koppelmann result = (r1 + r2); 484b00aa8ecSBastian Koppelmann 485b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u); 486b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 487b00aa8ecSBastian Koppelmann 488b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 489b00aa8ecSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 490b00aa8ecSBastian Koppelmann case, we flip the saturated value. */ 491b00aa8ecSBastian Koppelmann if (r2 == 0x8000000000000000LL) { 492b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) { 493b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 494b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 495b00aa8ecSBastian Koppelmann result = INT32_MIN; 496b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) { 497b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 498b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 499b00aa8ecSBastian Koppelmann result = INT32_MAX; 500b00aa8ecSBastian Koppelmann } else { 501b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 502b00aa8ecSBastian Koppelmann } 503b00aa8ecSBastian Koppelmann } else { 504b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) { 505b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 506b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 507b00aa8ecSBastian Koppelmann result = INT32_MAX; 508b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) { 509b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 510b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 511b00aa8ecSBastian Koppelmann result = INT32_MIN; 512b00aa8ecSBastian Koppelmann } else { 513b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 514b00aa8ecSBastian Koppelmann } 515b00aa8ecSBastian Koppelmann } 516b00aa8ecSBastian Koppelmann return (uint32_t)result; 517b00aa8ecSBastian Koppelmann } 518b00aa8ecSBastian Koppelmann 519b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 520b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 521b00aa8ecSBastian Koppelmann { 522b00aa8ecSBastian Koppelmann int64_t t1 = (int64_t)r1; 523b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 524b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 525b00aa8ecSBastian Koppelmann int64_t result, mul; 526b00aa8ecSBastian Koppelmann int64_t ovf; 527b00aa8ecSBastian Koppelmann 528b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 529b00aa8ecSBastian Koppelmann result = mul + t1; 530b00aa8ecSBastian Koppelmann 531b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 532b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 533b00aa8ecSBastian Koppelmann 534b00aa8ecSBastian Koppelmann ovf = (result ^ mul) & ~(mul ^ t1); 535b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 536b00aa8ecSBastian Koppelmann if the mul was (0x80000000 * 0x80000000) << 1). If this is the 537b00aa8ecSBastian Koppelmann case, we flip the saturated value. */ 538b00aa8ecSBastian Koppelmann if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) { 539b00aa8ecSBastian Koppelmann if (ovf >= 0) { 540b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 541b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 542b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */ 543b00aa8ecSBastian Koppelmann if (mul < 0) { 544b00aa8ecSBastian Koppelmann result = INT64_MAX; 545b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */ 546b00aa8ecSBastian Koppelmann } else { 547b00aa8ecSBastian Koppelmann result = INT64_MIN; 548b00aa8ecSBastian Koppelmann } 549b00aa8ecSBastian Koppelmann } else { 550b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 551b00aa8ecSBastian Koppelmann } 552b00aa8ecSBastian Koppelmann } else { 553b00aa8ecSBastian Koppelmann if (ovf < 0) { 554b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 555b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 556b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */ 557b00aa8ecSBastian Koppelmann if (mul >= 0) { 558b00aa8ecSBastian Koppelmann result = INT64_MAX; 559b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */ 560b00aa8ecSBastian Koppelmann } else { 561b00aa8ecSBastian Koppelmann result = INT64_MIN; 562b00aa8ecSBastian Koppelmann } 563b00aa8ecSBastian Koppelmann } else { 564b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 565b00aa8ecSBastian Koppelmann } 566b00aa8ecSBastian Koppelmann } 567b00aa8ecSBastian Koppelmann return (uint64_t)result; 568b00aa8ecSBastian Koppelmann } 569b00aa8ecSBastian Koppelmann 570b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 571b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 572b00aa8ecSBastian Koppelmann { 573b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 574b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 575b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 576b00aa8ecSBastian Koppelmann int64_t mul, ret; 577b00aa8ecSBastian Koppelmann 578b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 579b00aa8ecSBastian Koppelmann mul = 0x7fffffff; 580b00aa8ecSBastian Koppelmann } else { 581b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 582b00aa8ecSBastian Koppelmann } 583b00aa8ecSBastian Koppelmann 584b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000; 585b00aa8ecSBastian Koppelmann 586b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 587b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 588b00aa8ecSBastian Koppelmann 589b00aa8ecSBastian Koppelmann if (ret > 0x7fffffffll) { 590b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 591b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 592b00aa8ecSBastian Koppelmann ret = INT32_MAX; 593b00aa8ecSBastian Koppelmann } else if (ret < -0x80000000ll) { 594b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 595b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 596b00aa8ecSBastian Koppelmann ret = INT32_MIN; 597b00aa8ecSBastian Koppelmann } else { 598b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 599b00aa8ecSBastian Koppelmann } 600b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll; 601b00aa8ecSBastian Koppelmann } 602b00aa8ecSBastian Koppelmann 603328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1, 604328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 605328f1f0fSBastian Koppelmann { 606328f1f0fSBastian Koppelmann uint64_t ret, mul; 607328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 608328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 609328f1f0fSBastian Koppelmann 610328f1f0fSBastian Koppelmann mul = t1 * t3; 611328f1f0fSBastian Koppelmann ret = mul + r2; 612328f1f0fSBastian Koppelmann 613811ea608SBastian Koppelmann t1 = ret >> 32; 614811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 615811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 616811ea608SBastian Koppelmann 617328f1f0fSBastian Koppelmann if (ret < r2) { 618328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 619328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 620328f1f0fSBastian Koppelmann /* saturate */ 621328f1f0fSBastian Koppelmann ret = UINT64_MAX; 622328f1f0fSBastian Koppelmann } else { 623328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 624328f1f0fSBastian Koppelmann } 625328f1f0fSBastian Koppelmann return ret; 626328f1f0fSBastian Koppelmann } 627328f1f0fSBastian Koppelmann 628328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1, 629328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 630328f1f0fSBastian Koppelmann { 631328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 632328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 633328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 634328f1f0fSBastian Koppelmann int64_t result; 635328f1f0fSBastian Koppelmann 636328f1f0fSBastian Koppelmann result = t2 - (t1 * t3); 637e4e39176SBastian Koppelmann return ssov32(env, result); 638328f1f0fSBastian Koppelmann } 639328f1f0fSBastian Koppelmann 640328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1, 641328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 642328f1f0fSBastian Koppelmann { 6433debbb5aSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 6443debbb5aSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 6453debbb5aSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 6463debbb5aSBastian Koppelmann uint64_t result; 6473debbb5aSBastian Koppelmann uint64_t mul; 648328f1f0fSBastian Koppelmann 6493debbb5aSBastian Koppelmann mul = (t1 * t3); 6503debbb5aSBastian Koppelmann result = t2 - mul; 6513debbb5aSBastian Koppelmann 6523debbb5aSBastian Koppelmann env->PSW_USB_AV = result ^ result * 2u; 6533debbb5aSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 6543debbb5aSBastian Koppelmann /* we calculate ovf by hand here, because the multiplication can overflow on 6553debbb5aSBastian Koppelmann the host, which would give false results if we compare to less than 6563debbb5aSBastian Koppelmann zero */ 6573debbb5aSBastian Koppelmann if (mul > t2) { 6583debbb5aSBastian Koppelmann env->PSW_USB_V = (1 << 31); 6593debbb5aSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 6603debbb5aSBastian Koppelmann result = 0; 6613debbb5aSBastian Koppelmann } else { 6623debbb5aSBastian Koppelmann env->PSW_USB_V = 0; 6633debbb5aSBastian Koppelmann } 6643debbb5aSBastian Koppelmann return result; 665328f1f0fSBastian Koppelmann } 666328f1f0fSBastian Koppelmann 667328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1, 668328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 669328f1f0fSBastian Koppelmann { 670328f1f0fSBastian Koppelmann uint64_t ret, ovf; 671328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 672328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 673328f1f0fSBastian Koppelmann int64_t mul; 674328f1f0fSBastian Koppelmann 675328f1f0fSBastian Koppelmann mul = t1 * t3; 676328f1f0fSBastian Koppelmann ret = r2 - mul; 677328f1f0fSBastian Koppelmann ovf = (ret ^ r2) & (mul ^ r2); 678328f1f0fSBastian Koppelmann 679811ea608SBastian Koppelmann t1 = ret >> 32; 680811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 681811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 682811ea608SBastian Koppelmann 683328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 684328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 685328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 686328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 687328f1f0fSBastian Koppelmann if (mul < 0) { 688328f1f0fSBastian Koppelmann ret = INT64_MAX; 689328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 690328f1f0fSBastian Koppelmann } else { 691328f1f0fSBastian Koppelmann ret = INT64_MIN; 692328f1f0fSBastian Koppelmann } 693328f1f0fSBastian Koppelmann } else { 694328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 695328f1f0fSBastian Koppelmann } 696328f1f0fSBastian Koppelmann return ret; 697328f1f0fSBastian Koppelmann } 698328f1f0fSBastian Koppelmann 699328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1, 700328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 701328f1f0fSBastian Koppelmann { 702328f1f0fSBastian Koppelmann uint64_t ret, mul; 703328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 704328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 705328f1f0fSBastian Koppelmann 706328f1f0fSBastian Koppelmann mul = t1 * t3; 707328f1f0fSBastian Koppelmann ret = r2 - mul; 708328f1f0fSBastian Koppelmann 709811ea608SBastian Koppelmann t1 = ret >> 32; 710811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 711811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 712811ea608SBastian Koppelmann 713328f1f0fSBastian Koppelmann if (ret > r2) { 714328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 715328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 716328f1f0fSBastian Koppelmann /* saturate */ 717328f1f0fSBastian Koppelmann ret = 0; 718328f1f0fSBastian Koppelmann } else { 719328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 720328f1f0fSBastian Koppelmann } 721328f1f0fSBastian Koppelmann return ret; 722328f1f0fSBastian Koppelmann } 723328f1f0fSBastian Koppelmann 724d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg) 725d5de7839SBastian Koppelmann { 726d5de7839SBastian Koppelmann int32_t b, i; 727d5de7839SBastian Koppelmann int32_t ovf = 0; 728d5de7839SBastian Koppelmann int32_t avf = 0; 729d5de7839SBastian Koppelmann int32_t ret = 0; 730d5de7839SBastian Koppelmann 731d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 732d5de7839SBastian Koppelmann b = sextract32(arg, i * 8, 8); 733d5de7839SBastian Koppelmann b = (b >= 0) ? b : (0 - b); 734d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 735d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 736d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 737d5de7839SBastian Koppelmann } 738d5de7839SBastian Koppelmann 739d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 740d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 741d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 742d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 743d5de7839SBastian Koppelmann 744d5de7839SBastian Koppelmann return ret; 745d5de7839SBastian Koppelmann } 746d5de7839SBastian Koppelmann 747d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg) 748d5de7839SBastian Koppelmann { 749d5de7839SBastian Koppelmann int32_t h, i; 750d5de7839SBastian Koppelmann int32_t ovf = 0; 751d5de7839SBastian Koppelmann int32_t avf = 0; 752d5de7839SBastian Koppelmann int32_t ret = 0; 753d5de7839SBastian Koppelmann 754d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 755d5de7839SBastian Koppelmann h = sextract32(arg, i * 16, 16); 756d5de7839SBastian Koppelmann h = (h >= 0) ? h : (0 - h); 757d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 758d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 759d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 760d5de7839SBastian Koppelmann } 761d5de7839SBastian Koppelmann 762d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 763d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 764d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 765d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 766d5de7839SBastian Koppelmann 767d5de7839SBastian Koppelmann return ret; 768d5de7839SBastian Koppelmann } 769d5de7839SBastian Koppelmann 770d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 771d5de7839SBastian Koppelmann { 772d5de7839SBastian Koppelmann int32_t b, i; 773d5de7839SBastian Koppelmann int32_t extr_r2; 774d5de7839SBastian Koppelmann int32_t ovf = 0; 775d5de7839SBastian Koppelmann int32_t avf = 0; 776d5de7839SBastian Koppelmann int32_t ret = 0; 777d5de7839SBastian Koppelmann 778d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 779d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 780d5de7839SBastian Koppelmann b = sextract32(r1, i * 8, 8); 781d5de7839SBastian Koppelmann b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b); 782d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 783d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 784d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 785d5de7839SBastian Koppelmann } 786d5de7839SBastian Koppelmann 787d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 788d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 789d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 790d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 791d5de7839SBastian Koppelmann return ret; 792d5de7839SBastian Koppelmann } 793d5de7839SBastian Koppelmann 794d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 795d5de7839SBastian Koppelmann { 796d5de7839SBastian Koppelmann int32_t h, i; 797d5de7839SBastian Koppelmann int32_t extr_r2; 798d5de7839SBastian Koppelmann int32_t ovf = 0; 799d5de7839SBastian Koppelmann int32_t avf = 0; 800d5de7839SBastian Koppelmann int32_t ret = 0; 801d5de7839SBastian Koppelmann 802d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 803d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 804d5de7839SBastian Koppelmann h = sextract32(r1, i * 16, 16); 805d5de7839SBastian Koppelmann h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h); 806d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 807d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 808d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 809d5de7839SBastian Koppelmann } 810d5de7839SBastian Koppelmann 811d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 812d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 813d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 814d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 815d5de7839SBastian Koppelmann 816d5de7839SBastian Koppelmann return ret; 817d5de7839SBastian Koppelmann } 818d5de7839SBastian Koppelmann 8192e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 8202e430e1cSBastian Koppelmann uint32_t r2_h) 8212e430e1cSBastian Koppelmann { 8222e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 8232e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 8242e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 8252e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 8262e430e1cSBastian Koppelmann int64_t result0, result1; 8272e430e1cSBastian Koppelmann uint32_t ovf0, ovf1; 8282e430e1cSBastian Koppelmann uint32_t avf0, avf1; 8292e430e1cSBastian Koppelmann 8302e430e1cSBastian Koppelmann ovf0 = ovf1 = 0; 8312e430e1cSBastian Koppelmann 8322e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 8332e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 8342e430e1cSBastian Koppelmann 8352e430e1cSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 8362e430e1cSBastian Koppelmann ovf0 = (1 << 31); 8372e430e1cSBastian Koppelmann } 8382e430e1cSBastian Koppelmann 8392e430e1cSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 8402e430e1cSBastian Koppelmann ovf1 = (1 << 31); 8412e430e1cSBastian Koppelmann } 8422e430e1cSBastian Koppelmann 8432e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 8442e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 8452e430e1cSBastian Koppelmann 8462e430e1cSBastian Koppelmann avf0 = result0 * 2u; 8472e430e1cSBastian Koppelmann avf0 = result0 ^ avf0; 8482e430e1cSBastian Koppelmann avf1 = result1 * 2u; 8492e430e1cSBastian Koppelmann avf1 = result1 ^ avf1; 8502e430e1cSBastian Koppelmann 8512e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 8522e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 8532e430e1cSBastian Koppelmann 8542e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 8552e430e1cSBastian Koppelmann } 8562e430e1cSBastian Koppelmann 857b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 858b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 859b00aa8ecSBastian Koppelmann { 860b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 861b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 862b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 863b00aa8ecSBastian Koppelmann int64_t mul, ret; 864b00aa8ecSBastian Koppelmann 865b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 866b00aa8ecSBastian Koppelmann mul = 0x7fffffff; 867b00aa8ecSBastian Koppelmann } else { 868b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 869b00aa8ecSBastian Koppelmann } 870b00aa8ecSBastian Koppelmann 871b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000; 872b00aa8ecSBastian Koppelmann 873b00aa8ecSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 874b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 875b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 876b00aa8ecSBastian Koppelmann } else { 877b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 878b00aa8ecSBastian Koppelmann } 879b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 880b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 881b00aa8ecSBastian Koppelmann 882b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll; 883b00aa8ecSBastian Koppelmann } 884b00aa8ecSBastian Koppelmann 885d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 886d5de7839SBastian Koppelmann { 887d5de7839SBastian Koppelmann int32_t b, i; 888d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 889d5de7839SBastian Koppelmann int32_t ovf = 0; 890d5de7839SBastian Koppelmann int32_t avf = 0; 891d5de7839SBastian Koppelmann uint32_t ret = 0; 892d5de7839SBastian Koppelmann 893d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 894d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 895d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 896d5de7839SBastian Koppelmann 897d5de7839SBastian Koppelmann b = extr_r1 + extr_r2; 898d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 899d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 900d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 901d5de7839SBastian Koppelmann } 902d5de7839SBastian Koppelmann 903d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 904d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 905d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 906d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 907d5de7839SBastian Koppelmann 908d5de7839SBastian Koppelmann return ret; 909d5de7839SBastian Koppelmann } 910d5de7839SBastian Koppelmann 911d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 912d5de7839SBastian Koppelmann { 913d5de7839SBastian Koppelmann int32_t h, i; 914d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 915d5de7839SBastian Koppelmann int32_t ovf = 0; 916d5de7839SBastian Koppelmann int32_t avf = 0; 917d5de7839SBastian Koppelmann int32_t ret = 0; 918d5de7839SBastian Koppelmann 919d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 920d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 921d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 922d5de7839SBastian Koppelmann h = extr_r1 + extr_r2; 923d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 924d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 925d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 926d5de7839SBastian Koppelmann } 927d5de7839SBastian Koppelmann 928d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 929d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 930d5de7839SBastian Koppelmann env->PSW_USB_AV = (avf << 16); 931d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 932d5de7839SBastian Koppelmann 933d5de7839SBastian Koppelmann return ret; 934d5de7839SBastian Koppelmann } 935d5de7839SBastian Koppelmann 936d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 937d5de7839SBastian Koppelmann { 938d5de7839SBastian Koppelmann int32_t b, i; 939d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 940d5de7839SBastian Koppelmann int32_t ovf = 0; 941d5de7839SBastian Koppelmann int32_t avf = 0; 942d5de7839SBastian Koppelmann uint32_t ret = 0; 943d5de7839SBastian Koppelmann 944d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 945d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 946d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 947d5de7839SBastian Koppelmann 948d5de7839SBastian Koppelmann b = extr_r1 - extr_r2; 949d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 950d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 951d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 952d5de7839SBastian Koppelmann } 953d5de7839SBastian Koppelmann 954d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 955d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 956d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 957d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 958d5de7839SBastian Koppelmann 959d5de7839SBastian Koppelmann return ret; 960d5de7839SBastian Koppelmann } 961d5de7839SBastian Koppelmann 962d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 963d5de7839SBastian Koppelmann { 964d5de7839SBastian Koppelmann int32_t h, i; 965d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 966d5de7839SBastian Koppelmann int32_t ovf = 0; 967d5de7839SBastian Koppelmann int32_t avf = 0; 968d5de7839SBastian Koppelmann int32_t ret = 0; 969d5de7839SBastian Koppelmann 970d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 971d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 972d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 973d5de7839SBastian Koppelmann h = extr_r1 - extr_r2; 974d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 975d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 976d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 977d5de7839SBastian Koppelmann } 978d5de7839SBastian Koppelmann 979d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 980d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 981d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 982d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 983d5de7839SBastian Koppelmann 984d5de7839SBastian Koppelmann return ret; 985d5de7839SBastian Koppelmann } 986d5de7839SBastian Koppelmann 987d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2) 988d5de7839SBastian Koppelmann { 989d5de7839SBastian Koppelmann int32_t ret; 990d5de7839SBastian Koppelmann int32_t i, msk; 991d5de7839SBastian Koppelmann 992d5de7839SBastian Koppelmann ret = 0; 993d5de7839SBastian Koppelmann msk = 0xff; 994d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 995d5de7839SBastian Koppelmann if ((r1 & msk) == (r2 & msk)) { 996d5de7839SBastian Koppelmann ret |= msk; 997d5de7839SBastian Koppelmann } 998d5de7839SBastian Koppelmann msk = msk << 8; 999d5de7839SBastian Koppelmann } 1000d5de7839SBastian Koppelmann 1001d5de7839SBastian Koppelmann return ret; 1002d5de7839SBastian Koppelmann } 1003d5de7839SBastian Koppelmann 1004d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2) 1005d5de7839SBastian Koppelmann { 1006d5de7839SBastian Koppelmann int32_t ret = 0; 1007d5de7839SBastian Koppelmann 1008d5de7839SBastian Koppelmann if ((r1 & 0xffff) == (r2 & 0xffff)) { 1009d5de7839SBastian Koppelmann ret = 0xffff; 1010d5de7839SBastian Koppelmann } 1011d5de7839SBastian Koppelmann 1012d5de7839SBastian Koppelmann if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) { 1013d5de7839SBastian Koppelmann ret |= 0xffff0000; 1014d5de7839SBastian Koppelmann } 1015d5de7839SBastian Koppelmann 1016d5de7839SBastian Koppelmann return ret; 1017d5de7839SBastian Koppelmann } 1018d5de7839SBastian Koppelmann 1019d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2) 1020d5de7839SBastian Koppelmann { 1021d5de7839SBastian Koppelmann int32_t i; 1022d5de7839SBastian Koppelmann uint32_t ret = 0; 1023d5de7839SBastian Koppelmann 1024d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1025d5de7839SBastian Koppelmann ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8)); 1026d5de7839SBastian Koppelmann } 1027d5de7839SBastian Koppelmann 1028d5de7839SBastian Koppelmann return ret; 1029d5de7839SBastian Koppelmann } 1030d5de7839SBastian Koppelmann 1031d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2) 1032d5de7839SBastian Koppelmann { 1033d5de7839SBastian Koppelmann uint32_t ret; 1034d5de7839SBastian Koppelmann 1035d5de7839SBastian Koppelmann ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16)); 1036d5de7839SBastian Koppelmann ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16)); 1037d5de7839SBastian Koppelmann 1038d5de7839SBastian Koppelmann return ret; 1039d5de7839SBastian Koppelmann } 1040d5de7839SBastian Koppelmann 1041d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2) 1042d5de7839SBastian Koppelmann { 1043d5de7839SBastian Koppelmann int32_t i; 1044d5de7839SBastian Koppelmann uint32_t ret = 0; 1045d5de7839SBastian Koppelmann 1046d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1047d5de7839SBastian Koppelmann if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) { 1048d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 1049d5de7839SBastian Koppelmann } 1050d5de7839SBastian Koppelmann } 1051d5de7839SBastian Koppelmann 1052d5de7839SBastian Koppelmann return ret; 1053d5de7839SBastian Koppelmann } 1054d5de7839SBastian Koppelmann 1055d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2) 1056d5de7839SBastian Koppelmann { 1057d5de7839SBastian Koppelmann int32_t i; 1058d5de7839SBastian Koppelmann uint32_t ret = 0; 1059d5de7839SBastian Koppelmann 1060d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1061d5de7839SBastian Koppelmann if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) { 1062d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 1063d5de7839SBastian Koppelmann } 1064d5de7839SBastian Koppelmann } 1065d5de7839SBastian Koppelmann 1066d5de7839SBastian Koppelmann return ret; 1067d5de7839SBastian Koppelmann } 1068d5de7839SBastian Koppelmann 1069d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2) 1070d5de7839SBastian Koppelmann { 1071d5de7839SBastian Koppelmann uint32_t ret = 0; 1072d5de7839SBastian Koppelmann 1073d5de7839SBastian Koppelmann if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) { 1074d5de7839SBastian Koppelmann ret |= 0xffff; 1075d5de7839SBastian Koppelmann } 1076d5de7839SBastian Koppelmann 1077d5de7839SBastian Koppelmann if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) { 1078d5de7839SBastian Koppelmann ret |= 0xffff0000; 1079d5de7839SBastian Koppelmann } 1080d5de7839SBastian Koppelmann 1081d5de7839SBastian Koppelmann return ret; 1082d5de7839SBastian Koppelmann } 1083d5de7839SBastian Koppelmann 1084d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2) 1085d5de7839SBastian Koppelmann { 1086d5de7839SBastian Koppelmann uint32_t ret = 0; 1087d5de7839SBastian Koppelmann 1088d5de7839SBastian Koppelmann if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) { 1089d5de7839SBastian Koppelmann ret |= 0xffff; 1090d5de7839SBastian Koppelmann } 1091d5de7839SBastian Koppelmann 1092d5de7839SBastian Koppelmann if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) { 1093d5de7839SBastian Koppelmann ret |= 0xffff0000; 1094d5de7839SBastian Koppelmann } 1095d5de7839SBastian Koppelmann 1096d5de7839SBastian Koppelmann return ret; 1097d5de7839SBastian Koppelmann } 1098d5de7839SBastian Koppelmann 1099d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op) \ 1100d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \ 1101d5de7839SBastian Koppelmann { \ 1102d5de7839SBastian Koppelmann int32_t i, extr_r1, extr_r2; \ 1103d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1104d5de7839SBastian Koppelmann \ 1105d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 1106d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); \ 1107d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); \ 1108d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1109d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 1110d5de7839SBastian Koppelmann } \ 1111d5de7839SBastian Koppelmann return ret; \ 1112d5de7839SBastian Koppelmann } \ 1113d5de7839SBastian Koppelmann \ 1114d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\ 1115d5de7839SBastian Koppelmann { \ 1116d5de7839SBastian Koppelmann int32_t i; \ 1117d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 1118d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1119d5de7839SBastian Koppelmann \ 1120d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 1121d5de7839SBastian Koppelmann extr_r1 = extract32(r1, i * 8, 8); \ 1122d5de7839SBastian Koppelmann extr_r2 = extract32(r2, i * 8, 8); \ 1123d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1124d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 1125d5de7839SBastian Koppelmann } \ 1126d5de7839SBastian Koppelmann return ret; \ 1127d5de7839SBastian Koppelmann } \ 1128d5de7839SBastian Koppelmann \ 1129d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \ 1130d5de7839SBastian Koppelmann { \ 1131d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; \ 1132d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1133d5de7839SBastian Koppelmann \ 1134d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 0, 16); \ 1135d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 0, 16); \ 1136d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1137d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 1138d5de7839SBastian Koppelmann \ 1139d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 16, 16); \ 1140d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 16, 16); \ 1141d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1142d5de7839SBastian Koppelmann ret |= extr_r1 << 16; \ 1143d5de7839SBastian Koppelmann \ 1144d5de7839SBastian Koppelmann return ret; \ 1145d5de7839SBastian Koppelmann } \ 1146d5de7839SBastian Koppelmann \ 1147d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\ 1148d5de7839SBastian Koppelmann { \ 1149d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 1150d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1151d5de7839SBastian Koppelmann \ 1152d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 0, 16); \ 1153d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 0, 16); \ 1154d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1155d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 1156d5de7839SBastian Koppelmann \ 1157d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 16, 16); \ 1158d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 16, 16); \ 1159d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1160d5de7839SBastian Koppelmann ret |= extr_r1 << (16); \ 1161d5de7839SBastian Koppelmann \ 1162d5de7839SBastian Koppelmann return ret; \ 1163d5de7839SBastian Koppelmann } \ 116409532255SBastian Koppelmann \ 116509532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2) \ 116609532255SBastian Koppelmann { \ 116709532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \ 116809532255SBastian Koppelmann uint64_t ret = 0; \ 116909532255SBastian Koppelmann \ 117009532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \ 117109532255SBastian Koppelmann r2l = sextract64(r2, 0, 16); \ 117209532255SBastian Koppelmann r2h = sextract64(r2, 16, 16); \ 117309532255SBastian Koppelmann r1hl = sextract64(r1, 32, 16); \ 117409532255SBastian Koppelmann \ 117509532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 117609532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \ 117709532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \ 117809532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \ 117909532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \ 118009532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \ 118109532255SBastian Koppelmann } else { \ 118209532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \ 118309532255SBastian Koppelmann } \ 118409532255SBastian Koppelmann return ret; \ 118509532255SBastian Koppelmann } \ 118609532255SBastian Koppelmann \ 118709532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2) \ 118809532255SBastian Koppelmann { \ 118909532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \ 119009532255SBastian Koppelmann uint64_t ret = 0; \ 119109532255SBastian Koppelmann \ 119209532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \ 119309532255SBastian Koppelmann r2l = extract64(r2, 0, 16); \ 119409532255SBastian Koppelmann r2h = extract64(r2, 16, 16); \ 119509532255SBastian Koppelmann r1hl = extract64(r1, 32, 16); \ 119609532255SBastian Koppelmann \ 119709532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 119809532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \ 119909532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \ 120009532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \ 120109532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \ 120209532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \ 120309532255SBastian Koppelmann } else { \ 120409532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \ 120509532255SBastian Koppelmann } \ 120609532255SBastian Koppelmann return ret; \ 120709532255SBastian Koppelmann } 1208d5de7839SBastian Koppelmann 1209d5de7839SBastian Koppelmann EXTREMA_H_B(max, >) 1210d5de7839SBastian Koppelmann EXTREMA_H_B(min, <) 1211d5de7839SBastian Koppelmann 1212d5de7839SBastian Koppelmann #undef EXTREMA_H_B 1213d5de7839SBastian Koppelmann 12140b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1) 12150b79a781SBastian Koppelmann { 12160b79a781SBastian Koppelmann return clo32(r1); 12170b79a781SBastian Koppelmann } 12180b79a781SBastian Koppelmann 12190b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1) 12200b79a781SBastian Koppelmann { 12210b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 12220b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 12230b79a781SBastian Koppelmann 12240b79a781SBastian Koppelmann ret_hw0 = clo32(ret_hw0 << 16); 12250b79a781SBastian Koppelmann ret_hw1 = clo32(ret_hw1 << 16); 12260b79a781SBastian Koppelmann 12270b79a781SBastian Koppelmann if (ret_hw0 > 16) { 12280b79a781SBastian Koppelmann ret_hw0 = 16; 12290b79a781SBastian Koppelmann } 12300b79a781SBastian Koppelmann if (ret_hw1 > 16) { 12310b79a781SBastian Koppelmann ret_hw1 = 16; 12320b79a781SBastian Koppelmann } 12330b79a781SBastian Koppelmann 12340b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 12350b79a781SBastian Koppelmann } 12360b79a781SBastian Koppelmann 12370b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1) 12380b79a781SBastian Koppelmann { 12390b79a781SBastian Koppelmann return clz32(r1); 12400b79a781SBastian Koppelmann } 12410b79a781SBastian Koppelmann 12420b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1) 12430b79a781SBastian Koppelmann { 12440b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 12450b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 12460b79a781SBastian Koppelmann 12470b79a781SBastian Koppelmann ret_hw0 = clz32(ret_hw0 << 16); 12480b79a781SBastian Koppelmann ret_hw1 = clz32(ret_hw1 << 16); 12490b79a781SBastian Koppelmann 12500b79a781SBastian Koppelmann if (ret_hw0 > 16) { 12510b79a781SBastian Koppelmann ret_hw0 = 16; 12520b79a781SBastian Koppelmann } 12530b79a781SBastian Koppelmann if (ret_hw1 > 16) { 12540b79a781SBastian Koppelmann ret_hw1 = 16; 12550b79a781SBastian Koppelmann } 12560b79a781SBastian Koppelmann 12570b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 12580b79a781SBastian Koppelmann } 12590b79a781SBastian Koppelmann 12600b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1) 12610b79a781SBastian Koppelmann { 12620b79a781SBastian Koppelmann return clrsb32(r1); 12630b79a781SBastian Koppelmann } 12640b79a781SBastian Koppelmann 12650b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1) 12660b79a781SBastian Koppelmann { 12670b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 12680b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 12690b79a781SBastian Koppelmann 12700b79a781SBastian Koppelmann ret_hw0 = clrsb32(ret_hw0 << 16); 12710b79a781SBastian Koppelmann ret_hw1 = clrsb32(ret_hw1 << 16); 12720b79a781SBastian Koppelmann 12730b79a781SBastian Koppelmann if (ret_hw0 > 15) { 12740b79a781SBastian Koppelmann ret_hw0 = 15; 12750b79a781SBastian Koppelmann } 12760b79a781SBastian Koppelmann if (ret_hw1 > 15) { 12770b79a781SBastian Koppelmann ret_hw1 = 15; 12780b79a781SBastian Koppelmann } 12790b79a781SBastian Koppelmann 12800b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 12810b79a781SBastian Koppelmann } 12820b79a781SBastian Koppelmann 12830b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2) 12840b79a781SBastian Koppelmann { 12850b79a781SBastian Koppelmann int32_t shift_count = sextract32(r2, 0, 6); 12860b79a781SBastian Koppelmann 12870b79a781SBastian Koppelmann if (shift_count == -32) { 12880b79a781SBastian Koppelmann return 0; 12890b79a781SBastian Koppelmann } else if (shift_count < 0) { 12900b79a781SBastian Koppelmann return r1 >> -shift_count; 12910b79a781SBastian Koppelmann } else { 12920b79a781SBastian Koppelmann return r1 << shift_count; 12930b79a781SBastian Koppelmann } 12940b79a781SBastian Koppelmann } 12950b79a781SBastian Koppelmann 12960b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2) 12970b79a781SBastian Koppelmann { 12980b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 12990b79a781SBastian Koppelmann int32_t shift_count; 13000b79a781SBastian Koppelmann 13010b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 13020b79a781SBastian Koppelmann 13030b79a781SBastian Koppelmann if (shift_count == -16) { 13040b79a781SBastian Koppelmann return 0; 13050b79a781SBastian Koppelmann } else if (shift_count < 0) { 13060b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) >> -shift_count; 13070b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) >> -shift_count; 13080b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 13090b79a781SBastian Koppelmann } else { 13100b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) << shift_count; 13110b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) << shift_count; 13120b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 13130b79a781SBastian Koppelmann } 13140b79a781SBastian Koppelmann } 13150b79a781SBastian Koppelmann 13160b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 13170b79a781SBastian Koppelmann { 13180b79a781SBastian Koppelmann int32_t shift_count; 13190b79a781SBastian Koppelmann int64_t result, t1; 13200b79a781SBastian Koppelmann uint32_t ret; 13210b79a781SBastian Koppelmann 13220b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 6); 13230b79a781SBastian Koppelmann t1 = sextract32(r1, 0, 32); 13240b79a781SBastian Koppelmann 13250b79a781SBastian Koppelmann if (shift_count == 0) { 13260b79a781SBastian Koppelmann env->PSW_USB_C = env->PSW_USB_V = 0; 13270b79a781SBastian Koppelmann ret = r1; 13280b79a781SBastian Koppelmann } else if (shift_count == -32) { 13290b79a781SBastian Koppelmann env->PSW_USB_C = r1; 13300b79a781SBastian Koppelmann env->PSW_USB_V = 0; 13310b79a781SBastian Koppelmann ret = t1 >> 31; 13320b79a781SBastian Koppelmann } else if (shift_count > 0) { 13330b79a781SBastian Koppelmann result = t1 << shift_count; 13340b79a781SBastian Koppelmann /* calc carry */ 1335452e3d49SPeter Maydell env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0); 13360b79a781SBastian Koppelmann /* calc v */ 13370b79a781SBastian Koppelmann env->PSW_USB_V = (((result > 0x7fffffffLL) || 13380b79a781SBastian Koppelmann (result < -0x80000000LL)) << 31); 13390b79a781SBastian Koppelmann /* calc sv */ 13400b79a781SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 13410b79a781SBastian Koppelmann ret = (uint32_t)result; 13420b79a781SBastian Koppelmann } else { 13430b79a781SBastian Koppelmann env->PSW_USB_V = 0; 13440b79a781SBastian Koppelmann env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1)); 13450b79a781SBastian Koppelmann ret = t1 >> -shift_count; 13460b79a781SBastian Koppelmann } 13470b79a781SBastian Koppelmann 13480b79a781SBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 13490b79a781SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 13500b79a781SBastian Koppelmann 13510b79a781SBastian Koppelmann return ret; 13520b79a781SBastian Koppelmann } 13530b79a781SBastian Koppelmann 13540b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2) 13550b79a781SBastian Koppelmann { 13560b79a781SBastian Koppelmann int32_t shift_count; 13570b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 13580b79a781SBastian Koppelmann 13590b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 13600b79a781SBastian Koppelmann 13610b79a781SBastian Koppelmann if (shift_count == 0) { 13620b79a781SBastian Koppelmann return r1; 13630b79a781SBastian Koppelmann } else if (shift_count < 0) { 13640b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) >> -shift_count; 13650b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) >> -shift_count; 13660b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 13670b79a781SBastian Koppelmann } else { 13680b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) << shift_count; 13690b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) << shift_count; 13700b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 13710b79a781SBastian Koppelmann } 13720b79a781SBastian Koppelmann } 13730b79a781SBastian Koppelmann 1374e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2) 1375e2bed107SBastian Koppelmann { 1376e2bed107SBastian Koppelmann uint32_t i, ret; 1377e2bed107SBastian Koppelmann 1378e2bed107SBastian Koppelmann ret = 0; 1379e2bed107SBastian Koppelmann for (i = 0; i < 16; i++) { 1380e2bed107SBastian Koppelmann ret |= (r1 & 1) << (2 * i + 1); 1381e2bed107SBastian Koppelmann ret |= (r2 & 1) << (2 * i); 1382e2bed107SBastian Koppelmann r1 = r1 >> 1; 1383e2bed107SBastian Koppelmann r2 = r2 >> 1; 1384e2bed107SBastian Koppelmann } 1385e2bed107SBastian Koppelmann return ret; 1386e2bed107SBastian Koppelmann } 1387e2bed107SBastian Koppelmann 1388e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1) 1389e2bed107SBastian Koppelmann { 1390e2bed107SBastian Koppelmann int32_t i; 1391e2bed107SBastian Koppelmann uint64_t ret; 1392e2bed107SBastian Koppelmann 1393e2bed107SBastian Koppelmann ret = 0; 1394e2bed107SBastian Koppelmann for (i = 0; i < 32; i = i + 2) { 1395e2bed107SBastian Koppelmann /* even */ 1396e2bed107SBastian Koppelmann ret |= (r1 & 1) << (i/2); 1397e2bed107SBastian Koppelmann r1 = r1 >> 1; 1398e2bed107SBastian Koppelmann /* odd */ 1399e2bed107SBastian Koppelmann ret |= (uint64_t)(r1 & 1) << (i/2 + 32); 1400e2bed107SBastian Koppelmann r1 = r1 >> 1; 1401e2bed107SBastian Koppelmann } 1402e2bed107SBastian Koppelmann return ret; 1403e2bed107SBastian Koppelmann } 1404e2bed107SBastian Koppelmann 1405e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1) 1406e2bed107SBastian Koppelmann { 1407e2bed107SBastian Koppelmann uint32_t ret; 1408e2bed107SBastian Koppelmann uint32_t nOnes, i; 1409e2bed107SBastian Koppelmann 1410e2bed107SBastian Koppelmann ret = 0; 1411e2bed107SBastian Koppelmann nOnes = 0; 1412e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1413e2bed107SBastian Koppelmann ret ^= (r1 & 1); 1414e2bed107SBastian Koppelmann r1 = r1 >> 1; 1415e2bed107SBastian Koppelmann } 1416e2bed107SBastian Koppelmann /* second byte */ 1417e2bed107SBastian Koppelmann nOnes = 0; 1418e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1419e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1420e2bed107SBastian Koppelmann r1 = r1 >> 1; 1421e2bed107SBastian Koppelmann } 1422e2bed107SBastian Koppelmann ret |= nOnes << 8; 1423e2bed107SBastian Koppelmann /* third byte */ 1424e2bed107SBastian Koppelmann nOnes = 0; 1425e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1426e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1427e2bed107SBastian Koppelmann r1 = r1 >> 1; 1428e2bed107SBastian Koppelmann } 1429e2bed107SBastian Koppelmann ret |= nOnes << 16; 1430e2bed107SBastian Koppelmann /* fourth byte */ 1431e2bed107SBastian Koppelmann nOnes = 0; 1432e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1433e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1434e2bed107SBastian Koppelmann r1 = r1 >> 1; 1435e2bed107SBastian Koppelmann } 1436e2bed107SBastian Koppelmann ret |= nOnes << 24; 1437e2bed107SBastian Koppelmann 1438e2bed107SBastian Koppelmann return ret; 1439e2bed107SBastian Koppelmann } 1440e2bed107SBastian Koppelmann 144109532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high, 144209532255SBastian Koppelmann target_ulong r2) 144309532255SBastian Koppelmann { 144409532255SBastian Koppelmann uint32_t ret; 144509532255SBastian Koppelmann int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac; 144609532255SBastian Koppelmann int32_t int_exp = r1_high; 144709532255SBastian Koppelmann int32_t int_mant = r1_low; 144809532255SBastian Koppelmann uint32_t flag_rnd = (int_mant & (1 << 7)) && ( 144909532255SBastian Koppelmann (int_mant & (1 << 8)) || 145009532255SBastian Koppelmann (int_mant & 0x7f) || 145109532255SBastian Koppelmann (carry != 0)); 145209532255SBastian Koppelmann if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) { 145309532255SBastian Koppelmann fp_exp = 255; 145409532255SBastian Koppelmann fp_frac = extract32(int_mant, 8, 23); 145509532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp >= 127)) { 145609532255SBastian Koppelmann fp_exp = 255; 145709532255SBastian Koppelmann fp_frac = 0; 145809532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp <= -128)) { 145909532255SBastian Koppelmann fp_exp = 0; 146009532255SBastian Koppelmann fp_frac = 0; 146109532255SBastian Koppelmann } else if (int_mant == 0) { 146209532255SBastian Koppelmann fp_exp = 0; 146309532255SBastian Koppelmann fp_frac = 0; 146409532255SBastian Koppelmann } else { 146509532255SBastian Koppelmann if (((int_mant & (1 << 31)) == 0)) { 146609532255SBastian Koppelmann temp_exp = 0; 146709532255SBastian Koppelmann } else { 146809532255SBastian Koppelmann temp_exp = int_exp + 128; 146909532255SBastian Koppelmann } 147009532255SBastian Koppelmann fp_exp_frac = (((temp_exp & 0xff) << 23) | 147109532255SBastian Koppelmann extract32(int_mant, 8, 23)) 147209532255SBastian Koppelmann + flag_rnd; 147309532255SBastian Koppelmann fp_exp = extract32(fp_exp_frac, 23, 8); 147409532255SBastian Koppelmann fp_frac = extract32(fp_exp_frac, 0, 23); 147509532255SBastian Koppelmann } 147609532255SBastian Koppelmann ret = r2 & (1 << 31); 147709532255SBastian Koppelmann ret = ret + (fp_exp << 23); 147809532255SBastian Koppelmann ret = ret + (fp_frac & 0x7fffff); 147909532255SBastian Koppelmann 148009532255SBastian Koppelmann return ret; 148109532255SBastian Koppelmann } 148209532255SBastian Koppelmann 1483e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1) 1484e2bed107SBastian Koppelmann { 1485e2bed107SBastian Koppelmann int32_t fp_exp = extract32(arg1, 23, 8); 1486e2bed107SBastian Koppelmann int32_t fp_frac = extract32(arg1, 0, 23); 1487e2bed107SBastian Koppelmann uint64_t ret; 1488e2bed107SBastian Koppelmann int32_t int_exp, int_mant; 1489e2bed107SBastian Koppelmann 1490e2bed107SBastian Koppelmann if (fp_exp == 255) { 1491e2bed107SBastian Koppelmann int_exp = 255; 1492e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1493e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac == 0)) { 1494e2bed107SBastian Koppelmann int_exp = -127; 1495e2bed107SBastian Koppelmann int_mant = 0; 1496e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac != 0)) { 1497e2bed107SBastian Koppelmann int_exp = -126; 1498e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1499e2bed107SBastian Koppelmann } else { 1500e2bed107SBastian Koppelmann int_exp = fp_exp - 127; 1501e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1502e2bed107SBastian Koppelmann int_mant |= (1 << 30); 1503e2bed107SBastian Koppelmann } 1504e2bed107SBastian Koppelmann ret = int_exp; 1505e2bed107SBastian Koppelmann ret = ret << 32; 1506e2bed107SBastian Koppelmann ret |= int_mant; 1507e2bed107SBastian Koppelmann 1508e2bed107SBastian Koppelmann return ret; 1509e2bed107SBastian Koppelmann } 1510e2bed107SBastian Koppelmann 1511e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1512e2bed107SBastian Koppelmann { 1513e2bed107SBastian Koppelmann uint64_t ret; 1514e2bed107SBastian Koppelmann int32_t abs_sig_dividend, abs_base_dividend, abs_divisor; 1515e2bed107SBastian Koppelmann int32_t quotient_sign; 1516e2bed107SBastian Koppelmann 1517e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 1518e2bed107SBastian Koppelmann ret = ret << 24; 1519e2bed107SBastian Koppelmann quotient_sign = 0; 1520e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1521e2bed107SBastian Koppelmann ret |= 0xffffff; 1522e2bed107SBastian Koppelmann quotient_sign = 1; 1523e2bed107SBastian Koppelmann } 1524e2bed107SBastian Koppelmann 1525e2bed107SBastian Koppelmann abs_sig_dividend = abs(r1) >> 7; 1526e2bed107SBastian Koppelmann abs_base_dividend = abs(r1) & 0x7f; 1527e2bed107SBastian Koppelmann abs_divisor = abs(r1); 1528e2bed107SBastian Koppelmann /* calc overflow */ 1529e2bed107SBastian Koppelmann env->PSW_USB_V = 0; 1530e2bed107SBastian Koppelmann if ((quotient_sign) && (abs_divisor)) { 1531e2bed107SBastian Koppelmann env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) && 1532e2bed107SBastian Koppelmann (abs_base_dividend >= abs_divisor)) || 1533e2bed107SBastian Koppelmann (abs_sig_dividend > abs_divisor)); 1534e2bed107SBastian Koppelmann } else { 1535e2bed107SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor); 1536e2bed107SBastian Koppelmann } 1537e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1538e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1539e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1540e2bed107SBastian Koppelmann 1541e2bed107SBastian Koppelmann return ret; 1542e2bed107SBastian Koppelmann } 1543e2bed107SBastian Koppelmann 1544e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1545e2bed107SBastian Koppelmann { 1546e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 1547e2bed107SBastian Koppelmann 1548e2bed107SBastian Koppelmann ret = ret << 24; 1549e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1550e2bed107SBastian Koppelmann ret |= 0xffffff; 1551e2bed107SBastian Koppelmann } 1552e2bed107SBastian Koppelmann /* calc overflow */ 1553e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80))); 1554e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1555e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1556e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1557e2bed107SBastian Koppelmann 1558e2bed107SBastian Koppelmann return ret; 1559e2bed107SBastian Koppelmann } 1560e2bed107SBastian Koppelmann 1561e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1562e2bed107SBastian Koppelmann { 1563e2bed107SBastian Koppelmann uint64_t ret; 1564e2bed107SBastian Koppelmann int32_t abs_sig_dividend, abs_base_dividend, abs_divisor; 1565e2bed107SBastian Koppelmann int32_t quotient_sign; 1566e2bed107SBastian Koppelmann 1567e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 1568e2bed107SBastian Koppelmann ret = ret << 16; 1569e2bed107SBastian Koppelmann quotient_sign = 0; 1570e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1571e2bed107SBastian Koppelmann ret |= 0xffff; 1572e2bed107SBastian Koppelmann quotient_sign = 1; 1573e2bed107SBastian Koppelmann } 1574e2bed107SBastian Koppelmann 1575e2bed107SBastian Koppelmann abs_sig_dividend = abs(r1) >> 7; 1576e2bed107SBastian Koppelmann abs_base_dividend = abs(r1) & 0x7f; 1577e2bed107SBastian Koppelmann abs_divisor = abs(r1); 1578e2bed107SBastian Koppelmann /* calc overflow */ 1579e2bed107SBastian Koppelmann env->PSW_USB_V = 0; 1580e2bed107SBastian Koppelmann if ((quotient_sign) && (abs_divisor)) { 1581e2bed107SBastian Koppelmann env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) && 1582e2bed107SBastian Koppelmann (abs_base_dividend >= abs_divisor)) || 1583e2bed107SBastian Koppelmann (abs_sig_dividend > abs_divisor)); 1584e2bed107SBastian Koppelmann } else { 1585e2bed107SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor); 1586e2bed107SBastian Koppelmann } 1587e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1588e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1589e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1590e2bed107SBastian Koppelmann 1591e2bed107SBastian Koppelmann return ret; 1592e2bed107SBastian Koppelmann } 1593e2bed107SBastian Koppelmann 1594e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1595e2bed107SBastian Koppelmann { 1596e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 1597e2bed107SBastian Koppelmann 1598e2bed107SBastian Koppelmann ret = ret << 16; 1599e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1600e2bed107SBastian Koppelmann ret |= 0xffff; 1601e2bed107SBastian Koppelmann } 1602e2bed107SBastian Koppelmann /* calc overflow */ 1603e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000))); 1604e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1605e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1606e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1607e2bed107SBastian Koppelmann 1608e2bed107SBastian Koppelmann return ret; 1609e2bed107SBastian Koppelmann } 1610e2bed107SBastian Koppelmann 161109532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2) 161209532255SBastian Koppelmann { 161309532255SBastian Koppelmann int32_t x_sign = (r1 >> 63); 161409532255SBastian Koppelmann int32_t q_sign = x_sign ^ (r2 >> 31); 161509532255SBastian Koppelmann int32_t eq_pos = x_sign & ((r1 >> 32) == r2); 161609532255SBastian Koppelmann int32_t eq_neg = x_sign & ((r1 >> 32) == -r2); 161709532255SBastian Koppelmann uint32_t quotient; 161809532255SBastian Koppelmann uint64_t ret, remainder; 161909532255SBastian Koppelmann 162009532255SBastian Koppelmann if ((q_sign & ~eq_neg) | eq_pos) { 162109532255SBastian Koppelmann quotient = (r1 + 1) & 0xffffffff; 162209532255SBastian Koppelmann } else { 162309532255SBastian Koppelmann quotient = r1 & 0xffffffff; 162409532255SBastian Koppelmann } 162509532255SBastian Koppelmann 162609532255SBastian Koppelmann if (eq_pos | eq_neg) { 162709532255SBastian Koppelmann remainder = 0; 162809532255SBastian Koppelmann } else { 162909532255SBastian Koppelmann remainder = (r1 & 0xffffffff00000000ull); 163009532255SBastian Koppelmann } 163109532255SBastian Koppelmann ret = remainder|quotient; 163209532255SBastian Koppelmann return ret; 163309532255SBastian Koppelmann } 163409532255SBastian Koppelmann 163509532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2) 163609532255SBastian Koppelmann { 163709532255SBastian Koppelmann int32_t dividend_sign = extract64(r1, 63, 1); 163809532255SBastian Koppelmann int32_t divisor_sign = extract32(r2, 31, 1); 163909532255SBastian Koppelmann int32_t quotient_sign = (dividend_sign != divisor_sign); 164009532255SBastian Koppelmann int32_t addend, dividend_quotient, remainder; 164109532255SBastian Koppelmann int32_t i, temp; 164209532255SBastian Koppelmann 164309532255SBastian Koppelmann if (quotient_sign) { 164409532255SBastian Koppelmann addend = r2; 164509532255SBastian Koppelmann } else { 164609532255SBastian Koppelmann addend = -r2; 164709532255SBastian Koppelmann } 164809532255SBastian Koppelmann dividend_quotient = (int32_t)r1; 164909532255SBastian Koppelmann remainder = (int32_t)(r1 >> 32); 165009532255SBastian Koppelmann 165109532255SBastian Koppelmann for (i = 0; i < 8; i++) { 165209532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 165309532255SBastian Koppelmann dividend_quotient <<= 1; 165409532255SBastian Koppelmann temp = remainder + addend; 165509532255SBastian Koppelmann if ((temp < 0) == dividend_sign) { 165609532255SBastian Koppelmann remainder = temp; 165709532255SBastian Koppelmann } 165809532255SBastian Koppelmann if (((temp < 0) == dividend_sign)) { 165909532255SBastian Koppelmann dividend_quotient = dividend_quotient | !quotient_sign; 166009532255SBastian Koppelmann } else { 166109532255SBastian Koppelmann dividend_quotient = dividend_quotient | quotient_sign; 166209532255SBastian Koppelmann } 166309532255SBastian Koppelmann } 166409532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 166509532255SBastian Koppelmann } 166609532255SBastian Koppelmann 166709532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2) 166809532255SBastian Koppelmann { 166909532255SBastian Koppelmann int32_t dividend_quotient = extract64(r1, 0, 32); 167009532255SBastian Koppelmann int64_t remainder = extract64(r1, 32, 32); 167109532255SBastian Koppelmann int32_t i; 167209532255SBastian Koppelmann int64_t temp; 167309532255SBastian Koppelmann for (i = 0; i < 8; i++) { 167409532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 167509532255SBastian Koppelmann dividend_quotient <<= 1; 167609532255SBastian Koppelmann temp = (remainder & 0xffffffff) - r2; 167709532255SBastian Koppelmann if (temp >= 0) { 167809532255SBastian Koppelmann remainder = temp; 167909532255SBastian Koppelmann } 168009532255SBastian Koppelmann dividend_quotient = dividend_quotient | !(temp < 0); 168109532255SBastian Koppelmann } 168209532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 168309532255SBastian Koppelmann } 168409532255SBastian Koppelmann 16859655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01, 16869655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 16879655b932SBastian Koppelmann { 16889655b932SBastian Koppelmann uint64_t ret; 16899655b932SBastian Koppelmann uint32_t result0, result1; 16909655b932SBastian Koppelmann 16919655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 16929655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 16939655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 16949655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 16959655b932SBastian Koppelmann if (sc1) { 16969655b932SBastian Koppelmann result1 = 0x7fffffff; 16979655b932SBastian Koppelmann } else { 16989655b932SBastian Koppelmann result1 = (((uint32_t)(arg00 * arg10)) << n); 16999655b932SBastian Koppelmann } 17009655b932SBastian Koppelmann if (sc0) { 17019655b932SBastian Koppelmann result0 = 0x7fffffff; 17029655b932SBastian Koppelmann } else { 17039655b932SBastian Koppelmann result0 = (((uint32_t)(arg01 * arg11)) << n); 17049655b932SBastian Koppelmann } 17059655b932SBastian Koppelmann ret = (((uint64_t)result1 << 32)) | result0; 17069655b932SBastian Koppelmann return ret; 17079655b932SBastian Koppelmann } 17089655b932SBastian Koppelmann 17099655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01, 17109655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 17119655b932SBastian Koppelmann { 17129655b932SBastian Koppelmann uint64_t ret; 17139655b932SBastian Koppelmann int64_t result0, result1; 17149655b932SBastian Koppelmann 17159655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 17169655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 17179655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 17189655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 17199655b932SBastian Koppelmann 17209655b932SBastian Koppelmann if (sc1) { 17219655b932SBastian Koppelmann result1 = 0x7fffffff; 17229655b932SBastian Koppelmann } else { 17239655b932SBastian Koppelmann result1 = (((int32_t)arg00 * (int32_t)arg10) << n); 17249655b932SBastian Koppelmann } 17259655b932SBastian Koppelmann if (sc0) { 17269655b932SBastian Koppelmann result0 = 0x7fffffff; 17279655b932SBastian Koppelmann } else { 17289655b932SBastian Koppelmann result0 = (((int32_t)arg01 * (int32_t)arg11) << n); 17299655b932SBastian Koppelmann } 17309655b932SBastian Koppelmann ret = (result1 + result0); 17319655b932SBastian Koppelmann ret = ret << 16; 17329655b932SBastian Koppelmann return ret; 17339655b932SBastian Koppelmann } 17349655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01, 17359655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 17369655b932SBastian Koppelmann { 17379655b932SBastian Koppelmann uint32_t result0, result1; 17389655b932SBastian Koppelmann 17399655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 17409655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 17419655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 17429655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 17439655b932SBastian Koppelmann 17449655b932SBastian Koppelmann if (sc1) { 17459655b932SBastian Koppelmann result1 = 0x7fffffff; 17469655b932SBastian Koppelmann } else { 17479655b932SBastian Koppelmann result1 = ((arg00 * arg10) << n) + 0x8000; 17489655b932SBastian Koppelmann } 17499655b932SBastian Koppelmann if (sc0) { 17509655b932SBastian Koppelmann result0 = 0x7fffffff; 17519655b932SBastian Koppelmann } else { 17529655b932SBastian Koppelmann result0 = ((arg01 * arg11) << n) + 0x8000; 17539655b932SBastian Koppelmann } 17549655b932SBastian Koppelmann return (result1 & 0xffff0000) | (result0 >> 16); 17559655b932SBastian Koppelmann } 17569655b932SBastian Koppelmann 17579a31922bSBastian Koppelmann /* context save area (CSA) related helpers */ 17589a31922bSBastian Koppelmann 17599a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw) 17609a31922bSBastian Koppelmann { 17619a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 17629a31922bSBastian Koppelmann return 0; 17639a31922bSBastian Koppelmann } 17649a31922bSBastian Koppelmann 17659a31922bSBastian Koppelmann (*psw)++; 17669a31922bSBastian Koppelmann /* check for overflow */ 17679a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 17689a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 17699a31922bSBastian Koppelmann int count = *psw & mask; 17709a31922bSBastian Koppelmann if (count == 0) { 17719a31922bSBastian Koppelmann (*psw)--; 17729a31922bSBastian Koppelmann return 1; 17739a31922bSBastian Koppelmann } 17749a31922bSBastian Koppelmann return 0; 17759a31922bSBastian Koppelmann } 17769a31922bSBastian Koppelmann 17779a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw) 17789a31922bSBastian Koppelmann { 17799a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 17809a31922bSBastian Koppelmann return 0; 17819a31922bSBastian Koppelmann } 17829a31922bSBastian Koppelmann /* check for underflow */ 17839a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 17849a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 17859a31922bSBastian Koppelmann int count = *psw & mask; 17869a31922bSBastian Koppelmann if (count == 0) { 17879a31922bSBastian Koppelmann return 1; 17889a31922bSBastian Koppelmann } 17899a31922bSBastian Koppelmann (*psw)--; 17909a31922bSBastian Koppelmann return 0; 17919a31922bSBastian Koppelmann } 17929a31922bSBastian Koppelmann 179344ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw) 179444ea3430SBastian Koppelmann { 179544ea3430SBastian Koppelmann int cdc = *psw & MASK_PSW_CDC; 179644ea3430SBastian Koppelmann /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC == 179744ea3430SBastian Koppelmann 7'b1111111, otherwise returns FALSE. */ 179844ea3430SBastian Koppelmann if (cdc == 0x7f) { 179944ea3430SBastian Koppelmann return true; 180044ea3430SBastian Koppelmann } 180144ea3430SBastian Koppelmann /* find CDC.COUNT */ 180244ea3430SBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 180344ea3430SBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 180444ea3430SBastian Koppelmann int count = *psw & mask; 180544ea3430SBastian Koppelmann return count == 0; 180644ea3430SBastian Koppelmann } 180744ea3430SBastian Koppelmann 1808030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea) 18099a31922bSBastian Koppelmann { 18109a31922bSBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 18119a31922bSBastian Koppelmann cpu_stl_data(env, ea+4, env->PSW); 18129a31922bSBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[10]); 18139a31922bSBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[11]); 18149a31922bSBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[8]); 18159a31922bSBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[9]); 18169a31922bSBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[10]); 18179a31922bSBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[11]); 18189a31922bSBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[12]); 18199a31922bSBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[13]); 18209a31922bSBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[14]); 18219a31922bSBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[15]); 18229a31922bSBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[12]); 18239a31922bSBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[13]); 18249a31922bSBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[14]); 18259a31922bSBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[15]); 18269a31922bSBastian Koppelmann } 18279a31922bSBastian Koppelmann 1828030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea) 18295de93515SBastian Koppelmann { 18305de93515SBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 1831030c58dfSBastian Koppelmann cpu_stl_data(env, ea+4, env->gpr_a[11]); 18325de93515SBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[2]); 18335de93515SBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[3]); 18345de93515SBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[0]); 18355de93515SBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[1]); 18365de93515SBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[2]); 18375de93515SBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[3]); 18385de93515SBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[4]); 18395de93515SBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[5]); 18405de93515SBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[6]); 18415de93515SBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[7]); 18425de93515SBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[4]); 18435de93515SBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[5]); 18445de93515SBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[6]); 18455de93515SBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[7]); 18465de93515SBastian Koppelmann } 18475de93515SBastian Koppelmann 18489a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea, 18499a31922bSBastian Koppelmann target_ulong *new_PCXI, target_ulong *new_PSW) 18509a31922bSBastian Koppelmann { 18519a31922bSBastian Koppelmann *new_PCXI = cpu_ldl_data(env, ea); 18529a31922bSBastian Koppelmann *new_PSW = cpu_ldl_data(env, ea+4); 18539a31922bSBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, ea+8); 18549a31922bSBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, ea+12); 18559a31922bSBastian Koppelmann env->gpr_d[8] = cpu_ldl_data(env, ea+16); 18569a31922bSBastian Koppelmann env->gpr_d[9] = cpu_ldl_data(env, ea+20); 18579a31922bSBastian Koppelmann env->gpr_d[10] = cpu_ldl_data(env, ea+24); 18589a31922bSBastian Koppelmann env->gpr_d[11] = cpu_ldl_data(env, ea+28); 18599a31922bSBastian Koppelmann env->gpr_a[12] = cpu_ldl_data(env, ea+32); 18609a31922bSBastian Koppelmann env->gpr_a[13] = cpu_ldl_data(env, ea+36); 18619a31922bSBastian Koppelmann env->gpr_a[14] = cpu_ldl_data(env, ea+40); 18629a31922bSBastian Koppelmann env->gpr_a[15] = cpu_ldl_data(env, ea+44); 18639a31922bSBastian Koppelmann env->gpr_d[12] = cpu_ldl_data(env, ea+48); 18649a31922bSBastian Koppelmann env->gpr_d[13] = cpu_ldl_data(env, ea+52); 18659a31922bSBastian Koppelmann env->gpr_d[14] = cpu_ldl_data(env, ea+56); 18669a31922bSBastian Koppelmann env->gpr_d[15] = cpu_ldl_data(env, ea+60); 18679a31922bSBastian Koppelmann } 18689a31922bSBastian Koppelmann 186959543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea, 187059543d4eSBastian Koppelmann target_ulong *ra, target_ulong *pcxi) 187159543d4eSBastian Koppelmann { 187259543d4eSBastian Koppelmann *pcxi = cpu_ldl_data(env, ea); 187359543d4eSBastian Koppelmann *ra = cpu_ldl_data(env, ea+4); 187459543d4eSBastian Koppelmann env->gpr_a[2] = cpu_ldl_data(env, ea+8); 187559543d4eSBastian Koppelmann env->gpr_a[3] = cpu_ldl_data(env, ea+12); 187659543d4eSBastian Koppelmann env->gpr_d[0] = cpu_ldl_data(env, ea+16); 187759543d4eSBastian Koppelmann env->gpr_d[1] = cpu_ldl_data(env, ea+20); 187859543d4eSBastian Koppelmann env->gpr_d[2] = cpu_ldl_data(env, ea+24); 187959543d4eSBastian Koppelmann env->gpr_d[3] = cpu_ldl_data(env, ea+28); 188059543d4eSBastian Koppelmann env->gpr_a[4] = cpu_ldl_data(env, ea+32); 188159543d4eSBastian Koppelmann env->gpr_a[5] = cpu_ldl_data(env, ea+36); 188259543d4eSBastian Koppelmann env->gpr_a[6] = cpu_ldl_data(env, ea+40); 188359543d4eSBastian Koppelmann env->gpr_a[7] = cpu_ldl_data(env, ea+44); 188459543d4eSBastian Koppelmann env->gpr_d[4] = cpu_ldl_data(env, ea+48); 188559543d4eSBastian Koppelmann env->gpr_d[5] = cpu_ldl_data(env, ea+52); 188659543d4eSBastian Koppelmann env->gpr_d[6] = cpu_ldl_data(env, ea+56); 188759543d4eSBastian Koppelmann env->gpr_d[7] = cpu_ldl_data(env, ea+60); 188859543d4eSBastian Koppelmann } 188959543d4eSBastian Koppelmann 18909a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc) 18919a31922bSBastian Koppelmann { 18929a31922bSBastian Koppelmann target_ulong tmp_FCX; 18939a31922bSBastian Koppelmann target_ulong ea; 18949a31922bSBastian Koppelmann target_ulong new_FCX; 18959a31922bSBastian Koppelmann target_ulong psw; 18969a31922bSBastian Koppelmann 18979a31922bSBastian Koppelmann psw = psw_read(env); 18989a31922bSBastian Koppelmann /* if (FCX == 0) trap(FCU); */ 18999a31922bSBastian Koppelmann if (env->FCX == 0) { 19009a31922bSBastian Koppelmann /* FCU trap */ 19019a31922bSBastian Koppelmann } 19029a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */ 19039a31922bSBastian Koppelmann if (psw & MASK_PSW_CDE) { 19049a31922bSBastian Koppelmann if (cdc_increment(&psw)) { 19059a31922bSBastian Koppelmann /* CDO trap */ 19069a31922bSBastian Koppelmann } 19079a31922bSBastian Koppelmann } 19089a31922bSBastian Koppelmann /* PSW.CDE = 1;*/ 19099a31922bSBastian Koppelmann psw |= MASK_PSW_CDE; 19109a31922bSBastian Koppelmann /* tmp_FCX = FCX; */ 19119a31922bSBastian Koppelmann tmp_FCX = env->FCX; 19129a31922bSBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 19139a31922bSBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 19149a31922bSBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 1915030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 1916030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 1917030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 19189a31922bSBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 19199a31922bSBastian Koppelmann D[15]}; */ 1920030c58dfSBastian Koppelmann save_context_upper(env, ea); 19219a31922bSBastian Koppelmann 19229a31922bSBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 19239a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 19249a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 19259a31922bSBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 19269a31922bSBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 19279a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 19289a31922bSBastian Koppelmann /* PCXI.UL = 1; */ 19299a31922bSBastian Koppelmann env->PCXI |= MASK_PCXI_UL; 19309a31922bSBastian Koppelmann 19319a31922bSBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 19329a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 19339a31922bSBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 19349a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 19359a31922bSBastian Koppelmann /* A[11] = next_pc[31: 0]; */ 19369a31922bSBastian Koppelmann env->gpr_a[11] = next_pc; 19379a31922bSBastian Koppelmann 19389a31922bSBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 19399a31922bSBastian Koppelmann if (tmp_FCX == env->LCX) { 19409a31922bSBastian Koppelmann /* FCD trap */ 19419a31922bSBastian Koppelmann } 19429a31922bSBastian Koppelmann psw_write(env, psw); 19439a31922bSBastian Koppelmann } 19449a31922bSBastian Koppelmann 19459a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env) 19469a31922bSBastian Koppelmann { 19479a31922bSBastian Koppelmann target_ulong ea; 19489a31922bSBastian Koppelmann target_ulong new_PCXI; 19499a31922bSBastian Koppelmann target_ulong new_PSW, psw; 19509a31922bSBastian Koppelmann 19519a31922bSBastian Koppelmann psw = psw_read(env); 19529a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/ 19539a31922bSBastian Koppelmann if (env->PSW & MASK_PSW_CDE) { 19549a31922bSBastian Koppelmann if (cdc_decrement(&(env->PSW))) { 19559a31922bSBastian Koppelmann /* CDU trap */ 19569a31922bSBastian Koppelmann } 19579a31922bSBastian Koppelmann } 19589a31922bSBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 19599a31922bSBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 19609a31922bSBastian Koppelmann /* CSU trap */ 19619a31922bSBastian Koppelmann } 19629a31922bSBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 19639a31922bSBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 19649a31922bSBastian Koppelmann /* CTYP trap */ 19659a31922bSBastian Koppelmann } 19669a31922bSBastian Koppelmann /* PC = {A11 [31: 1], 1’b0}; */ 19679a31922bSBastian Koppelmann env->PC = env->gpr_a[11] & 0xfffffffe; 19689a31922bSBastian Koppelmann 19699a31922bSBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 19709a31922bSBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 19719a31922bSBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 19729a31922bSBastian Koppelmann /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 1973030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 19749a31922bSBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 1975030c58dfSBastian Koppelmann /* M(EA, word) = FCX; */ 1976030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 19779a31922bSBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 19789a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 19799a31922bSBastian Koppelmann /* PCXI = new_PCXI; */ 19809a31922bSBastian Koppelmann env->PCXI = new_PCXI; 19819a31922bSBastian Koppelmann 19829a31922bSBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_13)) { 19839a31922bSBastian Koppelmann /* PSW = new_PSW */ 19849a31922bSBastian Koppelmann psw_write(env, new_PSW); 19859a31922bSBastian Koppelmann } else { 19869a31922bSBastian Koppelmann /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */ 19879a31922bSBastian Koppelmann psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000))); 19889a31922bSBastian Koppelmann } 19899a31922bSBastian Koppelmann } 19909a31922bSBastian Koppelmann 19915de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9) 19925de93515SBastian Koppelmann { 19935de93515SBastian Koppelmann target_ulong tmp_FCX; 19945de93515SBastian Koppelmann target_ulong ea; 19955de93515SBastian Koppelmann target_ulong new_FCX; 19965de93515SBastian Koppelmann 19975de93515SBastian Koppelmann if (env->FCX == 0) { 19985de93515SBastian Koppelmann /* FCU trap */ 19995de93515SBastian Koppelmann } 20005de93515SBastian Koppelmann 20015de93515SBastian Koppelmann tmp_FCX = env->FCX; 20025de93515SBastian Koppelmann ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6); 20035de93515SBastian Koppelmann 2004030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 2005030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2006030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4] 2007030c58dfSBastian Koppelmann , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */ 2008030c58dfSBastian Koppelmann save_context_lower(env, ea); 2009030c58dfSBastian Koppelmann 20105de93515SBastian Koppelmann 20115de93515SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */ 20125de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 20135de93515SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 20145de93515SBastian Koppelmann /* PCXI.PIE = ICR.IE */ 20155de93515SBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 20165de93515SBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 20175de93515SBastian Koppelmann /* PCXI.UL = 0 */ 20185de93515SBastian Koppelmann env->PCXI &= ~(MASK_PCXI_UL); 20195de93515SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0] */ 20205de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 20215de93515SBastian Koppelmann /* FXC[19: 0] = new_FCX[19: 0] */ 20225de93515SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 20235de93515SBastian Koppelmann /* ICR.IE = 1 */ 20245de93515SBastian Koppelmann env->ICR |= MASK_ICR_IE; 20255de93515SBastian Koppelmann 20265de93515SBastian Koppelmann env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/ 20275de93515SBastian Koppelmann 20285de93515SBastian Koppelmann if (tmp_FCX == env->LCX) { 20295de93515SBastian Koppelmann /* FCD trap */ 20305de93515SBastian Koppelmann } 20315de93515SBastian Koppelmann } 20325de93515SBastian Koppelmann 203344ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env) 203444ea3430SBastian Koppelmann { 203544ea3430SBastian Koppelmann target_ulong ea; 203644ea3430SBastian Koppelmann target_ulong new_PCXI; 203744ea3430SBastian Koppelmann target_ulong new_PSW; 203844ea3430SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 203944ea3430SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 204044ea3430SBastian Koppelmann /* raise csu trap */ 204144ea3430SBastian Koppelmann } 204244ea3430SBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 204344ea3430SBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 204444ea3430SBastian Koppelmann /* raise CTYP trap */ 204544ea3430SBastian Koppelmann } 204644ea3430SBastian Koppelmann /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */ 204744ea3430SBastian Koppelmann if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) { 204844ea3430SBastian Koppelmann /* raise MNG trap */ 204944ea3430SBastian Koppelmann } 205044ea3430SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 205144ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15); 205244ea3430SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 205344ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) + 205444ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCPN) >> 24); 205544ea3430SBastian Koppelmann /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/ 205644ea3430SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 205744ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 205844ea3430SBastian Koppelmann /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2059030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 206044ea3430SBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2061030c58dfSBastian Koppelmann /* M(EA, word) = FCX;*/ 2062030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 206344ea3430SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 206444ea3430SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 206544ea3430SBastian Koppelmann /* PCXI = new_PCXI; */ 206644ea3430SBastian Koppelmann env->PCXI = new_PCXI; 206744ea3430SBastian Koppelmann /* write psw */ 206844ea3430SBastian Koppelmann psw_write(env, new_PSW); 206944ea3430SBastian Koppelmann } 207044ea3430SBastian Koppelmann 207159543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) 207259543d4eSBastian Koppelmann { 207359543d4eSBastian Koppelmann uint32_t dummy; 207459543d4eSBastian Koppelmann /* insn doesn't load PCXI and RA */ 207559543d4eSBastian Koppelmann restore_context_lower(env, ea, &dummy, &dummy); 207659543d4eSBastian Koppelmann } 207759543d4eSBastian Koppelmann 207859543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea) 207959543d4eSBastian Koppelmann { 208059543d4eSBastian Koppelmann uint32_t dummy; 208159543d4eSBastian Koppelmann /* insn doesn't load PCXI and PSW */ 208259543d4eSBastian Koppelmann restore_context_upper(env, ea, &dummy, &dummy); 208359543d4eSBastian Koppelmann } 208459543d4eSBastian Koppelmann 208559543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea) 208659543d4eSBastian Koppelmann { 208759543d4eSBastian Koppelmann save_context_lower(env, ea); 208859543d4eSBastian Koppelmann } 208959543d4eSBastian Koppelmann 209059543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea) 209159543d4eSBastian Koppelmann { 209259543d4eSBastian Koppelmann save_context_upper(env, ea); 209359543d4eSBastian Koppelmann } 209459543d4eSBastian Koppelmann 20952b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg) 20962b2f7d97SBastian Koppelmann { 20972b2f7d97SBastian Koppelmann psw_write(env, arg); 20982b2f7d97SBastian Koppelmann } 20992b2f7d97SBastian Koppelmann 21002b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env) 21012b2f7d97SBastian Koppelmann { 21022b2f7d97SBastian Koppelmann return psw_read(env); 21032b2f7d97SBastian Koppelmann } 21042b2f7d97SBastian Koppelmann 21052b2f7d97SBastian Koppelmann 21062d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env, 21072d30267eSBastian Koppelmann uint32_t exception, 21082d30267eSBastian Koppelmann int error_code, 21092d30267eSBastian Koppelmann uintptr_t pc) 21102d30267eSBastian Koppelmann { 21112d30267eSBastian Koppelmann CPUState *cs = CPU(tricore_env_get_cpu(env)); 21122d30267eSBastian Koppelmann cs->exception_index = exception; 21132d30267eSBastian Koppelmann env->error_code = error_code; 21142d30267eSBastian Koppelmann 21152d30267eSBastian Koppelmann if (pc) { 21162d30267eSBastian Koppelmann /* now we have a real cpu fault */ 21172d30267eSBastian Koppelmann cpu_restore_state(cs, pc); 21182d30267eSBastian Koppelmann } 21192d30267eSBastian Koppelmann 21202d30267eSBastian Koppelmann cpu_loop_exit(cs); 21212d30267eSBastian Koppelmann } 21222d30267eSBastian Koppelmann 212348e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, 212448e06fe0SBastian Koppelmann uintptr_t retaddr) 212548e06fe0SBastian Koppelmann { 21262d30267eSBastian Koppelmann int ret; 21272d30267eSBastian Koppelmann ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx); 21282d30267eSBastian Koppelmann if (ret) { 21292d30267eSBastian Koppelmann TriCoreCPU *cpu = TRICORE_CPU(cs); 21302d30267eSBastian Koppelmann CPUTriCoreState *env = &cpu->env; 21312d30267eSBastian Koppelmann do_raise_exception_err(env, cs->exception_index, 21322d30267eSBastian Koppelmann env->error_code, retaddr); 213348e06fe0SBastian Koppelmann } 21342d30267eSBastian Koppelmann } 2135