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 83e4e39176SBastian Koppelmann static uint32_t suov32(CPUTriCoreState *env, int64_t arg) 84e4e39176SBastian Koppelmann { 85e4e39176SBastian Koppelmann uint32_t ret; 86e4e39176SBastian Koppelmann int64_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 { 92e4e39176SBastian Koppelmann if (arg < 0) { 93e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 94e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 95e4e39176SBastian Koppelmann ret = 0; 96e4e39176SBastian Koppelmann } else { 97e4e39176SBastian Koppelmann env->PSW_USB_V = 0; 98e4e39176SBastian Koppelmann ret = (target_ulong)arg; 99e4e39176SBastian Koppelmann } 100e4e39176SBastian Koppelmann } 101e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 102e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 103e4e39176SBastian Koppelmann return ret; 104e4e39176SBastian Koppelmann } 1050974257eSBastian Koppelmann 106d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 107d5de7839SBastian Koppelmann { 108d5de7839SBastian Koppelmann int32_t max_pos = INT16_MAX; 109d5de7839SBastian Koppelmann int32_t max_neg = INT16_MIN; 110d5de7839SBastian Koppelmann int32_t av0, av1; 111d5de7839SBastian Koppelmann 112d5de7839SBastian Koppelmann env->PSW_USB_V = 0; 113d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u; 114d5de7839SBastian Koppelmann if (hw0 > max_pos) { 115d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 116d5de7839SBastian Koppelmann hw0 = max_pos; 117d5de7839SBastian Koppelmann } else if (hw0 < max_neg) { 118d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 119d5de7839SBastian Koppelmann hw0 = max_neg; 120d5de7839SBastian Koppelmann } 121d5de7839SBastian Koppelmann 122d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u; 123d5de7839SBastian Koppelmann if (hw1 > max_pos) { 124d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 125d5de7839SBastian Koppelmann hw1 = max_pos; 126d5de7839SBastian Koppelmann } else if (hw1 < max_neg) { 127d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 128d5de7839SBastian Koppelmann hw1 = max_neg; 129d5de7839SBastian Koppelmann } 130d5de7839SBastian Koppelmann 131d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 132d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16; 133d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 134d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16); 135d5de7839SBastian Koppelmann } 136d5de7839SBastian Koppelmann 137d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 138d5de7839SBastian Koppelmann { 139d5de7839SBastian Koppelmann int32_t max_pos = UINT16_MAX; 140d5de7839SBastian Koppelmann int32_t av0, av1; 141d5de7839SBastian Koppelmann 142d5de7839SBastian Koppelmann env->PSW_USB_V = 0; 143d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u; 144d5de7839SBastian Koppelmann if (hw0 > max_pos) { 145d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 146d5de7839SBastian Koppelmann hw0 = max_pos; 147d5de7839SBastian Koppelmann } else if (hw0 < 0) { 148d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 149d5de7839SBastian Koppelmann hw0 = 0; 150d5de7839SBastian Koppelmann } 151d5de7839SBastian Koppelmann 152d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u; 153d5de7839SBastian Koppelmann if (hw1 > max_pos) { 154d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 155d5de7839SBastian Koppelmann hw1 = max_pos; 156d5de7839SBastian Koppelmann } else if (hw1 < 0) { 157d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 158d5de7839SBastian Koppelmann hw1 = 0; 159d5de7839SBastian Koppelmann } 160d5de7839SBastian Koppelmann 161d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 162d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16; 163d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 164d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16); 165d5de7839SBastian Koppelmann } 1660974257eSBastian Koppelmann 1672692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1, 1682692802aSBastian Koppelmann target_ulong r2) 1692692802aSBastian Koppelmann { 1702692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 1712692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 1722692802aSBastian Koppelmann int64_t result = t1 + t2; 173e4e39176SBastian Koppelmann return ssov32(env, result); 1742692802aSBastian Koppelmann } 1752692802aSBastian Koppelmann 176d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1, 177d5de7839SBastian Koppelmann target_ulong r2) 178d5de7839SBastian Koppelmann { 179d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 180d5de7839SBastian Koppelmann 181d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16); 182d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16); 183d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 184d5de7839SBastian Koppelmann } 185d5de7839SBastian Koppelmann 1860974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1, 1870974257eSBastian Koppelmann target_ulong r2) 1880974257eSBastian Koppelmann { 1890974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 1900974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 1910974257eSBastian Koppelmann int64_t result = t1 + t2; 192e4e39176SBastian Koppelmann return suov32(env, result); 1930974257eSBastian Koppelmann } 1940974257eSBastian Koppelmann 195d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1, 196d5de7839SBastian Koppelmann target_ulong r2) 197d5de7839SBastian Koppelmann { 198d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 199d5de7839SBastian Koppelmann 200d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16); 201d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16); 202d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 203d5de7839SBastian Koppelmann } 204d5de7839SBastian Koppelmann 2052692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1, 2062692802aSBastian Koppelmann target_ulong r2) 2072692802aSBastian Koppelmann { 2082692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 2092692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 2102692802aSBastian Koppelmann int64_t result = t1 - t2; 211e4e39176SBastian Koppelmann return ssov32(env, result); 2122692802aSBastian Koppelmann } 2132692802aSBastian Koppelmann 214d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1, 215d5de7839SBastian Koppelmann target_ulong r2) 216d5de7839SBastian Koppelmann { 217d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 218d5de7839SBastian Koppelmann 219d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16); 220d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16); 221d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 222d5de7839SBastian Koppelmann } 223d5de7839SBastian Koppelmann 2240974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1, 2250974257eSBastian Koppelmann target_ulong r2) 2260974257eSBastian Koppelmann { 2270974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 2280974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 2290974257eSBastian Koppelmann int64_t result = t1 - t2; 230e4e39176SBastian Koppelmann return suov32(env, result); 2310974257eSBastian Koppelmann } 2320974257eSBastian Koppelmann 233d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1, 234d5de7839SBastian Koppelmann target_ulong r2) 235d5de7839SBastian Koppelmann { 236d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 237d5de7839SBastian Koppelmann 238d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16); 239d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16); 240d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 241d5de7839SBastian Koppelmann } 242d5de7839SBastian Koppelmann 2430974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1, 2440974257eSBastian Koppelmann target_ulong r2) 2450974257eSBastian Koppelmann { 2460974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 2470974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 2480974257eSBastian Koppelmann int64_t result = t1 * t2; 249e4e39176SBastian Koppelmann return ssov32(env, result); 2500974257eSBastian Koppelmann } 2510974257eSBastian Koppelmann 2520974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1, 2530974257eSBastian Koppelmann target_ulong r2) 2540974257eSBastian Koppelmann { 2550974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 2560974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 2570974257eSBastian Koppelmann int64_t result = t1 * t2; 2585f30046fSBastian Koppelmann 259e4e39176SBastian Koppelmann return suov32(env, result); 2600974257eSBastian Koppelmann } 2610974257eSBastian Koppelmann 2620974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1, 2630974257eSBastian Koppelmann target_ulong r2) 2640974257eSBastian Koppelmann { 2650974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 2660974257eSBastian Koppelmann int32_t t2 = sextract64(r2, 0, 6); 2670974257eSBastian Koppelmann int64_t result; 2680974257eSBastian Koppelmann if (t2 == 0) { 2690974257eSBastian Koppelmann result = t1; 2700974257eSBastian Koppelmann } else if (t2 > 0) { 2710974257eSBastian Koppelmann result = t1 << t2; 2720974257eSBastian Koppelmann } else { 2730974257eSBastian Koppelmann result = t1 >> -t2; 2740974257eSBastian Koppelmann } 275e4e39176SBastian Koppelmann return ssov32(env, result); 2760974257eSBastian Koppelmann } 2770974257eSBastian Koppelmann 278d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1) 279d5de7839SBastian Koppelmann { 280d5de7839SBastian Koppelmann target_ulong result; 281d5de7839SBastian Koppelmann result = ((int32_t)r1 >= 0) ? r1 : (0 - r1); 282d5de7839SBastian Koppelmann return ssov32(env, result); 283d5de7839SBastian Koppelmann } 284d5de7839SBastian Koppelmann 285d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1) 286d5de7839SBastian Koppelmann { 287d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 288d5de7839SBastian Koppelmann 289d5de7839SBastian Koppelmann ret_h0 = sextract32(r1, 0, 16); 290d5de7839SBastian Koppelmann ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0); 291d5de7839SBastian Koppelmann 292d5de7839SBastian Koppelmann ret_h1 = sextract32(r1, 16, 16); 293d5de7839SBastian Koppelmann ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1); 294d5de7839SBastian Koppelmann 295d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 296d5de7839SBastian Koppelmann } 297d5de7839SBastian Koppelmann 2980974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1, 2990974257eSBastian Koppelmann target_ulong r2) 3000974257eSBastian Koppelmann { 3010974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 3020974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 3030974257eSBastian Koppelmann int64_t result; 3040974257eSBastian Koppelmann 3050974257eSBastian Koppelmann if (t1 > t2) { 3060974257eSBastian Koppelmann result = t1 - t2; 3070974257eSBastian Koppelmann } else { 3080974257eSBastian Koppelmann result = t2 - t1; 3090974257eSBastian Koppelmann } 310e4e39176SBastian Koppelmann return ssov32(env, result); 3110974257eSBastian Koppelmann } 312328f1f0fSBastian Koppelmann 313d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1, 314d5de7839SBastian Koppelmann target_ulong r2) 315d5de7839SBastian Koppelmann { 316d5de7839SBastian Koppelmann int32_t t1, t2; 317d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 318d5de7839SBastian Koppelmann 319d5de7839SBastian Koppelmann t1 = sextract32(r1, 0, 16); 320d5de7839SBastian Koppelmann t2 = sextract32(r2, 0, 16); 321d5de7839SBastian Koppelmann if (t1 > t2) { 322d5de7839SBastian Koppelmann ret_h0 = t1 - t2; 323d5de7839SBastian Koppelmann } else { 324d5de7839SBastian Koppelmann ret_h0 = t2 - t1; 325d5de7839SBastian Koppelmann } 326d5de7839SBastian Koppelmann 327d5de7839SBastian Koppelmann t1 = sextract32(r1, 16, 16); 328d5de7839SBastian Koppelmann t2 = sextract32(r2, 16, 16); 329d5de7839SBastian Koppelmann if (t1 > t2) { 330d5de7839SBastian Koppelmann ret_h1 = t1 - t2; 331d5de7839SBastian Koppelmann } else { 332d5de7839SBastian Koppelmann ret_h1 = t2 - t1; 333d5de7839SBastian Koppelmann } 334d5de7839SBastian Koppelmann 335d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 336d5de7839SBastian Koppelmann } 337d5de7839SBastian Koppelmann 338328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1, 339328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 340328f1f0fSBastian Koppelmann { 341328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 342328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 343328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 344328f1f0fSBastian Koppelmann int64_t result; 345328f1f0fSBastian Koppelmann 346328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 347e4e39176SBastian Koppelmann return ssov32(env, result); 348328f1f0fSBastian Koppelmann } 349328f1f0fSBastian Koppelmann 350328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1, 351328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 352328f1f0fSBastian Koppelmann { 353328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 354328f1f0fSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 355328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 356328f1f0fSBastian Koppelmann int64_t result; 357328f1f0fSBastian Koppelmann 358328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 359e4e39176SBastian Koppelmann return suov32(env, result); 360328f1f0fSBastian Koppelmann } 361328f1f0fSBastian Koppelmann 362328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1, 363328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 364328f1f0fSBastian Koppelmann { 365328f1f0fSBastian Koppelmann uint64_t ret, ovf; 366328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 367328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 368328f1f0fSBastian Koppelmann int64_t mul; 369328f1f0fSBastian Koppelmann 370328f1f0fSBastian Koppelmann mul = t1 * t3; 371328f1f0fSBastian Koppelmann ret = mul + r2; 372328f1f0fSBastian Koppelmann ovf = (ret ^ mul) & ~(mul ^ r2); 373328f1f0fSBastian Koppelmann 374811ea608SBastian Koppelmann t1 = ret >> 32; 375811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 376811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 377811ea608SBastian Koppelmann 378328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 379328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 380328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 381328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 382328f1f0fSBastian Koppelmann if (mul >= 0) { 383328f1f0fSBastian Koppelmann ret = INT64_MAX; 384328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 385328f1f0fSBastian Koppelmann } else { 386328f1f0fSBastian Koppelmann ret = INT64_MIN; 387328f1f0fSBastian Koppelmann } 388328f1f0fSBastian Koppelmann } else { 389328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 390328f1f0fSBastian Koppelmann } 391328f1f0fSBastian Koppelmann 392328f1f0fSBastian Koppelmann return ret; 393328f1f0fSBastian Koppelmann } 394328f1f0fSBastian Koppelmann 395328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1, 396328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 397328f1f0fSBastian Koppelmann { 398328f1f0fSBastian Koppelmann uint64_t ret, mul; 399328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 400328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 401328f1f0fSBastian Koppelmann 402328f1f0fSBastian Koppelmann mul = t1 * t3; 403328f1f0fSBastian Koppelmann ret = mul + r2; 404328f1f0fSBastian Koppelmann 405811ea608SBastian Koppelmann t1 = ret >> 32; 406811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 407811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 408811ea608SBastian Koppelmann 409328f1f0fSBastian Koppelmann if (ret < r2) { 410328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 411328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 412328f1f0fSBastian Koppelmann /* saturate */ 413328f1f0fSBastian Koppelmann ret = UINT64_MAX; 414328f1f0fSBastian Koppelmann } else { 415328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 416328f1f0fSBastian Koppelmann } 417328f1f0fSBastian Koppelmann return ret; 418328f1f0fSBastian Koppelmann } 419328f1f0fSBastian Koppelmann 420328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1, 421328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 422328f1f0fSBastian Koppelmann { 423328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 424328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 425328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 426328f1f0fSBastian Koppelmann int64_t result; 427328f1f0fSBastian Koppelmann 428328f1f0fSBastian Koppelmann result = t2 - (t1 * t3); 429e4e39176SBastian Koppelmann return ssov32(env, result); 430328f1f0fSBastian Koppelmann } 431328f1f0fSBastian Koppelmann 432328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1, 433328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 434328f1f0fSBastian Koppelmann { 435328f1f0fSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 436328f1f0fSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 437328f1f0fSBastian Koppelmann int64_t t3 = extract64(r3, 0, 32); 438328f1f0fSBastian Koppelmann int64_t result; 439328f1f0fSBastian Koppelmann 440328f1f0fSBastian Koppelmann result = t2 - (t1 * t3); 441e4e39176SBastian Koppelmann return suov32(env, result); 442328f1f0fSBastian Koppelmann } 443328f1f0fSBastian Koppelmann 444328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1, 445328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 446328f1f0fSBastian Koppelmann { 447328f1f0fSBastian Koppelmann uint64_t ret, ovf; 448328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 449328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 450328f1f0fSBastian Koppelmann int64_t mul; 451328f1f0fSBastian Koppelmann 452328f1f0fSBastian Koppelmann mul = t1 * t3; 453328f1f0fSBastian Koppelmann ret = r2 - mul; 454328f1f0fSBastian Koppelmann ovf = (ret ^ r2) & (mul ^ r2); 455328f1f0fSBastian Koppelmann 456811ea608SBastian Koppelmann t1 = ret >> 32; 457811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 458811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 459811ea608SBastian Koppelmann 460328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 461328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 462328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 463328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 464328f1f0fSBastian Koppelmann if (mul < 0) { 465328f1f0fSBastian Koppelmann ret = INT64_MAX; 466328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 467328f1f0fSBastian Koppelmann } else { 468328f1f0fSBastian Koppelmann ret = INT64_MIN; 469328f1f0fSBastian Koppelmann } 470328f1f0fSBastian Koppelmann } else { 471328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 472328f1f0fSBastian Koppelmann } 473328f1f0fSBastian Koppelmann return ret; 474328f1f0fSBastian Koppelmann } 475328f1f0fSBastian Koppelmann 476328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1, 477328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 478328f1f0fSBastian Koppelmann { 479328f1f0fSBastian Koppelmann uint64_t ret, mul; 480328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 481328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 482328f1f0fSBastian Koppelmann 483328f1f0fSBastian Koppelmann mul = t1 * t3; 484328f1f0fSBastian Koppelmann ret = r2 - mul; 485328f1f0fSBastian Koppelmann 486811ea608SBastian Koppelmann t1 = ret >> 32; 487811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 488811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 489811ea608SBastian Koppelmann 490328f1f0fSBastian Koppelmann if (ret > r2) { 491328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 492328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 493328f1f0fSBastian Koppelmann /* saturate */ 494328f1f0fSBastian Koppelmann ret = 0; 495328f1f0fSBastian Koppelmann } else { 496328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 497328f1f0fSBastian Koppelmann } 498328f1f0fSBastian Koppelmann return ret; 499328f1f0fSBastian Koppelmann } 500328f1f0fSBastian Koppelmann 501d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg) 502d5de7839SBastian Koppelmann { 503d5de7839SBastian Koppelmann int32_t b, i; 504d5de7839SBastian Koppelmann int32_t ovf = 0; 505d5de7839SBastian Koppelmann int32_t avf = 0; 506d5de7839SBastian Koppelmann int32_t ret = 0; 507d5de7839SBastian Koppelmann 508d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 509d5de7839SBastian Koppelmann b = sextract32(arg, i * 8, 8); 510d5de7839SBastian Koppelmann b = (b >= 0) ? b : (0 - b); 511d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 512d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 513d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 514d5de7839SBastian Koppelmann } 515d5de7839SBastian Koppelmann 516d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 517d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 518d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 519d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 520d5de7839SBastian Koppelmann 521d5de7839SBastian Koppelmann return ret; 522d5de7839SBastian Koppelmann } 523d5de7839SBastian Koppelmann 524d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg) 525d5de7839SBastian Koppelmann { 526d5de7839SBastian Koppelmann int32_t h, i; 527d5de7839SBastian Koppelmann int32_t ovf = 0; 528d5de7839SBastian Koppelmann int32_t avf = 0; 529d5de7839SBastian Koppelmann int32_t ret = 0; 530d5de7839SBastian Koppelmann 531d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 532d5de7839SBastian Koppelmann h = sextract32(arg, i * 16, 16); 533d5de7839SBastian Koppelmann h = (h >= 0) ? h : (0 - h); 534d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 535d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 536d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 537d5de7839SBastian Koppelmann } 538d5de7839SBastian Koppelmann 539d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 540d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 541d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 542d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 543d5de7839SBastian Koppelmann 544d5de7839SBastian Koppelmann return ret; 545d5de7839SBastian Koppelmann } 546d5de7839SBastian Koppelmann 547d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 548d5de7839SBastian Koppelmann { 549d5de7839SBastian Koppelmann int32_t b, i; 550d5de7839SBastian Koppelmann int32_t extr_r2; 551d5de7839SBastian Koppelmann int32_t ovf = 0; 552d5de7839SBastian Koppelmann int32_t avf = 0; 553d5de7839SBastian Koppelmann int32_t ret = 0; 554d5de7839SBastian Koppelmann 555d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 556d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 557d5de7839SBastian Koppelmann b = sextract32(r1, i * 8, 8); 558d5de7839SBastian Koppelmann b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b); 559d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 560d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 561d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 562d5de7839SBastian Koppelmann } 563d5de7839SBastian Koppelmann 564d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 565d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 566d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 567d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 568d5de7839SBastian Koppelmann return ret; 569d5de7839SBastian Koppelmann } 570d5de7839SBastian Koppelmann 571d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 572d5de7839SBastian Koppelmann { 573d5de7839SBastian Koppelmann int32_t h, i; 574d5de7839SBastian Koppelmann int32_t extr_r2; 575d5de7839SBastian Koppelmann int32_t ovf = 0; 576d5de7839SBastian Koppelmann int32_t avf = 0; 577d5de7839SBastian Koppelmann int32_t ret = 0; 578d5de7839SBastian Koppelmann 579d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 580d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 581d5de7839SBastian Koppelmann h = sextract32(r1, i * 16, 16); 582d5de7839SBastian Koppelmann h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h); 583d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 584d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 585d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 586d5de7839SBastian Koppelmann } 587d5de7839SBastian Koppelmann 588d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 589d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 590d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 591d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 592d5de7839SBastian Koppelmann 593d5de7839SBastian Koppelmann return ret; 594d5de7839SBastian Koppelmann } 595d5de7839SBastian Koppelmann 596d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 597d5de7839SBastian Koppelmann { 598d5de7839SBastian Koppelmann int32_t b, i; 599d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 600d5de7839SBastian Koppelmann int32_t ovf = 0; 601d5de7839SBastian Koppelmann int32_t avf = 0; 602d5de7839SBastian Koppelmann uint32_t ret = 0; 603d5de7839SBastian Koppelmann 604d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 605d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 606d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 607d5de7839SBastian Koppelmann 608d5de7839SBastian Koppelmann b = extr_r1 + extr_r2; 609d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 610d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 611d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 612d5de7839SBastian Koppelmann } 613d5de7839SBastian Koppelmann 614d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 615d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 616d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 617d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 618d5de7839SBastian Koppelmann 619d5de7839SBastian Koppelmann return ret; 620d5de7839SBastian Koppelmann } 621d5de7839SBastian Koppelmann 622d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 623d5de7839SBastian Koppelmann { 624d5de7839SBastian Koppelmann int32_t h, i; 625d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 626d5de7839SBastian Koppelmann int32_t ovf = 0; 627d5de7839SBastian Koppelmann int32_t avf = 0; 628d5de7839SBastian Koppelmann int32_t ret = 0; 629d5de7839SBastian Koppelmann 630d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 631d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 632d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 633d5de7839SBastian Koppelmann h = extr_r1 + extr_r2; 634d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 635d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 636d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 637d5de7839SBastian Koppelmann } 638d5de7839SBastian Koppelmann 639d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 640d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 641d5de7839SBastian Koppelmann env->PSW_USB_AV = (avf << 16); 642d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 643d5de7839SBastian Koppelmann 644d5de7839SBastian Koppelmann return ret; 645d5de7839SBastian Koppelmann } 646d5de7839SBastian Koppelmann 647d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 648d5de7839SBastian Koppelmann { 649d5de7839SBastian Koppelmann int32_t b, i; 650d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 651d5de7839SBastian Koppelmann int32_t ovf = 0; 652d5de7839SBastian Koppelmann int32_t avf = 0; 653d5de7839SBastian Koppelmann uint32_t ret = 0; 654d5de7839SBastian Koppelmann 655d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 656d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 657d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 658d5de7839SBastian Koppelmann 659d5de7839SBastian Koppelmann b = extr_r1 - extr_r2; 660d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 661d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 662d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 663d5de7839SBastian Koppelmann } 664d5de7839SBastian Koppelmann 665d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 666d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 667d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 668d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 669d5de7839SBastian Koppelmann 670d5de7839SBastian Koppelmann return ret; 671d5de7839SBastian Koppelmann } 672d5de7839SBastian Koppelmann 673d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 674d5de7839SBastian Koppelmann { 675d5de7839SBastian Koppelmann int32_t h, i; 676d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 677d5de7839SBastian Koppelmann int32_t ovf = 0; 678d5de7839SBastian Koppelmann int32_t avf = 0; 679d5de7839SBastian Koppelmann int32_t ret = 0; 680d5de7839SBastian Koppelmann 681d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 682d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 683d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 684d5de7839SBastian Koppelmann h = extr_r1 - extr_r2; 685d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 686d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 687d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 688d5de7839SBastian Koppelmann } 689d5de7839SBastian Koppelmann 690d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 691d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 692d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 693d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 694d5de7839SBastian Koppelmann 695d5de7839SBastian Koppelmann return ret; 696d5de7839SBastian Koppelmann } 697d5de7839SBastian Koppelmann 698d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2) 699d5de7839SBastian Koppelmann { 700d5de7839SBastian Koppelmann int32_t ret; 701d5de7839SBastian Koppelmann int32_t i, msk; 702d5de7839SBastian Koppelmann 703d5de7839SBastian Koppelmann ret = 0; 704d5de7839SBastian Koppelmann msk = 0xff; 705d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 706d5de7839SBastian Koppelmann if ((r1 & msk) == (r2 & msk)) { 707d5de7839SBastian Koppelmann ret |= msk; 708d5de7839SBastian Koppelmann } 709d5de7839SBastian Koppelmann msk = msk << 8; 710d5de7839SBastian Koppelmann } 711d5de7839SBastian Koppelmann 712d5de7839SBastian Koppelmann return ret; 713d5de7839SBastian Koppelmann } 714d5de7839SBastian Koppelmann 715d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2) 716d5de7839SBastian Koppelmann { 717d5de7839SBastian Koppelmann int32_t ret = 0; 718d5de7839SBastian Koppelmann 719d5de7839SBastian Koppelmann if ((r1 & 0xffff) == (r2 & 0xffff)) { 720d5de7839SBastian Koppelmann ret = 0xffff; 721d5de7839SBastian Koppelmann } 722d5de7839SBastian Koppelmann 723d5de7839SBastian Koppelmann if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) { 724d5de7839SBastian Koppelmann ret |= 0xffff0000; 725d5de7839SBastian Koppelmann } 726d5de7839SBastian Koppelmann 727d5de7839SBastian Koppelmann return ret; 728d5de7839SBastian Koppelmann } 729d5de7839SBastian Koppelmann 730d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2) 731d5de7839SBastian Koppelmann { 732d5de7839SBastian Koppelmann int32_t i; 733d5de7839SBastian Koppelmann uint32_t ret = 0; 734d5de7839SBastian Koppelmann 735d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 736d5de7839SBastian Koppelmann ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8)); 737d5de7839SBastian Koppelmann } 738d5de7839SBastian Koppelmann 739d5de7839SBastian Koppelmann return ret; 740d5de7839SBastian Koppelmann } 741d5de7839SBastian Koppelmann 742d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2) 743d5de7839SBastian Koppelmann { 744d5de7839SBastian Koppelmann uint32_t ret; 745d5de7839SBastian Koppelmann 746d5de7839SBastian Koppelmann ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16)); 747d5de7839SBastian Koppelmann ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16)); 748d5de7839SBastian Koppelmann 749d5de7839SBastian Koppelmann return ret; 750d5de7839SBastian Koppelmann } 751d5de7839SBastian Koppelmann 752d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2) 753d5de7839SBastian Koppelmann { 754d5de7839SBastian Koppelmann int32_t i; 755d5de7839SBastian Koppelmann uint32_t ret = 0; 756d5de7839SBastian Koppelmann 757d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 758d5de7839SBastian Koppelmann if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) { 759d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 760d5de7839SBastian Koppelmann } 761d5de7839SBastian Koppelmann } 762d5de7839SBastian Koppelmann 763d5de7839SBastian Koppelmann return ret; 764d5de7839SBastian Koppelmann } 765d5de7839SBastian Koppelmann 766d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2) 767d5de7839SBastian Koppelmann { 768d5de7839SBastian Koppelmann int32_t i; 769d5de7839SBastian Koppelmann uint32_t ret = 0; 770d5de7839SBastian Koppelmann 771d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 772d5de7839SBastian Koppelmann if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) { 773d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 774d5de7839SBastian Koppelmann } 775d5de7839SBastian Koppelmann } 776d5de7839SBastian Koppelmann 777d5de7839SBastian Koppelmann return ret; 778d5de7839SBastian Koppelmann } 779d5de7839SBastian Koppelmann 780d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2) 781d5de7839SBastian Koppelmann { 782d5de7839SBastian Koppelmann uint32_t ret = 0; 783d5de7839SBastian Koppelmann 784d5de7839SBastian Koppelmann if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) { 785d5de7839SBastian Koppelmann ret |= 0xffff; 786d5de7839SBastian Koppelmann } 787d5de7839SBastian Koppelmann 788d5de7839SBastian Koppelmann if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) { 789d5de7839SBastian Koppelmann ret |= 0xffff0000; 790d5de7839SBastian Koppelmann } 791d5de7839SBastian Koppelmann 792d5de7839SBastian Koppelmann return ret; 793d5de7839SBastian Koppelmann } 794d5de7839SBastian Koppelmann 795d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2) 796d5de7839SBastian Koppelmann { 797d5de7839SBastian Koppelmann uint32_t ret = 0; 798d5de7839SBastian Koppelmann 799d5de7839SBastian Koppelmann if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) { 800d5de7839SBastian Koppelmann ret |= 0xffff; 801d5de7839SBastian Koppelmann } 802d5de7839SBastian Koppelmann 803d5de7839SBastian Koppelmann if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) { 804d5de7839SBastian Koppelmann ret |= 0xffff0000; 805d5de7839SBastian Koppelmann } 806d5de7839SBastian Koppelmann 807d5de7839SBastian Koppelmann return ret; 808d5de7839SBastian Koppelmann } 809d5de7839SBastian Koppelmann 810d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op) \ 811d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \ 812d5de7839SBastian Koppelmann { \ 813d5de7839SBastian Koppelmann int32_t i, extr_r1, extr_r2; \ 814d5de7839SBastian Koppelmann uint32_t ret = 0; \ 815d5de7839SBastian Koppelmann \ 816d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 817d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); \ 818d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); \ 819d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 820d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 821d5de7839SBastian Koppelmann } \ 822d5de7839SBastian Koppelmann return ret; \ 823d5de7839SBastian Koppelmann } \ 824d5de7839SBastian Koppelmann \ 825d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\ 826d5de7839SBastian Koppelmann { \ 827d5de7839SBastian Koppelmann int32_t i; \ 828d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 829d5de7839SBastian Koppelmann uint32_t ret = 0; \ 830d5de7839SBastian Koppelmann \ 831d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 832d5de7839SBastian Koppelmann extr_r1 = extract32(r1, i * 8, 8); \ 833d5de7839SBastian Koppelmann extr_r2 = extract32(r2, i * 8, 8); \ 834d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 835d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 836d5de7839SBastian Koppelmann } \ 837d5de7839SBastian Koppelmann return ret; \ 838d5de7839SBastian Koppelmann } \ 839d5de7839SBastian Koppelmann \ 840d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \ 841d5de7839SBastian Koppelmann { \ 842d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; \ 843d5de7839SBastian Koppelmann uint32_t ret = 0; \ 844d5de7839SBastian Koppelmann \ 845d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 0, 16); \ 846d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 0, 16); \ 847d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 848d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 849d5de7839SBastian Koppelmann \ 850d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 16, 16); \ 851d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 16, 16); \ 852d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 853d5de7839SBastian Koppelmann ret |= extr_r1 << 16; \ 854d5de7839SBastian Koppelmann \ 855d5de7839SBastian Koppelmann return ret; \ 856d5de7839SBastian Koppelmann } \ 857d5de7839SBastian Koppelmann \ 858d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\ 859d5de7839SBastian Koppelmann { \ 860d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 861d5de7839SBastian Koppelmann uint32_t ret = 0; \ 862d5de7839SBastian Koppelmann \ 863d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 0, 16); \ 864d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 0, 16); \ 865d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 866d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 867d5de7839SBastian Koppelmann \ 868d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 16, 16); \ 869d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 16, 16); \ 870d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 871d5de7839SBastian Koppelmann ret |= extr_r1 << (16); \ 872d5de7839SBastian Koppelmann \ 873d5de7839SBastian Koppelmann return ret; \ 874d5de7839SBastian Koppelmann } \ 875d5de7839SBastian Koppelmann 876d5de7839SBastian Koppelmann EXTREMA_H_B(max, >) 877d5de7839SBastian Koppelmann EXTREMA_H_B(min, <) 878d5de7839SBastian Koppelmann 879d5de7839SBastian Koppelmann #undef EXTREMA_H_B 880d5de7839SBastian Koppelmann 8810b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1) 8820b79a781SBastian Koppelmann { 8830b79a781SBastian Koppelmann return clo32(r1); 8840b79a781SBastian Koppelmann } 8850b79a781SBastian Koppelmann 8860b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1) 8870b79a781SBastian Koppelmann { 8880b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 8890b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 8900b79a781SBastian Koppelmann 8910b79a781SBastian Koppelmann ret_hw0 = clo32(ret_hw0 << 16); 8920b79a781SBastian Koppelmann ret_hw1 = clo32(ret_hw1 << 16); 8930b79a781SBastian Koppelmann 8940b79a781SBastian Koppelmann if (ret_hw0 > 16) { 8950b79a781SBastian Koppelmann ret_hw0 = 16; 8960b79a781SBastian Koppelmann } 8970b79a781SBastian Koppelmann if (ret_hw1 > 16) { 8980b79a781SBastian Koppelmann ret_hw1 = 16; 8990b79a781SBastian Koppelmann } 9000b79a781SBastian Koppelmann 9010b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 9020b79a781SBastian Koppelmann } 9030b79a781SBastian Koppelmann 9040b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1) 9050b79a781SBastian Koppelmann { 9060b79a781SBastian Koppelmann return clz32(r1); 9070b79a781SBastian Koppelmann } 9080b79a781SBastian Koppelmann 9090b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1) 9100b79a781SBastian Koppelmann { 9110b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 9120b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 9130b79a781SBastian Koppelmann 9140b79a781SBastian Koppelmann ret_hw0 = clz32(ret_hw0 << 16); 9150b79a781SBastian Koppelmann ret_hw1 = clz32(ret_hw1 << 16); 9160b79a781SBastian Koppelmann 9170b79a781SBastian Koppelmann if (ret_hw0 > 16) { 9180b79a781SBastian Koppelmann ret_hw0 = 16; 9190b79a781SBastian Koppelmann } 9200b79a781SBastian Koppelmann if (ret_hw1 > 16) { 9210b79a781SBastian Koppelmann ret_hw1 = 16; 9220b79a781SBastian Koppelmann } 9230b79a781SBastian Koppelmann 9240b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 9250b79a781SBastian Koppelmann } 9260b79a781SBastian Koppelmann 9270b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1) 9280b79a781SBastian Koppelmann { 9290b79a781SBastian Koppelmann return clrsb32(r1); 9300b79a781SBastian Koppelmann } 9310b79a781SBastian Koppelmann 9320b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1) 9330b79a781SBastian Koppelmann { 9340b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 9350b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 9360b79a781SBastian Koppelmann 9370b79a781SBastian Koppelmann ret_hw0 = clrsb32(ret_hw0 << 16); 9380b79a781SBastian Koppelmann ret_hw1 = clrsb32(ret_hw1 << 16); 9390b79a781SBastian Koppelmann 9400b79a781SBastian Koppelmann if (ret_hw0 > 15) { 9410b79a781SBastian Koppelmann ret_hw0 = 15; 9420b79a781SBastian Koppelmann } 9430b79a781SBastian Koppelmann if (ret_hw1 > 15) { 9440b79a781SBastian Koppelmann ret_hw1 = 15; 9450b79a781SBastian Koppelmann } 9460b79a781SBastian Koppelmann 9470b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 9480b79a781SBastian Koppelmann } 9490b79a781SBastian Koppelmann 9500b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2) 9510b79a781SBastian Koppelmann { 9520b79a781SBastian Koppelmann int32_t shift_count = sextract32(r2, 0, 6); 9530b79a781SBastian Koppelmann 9540b79a781SBastian Koppelmann if (shift_count == -32) { 9550b79a781SBastian Koppelmann return 0; 9560b79a781SBastian Koppelmann } else if (shift_count < 0) { 9570b79a781SBastian Koppelmann return r1 >> -shift_count; 9580b79a781SBastian Koppelmann } else { 9590b79a781SBastian Koppelmann return r1 << shift_count; 9600b79a781SBastian Koppelmann } 9610b79a781SBastian Koppelmann } 9620b79a781SBastian Koppelmann 9630b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2) 9640b79a781SBastian Koppelmann { 9650b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 9660b79a781SBastian Koppelmann int32_t shift_count; 9670b79a781SBastian Koppelmann 9680b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 9690b79a781SBastian Koppelmann 9700b79a781SBastian Koppelmann if (shift_count == -16) { 9710b79a781SBastian Koppelmann return 0; 9720b79a781SBastian Koppelmann } else if (shift_count < 0) { 9730b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) >> -shift_count; 9740b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) >> -shift_count; 9750b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 9760b79a781SBastian Koppelmann } else { 9770b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) << shift_count; 9780b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) << shift_count; 9790b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 9800b79a781SBastian Koppelmann } 9810b79a781SBastian Koppelmann } 9820b79a781SBastian Koppelmann 9830b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 9840b79a781SBastian Koppelmann { 9850b79a781SBastian Koppelmann int32_t shift_count; 9860b79a781SBastian Koppelmann int64_t result, t1; 9870b79a781SBastian Koppelmann uint32_t ret; 9880b79a781SBastian Koppelmann 9890b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 6); 9900b79a781SBastian Koppelmann t1 = sextract32(r1, 0, 32); 9910b79a781SBastian Koppelmann 9920b79a781SBastian Koppelmann if (shift_count == 0) { 9930b79a781SBastian Koppelmann env->PSW_USB_C = env->PSW_USB_V = 0; 9940b79a781SBastian Koppelmann ret = r1; 9950b79a781SBastian Koppelmann } else if (shift_count == -32) { 9960b79a781SBastian Koppelmann env->PSW_USB_C = r1; 9970b79a781SBastian Koppelmann env->PSW_USB_V = 0; 9980b79a781SBastian Koppelmann ret = t1 >> 31; 9990b79a781SBastian Koppelmann } else if (shift_count > 0) { 10000b79a781SBastian Koppelmann result = t1 << shift_count; 10010b79a781SBastian Koppelmann /* calc carry */ 1002452e3d49SPeter Maydell env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0); 10030b79a781SBastian Koppelmann /* calc v */ 10040b79a781SBastian Koppelmann env->PSW_USB_V = (((result > 0x7fffffffLL) || 10050b79a781SBastian Koppelmann (result < -0x80000000LL)) << 31); 10060b79a781SBastian Koppelmann /* calc sv */ 10070b79a781SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 10080b79a781SBastian Koppelmann ret = (uint32_t)result; 10090b79a781SBastian Koppelmann } else { 10100b79a781SBastian Koppelmann env->PSW_USB_V = 0; 10110b79a781SBastian Koppelmann env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1)); 10120b79a781SBastian Koppelmann ret = t1 >> -shift_count; 10130b79a781SBastian Koppelmann } 10140b79a781SBastian Koppelmann 10150b79a781SBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 10160b79a781SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 10170b79a781SBastian Koppelmann 10180b79a781SBastian Koppelmann return ret; 10190b79a781SBastian Koppelmann } 10200b79a781SBastian Koppelmann 10210b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2) 10220b79a781SBastian Koppelmann { 10230b79a781SBastian Koppelmann int32_t shift_count; 10240b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 10250b79a781SBastian Koppelmann 10260b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 10270b79a781SBastian Koppelmann 10280b79a781SBastian Koppelmann if (shift_count == 0) { 10290b79a781SBastian Koppelmann return r1; 10300b79a781SBastian Koppelmann } else if (shift_count < 0) { 10310b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) >> -shift_count; 10320b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) >> -shift_count; 10330b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 10340b79a781SBastian Koppelmann } else { 10350b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) << shift_count; 10360b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) << shift_count; 10370b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 10380b79a781SBastian Koppelmann } 10390b79a781SBastian Koppelmann } 10400b79a781SBastian Koppelmann 1041e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2) 1042e2bed107SBastian Koppelmann { 1043e2bed107SBastian Koppelmann uint32_t i, ret; 1044e2bed107SBastian Koppelmann 1045e2bed107SBastian Koppelmann ret = 0; 1046e2bed107SBastian Koppelmann for (i = 0; i < 16; i++) { 1047e2bed107SBastian Koppelmann ret |= (r1 & 1) << (2 * i + 1); 1048e2bed107SBastian Koppelmann ret |= (r2 & 1) << (2 * i); 1049e2bed107SBastian Koppelmann r1 = r1 >> 1; 1050e2bed107SBastian Koppelmann r2 = r2 >> 1; 1051e2bed107SBastian Koppelmann } 1052e2bed107SBastian Koppelmann return ret; 1053e2bed107SBastian Koppelmann } 1054e2bed107SBastian Koppelmann 1055e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1) 1056e2bed107SBastian Koppelmann { 1057e2bed107SBastian Koppelmann int32_t i; 1058e2bed107SBastian Koppelmann uint64_t ret; 1059e2bed107SBastian Koppelmann 1060e2bed107SBastian Koppelmann ret = 0; 1061e2bed107SBastian Koppelmann for (i = 0; i < 32; i = i + 2) { 1062e2bed107SBastian Koppelmann /* even */ 1063e2bed107SBastian Koppelmann ret |= (r1 & 1) << (i/2); 1064e2bed107SBastian Koppelmann r1 = r1 >> 1; 1065e2bed107SBastian Koppelmann /* odd */ 1066e2bed107SBastian Koppelmann ret |= (uint64_t)(r1 & 1) << (i/2 + 32); 1067e2bed107SBastian Koppelmann r1 = r1 >> 1; 1068e2bed107SBastian Koppelmann } 1069e2bed107SBastian Koppelmann return ret; 1070e2bed107SBastian Koppelmann } 1071e2bed107SBastian Koppelmann 1072e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1) 1073e2bed107SBastian Koppelmann { 1074e2bed107SBastian Koppelmann uint32_t ret; 1075e2bed107SBastian Koppelmann uint32_t nOnes, i; 1076e2bed107SBastian Koppelmann 1077e2bed107SBastian Koppelmann ret = 0; 1078e2bed107SBastian Koppelmann nOnes = 0; 1079e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1080e2bed107SBastian Koppelmann ret ^= (r1 & 1); 1081e2bed107SBastian Koppelmann r1 = r1 >> 1; 1082e2bed107SBastian Koppelmann } 1083e2bed107SBastian Koppelmann /* second byte */ 1084e2bed107SBastian Koppelmann nOnes = 0; 1085e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1086e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1087e2bed107SBastian Koppelmann r1 = r1 >> 1; 1088e2bed107SBastian Koppelmann } 1089e2bed107SBastian Koppelmann ret |= nOnes << 8; 1090e2bed107SBastian Koppelmann /* third byte */ 1091e2bed107SBastian Koppelmann nOnes = 0; 1092e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1093e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1094e2bed107SBastian Koppelmann r1 = r1 >> 1; 1095e2bed107SBastian Koppelmann } 1096e2bed107SBastian Koppelmann ret |= nOnes << 16; 1097e2bed107SBastian Koppelmann /* fourth byte */ 1098e2bed107SBastian Koppelmann nOnes = 0; 1099e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1100e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1101e2bed107SBastian Koppelmann r1 = r1 >> 1; 1102e2bed107SBastian Koppelmann } 1103e2bed107SBastian Koppelmann ret |= nOnes << 24; 1104e2bed107SBastian Koppelmann 1105e2bed107SBastian Koppelmann return ret; 1106e2bed107SBastian Koppelmann } 1107e2bed107SBastian Koppelmann 1108e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1) 1109e2bed107SBastian Koppelmann { 1110e2bed107SBastian Koppelmann int32_t fp_exp = extract32(arg1, 23, 8); 1111e2bed107SBastian Koppelmann int32_t fp_frac = extract32(arg1, 0, 23); 1112e2bed107SBastian Koppelmann uint64_t ret; 1113e2bed107SBastian Koppelmann int32_t int_exp, int_mant; 1114e2bed107SBastian Koppelmann 1115e2bed107SBastian Koppelmann if (fp_exp == 255) { 1116e2bed107SBastian Koppelmann int_exp = 255; 1117e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1118e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac == 0)) { 1119e2bed107SBastian Koppelmann int_exp = -127; 1120e2bed107SBastian Koppelmann int_mant = 0; 1121e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac != 0)) { 1122e2bed107SBastian Koppelmann int_exp = -126; 1123e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1124e2bed107SBastian Koppelmann } else { 1125e2bed107SBastian Koppelmann int_exp = fp_exp - 127; 1126e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1127e2bed107SBastian Koppelmann int_mant |= (1 << 30); 1128e2bed107SBastian Koppelmann } 1129e2bed107SBastian Koppelmann ret = int_exp; 1130e2bed107SBastian Koppelmann ret = ret << 32; 1131e2bed107SBastian Koppelmann ret |= int_mant; 1132e2bed107SBastian Koppelmann 1133e2bed107SBastian Koppelmann return ret; 1134e2bed107SBastian Koppelmann } 1135e2bed107SBastian Koppelmann 1136e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1137e2bed107SBastian Koppelmann { 1138e2bed107SBastian Koppelmann uint64_t ret; 1139e2bed107SBastian Koppelmann int32_t abs_sig_dividend, abs_base_dividend, abs_divisor; 1140e2bed107SBastian Koppelmann int32_t quotient_sign; 1141e2bed107SBastian Koppelmann 1142e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 1143e2bed107SBastian Koppelmann ret = ret << 24; 1144e2bed107SBastian Koppelmann quotient_sign = 0; 1145e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1146e2bed107SBastian Koppelmann ret |= 0xffffff; 1147e2bed107SBastian Koppelmann quotient_sign = 1; 1148e2bed107SBastian Koppelmann } 1149e2bed107SBastian Koppelmann 1150e2bed107SBastian Koppelmann abs_sig_dividend = abs(r1) >> 7; 1151e2bed107SBastian Koppelmann abs_base_dividend = abs(r1) & 0x7f; 1152e2bed107SBastian Koppelmann abs_divisor = abs(r1); 1153e2bed107SBastian Koppelmann /* calc overflow */ 1154e2bed107SBastian Koppelmann env->PSW_USB_V = 0; 1155e2bed107SBastian Koppelmann if ((quotient_sign) && (abs_divisor)) { 1156e2bed107SBastian Koppelmann env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) && 1157e2bed107SBastian Koppelmann (abs_base_dividend >= abs_divisor)) || 1158e2bed107SBastian Koppelmann (abs_sig_dividend > abs_divisor)); 1159e2bed107SBastian Koppelmann } else { 1160e2bed107SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor); 1161e2bed107SBastian Koppelmann } 1162e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1163e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1164e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1165e2bed107SBastian Koppelmann 1166e2bed107SBastian Koppelmann return ret; 1167e2bed107SBastian Koppelmann } 1168e2bed107SBastian Koppelmann 1169e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1170e2bed107SBastian Koppelmann { 1171e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 1172e2bed107SBastian Koppelmann 1173e2bed107SBastian Koppelmann ret = ret << 24; 1174e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1175e2bed107SBastian Koppelmann ret |= 0xffffff; 1176e2bed107SBastian Koppelmann } 1177e2bed107SBastian Koppelmann /* calc overflow */ 1178e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80))); 1179e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1180e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1181e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1182e2bed107SBastian Koppelmann 1183e2bed107SBastian Koppelmann return ret; 1184e2bed107SBastian Koppelmann } 1185e2bed107SBastian Koppelmann 1186e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1187e2bed107SBastian Koppelmann { 1188e2bed107SBastian Koppelmann uint64_t ret; 1189e2bed107SBastian Koppelmann int32_t abs_sig_dividend, abs_base_dividend, abs_divisor; 1190e2bed107SBastian Koppelmann int32_t quotient_sign; 1191e2bed107SBastian Koppelmann 1192e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 1193e2bed107SBastian Koppelmann ret = ret << 16; 1194e2bed107SBastian Koppelmann quotient_sign = 0; 1195e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1196e2bed107SBastian Koppelmann ret |= 0xffff; 1197e2bed107SBastian Koppelmann quotient_sign = 1; 1198e2bed107SBastian Koppelmann } 1199e2bed107SBastian Koppelmann 1200e2bed107SBastian Koppelmann abs_sig_dividend = abs(r1) >> 7; 1201e2bed107SBastian Koppelmann abs_base_dividend = abs(r1) & 0x7f; 1202e2bed107SBastian Koppelmann abs_divisor = abs(r1); 1203e2bed107SBastian Koppelmann /* calc overflow */ 1204e2bed107SBastian Koppelmann env->PSW_USB_V = 0; 1205e2bed107SBastian Koppelmann if ((quotient_sign) && (abs_divisor)) { 1206e2bed107SBastian Koppelmann env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) && 1207e2bed107SBastian Koppelmann (abs_base_dividend >= abs_divisor)) || 1208e2bed107SBastian Koppelmann (abs_sig_dividend > abs_divisor)); 1209e2bed107SBastian Koppelmann } else { 1210e2bed107SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor); 1211e2bed107SBastian Koppelmann } 1212e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1213e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1214e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1215e2bed107SBastian Koppelmann 1216e2bed107SBastian Koppelmann return ret; 1217e2bed107SBastian Koppelmann } 1218e2bed107SBastian Koppelmann 1219e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 1220e2bed107SBastian Koppelmann { 1221e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 1222e2bed107SBastian Koppelmann 1223e2bed107SBastian Koppelmann ret = ret << 16; 1224e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 1225e2bed107SBastian Koppelmann ret |= 0xffff; 1226e2bed107SBastian Koppelmann } 1227e2bed107SBastian Koppelmann /* calc overflow */ 1228e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000))); 1229e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 1230e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1231e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 1232e2bed107SBastian Koppelmann 1233e2bed107SBastian Koppelmann return ret; 1234e2bed107SBastian Koppelmann } 1235e2bed107SBastian Koppelmann 12369655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01, 12379655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 12389655b932SBastian Koppelmann { 12399655b932SBastian Koppelmann uint64_t ret; 12409655b932SBastian Koppelmann uint32_t result0, result1; 12419655b932SBastian Koppelmann 12429655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 12439655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 12449655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 12459655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 12469655b932SBastian Koppelmann if (sc1) { 12479655b932SBastian Koppelmann result1 = 0x7fffffff; 12489655b932SBastian Koppelmann } else { 12499655b932SBastian Koppelmann result1 = (((uint32_t)(arg00 * arg10)) << n); 12509655b932SBastian Koppelmann } 12519655b932SBastian Koppelmann if (sc0) { 12529655b932SBastian Koppelmann result0 = 0x7fffffff; 12539655b932SBastian Koppelmann } else { 12549655b932SBastian Koppelmann result0 = (((uint32_t)(arg01 * arg11)) << n); 12559655b932SBastian Koppelmann } 12569655b932SBastian Koppelmann ret = (((uint64_t)result1 << 32)) | result0; 12579655b932SBastian Koppelmann return ret; 12589655b932SBastian Koppelmann } 12599655b932SBastian Koppelmann 12609655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01, 12619655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 12629655b932SBastian Koppelmann { 12639655b932SBastian Koppelmann uint64_t ret; 12649655b932SBastian Koppelmann int64_t result0, result1; 12659655b932SBastian Koppelmann 12669655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 12679655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 12689655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 12699655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 12709655b932SBastian Koppelmann 12719655b932SBastian Koppelmann if (sc1) { 12729655b932SBastian Koppelmann result1 = 0x7fffffff; 12739655b932SBastian Koppelmann } else { 12749655b932SBastian Koppelmann result1 = (((int32_t)arg00 * (int32_t)arg10) << n); 12759655b932SBastian Koppelmann } 12769655b932SBastian Koppelmann if (sc0) { 12779655b932SBastian Koppelmann result0 = 0x7fffffff; 12789655b932SBastian Koppelmann } else { 12799655b932SBastian Koppelmann result0 = (((int32_t)arg01 * (int32_t)arg11) << n); 12809655b932SBastian Koppelmann } 12819655b932SBastian Koppelmann ret = (result1 + result0); 12829655b932SBastian Koppelmann ret = ret << 16; 12839655b932SBastian Koppelmann return ret; 12849655b932SBastian Koppelmann } 12859655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01, 12869655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 12879655b932SBastian Koppelmann { 12889655b932SBastian Koppelmann uint32_t result0, result1; 12899655b932SBastian Koppelmann 12909655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 12919655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 12929655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 12939655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 12949655b932SBastian Koppelmann 12959655b932SBastian Koppelmann if (sc1) { 12969655b932SBastian Koppelmann result1 = 0x7fffffff; 12979655b932SBastian Koppelmann } else { 12989655b932SBastian Koppelmann result1 = ((arg00 * arg10) << n) + 0x8000; 12999655b932SBastian Koppelmann } 13009655b932SBastian Koppelmann if (sc0) { 13019655b932SBastian Koppelmann result0 = 0x7fffffff; 13029655b932SBastian Koppelmann } else { 13039655b932SBastian Koppelmann result0 = ((arg01 * arg11) << n) + 0x8000; 13049655b932SBastian Koppelmann } 13059655b932SBastian Koppelmann return (result1 & 0xffff0000) | (result0 >> 16); 13069655b932SBastian Koppelmann } 13079655b932SBastian Koppelmann 13089a31922bSBastian Koppelmann /* context save area (CSA) related helpers */ 13099a31922bSBastian Koppelmann 13109a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw) 13119a31922bSBastian Koppelmann { 13129a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 13139a31922bSBastian Koppelmann return 0; 13149a31922bSBastian Koppelmann } 13159a31922bSBastian Koppelmann 13169a31922bSBastian Koppelmann (*psw)++; 13179a31922bSBastian Koppelmann /* check for overflow */ 13189a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 13199a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 13209a31922bSBastian Koppelmann int count = *psw & mask; 13219a31922bSBastian Koppelmann if (count == 0) { 13229a31922bSBastian Koppelmann (*psw)--; 13239a31922bSBastian Koppelmann return 1; 13249a31922bSBastian Koppelmann } 13259a31922bSBastian Koppelmann return 0; 13269a31922bSBastian Koppelmann } 13279a31922bSBastian Koppelmann 13289a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw) 13299a31922bSBastian Koppelmann { 13309a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 13319a31922bSBastian Koppelmann return 0; 13329a31922bSBastian Koppelmann } 13339a31922bSBastian Koppelmann /* check for underflow */ 13349a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 13359a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 13369a31922bSBastian Koppelmann int count = *psw & mask; 13379a31922bSBastian Koppelmann if (count == 0) { 13389a31922bSBastian Koppelmann return 1; 13399a31922bSBastian Koppelmann } 13409a31922bSBastian Koppelmann (*psw)--; 13419a31922bSBastian Koppelmann return 0; 13429a31922bSBastian Koppelmann } 13439a31922bSBastian Koppelmann 134444ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw) 134544ea3430SBastian Koppelmann { 134644ea3430SBastian Koppelmann int cdc = *psw & MASK_PSW_CDC; 134744ea3430SBastian Koppelmann /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC == 134844ea3430SBastian Koppelmann 7'b1111111, otherwise returns FALSE. */ 134944ea3430SBastian Koppelmann if (cdc == 0x7f) { 135044ea3430SBastian Koppelmann return true; 135144ea3430SBastian Koppelmann } 135244ea3430SBastian Koppelmann /* find CDC.COUNT */ 135344ea3430SBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 135444ea3430SBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 135544ea3430SBastian Koppelmann int count = *psw & mask; 135644ea3430SBastian Koppelmann return count == 0; 135744ea3430SBastian Koppelmann } 135844ea3430SBastian Koppelmann 1359030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea) 13609a31922bSBastian Koppelmann { 13619a31922bSBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 13629a31922bSBastian Koppelmann cpu_stl_data(env, ea+4, env->PSW); 13639a31922bSBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[10]); 13649a31922bSBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[11]); 13659a31922bSBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[8]); 13669a31922bSBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[9]); 13679a31922bSBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[10]); 13689a31922bSBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[11]); 13699a31922bSBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[12]); 13709a31922bSBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[13]); 13719a31922bSBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[14]); 13729a31922bSBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[15]); 13739a31922bSBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[12]); 13749a31922bSBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[13]); 13759a31922bSBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[14]); 13769a31922bSBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[15]); 13779a31922bSBastian Koppelmann } 13789a31922bSBastian Koppelmann 1379030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea) 13805de93515SBastian Koppelmann { 13815de93515SBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 1382030c58dfSBastian Koppelmann cpu_stl_data(env, ea+4, env->gpr_a[11]); 13835de93515SBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[2]); 13845de93515SBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[3]); 13855de93515SBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[0]); 13865de93515SBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[1]); 13875de93515SBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[2]); 13885de93515SBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[3]); 13895de93515SBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[4]); 13905de93515SBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[5]); 13915de93515SBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[6]); 13925de93515SBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[7]); 13935de93515SBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[4]); 13945de93515SBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[5]); 13955de93515SBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[6]); 13965de93515SBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[7]); 13975de93515SBastian Koppelmann } 13985de93515SBastian Koppelmann 13999a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea, 14009a31922bSBastian Koppelmann target_ulong *new_PCXI, target_ulong *new_PSW) 14019a31922bSBastian Koppelmann { 14029a31922bSBastian Koppelmann *new_PCXI = cpu_ldl_data(env, ea); 14039a31922bSBastian Koppelmann *new_PSW = cpu_ldl_data(env, ea+4); 14049a31922bSBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, ea+8); 14059a31922bSBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, ea+12); 14069a31922bSBastian Koppelmann env->gpr_d[8] = cpu_ldl_data(env, ea+16); 14079a31922bSBastian Koppelmann env->gpr_d[9] = cpu_ldl_data(env, ea+20); 14089a31922bSBastian Koppelmann env->gpr_d[10] = cpu_ldl_data(env, ea+24); 14099a31922bSBastian Koppelmann env->gpr_d[11] = cpu_ldl_data(env, ea+28); 14109a31922bSBastian Koppelmann env->gpr_a[12] = cpu_ldl_data(env, ea+32); 14119a31922bSBastian Koppelmann env->gpr_a[13] = cpu_ldl_data(env, ea+36); 14129a31922bSBastian Koppelmann env->gpr_a[14] = cpu_ldl_data(env, ea+40); 14139a31922bSBastian Koppelmann env->gpr_a[15] = cpu_ldl_data(env, ea+44); 14149a31922bSBastian Koppelmann env->gpr_d[12] = cpu_ldl_data(env, ea+48); 14159a31922bSBastian Koppelmann env->gpr_d[13] = cpu_ldl_data(env, ea+52); 14169a31922bSBastian Koppelmann env->gpr_d[14] = cpu_ldl_data(env, ea+56); 14179a31922bSBastian Koppelmann env->gpr_d[15] = cpu_ldl_data(env, ea+60); 14189a31922bSBastian Koppelmann } 14199a31922bSBastian Koppelmann 142059543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea, 142159543d4eSBastian Koppelmann target_ulong *ra, target_ulong *pcxi) 142259543d4eSBastian Koppelmann { 142359543d4eSBastian Koppelmann *pcxi = cpu_ldl_data(env, ea); 142459543d4eSBastian Koppelmann *ra = cpu_ldl_data(env, ea+4); 142559543d4eSBastian Koppelmann env->gpr_a[2] = cpu_ldl_data(env, ea+8); 142659543d4eSBastian Koppelmann env->gpr_a[3] = cpu_ldl_data(env, ea+12); 142759543d4eSBastian Koppelmann env->gpr_d[0] = cpu_ldl_data(env, ea+16); 142859543d4eSBastian Koppelmann env->gpr_d[1] = cpu_ldl_data(env, ea+20); 142959543d4eSBastian Koppelmann env->gpr_d[2] = cpu_ldl_data(env, ea+24); 143059543d4eSBastian Koppelmann env->gpr_d[3] = cpu_ldl_data(env, ea+28); 143159543d4eSBastian Koppelmann env->gpr_a[4] = cpu_ldl_data(env, ea+32); 143259543d4eSBastian Koppelmann env->gpr_a[5] = cpu_ldl_data(env, ea+36); 143359543d4eSBastian Koppelmann env->gpr_a[6] = cpu_ldl_data(env, ea+40); 143459543d4eSBastian Koppelmann env->gpr_a[7] = cpu_ldl_data(env, ea+44); 143559543d4eSBastian Koppelmann env->gpr_d[4] = cpu_ldl_data(env, ea+48); 143659543d4eSBastian Koppelmann env->gpr_d[5] = cpu_ldl_data(env, ea+52); 143759543d4eSBastian Koppelmann env->gpr_d[6] = cpu_ldl_data(env, ea+56); 143859543d4eSBastian Koppelmann env->gpr_d[7] = cpu_ldl_data(env, ea+60); 143959543d4eSBastian Koppelmann } 144059543d4eSBastian Koppelmann 14419a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc) 14429a31922bSBastian Koppelmann { 14439a31922bSBastian Koppelmann target_ulong tmp_FCX; 14449a31922bSBastian Koppelmann target_ulong ea; 14459a31922bSBastian Koppelmann target_ulong new_FCX; 14469a31922bSBastian Koppelmann target_ulong psw; 14479a31922bSBastian Koppelmann 14489a31922bSBastian Koppelmann psw = psw_read(env); 14499a31922bSBastian Koppelmann /* if (FCX == 0) trap(FCU); */ 14509a31922bSBastian Koppelmann if (env->FCX == 0) { 14519a31922bSBastian Koppelmann /* FCU trap */ 14529a31922bSBastian Koppelmann } 14539a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */ 14549a31922bSBastian Koppelmann if (psw & MASK_PSW_CDE) { 14559a31922bSBastian Koppelmann if (cdc_increment(&psw)) { 14569a31922bSBastian Koppelmann /* CDO trap */ 14579a31922bSBastian Koppelmann } 14589a31922bSBastian Koppelmann } 14599a31922bSBastian Koppelmann /* PSW.CDE = 1;*/ 14609a31922bSBastian Koppelmann psw |= MASK_PSW_CDE; 14619a31922bSBastian Koppelmann /* tmp_FCX = FCX; */ 14629a31922bSBastian Koppelmann tmp_FCX = env->FCX; 14639a31922bSBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 14649a31922bSBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 14659a31922bSBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 1466030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 1467030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 1468030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 14699a31922bSBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 14709a31922bSBastian Koppelmann D[15]}; */ 1471030c58dfSBastian Koppelmann save_context_upper(env, ea); 14729a31922bSBastian Koppelmann 14739a31922bSBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 14749a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 14759a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 14769a31922bSBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 14779a31922bSBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 14789a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 14799a31922bSBastian Koppelmann /* PCXI.UL = 1; */ 14809a31922bSBastian Koppelmann env->PCXI |= MASK_PCXI_UL; 14819a31922bSBastian Koppelmann 14829a31922bSBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 14839a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 14849a31922bSBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 14859a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 14869a31922bSBastian Koppelmann /* A[11] = next_pc[31: 0]; */ 14879a31922bSBastian Koppelmann env->gpr_a[11] = next_pc; 14889a31922bSBastian Koppelmann 14899a31922bSBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 14909a31922bSBastian Koppelmann if (tmp_FCX == env->LCX) { 14919a31922bSBastian Koppelmann /* FCD trap */ 14929a31922bSBastian Koppelmann } 14939a31922bSBastian Koppelmann psw_write(env, psw); 14949a31922bSBastian Koppelmann } 14959a31922bSBastian Koppelmann 14969a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env) 14979a31922bSBastian Koppelmann { 14989a31922bSBastian Koppelmann target_ulong ea; 14999a31922bSBastian Koppelmann target_ulong new_PCXI; 15009a31922bSBastian Koppelmann target_ulong new_PSW, psw; 15019a31922bSBastian Koppelmann 15029a31922bSBastian Koppelmann psw = psw_read(env); 15039a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/ 15049a31922bSBastian Koppelmann if (env->PSW & MASK_PSW_CDE) { 15059a31922bSBastian Koppelmann if (cdc_decrement(&(env->PSW))) { 15069a31922bSBastian Koppelmann /* CDU trap */ 15079a31922bSBastian Koppelmann } 15089a31922bSBastian Koppelmann } 15099a31922bSBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 15109a31922bSBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 15119a31922bSBastian Koppelmann /* CSU trap */ 15129a31922bSBastian Koppelmann } 15139a31922bSBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 15149a31922bSBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 15159a31922bSBastian Koppelmann /* CTYP trap */ 15169a31922bSBastian Koppelmann } 15179a31922bSBastian Koppelmann /* PC = {A11 [31: 1], 1’b0}; */ 15189a31922bSBastian Koppelmann env->PC = env->gpr_a[11] & 0xfffffffe; 15199a31922bSBastian Koppelmann 15209a31922bSBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 15219a31922bSBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 15229a31922bSBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 15239a31922bSBastian Koppelmann /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 1524030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 15259a31922bSBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 1526030c58dfSBastian Koppelmann /* M(EA, word) = FCX; */ 1527030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 15289a31922bSBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 15299a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 15309a31922bSBastian Koppelmann /* PCXI = new_PCXI; */ 15319a31922bSBastian Koppelmann env->PCXI = new_PCXI; 15329a31922bSBastian Koppelmann 15339a31922bSBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_13)) { 15349a31922bSBastian Koppelmann /* PSW = new_PSW */ 15359a31922bSBastian Koppelmann psw_write(env, new_PSW); 15369a31922bSBastian Koppelmann } else { 15379a31922bSBastian Koppelmann /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */ 15389a31922bSBastian Koppelmann psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000))); 15399a31922bSBastian Koppelmann } 15409a31922bSBastian Koppelmann } 15419a31922bSBastian Koppelmann 15425de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9) 15435de93515SBastian Koppelmann { 15445de93515SBastian Koppelmann target_ulong tmp_FCX; 15455de93515SBastian Koppelmann target_ulong ea; 15465de93515SBastian Koppelmann target_ulong new_FCX; 15475de93515SBastian Koppelmann 15485de93515SBastian Koppelmann if (env->FCX == 0) { 15495de93515SBastian Koppelmann /* FCU trap */ 15505de93515SBastian Koppelmann } 15515de93515SBastian Koppelmann 15525de93515SBastian Koppelmann tmp_FCX = env->FCX; 15535de93515SBastian Koppelmann ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6); 15545de93515SBastian Koppelmann 1555030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 1556030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 1557030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4] 1558030c58dfSBastian Koppelmann , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */ 1559030c58dfSBastian Koppelmann save_context_lower(env, ea); 1560030c58dfSBastian Koppelmann 15615de93515SBastian Koppelmann 15625de93515SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */ 15635de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 15645de93515SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 15655de93515SBastian Koppelmann /* PCXI.PIE = ICR.IE */ 15665de93515SBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 15675de93515SBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 15685de93515SBastian Koppelmann /* PCXI.UL = 0 */ 15695de93515SBastian Koppelmann env->PCXI &= ~(MASK_PCXI_UL); 15705de93515SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0] */ 15715de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 15725de93515SBastian Koppelmann /* FXC[19: 0] = new_FCX[19: 0] */ 15735de93515SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 15745de93515SBastian Koppelmann /* ICR.IE = 1 */ 15755de93515SBastian Koppelmann env->ICR |= MASK_ICR_IE; 15765de93515SBastian Koppelmann 15775de93515SBastian Koppelmann env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/ 15785de93515SBastian Koppelmann 15795de93515SBastian Koppelmann if (tmp_FCX == env->LCX) { 15805de93515SBastian Koppelmann /* FCD trap */ 15815de93515SBastian Koppelmann } 15825de93515SBastian Koppelmann } 15835de93515SBastian Koppelmann 158444ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env) 158544ea3430SBastian Koppelmann { 158644ea3430SBastian Koppelmann target_ulong ea; 158744ea3430SBastian Koppelmann target_ulong new_PCXI; 158844ea3430SBastian Koppelmann target_ulong new_PSW; 158944ea3430SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 159044ea3430SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 159144ea3430SBastian Koppelmann /* raise csu trap */ 159244ea3430SBastian Koppelmann } 159344ea3430SBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 159444ea3430SBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 159544ea3430SBastian Koppelmann /* raise CTYP trap */ 159644ea3430SBastian Koppelmann } 159744ea3430SBastian Koppelmann /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */ 159844ea3430SBastian Koppelmann if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) { 159944ea3430SBastian Koppelmann /* raise MNG trap */ 160044ea3430SBastian Koppelmann } 160144ea3430SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 160244ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15); 160344ea3430SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 160444ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) + 160544ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCPN) >> 24); 160644ea3430SBastian Koppelmann /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/ 160744ea3430SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 160844ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 160944ea3430SBastian Koppelmann /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 1610030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 161144ea3430SBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 1612030c58dfSBastian Koppelmann /* M(EA, word) = FCX;*/ 1613030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 161444ea3430SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 161544ea3430SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 161644ea3430SBastian Koppelmann /* PCXI = new_PCXI; */ 161744ea3430SBastian Koppelmann env->PCXI = new_PCXI; 161844ea3430SBastian Koppelmann /* write psw */ 161944ea3430SBastian Koppelmann psw_write(env, new_PSW); 162044ea3430SBastian Koppelmann } 162144ea3430SBastian Koppelmann 162259543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) 162359543d4eSBastian Koppelmann { 162459543d4eSBastian Koppelmann uint32_t dummy; 162559543d4eSBastian Koppelmann /* insn doesn't load PCXI and RA */ 162659543d4eSBastian Koppelmann restore_context_lower(env, ea, &dummy, &dummy); 162759543d4eSBastian Koppelmann } 162859543d4eSBastian Koppelmann 162959543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea) 163059543d4eSBastian Koppelmann { 163159543d4eSBastian Koppelmann uint32_t dummy; 163259543d4eSBastian Koppelmann /* insn doesn't load PCXI and PSW */ 163359543d4eSBastian Koppelmann restore_context_upper(env, ea, &dummy, &dummy); 163459543d4eSBastian Koppelmann } 163559543d4eSBastian Koppelmann 163659543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea) 163759543d4eSBastian Koppelmann { 163859543d4eSBastian Koppelmann save_context_lower(env, ea); 163959543d4eSBastian Koppelmann } 164059543d4eSBastian Koppelmann 164159543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea) 164259543d4eSBastian Koppelmann { 164359543d4eSBastian Koppelmann save_context_upper(env, ea); 164459543d4eSBastian Koppelmann } 164559543d4eSBastian Koppelmann 16462b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg) 16472b2f7d97SBastian Koppelmann { 16482b2f7d97SBastian Koppelmann psw_write(env, arg); 16492b2f7d97SBastian Koppelmann } 16502b2f7d97SBastian Koppelmann 16512b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env) 16522b2f7d97SBastian Koppelmann { 16532b2f7d97SBastian Koppelmann return psw_read(env); 16542b2f7d97SBastian Koppelmann } 16552b2f7d97SBastian Koppelmann 16562b2f7d97SBastian Koppelmann 16572d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env, 16582d30267eSBastian Koppelmann uint32_t exception, 16592d30267eSBastian Koppelmann int error_code, 16602d30267eSBastian Koppelmann uintptr_t pc) 16612d30267eSBastian Koppelmann { 16622d30267eSBastian Koppelmann CPUState *cs = CPU(tricore_env_get_cpu(env)); 16632d30267eSBastian Koppelmann cs->exception_index = exception; 16642d30267eSBastian Koppelmann env->error_code = error_code; 16652d30267eSBastian Koppelmann 16662d30267eSBastian Koppelmann if (pc) { 16672d30267eSBastian Koppelmann /* now we have a real cpu fault */ 16682d30267eSBastian Koppelmann cpu_restore_state(cs, pc); 16692d30267eSBastian Koppelmann } 16702d30267eSBastian Koppelmann 16712d30267eSBastian Koppelmann cpu_loop_exit(cs); 16722d30267eSBastian Koppelmann } 16732d30267eSBastian Koppelmann 167448e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, 167548e06fe0SBastian Koppelmann uintptr_t retaddr) 167648e06fe0SBastian Koppelmann { 16772d30267eSBastian Koppelmann int ret; 16782d30267eSBastian Koppelmann ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx); 16792d30267eSBastian Koppelmann if (ret) { 16802d30267eSBastian Koppelmann TriCoreCPU *cpu = TRICORE_CPU(cs); 16812d30267eSBastian Koppelmann CPUTriCoreState *env = &cpu->env; 16822d30267eSBastian Koppelmann do_raise_exception_err(env, cs->exception_index, 16832d30267eSBastian Koppelmann env->error_code, retaddr); 168448e06fe0SBastian Koppelmann } 16852d30267eSBastian Koppelmann } 1686