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; 258e4e39176SBastian Koppelmann return suov32(env, result); 2590974257eSBastian Koppelmann } 2600974257eSBastian Koppelmann 2610974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1, 2620974257eSBastian Koppelmann target_ulong r2) 2630974257eSBastian Koppelmann { 2640974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 2650974257eSBastian Koppelmann int32_t t2 = sextract64(r2, 0, 6); 2660974257eSBastian Koppelmann int64_t result; 2670974257eSBastian Koppelmann if (t2 == 0) { 2680974257eSBastian Koppelmann result = t1; 2690974257eSBastian Koppelmann } else if (t2 > 0) { 2700974257eSBastian Koppelmann result = t1 << t2; 2710974257eSBastian Koppelmann } else { 2720974257eSBastian Koppelmann result = t1 >> -t2; 2730974257eSBastian Koppelmann } 274e4e39176SBastian Koppelmann return ssov32(env, result); 2750974257eSBastian Koppelmann } 2760974257eSBastian Koppelmann 277d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1) 278d5de7839SBastian Koppelmann { 279d5de7839SBastian Koppelmann target_ulong result; 280d5de7839SBastian Koppelmann result = ((int32_t)r1 >= 0) ? r1 : (0 - r1); 281d5de7839SBastian Koppelmann return ssov32(env, result); 282d5de7839SBastian Koppelmann } 283d5de7839SBastian Koppelmann 284d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1) 285d5de7839SBastian Koppelmann { 286d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 287d5de7839SBastian Koppelmann 288d5de7839SBastian Koppelmann ret_h0 = sextract32(r1, 0, 16); 289d5de7839SBastian Koppelmann ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0); 290d5de7839SBastian Koppelmann 291d5de7839SBastian Koppelmann ret_h1 = sextract32(r1, 16, 16); 292d5de7839SBastian Koppelmann ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1); 293d5de7839SBastian Koppelmann 294d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 295d5de7839SBastian Koppelmann } 296d5de7839SBastian Koppelmann 2970974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1, 2980974257eSBastian Koppelmann target_ulong r2) 2990974257eSBastian Koppelmann { 3000974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 3010974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 3020974257eSBastian Koppelmann int64_t result; 3030974257eSBastian Koppelmann 3040974257eSBastian Koppelmann if (t1 > t2) { 3050974257eSBastian Koppelmann result = t1 - t2; 3060974257eSBastian Koppelmann } else { 3070974257eSBastian Koppelmann result = t2 - t1; 3080974257eSBastian Koppelmann } 309e4e39176SBastian Koppelmann return ssov32(env, result); 3100974257eSBastian Koppelmann } 311328f1f0fSBastian Koppelmann 312d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1, 313d5de7839SBastian Koppelmann target_ulong r2) 314d5de7839SBastian Koppelmann { 315d5de7839SBastian Koppelmann int32_t t1, t2; 316d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 317d5de7839SBastian Koppelmann 318d5de7839SBastian Koppelmann t1 = sextract32(r1, 0, 16); 319d5de7839SBastian Koppelmann t2 = sextract32(r2, 0, 16); 320d5de7839SBastian Koppelmann if (t1 > t2) { 321d5de7839SBastian Koppelmann ret_h0 = t1 - t2; 322d5de7839SBastian Koppelmann } else { 323d5de7839SBastian Koppelmann ret_h0 = t2 - t1; 324d5de7839SBastian Koppelmann } 325d5de7839SBastian Koppelmann 326d5de7839SBastian Koppelmann t1 = sextract32(r1, 16, 16); 327d5de7839SBastian Koppelmann t2 = sextract32(r2, 16, 16); 328d5de7839SBastian Koppelmann if (t1 > t2) { 329d5de7839SBastian Koppelmann ret_h1 = t1 - t2; 330d5de7839SBastian Koppelmann } else { 331d5de7839SBastian Koppelmann ret_h1 = t2 - t1; 332d5de7839SBastian Koppelmann } 333d5de7839SBastian Koppelmann 334d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 335d5de7839SBastian Koppelmann } 336d5de7839SBastian Koppelmann 337328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1, 338328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 339328f1f0fSBastian Koppelmann { 340328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 341328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 342328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 343328f1f0fSBastian Koppelmann int64_t result; 344328f1f0fSBastian Koppelmann 345328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 346e4e39176SBastian Koppelmann return ssov32(env, result); 347328f1f0fSBastian Koppelmann } 348328f1f0fSBastian Koppelmann 349328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1, 350328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 351328f1f0fSBastian Koppelmann { 352328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 353328f1f0fSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 354328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 355328f1f0fSBastian Koppelmann int64_t result; 356328f1f0fSBastian Koppelmann 357328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 358e4e39176SBastian Koppelmann return suov32(env, result); 359328f1f0fSBastian Koppelmann } 360328f1f0fSBastian Koppelmann 361328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1, 362328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 363328f1f0fSBastian Koppelmann { 364328f1f0fSBastian Koppelmann uint64_t ret, ovf; 365328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 366328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 367328f1f0fSBastian Koppelmann int64_t mul; 368328f1f0fSBastian Koppelmann 369328f1f0fSBastian Koppelmann mul = t1 * t3; 370328f1f0fSBastian Koppelmann ret = mul + r2; 371328f1f0fSBastian Koppelmann ovf = (ret ^ mul) & ~(mul ^ r2); 372328f1f0fSBastian Koppelmann 373328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 374328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 375328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 376328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 377328f1f0fSBastian Koppelmann if (mul >= 0) { 378328f1f0fSBastian Koppelmann ret = INT64_MAX; 379328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 380328f1f0fSBastian Koppelmann } else { 381328f1f0fSBastian Koppelmann ret = INT64_MIN; 382328f1f0fSBastian Koppelmann } 383328f1f0fSBastian Koppelmann } else { 384328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 385328f1f0fSBastian Koppelmann } 386328f1f0fSBastian Koppelmann t1 = ret >> 32; 387328f1f0fSBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 388328f1f0fSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 389328f1f0fSBastian Koppelmann 390328f1f0fSBastian Koppelmann return ret; 391328f1f0fSBastian Koppelmann } 392328f1f0fSBastian Koppelmann 393328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1, 394328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 395328f1f0fSBastian Koppelmann { 396328f1f0fSBastian Koppelmann uint64_t ret, mul; 397328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 398328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 399328f1f0fSBastian Koppelmann 400328f1f0fSBastian Koppelmann mul = t1 * t3; 401328f1f0fSBastian Koppelmann ret = mul + r2; 402328f1f0fSBastian Koppelmann 403328f1f0fSBastian Koppelmann if (ret < r2) { 404328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 405328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 406328f1f0fSBastian Koppelmann /* saturate */ 407328f1f0fSBastian Koppelmann ret = UINT64_MAX; 408328f1f0fSBastian Koppelmann } else { 409328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 410328f1f0fSBastian Koppelmann } 411328f1f0fSBastian Koppelmann t1 = ret >> 32; 412328f1f0fSBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 413328f1f0fSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 414328f1f0fSBastian Koppelmann return ret; 415328f1f0fSBastian Koppelmann } 416328f1f0fSBastian Koppelmann 417328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1, 418328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 419328f1f0fSBastian Koppelmann { 420328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 421328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 422328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 423328f1f0fSBastian Koppelmann int64_t result; 424328f1f0fSBastian Koppelmann 425328f1f0fSBastian Koppelmann result = t2 - (t1 * t3); 426e4e39176SBastian Koppelmann return ssov32(env, result); 427328f1f0fSBastian Koppelmann } 428328f1f0fSBastian Koppelmann 429328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1, 430328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 431328f1f0fSBastian Koppelmann { 432328f1f0fSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 433328f1f0fSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 434328f1f0fSBastian Koppelmann int64_t t3 = extract64(r3, 0, 32); 435328f1f0fSBastian Koppelmann int64_t result; 436328f1f0fSBastian Koppelmann 437328f1f0fSBastian Koppelmann result = t2 - (t1 * t3); 438e4e39176SBastian Koppelmann return suov32(env, result); 439328f1f0fSBastian Koppelmann } 440328f1f0fSBastian Koppelmann 441328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1, 442328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 443328f1f0fSBastian Koppelmann { 444328f1f0fSBastian Koppelmann uint64_t ret, ovf; 445328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 446328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 447328f1f0fSBastian Koppelmann int64_t mul; 448328f1f0fSBastian Koppelmann 449328f1f0fSBastian Koppelmann mul = t1 * t3; 450328f1f0fSBastian Koppelmann ret = r2 - mul; 451328f1f0fSBastian Koppelmann ovf = (ret ^ r2) & (mul ^ r2); 452328f1f0fSBastian Koppelmann 453328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 454328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 455328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 456328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 457328f1f0fSBastian Koppelmann if (mul < 0) { 458328f1f0fSBastian Koppelmann ret = INT64_MAX; 459328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 460328f1f0fSBastian Koppelmann } else { 461328f1f0fSBastian Koppelmann ret = INT64_MIN; 462328f1f0fSBastian Koppelmann } 463328f1f0fSBastian Koppelmann } else { 464328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 465328f1f0fSBastian Koppelmann } 466328f1f0fSBastian Koppelmann t1 = ret >> 32; 467328f1f0fSBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 468328f1f0fSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 469328f1f0fSBastian Koppelmann return ret; 470328f1f0fSBastian Koppelmann } 471328f1f0fSBastian Koppelmann 472328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1, 473328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 474328f1f0fSBastian Koppelmann { 475328f1f0fSBastian Koppelmann uint64_t ret, mul; 476328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 477328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 478328f1f0fSBastian Koppelmann 479328f1f0fSBastian Koppelmann mul = t1 * t3; 480328f1f0fSBastian Koppelmann ret = r2 - mul; 481328f1f0fSBastian Koppelmann 482328f1f0fSBastian Koppelmann if (ret > r2) { 483328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 484328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 485328f1f0fSBastian Koppelmann /* saturate */ 486328f1f0fSBastian Koppelmann ret = 0; 487328f1f0fSBastian Koppelmann } else { 488328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 489328f1f0fSBastian Koppelmann } 490328f1f0fSBastian Koppelmann t1 = ret >> 32; 491328f1f0fSBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 492328f1f0fSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 493328f1f0fSBastian Koppelmann return ret; 494328f1f0fSBastian Koppelmann } 495328f1f0fSBastian Koppelmann 496d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg) 497d5de7839SBastian Koppelmann { 498d5de7839SBastian Koppelmann int32_t b, i; 499d5de7839SBastian Koppelmann int32_t ovf = 0; 500d5de7839SBastian Koppelmann int32_t avf = 0; 501d5de7839SBastian Koppelmann int32_t ret = 0; 502d5de7839SBastian Koppelmann 503d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 504d5de7839SBastian Koppelmann b = sextract32(arg, i * 8, 8); 505d5de7839SBastian Koppelmann b = (b >= 0) ? b : (0 - b); 506d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 507d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 508d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 509d5de7839SBastian Koppelmann } 510d5de7839SBastian Koppelmann 511d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 512d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 513d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 514d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 515d5de7839SBastian Koppelmann 516d5de7839SBastian Koppelmann return ret; 517d5de7839SBastian Koppelmann } 518d5de7839SBastian Koppelmann 519d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg) 520d5de7839SBastian Koppelmann { 521d5de7839SBastian Koppelmann int32_t h, i; 522d5de7839SBastian Koppelmann int32_t ovf = 0; 523d5de7839SBastian Koppelmann int32_t avf = 0; 524d5de7839SBastian Koppelmann int32_t ret = 0; 525d5de7839SBastian Koppelmann 526d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 527d5de7839SBastian Koppelmann h = sextract32(arg, i * 16, 16); 528d5de7839SBastian Koppelmann h = (h >= 0) ? h : (0 - h); 529d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 530d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 531d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 532d5de7839SBastian Koppelmann } 533d5de7839SBastian Koppelmann 534d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 535d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 536d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 537d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 538d5de7839SBastian Koppelmann 539d5de7839SBastian Koppelmann return ret; 540d5de7839SBastian Koppelmann } 541d5de7839SBastian Koppelmann 542d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 543d5de7839SBastian Koppelmann { 544d5de7839SBastian Koppelmann int32_t b, i; 545d5de7839SBastian Koppelmann int32_t extr_r2; 546d5de7839SBastian Koppelmann int32_t ovf = 0; 547d5de7839SBastian Koppelmann int32_t avf = 0; 548d5de7839SBastian Koppelmann int32_t ret = 0; 549d5de7839SBastian Koppelmann 550d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 551d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 552d5de7839SBastian Koppelmann b = sextract32(r1, i * 8, 8); 553d5de7839SBastian Koppelmann b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b); 554d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 555d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 556d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 557d5de7839SBastian Koppelmann } 558d5de7839SBastian Koppelmann 559d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 560d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 561d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 562d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 563d5de7839SBastian Koppelmann return ret; 564d5de7839SBastian Koppelmann } 565d5de7839SBastian Koppelmann 566d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 567d5de7839SBastian Koppelmann { 568d5de7839SBastian Koppelmann int32_t h, i; 569d5de7839SBastian Koppelmann int32_t extr_r2; 570d5de7839SBastian Koppelmann int32_t ovf = 0; 571d5de7839SBastian Koppelmann int32_t avf = 0; 572d5de7839SBastian Koppelmann int32_t ret = 0; 573d5de7839SBastian Koppelmann 574d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 575d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 576d5de7839SBastian Koppelmann h = sextract32(r1, i * 16, 16); 577d5de7839SBastian Koppelmann h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h); 578d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 579d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 580d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 581d5de7839SBastian Koppelmann } 582d5de7839SBastian Koppelmann 583d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 584d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 585d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 586d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 587d5de7839SBastian Koppelmann 588d5de7839SBastian Koppelmann return ret; 589d5de7839SBastian Koppelmann } 590d5de7839SBastian Koppelmann 591d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 592d5de7839SBastian Koppelmann { 593d5de7839SBastian Koppelmann int32_t b, i; 594d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 595d5de7839SBastian Koppelmann int32_t ovf = 0; 596d5de7839SBastian Koppelmann int32_t avf = 0; 597d5de7839SBastian Koppelmann uint32_t ret = 0; 598d5de7839SBastian Koppelmann 599d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 600d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 601d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 602d5de7839SBastian Koppelmann 603d5de7839SBastian Koppelmann b = extr_r1 + extr_r2; 604d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 605d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 606d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 607d5de7839SBastian Koppelmann } 608d5de7839SBastian Koppelmann 609d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 610d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 611d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 612d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 613d5de7839SBastian Koppelmann 614d5de7839SBastian Koppelmann return ret; 615d5de7839SBastian Koppelmann } 616d5de7839SBastian Koppelmann 617d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 618d5de7839SBastian Koppelmann { 619d5de7839SBastian Koppelmann int32_t h, i; 620d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 621d5de7839SBastian Koppelmann int32_t ovf = 0; 622d5de7839SBastian Koppelmann int32_t avf = 0; 623d5de7839SBastian Koppelmann int32_t ret = 0; 624d5de7839SBastian Koppelmann 625d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 626d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 627d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 628d5de7839SBastian Koppelmann h = extr_r1 + extr_r2; 629d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 630d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 631d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 632d5de7839SBastian Koppelmann } 633d5de7839SBastian Koppelmann 634d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 635d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 636d5de7839SBastian Koppelmann env->PSW_USB_AV = (avf << 16); 637d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 638d5de7839SBastian Koppelmann 639d5de7839SBastian Koppelmann return ret; 640d5de7839SBastian Koppelmann } 641d5de7839SBastian Koppelmann 642d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 643d5de7839SBastian Koppelmann { 644d5de7839SBastian Koppelmann int32_t b, i; 645d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 646d5de7839SBastian Koppelmann int32_t ovf = 0; 647d5de7839SBastian Koppelmann int32_t avf = 0; 648d5de7839SBastian Koppelmann uint32_t ret = 0; 649d5de7839SBastian Koppelmann 650d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 651d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 652d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 653d5de7839SBastian Koppelmann 654d5de7839SBastian Koppelmann b = extr_r1 - extr_r2; 655d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 656d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 657d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 658d5de7839SBastian Koppelmann } 659d5de7839SBastian Koppelmann 660d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 661d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 662d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 663d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 664d5de7839SBastian Koppelmann 665d5de7839SBastian Koppelmann return ret; 666d5de7839SBastian Koppelmann } 667d5de7839SBastian Koppelmann 668d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 669d5de7839SBastian Koppelmann { 670d5de7839SBastian Koppelmann int32_t h, i; 671d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 672d5de7839SBastian Koppelmann int32_t ovf = 0; 673d5de7839SBastian Koppelmann int32_t avf = 0; 674d5de7839SBastian Koppelmann int32_t ret = 0; 675d5de7839SBastian Koppelmann 676d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 677d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 678d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 679d5de7839SBastian Koppelmann h = extr_r1 - extr_r2; 680d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 681d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 682d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 683d5de7839SBastian Koppelmann } 684d5de7839SBastian Koppelmann 685d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 686d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 687d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 688d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 689d5de7839SBastian Koppelmann 690d5de7839SBastian Koppelmann return ret; 691d5de7839SBastian Koppelmann } 692d5de7839SBastian Koppelmann 693d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2) 694d5de7839SBastian Koppelmann { 695d5de7839SBastian Koppelmann int32_t ret; 696d5de7839SBastian Koppelmann int32_t i, msk; 697d5de7839SBastian Koppelmann 698d5de7839SBastian Koppelmann ret = 0; 699d5de7839SBastian Koppelmann msk = 0xff; 700d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 701d5de7839SBastian Koppelmann if ((r1 & msk) == (r2 & msk)) { 702d5de7839SBastian Koppelmann ret |= msk; 703d5de7839SBastian Koppelmann } 704d5de7839SBastian Koppelmann msk = msk << 8; 705d5de7839SBastian Koppelmann } 706d5de7839SBastian Koppelmann 707d5de7839SBastian Koppelmann return ret; 708d5de7839SBastian Koppelmann } 709d5de7839SBastian Koppelmann 710d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2) 711d5de7839SBastian Koppelmann { 712d5de7839SBastian Koppelmann int32_t ret = 0; 713d5de7839SBastian Koppelmann 714d5de7839SBastian Koppelmann if ((r1 & 0xffff) == (r2 & 0xffff)) { 715d5de7839SBastian Koppelmann ret = 0xffff; 716d5de7839SBastian Koppelmann } 717d5de7839SBastian Koppelmann 718d5de7839SBastian Koppelmann if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) { 719d5de7839SBastian Koppelmann ret |= 0xffff0000; 720d5de7839SBastian Koppelmann } 721d5de7839SBastian Koppelmann 722d5de7839SBastian Koppelmann return ret; 723d5de7839SBastian Koppelmann } 724d5de7839SBastian Koppelmann 725d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2) 726d5de7839SBastian Koppelmann { 727d5de7839SBastian Koppelmann int32_t i; 728d5de7839SBastian Koppelmann uint32_t ret = 0; 729d5de7839SBastian Koppelmann 730d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 731d5de7839SBastian Koppelmann ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8)); 732d5de7839SBastian Koppelmann } 733d5de7839SBastian Koppelmann 734d5de7839SBastian Koppelmann return ret; 735d5de7839SBastian Koppelmann } 736d5de7839SBastian Koppelmann 737d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2) 738d5de7839SBastian Koppelmann { 739d5de7839SBastian Koppelmann uint32_t ret; 740d5de7839SBastian Koppelmann 741d5de7839SBastian Koppelmann ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16)); 742d5de7839SBastian Koppelmann ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16)); 743d5de7839SBastian Koppelmann 744d5de7839SBastian Koppelmann return ret; 745d5de7839SBastian Koppelmann } 746d5de7839SBastian Koppelmann 747d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2) 748d5de7839SBastian Koppelmann { 749d5de7839SBastian Koppelmann int32_t i; 750d5de7839SBastian Koppelmann uint32_t ret = 0; 751d5de7839SBastian Koppelmann 752d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 753d5de7839SBastian Koppelmann if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) { 754d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 755d5de7839SBastian Koppelmann } 756d5de7839SBastian Koppelmann } 757d5de7839SBastian Koppelmann 758d5de7839SBastian Koppelmann return ret; 759d5de7839SBastian Koppelmann } 760d5de7839SBastian Koppelmann 761d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2) 762d5de7839SBastian Koppelmann { 763d5de7839SBastian Koppelmann int32_t i; 764d5de7839SBastian Koppelmann uint32_t ret = 0; 765d5de7839SBastian Koppelmann 766d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 767d5de7839SBastian Koppelmann if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) { 768d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 769d5de7839SBastian Koppelmann } 770d5de7839SBastian Koppelmann } 771d5de7839SBastian Koppelmann 772d5de7839SBastian Koppelmann return ret; 773d5de7839SBastian Koppelmann } 774d5de7839SBastian Koppelmann 775d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2) 776d5de7839SBastian Koppelmann { 777d5de7839SBastian Koppelmann uint32_t ret = 0; 778d5de7839SBastian Koppelmann 779d5de7839SBastian Koppelmann if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) { 780d5de7839SBastian Koppelmann ret |= 0xffff; 781d5de7839SBastian Koppelmann } 782d5de7839SBastian Koppelmann 783d5de7839SBastian Koppelmann if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) { 784d5de7839SBastian Koppelmann ret |= 0xffff0000; 785d5de7839SBastian Koppelmann } 786d5de7839SBastian Koppelmann 787d5de7839SBastian Koppelmann return ret; 788d5de7839SBastian Koppelmann } 789d5de7839SBastian Koppelmann 790d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2) 791d5de7839SBastian Koppelmann { 792d5de7839SBastian Koppelmann uint32_t ret = 0; 793d5de7839SBastian Koppelmann 794d5de7839SBastian Koppelmann if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) { 795d5de7839SBastian Koppelmann ret |= 0xffff; 796d5de7839SBastian Koppelmann } 797d5de7839SBastian Koppelmann 798d5de7839SBastian Koppelmann if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) { 799d5de7839SBastian Koppelmann ret |= 0xffff0000; 800d5de7839SBastian Koppelmann } 801d5de7839SBastian Koppelmann 802d5de7839SBastian Koppelmann return ret; 803d5de7839SBastian Koppelmann } 804d5de7839SBastian Koppelmann 805d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op) \ 806d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \ 807d5de7839SBastian Koppelmann { \ 808d5de7839SBastian Koppelmann int32_t i, extr_r1, extr_r2; \ 809d5de7839SBastian Koppelmann uint32_t ret = 0; \ 810d5de7839SBastian Koppelmann \ 811d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 812d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); \ 813d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); \ 814d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 815d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 816d5de7839SBastian Koppelmann } \ 817d5de7839SBastian Koppelmann return ret; \ 818d5de7839SBastian Koppelmann } \ 819d5de7839SBastian Koppelmann \ 820d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\ 821d5de7839SBastian Koppelmann { \ 822d5de7839SBastian Koppelmann int32_t i; \ 823d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 824d5de7839SBastian Koppelmann uint32_t ret = 0; \ 825d5de7839SBastian Koppelmann \ 826d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 827d5de7839SBastian Koppelmann extr_r1 = extract32(r1, i * 8, 8); \ 828d5de7839SBastian Koppelmann extr_r2 = extract32(r2, i * 8, 8); \ 829d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 830d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 831d5de7839SBastian Koppelmann } \ 832d5de7839SBastian Koppelmann return ret; \ 833d5de7839SBastian Koppelmann } \ 834d5de7839SBastian Koppelmann \ 835d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \ 836d5de7839SBastian Koppelmann { \ 837d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; \ 838d5de7839SBastian Koppelmann uint32_t ret = 0; \ 839d5de7839SBastian Koppelmann \ 840d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 0, 16); \ 841d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 0, 16); \ 842d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 843d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 844d5de7839SBastian Koppelmann \ 845d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 16, 16); \ 846d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 16, 16); \ 847d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 848d5de7839SBastian Koppelmann ret |= extr_r1 << 16; \ 849d5de7839SBastian Koppelmann \ 850d5de7839SBastian Koppelmann return ret; \ 851d5de7839SBastian Koppelmann } \ 852d5de7839SBastian Koppelmann \ 853d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\ 854d5de7839SBastian Koppelmann { \ 855d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 856d5de7839SBastian Koppelmann uint32_t ret = 0; \ 857d5de7839SBastian Koppelmann \ 858d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 0, 16); \ 859d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 0, 16); \ 860d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 861d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 862d5de7839SBastian Koppelmann \ 863d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 16, 16); \ 864d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 16, 16); \ 865d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 866d5de7839SBastian Koppelmann ret |= extr_r1 << (16); \ 867d5de7839SBastian Koppelmann \ 868d5de7839SBastian Koppelmann return ret; \ 869d5de7839SBastian Koppelmann } \ 870d5de7839SBastian Koppelmann 871d5de7839SBastian Koppelmann EXTREMA_H_B(max, >) 872d5de7839SBastian Koppelmann EXTREMA_H_B(min, <) 873d5de7839SBastian Koppelmann 874d5de7839SBastian Koppelmann #undef EXTREMA_H_B 875d5de7839SBastian Koppelmann 8760b79a781SBastian Koppelmann uint32_t helper_clo(target_ulong r1) 8770b79a781SBastian Koppelmann { 8780b79a781SBastian Koppelmann return clo32(r1); 8790b79a781SBastian Koppelmann } 8800b79a781SBastian Koppelmann 8810b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1) 8820b79a781SBastian Koppelmann { 8830b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 8840b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 8850b79a781SBastian Koppelmann 8860b79a781SBastian Koppelmann ret_hw0 = clo32(ret_hw0 << 16); 8870b79a781SBastian Koppelmann ret_hw1 = clo32(ret_hw1 << 16); 8880b79a781SBastian Koppelmann 8890b79a781SBastian Koppelmann if (ret_hw0 > 16) { 8900b79a781SBastian Koppelmann ret_hw0 = 16; 8910b79a781SBastian Koppelmann } 8920b79a781SBastian Koppelmann if (ret_hw1 > 16) { 8930b79a781SBastian Koppelmann ret_hw1 = 16; 8940b79a781SBastian Koppelmann } 8950b79a781SBastian Koppelmann 8960b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 8970b79a781SBastian Koppelmann } 8980b79a781SBastian Koppelmann 8990b79a781SBastian Koppelmann uint32_t helper_clz(target_ulong r1) 9000b79a781SBastian Koppelmann { 9010b79a781SBastian Koppelmann return clz32(r1); 9020b79a781SBastian Koppelmann } 9030b79a781SBastian Koppelmann 9040b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1) 9050b79a781SBastian Koppelmann { 9060b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 9070b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 9080b79a781SBastian Koppelmann 9090b79a781SBastian Koppelmann ret_hw0 = clz32(ret_hw0 << 16); 9100b79a781SBastian Koppelmann ret_hw1 = clz32(ret_hw1 << 16); 9110b79a781SBastian Koppelmann 9120b79a781SBastian Koppelmann if (ret_hw0 > 16) { 9130b79a781SBastian Koppelmann ret_hw0 = 16; 9140b79a781SBastian Koppelmann } 9150b79a781SBastian Koppelmann if (ret_hw1 > 16) { 9160b79a781SBastian Koppelmann ret_hw1 = 16; 9170b79a781SBastian Koppelmann } 9180b79a781SBastian Koppelmann 9190b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 9200b79a781SBastian Koppelmann } 9210b79a781SBastian Koppelmann 9220b79a781SBastian Koppelmann uint32_t helper_cls(target_ulong r1) 9230b79a781SBastian Koppelmann { 9240b79a781SBastian Koppelmann return clrsb32(r1); 9250b79a781SBastian Koppelmann } 9260b79a781SBastian Koppelmann 9270b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1) 9280b79a781SBastian Koppelmann { 9290b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 9300b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 9310b79a781SBastian Koppelmann 9320b79a781SBastian Koppelmann ret_hw0 = clrsb32(ret_hw0 << 16); 9330b79a781SBastian Koppelmann ret_hw1 = clrsb32(ret_hw1 << 16); 9340b79a781SBastian Koppelmann 9350b79a781SBastian Koppelmann if (ret_hw0 > 15) { 9360b79a781SBastian Koppelmann ret_hw0 = 15; 9370b79a781SBastian Koppelmann } 9380b79a781SBastian Koppelmann if (ret_hw1 > 15) { 9390b79a781SBastian Koppelmann ret_hw1 = 15; 9400b79a781SBastian Koppelmann } 9410b79a781SBastian Koppelmann 9420b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 9430b79a781SBastian Koppelmann } 9440b79a781SBastian Koppelmann 9450b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2) 9460b79a781SBastian Koppelmann { 9470b79a781SBastian Koppelmann int32_t shift_count = sextract32(r2, 0, 6); 9480b79a781SBastian Koppelmann 9490b79a781SBastian Koppelmann if (shift_count == -32) { 9500b79a781SBastian Koppelmann return 0; 9510b79a781SBastian Koppelmann } else if (shift_count < 0) { 9520b79a781SBastian Koppelmann return r1 >> -shift_count; 9530b79a781SBastian Koppelmann } else { 9540b79a781SBastian Koppelmann return r1 << shift_count; 9550b79a781SBastian Koppelmann } 9560b79a781SBastian Koppelmann } 9570b79a781SBastian Koppelmann 9580b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2) 9590b79a781SBastian Koppelmann { 9600b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 9610b79a781SBastian Koppelmann int32_t shift_count; 9620b79a781SBastian Koppelmann 9630b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 9640b79a781SBastian Koppelmann 9650b79a781SBastian Koppelmann if (shift_count == -16) { 9660b79a781SBastian Koppelmann return 0; 9670b79a781SBastian Koppelmann } else if (shift_count < 0) { 9680b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) >> -shift_count; 9690b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) >> -shift_count; 9700b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 9710b79a781SBastian Koppelmann } else { 9720b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) << shift_count; 9730b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) << shift_count; 9740b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 9750b79a781SBastian Koppelmann } 9760b79a781SBastian Koppelmann } 9770b79a781SBastian Koppelmann 9780b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 9790b79a781SBastian Koppelmann { 9800b79a781SBastian Koppelmann int32_t shift_count; 9810b79a781SBastian Koppelmann int64_t result, t1; 9820b79a781SBastian Koppelmann uint32_t ret; 9830b79a781SBastian Koppelmann 9840b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 6); 9850b79a781SBastian Koppelmann t1 = sextract32(r1, 0, 32); 9860b79a781SBastian Koppelmann 9870b79a781SBastian Koppelmann if (shift_count == 0) { 9880b79a781SBastian Koppelmann env->PSW_USB_C = env->PSW_USB_V = 0; 9890b79a781SBastian Koppelmann ret = r1; 9900b79a781SBastian Koppelmann } else if (shift_count == -32) { 9910b79a781SBastian Koppelmann env->PSW_USB_C = r1; 9920b79a781SBastian Koppelmann env->PSW_USB_V = 0; 9930b79a781SBastian Koppelmann ret = t1 >> 31; 9940b79a781SBastian Koppelmann } else if (shift_count > 0) { 9950b79a781SBastian Koppelmann result = t1 << shift_count; 9960b79a781SBastian Koppelmann /* calc carry */ 9970b79a781SBastian Koppelmann env->PSW_USB_C = ((result & 0xffffffff00000000) != 0); 9980b79a781SBastian Koppelmann /* calc v */ 9990b79a781SBastian Koppelmann env->PSW_USB_V = (((result > 0x7fffffffLL) || 10000b79a781SBastian Koppelmann (result < -0x80000000LL)) << 31); 10010b79a781SBastian Koppelmann /* calc sv */ 10020b79a781SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 10030b79a781SBastian Koppelmann ret = (uint32_t)result; 10040b79a781SBastian Koppelmann } else { 10050b79a781SBastian Koppelmann env->PSW_USB_V = 0; 10060b79a781SBastian Koppelmann env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1)); 10070b79a781SBastian Koppelmann ret = t1 >> -shift_count; 10080b79a781SBastian Koppelmann } 10090b79a781SBastian Koppelmann 10100b79a781SBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 10110b79a781SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 10120b79a781SBastian Koppelmann 10130b79a781SBastian Koppelmann return ret; 10140b79a781SBastian Koppelmann } 10150b79a781SBastian Koppelmann 10160b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2) 10170b79a781SBastian Koppelmann { 10180b79a781SBastian Koppelmann int32_t shift_count; 10190b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 10200b79a781SBastian Koppelmann 10210b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 10220b79a781SBastian Koppelmann 10230b79a781SBastian Koppelmann if (shift_count == 0) { 10240b79a781SBastian Koppelmann return r1; 10250b79a781SBastian Koppelmann } else if (shift_count < 0) { 10260b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) >> -shift_count; 10270b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) >> -shift_count; 10280b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 10290b79a781SBastian Koppelmann } else { 10300b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) << shift_count; 10310b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) << shift_count; 10320b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 10330b79a781SBastian Koppelmann } 10340b79a781SBastian Koppelmann } 10350b79a781SBastian Koppelmann 10369a31922bSBastian Koppelmann /* context save area (CSA) related helpers */ 10379a31922bSBastian Koppelmann 10389a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw) 10399a31922bSBastian Koppelmann { 10409a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 10419a31922bSBastian Koppelmann return 0; 10429a31922bSBastian Koppelmann } 10439a31922bSBastian Koppelmann 10449a31922bSBastian Koppelmann (*psw)++; 10459a31922bSBastian Koppelmann /* check for overflow */ 10469a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 10479a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 10489a31922bSBastian Koppelmann int count = *psw & mask; 10499a31922bSBastian Koppelmann if (count == 0) { 10509a31922bSBastian Koppelmann (*psw)--; 10519a31922bSBastian Koppelmann return 1; 10529a31922bSBastian Koppelmann } 10539a31922bSBastian Koppelmann return 0; 10549a31922bSBastian Koppelmann } 10559a31922bSBastian Koppelmann 10569a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw) 10579a31922bSBastian Koppelmann { 10589a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 10599a31922bSBastian Koppelmann return 0; 10609a31922bSBastian Koppelmann } 10619a31922bSBastian Koppelmann /* check for underflow */ 10629a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 10639a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 10649a31922bSBastian Koppelmann int count = *psw & mask; 10659a31922bSBastian Koppelmann if (count == 0) { 10669a31922bSBastian Koppelmann return 1; 10679a31922bSBastian Koppelmann } 10689a31922bSBastian Koppelmann (*psw)--; 10699a31922bSBastian Koppelmann return 0; 10709a31922bSBastian Koppelmann } 10719a31922bSBastian Koppelmann 107244ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw) 107344ea3430SBastian Koppelmann { 107444ea3430SBastian Koppelmann int cdc = *psw & MASK_PSW_CDC; 107544ea3430SBastian Koppelmann /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC == 107644ea3430SBastian Koppelmann 7'b1111111, otherwise returns FALSE. */ 107744ea3430SBastian Koppelmann if (cdc == 0x7f) { 107844ea3430SBastian Koppelmann return true; 107944ea3430SBastian Koppelmann } 108044ea3430SBastian Koppelmann /* find CDC.COUNT */ 108144ea3430SBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 108244ea3430SBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 108344ea3430SBastian Koppelmann int count = *psw & mask; 108444ea3430SBastian Koppelmann return count == 0; 108544ea3430SBastian Koppelmann } 108644ea3430SBastian Koppelmann 1087030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea) 10889a31922bSBastian Koppelmann { 10899a31922bSBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 10909a31922bSBastian Koppelmann cpu_stl_data(env, ea+4, env->PSW); 10919a31922bSBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[10]); 10929a31922bSBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[11]); 10939a31922bSBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[8]); 10949a31922bSBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[9]); 10959a31922bSBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[10]); 10969a31922bSBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[11]); 10979a31922bSBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[12]); 10989a31922bSBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[13]); 10999a31922bSBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[14]); 11009a31922bSBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[15]); 11019a31922bSBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[12]); 11029a31922bSBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[13]); 11039a31922bSBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[14]); 11049a31922bSBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[15]); 11059a31922bSBastian Koppelmann } 11069a31922bSBastian Koppelmann 1107030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea) 11085de93515SBastian Koppelmann { 11095de93515SBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 1110030c58dfSBastian Koppelmann cpu_stl_data(env, ea+4, env->gpr_a[11]); 11115de93515SBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[2]); 11125de93515SBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[3]); 11135de93515SBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[0]); 11145de93515SBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[1]); 11155de93515SBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[2]); 11165de93515SBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[3]); 11175de93515SBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[4]); 11185de93515SBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[5]); 11195de93515SBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[6]); 11205de93515SBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[7]); 11215de93515SBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[4]); 11225de93515SBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[5]); 11235de93515SBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[6]); 11245de93515SBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[7]); 11255de93515SBastian Koppelmann } 11265de93515SBastian Koppelmann 11279a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea, 11289a31922bSBastian Koppelmann target_ulong *new_PCXI, target_ulong *new_PSW) 11299a31922bSBastian Koppelmann { 11309a31922bSBastian Koppelmann *new_PCXI = cpu_ldl_data(env, ea); 11319a31922bSBastian Koppelmann *new_PSW = cpu_ldl_data(env, ea+4); 11329a31922bSBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, ea+8); 11339a31922bSBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, ea+12); 11349a31922bSBastian Koppelmann env->gpr_d[8] = cpu_ldl_data(env, ea+16); 11359a31922bSBastian Koppelmann env->gpr_d[9] = cpu_ldl_data(env, ea+20); 11369a31922bSBastian Koppelmann env->gpr_d[10] = cpu_ldl_data(env, ea+24); 11379a31922bSBastian Koppelmann env->gpr_d[11] = cpu_ldl_data(env, ea+28); 11389a31922bSBastian Koppelmann env->gpr_a[12] = cpu_ldl_data(env, ea+32); 11399a31922bSBastian Koppelmann env->gpr_a[13] = cpu_ldl_data(env, ea+36); 11409a31922bSBastian Koppelmann env->gpr_a[14] = cpu_ldl_data(env, ea+40); 11419a31922bSBastian Koppelmann env->gpr_a[15] = cpu_ldl_data(env, ea+44); 11429a31922bSBastian Koppelmann env->gpr_d[12] = cpu_ldl_data(env, ea+48); 11439a31922bSBastian Koppelmann env->gpr_d[13] = cpu_ldl_data(env, ea+52); 11449a31922bSBastian Koppelmann env->gpr_d[14] = cpu_ldl_data(env, ea+56); 11459a31922bSBastian Koppelmann env->gpr_d[15] = cpu_ldl_data(env, ea+60); 11469a31922bSBastian Koppelmann } 11479a31922bSBastian Koppelmann 114859543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea, 114959543d4eSBastian Koppelmann target_ulong *ra, target_ulong *pcxi) 115059543d4eSBastian Koppelmann { 115159543d4eSBastian Koppelmann *pcxi = cpu_ldl_data(env, ea); 115259543d4eSBastian Koppelmann *ra = cpu_ldl_data(env, ea+4); 115359543d4eSBastian Koppelmann env->gpr_a[2] = cpu_ldl_data(env, ea+8); 115459543d4eSBastian Koppelmann env->gpr_a[3] = cpu_ldl_data(env, ea+12); 115559543d4eSBastian Koppelmann env->gpr_d[0] = cpu_ldl_data(env, ea+16); 115659543d4eSBastian Koppelmann env->gpr_d[1] = cpu_ldl_data(env, ea+20); 115759543d4eSBastian Koppelmann env->gpr_d[2] = cpu_ldl_data(env, ea+24); 115859543d4eSBastian Koppelmann env->gpr_d[3] = cpu_ldl_data(env, ea+28); 115959543d4eSBastian Koppelmann env->gpr_a[4] = cpu_ldl_data(env, ea+32); 116059543d4eSBastian Koppelmann env->gpr_a[5] = cpu_ldl_data(env, ea+36); 116159543d4eSBastian Koppelmann env->gpr_a[6] = cpu_ldl_data(env, ea+40); 116259543d4eSBastian Koppelmann env->gpr_a[7] = cpu_ldl_data(env, ea+44); 116359543d4eSBastian Koppelmann env->gpr_d[4] = cpu_ldl_data(env, ea+48); 116459543d4eSBastian Koppelmann env->gpr_d[5] = cpu_ldl_data(env, ea+52); 116559543d4eSBastian Koppelmann env->gpr_d[6] = cpu_ldl_data(env, ea+56); 116659543d4eSBastian Koppelmann env->gpr_d[7] = cpu_ldl_data(env, ea+60); 116759543d4eSBastian Koppelmann } 116859543d4eSBastian Koppelmann 11699a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc) 11709a31922bSBastian Koppelmann { 11719a31922bSBastian Koppelmann target_ulong tmp_FCX; 11729a31922bSBastian Koppelmann target_ulong ea; 11739a31922bSBastian Koppelmann target_ulong new_FCX; 11749a31922bSBastian Koppelmann target_ulong psw; 11759a31922bSBastian Koppelmann 11769a31922bSBastian Koppelmann psw = psw_read(env); 11779a31922bSBastian Koppelmann /* if (FCX == 0) trap(FCU); */ 11789a31922bSBastian Koppelmann if (env->FCX == 0) { 11799a31922bSBastian Koppelmann /* FCU trap */ 11809a31922bSBastian Koppelmann } 11819a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */ 11829a31922bSBastian Koppelmann if (psw & MASK_PSW_CDE) { 11839a31922bSBastian Koppelmann if (cdc_increment(&psw)) { 11849a31922bSBastian Koppelmann /* CDO trap */ 11859a31922bSBastian Koppelmann } 11869a31922bSBastian Koppelmann } 11879a31922bSBastian Koppelmann /* PSW.CDE = 1;*/ 11889a31922bSBastian Koppelmann psw |= MASK_PSW_CDE; 11899a31922bSBastian Koppelmann /* tmp_FCX = FCX; */ 11909a31922bSBastian Koppelmann tmp_FCX = env->FCX; 11919a31922bSBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 11929a31922bSBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 11939a31922bSBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 1194030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 1195030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 1196030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 11979a31922bSBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 11989a31922bSBastian Koppelmann D[15]}; */ 1199030c58dfSBastian Koppelmann save_context_upper(env, ea); 12009a31922bSBastian Koppelmann 12019a31922bSBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 12029a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 12039a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 12049a31922bSBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 12059a31922bSBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 12069a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 12079a31922bSBastian Koppelmann /* PCXI.UL = 1; */ 12089a31922bSBastian Koppelmann env->PCXI |= MASK_PCXI_UL; 12099a31922bSBastian Koppelmann 12109a31922bSBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 12119a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 12129a31922bSBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 12139a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 12149a31922bSBastian Koppelmann /* A[11] = next_pc[31: 0]; */ 12159a31922bSBastian Koppelmann env->gpr_a[11] = next_pc; 12169a31922bSBastian Koppelmann 12179a31922bSBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 12189a31922bSBastian Koppelmann if (tmp_FCX == env->LCX) { 12199a31922bSBastian Koppelmann /* FCD trap */ 12209a31922bSBastian Koppelmann } 12219a31922bSBastian Koppelmann psw_write(env, psw); 12229a31922bSBastian Koppelmann } 12239a31922bSBastian Koppelmann 12249a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env) 12259a31922bSBastian Koppelmann { 12269a31922bSBastian Koppelmann target_ulong ea; 12279a31922bSBastian Koppelmann target_ulong new_PCXI; 12289a31922bSBastian Koppelmann target_ulong new_PSW, psw; 12299a31922bSBastian Koppelmann 12309a31922bSBastian Koppelmann psw = psw_read(env); 12319a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/ 12329a31922bSBastian Koppelmann if (env->PSW & MASK_PSW_CDE) { 12339a31922bSBastian Koppelmann if (cdc_decrement(&(env->PSW))) { 12349a31922bSBastian Koppelmann /* CDU trap */ 12359a31922bSBastian Koppelmann } 12369a31922bSBastian Koppelmann } 12379a31922bSBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 12389a31922bSBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 12399a31922bSBastian Koppelmann /* CSU trap */ 12409a31922bSBastian Koppelmann } 12419a31922bSBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 12429a31922bSBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 12439a31922bSBastian Koppelmann /* CTYP trap */ 12449a31922bSBastian Koppelmann } 12459a31922bSBastian Koppelmann /* PC = {A11 [31: 1], 1’b0}; */ 12469a31922bSBastian Koppelmann env->PC = env->gpr_a[11] & 0xfffffffe; 12479a31922bSBastian Koppelmann 12489a31922bSBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 12499a31922bSBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 12509a31922bSBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 12519a31922bSBastian Koppelmann /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 1252030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 12539a31922bSBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 1254030c58dfSBastian Koppelmann /* M(EA, word) = FCX; */ 1255030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 12569a31922bSBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 12579a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 12589a31922bSBastian Koppelmann /* PCXI = new_PCXI; */ 12599a31922bSBastian Koppelmann env->PCXI = new_PCXI; 12609a31922bSBastian Koppelmann 12619a31922bSBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_13)) { 12629a31922bSBastian Koppelmann /* PSW = new_PSW */ 12639a31922bSBastian Koppelmann psw_write(env, new_PSW); 12649a31922bSBastian Koppelmann } else { 12659a31922bSBastian Koppelmann /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */ 12669a31922bSBastian Koppelmann psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000))); 12679a31922bSBastian Koppelmann } 12689a31922bSBastian Koppelmann } 12699a31922bSBastian Koppelmann 12705de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9) 12715de93515SBastian Koppelmann { 12725de93515SBastian Koppelmann target_ulong tmp_FCX; 12735de93515SBastian Koppelmann target_ulong ea; 12745de93515SBastian Koppelmann target_ulong new_FCX; 12755de93515SBastian Koppelmann 12765de93515SBastian Koppelmann if (env->FCX == 0) { 12775de93515SBastian Koppelmann /* FCU trap */ 12785de93515SBastian Koppelmann } 12795de93515SBastian Koppelmann 12805de93515SBastian Koppelmann tmp_FCX = env->FCX; 12815de93515SBastian Koppelmann ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6); 12825de93515SBastian Koppelmann 1283030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 1284030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 1285030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4] 1286030c58dfSBastian Koppelmann , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */ 1287030c58dfSBastian Koppelmann save_context_lower(env, ea); 1288030c58dfSBastian Koppelmann 12895de93515SBastian Koppelmann 12905de93515SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */ 12915de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 12925de93515SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 12935de93515SBastian Koppelmann /* PCXI.PIE = ICR.IE */ 12945de93515SBastian Koppelmann env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) + 12955de93515SBastian Koppelmann ((env->ICR & MASK_ICR_IE) << 15)); 12965de93515SBastian Koppelmann /* PCXI.UL = 0 */ 12975de93515SBastian Koppelmann env->PCXI &= ~(MASK_PCXI_UL); 12985de93515SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0] */ 12995de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 13005de93515SBastian Koppelmann /* FXC[19: 0] = new_FCX[19: 0] */ 13015de93515SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 13025de93515SBastian Koppelmann /* ICR.IE = 1 */ 13035de93515SBastian Koppelmann env->ICR |= MASK_ICR_IE; 13045de93515SBastian Koppelmann 13055de93515SBastian Koppelmann env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/ 13065de93515SBastian Koppelmann 13075de93515SBastian Koppelmann if (tmp_FCX == env->LCX) { 13085de93515SBastian Koppelmann /* FCD trap */ 13095de93515SBastian Koppelmann } 13105de93515SBastian Koppelmann } 13115de93515SBastian Koppelmann 131244ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env) 131344ea3430SBastian Koppelmann { 131444ea3430SBastian Koppelmann target_ulong ea; 131544ea3430SBastian Koppelmann target_ulong new_PCXI; 131644ea3430SBastian Koppelmann target_ulong new_PSW; 131744ea3430SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 131844ea3430SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 131944ea3430SBastian Koppelmann /* raise csu trap */ 132044ea3430SBastian Koppelmann } 132144ea3430SBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 132244ea3430SBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 132344ea3430SBastian Koppelmann /* raise CTYP trap */ 132444ea3430SBastian Koppelmann } 132544ea3430SBastian Koppelmann /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */ 132644ea3430SBastian Koppelmann if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) { 132744ea3430SBastian Koppelmann /* raise MNG trap */ 132844ea3430SBastian Koppelmann } 132944ea3430SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 133044ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15); 133144ea3430SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 133244ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) + 133344ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCPN) >> 24); 133444ea3430SBastian Koppelmann /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/ 133544ea3430SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 133644ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 133744ea3430SBastian Koppelmann /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 1338030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 133944ea3430SBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 1340030c58dfSBastian Koppelmann /* M(EA, word) = FCX;*/ 1341030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 134244ea3430SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 134344ea3430SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 134444ea3430SBastian Koppelmann /* PCXI = new_PCXI; */ 134544ea3430SBastian Koppelmann env->PCXI = new_PCXI; 134644ea3430SBastian Koppelmann /* write psw */ 134744ea3430SBastian Koppelmann psw_write(env, new_PSW); 134844ea3430SBastian Koppelmann } 134944ea3430SBastian Koppelmann 135059543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) 135159543d4eSBastian Koppelmann { 135259543d4eSBastian Koppelmann uint32_t dummy; 135359543d4eSBastian Koppelmann /* insn doesn't load PCXI and RA */ 135459543d4eSBastian Koppelmann restore_context_lower(env, ea, &dummy, &dummy); 135559543d4eSBastian Koppelmann } 135659543d4eSBastian Koppelmann 135759543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea) 135859543d4eSBastian Koppelmann { 135959543d4eSBastian Koppelmann uint32_t dummy; 136059543d4eSBastian Koppelmann /* insn doesn't load PCXI and PSW */ 136159543d4eSBastian Koppelmann restore_context_upper(env, ea, &dummy, &dummy); 136259543d4eSBastian Koppelmann } 136359543d4eSBastian Koppelmann 136459543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea) 136559543d4eSBastian Koppelmann { 136659543d4eSBastian Koppelmann save_context_lower(env, ea); 136759543d4eSBastian Koppelmann } 136859543d4eSBastian Koppelmann 136959543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea) 137059543d4eSBastian Koppelmann { 137159543d4eSBastian Koppelmann save_context_upper(env, ea); 137259543d4eSBastian Koppelmann } 137359543d4eSBastian Koppelmann 13742b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg) 13752b2f7d97SBastian Koppelmann { 13762b2f7d97SBastian Koppelmann psw_write(env, arg); 13772b2f7d97SBastian Koppelmann } 13782b2f7d97SBastian Koppelmann 13792b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env) 13802b2f7d97SBastian Koppelmann { 13812b2f7d97SBastian Koppelmann return psw_read(env); 13822b2f7d97SBastian Koppelmann } 13832b2f7d97SBastian Koppelmann 13842b2f7d97SBastian Koppelmann 13852d30267eSBastian Koppelmann static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env, 13862d30267eSBastian Koppelmann uint32_t exception, 13872d30267eSBastian Koppelmann int error_code, 13882d30267eSBastian Koppelmann uintptr_t pc) 13892d30267eSBastian Koppelmann { 13902d30267eSBastian Koppelmann CPUState *cs = CPU(tricore_env_get_cpu(env)); 13912d30267eSBastian Koppelmann cs->exception_index = exception; 13922d30267eSBastian Koppelmann env->error_code = error_code; 13932d30267eSBastian Koppelmann 13942d30267eSBastian Koppelmann if (pc) { 13952d30267eSBastian Koppelmann /* now we have a real cpu fault */ 13962d30267eSBastian Koppelmann cpu_restore_state(cs, pc); 13972d30267eSBastian Koppelmann } 13982d30267eSBastian Koppelmann 13992d30267eSBastian Koppelmann cpu_loop_exit(cs); 14002d30267eSBastian Koppelmann } 14012d30267eSBastian Koppelmann 140248e06fe0SBastian Koppelmann void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx, 140348e06fe0SBastian Koppelmann uintptr_t retaddr) 140448e06fe0SBastian Koppelmann { 14052d30267eSBastian Koppelmann int ret; 14062d30267eSBastian Koppelmann ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx); 14072d30267eSBastian Koppelmann if (ret) { 14082d30267eSBastian Koppelmann TriCoreCPU *cpu = TRICORE_CPU(cs); 14092d30267eSBastian Koppelmann CPUTriCoreState *env = &cpu->env; 14102d30267eSBastian Koppelmann do_raise_exception_err(env, cs->exception_index, 14112d30267eSBastian Koppelmann env->error_code, retaddr); 141248e06fe0SBastian Koppelmann } 14132d30267eSBastian Koppelmann } 1414