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 702754acdSThomas Huth * version 2.1 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 */ 1761d9f32bSPeter Maydell #include "qemu/osdep.h" 1848e06fe0SBastian Koppelmann #include "cpu.h" 1948e06fe0SBastian Koppelmann #include "qemu/host-utils.h" 2048e06fe0SBastian Koppelmann #include "exec/helper-proto.h" 2163c91552SPaolo Bonzini #include "exec/exec-all.h" 2248e06fe0SBastian Koppelmann #include "exec/cpu_ldst.h" 23e5c96c82SBastian Koppelmann #include <zlib.h> /* for crc32 */ 2448e06fe0SBastian Koppelmann 25518d7fd2SBastian Koppelmann 26518d7fd2SBastian Koppelmann /* Exception helpers */ 27518d7fd2SBastian Koppelmann 28*8905770bSMarc-André Lureau static G_NORETURN 29*8905770bSMarc-André Lureau void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin, 30518d7fd2SBastian Koppelmann uintptr_t pc, uint32_t fcd_pc) 31518d7fd2SBastian Koppelmann { 3206eb2e29SRichard Henderson CPUState *cs = env_cpu(env); 33518d7fd2SBastian Koppelmann /* in case we come from a helper-call we need to restore the PC */ 34afd46fcaSPavel Dovgalyuk cpu_restore_state(cs, pc, true); 35518d7fd2SBastian Koppelmann 36518d7fd2SBastian Koppelmann /* Tin is loaded into d[15] */ 37518d7fd2SBastian Koppelmann env->gpr_d[15] = tin; 38518d7fd2SBastian Koppelmann 39518d7fd2SBastian Koppelmann if (class == TRAPC_CTX_MNG && tin == TIN3_FCU) { 40518d7fd2SBastian Koppelmann /* upper context cannot be saved, if the context list is empty */ 41518d7fd2SBastian Koppelmann } else { 42518d7fd2SBastian Koppelmann helper_svucx(env); 43518d7fd2SBastian Koppelmann } 44518d7fd2SBastian Koppelmann 45518d7fd2SBastian Koppelmann /* The return address in a[11] is updated */ 46518d7fd2SBastian Koppelmann if (class == TRAPC_CTX_MNG && tin == TIN3_FCD) { 47518d7fd2SBastian Koppelmann env->SYSCON |= MASK_SYSCON_FCD_SF; 48518d7fd2SBastian Koppelmann /* when we run out of CSAs after saving a context a FCD trap is taken 49518d7fd2SBastian Koppelmann and the return address is the start of the trap handler which used 50518d7fd2SBastian Koppelmann the last CSA */ 51518d7fd2SBastian Koppelmann env->gpr_a[11] = fcd_pc; 52518d7fd2SBastian Koppelmann } else if (class == TRAPC_SYSCALL) { 53518d7fd2SBastian Koppelmann env->gpr_a[11] = env->PC + 4; 54518d7fd2SBastian Koppelmann } else { 55518d7fd2SBastian Koppelmann env->gpr_a[11] = env->PC; 56518d7fd2SBastian Koppelmann } 57518d7fd2SBastian Koppelmann /* The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP) 58518d7fd2SBastian Koppelmann when the processor was not previously using the interrupt stack 59518d7fd2SBastian Koppelmann (in case of PSW.IS = 0). The stack pointer bit is set for using the 60518d7fd2SBastian Koppelmann interrupt stack: PSW.IS = 1. */ 61518d7fd2SBastian Koppelmann if ((env->PSW & MASK_PSW_IS) == 0) { 62518d7fd2SBastian Koppelmann env->gpr_a[10] = env->ISP; 63518d7fd2SBastian Koppelmann } 64518d7fd2SBastian Koppelmann env->PSW |= MASK_PSW_IS; 65518d7fd2SBastian Koppelmann /* The I/O mode is set to Supervisor mode, which means all permissions 66518d7fd2SBastian Koppelmann are enabled: PSW.IO = 10 B .*/ 67518d7fd2SBastian Koppelmann env->PSW |= (2 << 10); 68518d7fd2SBastian Koppelmann 69518d7fd2SBastian Koppelmann /*The current Protection Register Set is set to 0: PSW.PRS = 00 B .*/ 70518d7fd2SBastian Koppelmann env->PSW &= ~MASK_PSW_PRS; 71518d7fd2SBastian Koppelmann 72518d7fd2SBastian Koppelmann /* The Call Depth Counter (CDC) is cleared, and the call depth limit is 73518d7fd2SBastian Koppelmann set for 64: PSW.CDC = 0000000 B .*/ 74518d7fd2SBastian Koppelmann env->PSW &= ~MASK_PSW_CDC; 75518d7fd2SBastian Koppelmann 76518d7fd2SBastian Koppelmann /* Call Depth Counter is enabled, PSW.CDE = 1. */ 77518d7fd2SBastian Koppelmann env->PSW |= MASK_PSW_CDE; 78518d7fd2SBastian Koppelmann 79518d7fd2SBastian Koppelmann /* Write permission to global registers A[0], A[1], A[8], A[9] is 80518d7fd2SBastian Koppelmann disabled: PSW.GW = 0. */ 81518d7fd2SBastian Koppelmann env->PSW &= ~MASK_PSW_GW; 82518d7fd2SBastian Koppelmann 83518d7fd2SBastian Koppelmann /*The interrupt system is globally disabled: ICR.IE = 0. The ‘old’ 84518d7fd2SBastian Koppelmann ICR.IE and ICR.CCPN are saved */ 85518d7fd2SBastian Koppelmann 86518d7fd2SBastian Koppelmann /* PCXI.PIE = ICR.IE */ 87ce46335cSDavid Brenken env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 88d1cbc28aSDavid Brenken ((env->ICR & MASK_ICR_IE_1_3) << 15)); 89518d7fd2SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */ 90518d7fd2SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 91518d7fd2SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 92518d7fd2SBastian Koppelmann /* Update PC using the trap vector table */ 93518d7fd2SBastian Koppelmann env->PC = env->BTV | (class << 5); 94518d7fd2SBastian Koppelmann 95518d7fd2SBastian Koppelmann cpu_loop_exit(cs); 96518d7fd2SBastian Koppelmann } 97518d7fd2SBastian Koppelmann 98518d7fd2SBastian Koppelmann void helper_raise_exception_sync(CPUTriCoreState *env, uint32_t class, 99518d7fd2SBastian Koppelmann uint32_t tin) 100518d7fd2SBastian Koppelmann { 101518d7fd2SBastian Koppelmann raise_exception_sync_internal(env, class, tin, 0, 0); 102518d7fd2SBastian Koppelmann } 103518d7fd2SBastian Koppelmann 1043292b447SBastian Koppelmann static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class, 1053292b447SBastian Koppelmann uint32_t tin, uintptr_t pc) 1063292b447SBastian Koppelmann { 1073292b447SBastian Koppelmann raise_exception_sync_internal(env, class, tin, pc, 0); 1083292b447SBastian Koppelmann } 1093292b447SBastian Koppelmann 1103a16ecb0SBastian Koppelmann /* Addressing mode helper */ 1113a16ecb0SBastian Koppelmann 1123a16ecb0SBastian Koppelmann static uint16_t reverse16(uint16_t val) 1133a16ecb0SBastian Koppelmann { 1143a16ecb0SBastian Koppelmann uint8_t high = (uint8_t)(val >> 8); 1153a16ecb0SBastian Koppelmann uint8_t low = (uint8_t)(val & 0xff); 1163a16ecb0SBastian Koppelmann 1173a16ecb0SBastian Koppelmann uint16_t rh, rl; 1183a16ecb0SBastian Koppelmann 1193a16ecb0SBastian Koppelmann rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023); 1203a16ecb0SBastian Koppelmann rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023); 1213a16ecb0SBastian Koppelmann 1223a16ecb0SBastian Koppelmann return (rh << 8) | rl; 1233a16ecb0SBastian Koppelmann } 1243a16ecb0SBastian Koppelmann 1253a16ecb0SBastian Koppelmann uint32_t helper_br_update(uint32_t reg) 1263a16ecb0SBastian Koppelmann { 1273a16ecb0SBastian Koppelmann uint32_t index = reg & 0xffff; 1283a16ecb0SBastian Koppelmann uint32_t incr = reg >> 16; 1293a16ecb0SBastian Koppelmann uint32_t new_index = reverse16(reverse16(index) + reverse16(incr)); 1303a16ecb0SBastian Koppelmann return reg - index + new_index; 1313a16ecb0SBastian Koppelmann } 1323a16ecb0SBastian Koppelmann 1333a16ecb0SBastian Koppelmann uint32_t helper_circ_update(uint32_t reg, uint32_t off) 1343a16ecb0SBastian Koppelmann { 1353a16ecb0SBastian Koppelmann uint32_t index = reg & 0xffff; 1363a16ecb0SBastian Koppelmann uint32_t length = reg >> 16; 1373a16ecb0SBastian Koppelmann int32_t new_index = index + off; 1383a16ecb0SBastian Koppelmann if (new_index < 0) { 1393a16ecb0SBastian Koppelmann new_index += length; 1403a16ecb0SBastian Koppelmann } else { 1413a16ecb0SBastian Koppelmann new_index %= length; 1423a16ecb0SBastian Koppelmann } 1433a16ecb0SBastian Koppelmann return reg - index + new_index; 1443a16ecb0SBastian Koppelmann } 1453a16ecb0SBastian Koppelmann 146e4e39176SBastian Koppelmann static uint32_t ssov32(CPUTriCoreState *env, int64_t arg) 147e4e39176SBastian Koppelmann { 148e4e39176SBastian Koppelmann uint32_t ret; 149e4e39176SBastian Koppelmann int64_t max_pos = INT32_MAX; 150e4e39176SBastian Koppelmann int64_t max_neg = INT32_MIN; 151e4e39176SBastian Koppelmann if (arg > max_pos) { 152e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 153e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 154e4e39176SBastian Koppelmann ret = (target_ulong)max_pos; 155e4e39176SBastian Koppelmann } else { 156e4e39176SBastian Koppelmann if (arg < max_neg) { 157e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 158e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 159e4e39176SBastian Koppelmann ret = (target_ulong)max_neg; 160e4e39176SBastian Koppelmann } else { 161e4e39176SBastian Koppelmann env->PSW_USB_V = 0; 162e4e39176SBastian Koppelmann ret = (target_ulong)arg; 163e4e39176SBastian Koppelmann } 164e4e39176SBastian Koppelmann } 165e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 166e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 167e4e39176SBastian Koppelmann return ret; 168e4e39176SBastian Koppelmann } 1692692802aSBastian Koppelmann 17085d604afSBastian Koppelmann static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg) 171e4e39176SBastian Koppelmann { 172e4e39176SBastian Koppelmann uint32_t ret; 17385d604afSBastian Koppelmann uint64_t max_pos = UINT32_MAX; 174e4e39176SBastian Koppelmann if (arg > max_pos) { 175e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 176e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 177e4e39176SBastian Koppelmann ret = (target_ulong)max_pos; 178e4e39176SBastian Koppelmann } else { 17985d604afSBastian Koppelmann env->PSW_USB_V = 0; 18085d604afSBastian Koppelmann ret = (target_ulong)arg; 18185d604afSBastian Koppelmann } 18285d604afSBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 18385d604afSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 18485d604afSBastian Koppelmann return ret; 18585d604afSBastian Koppelmann } 18685d604afSBastian Koppelmann 18785d604afSBastian Koppelmann static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg) 18885d604afSBastian Koppelmann { 18985d604afSBastian Koppelmann uint32_t ret; 19085d604afSBastian Koppelmann 191e4e39176SBastian Koppelmann if (arg < 0) { 192e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31); 193e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 194e4e39176SBastian Koppelmann ret = 0; 195e4e39176SBastian Koppelmann } else { 196e4e39176SBastian Koppelmann env->PSW_USB_V = 0; 197e4e39176SBastian Koppelmann ret = (target_ulong)arg; 198e4e39176SBastian Koppelmann } 199e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u; 200e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 201e4e39176SBastian Koppelmann return ret; 202e4e39176SBastian Koppelmann } 2030974257eSBastian Koppelmann 204d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 205d5de7839SBastian Koppelmann { 206d5de7839SBastian Koppelmann int32_t max_pos = INT16_MAX; 207d5de7839SBastian Koppelmann int32_t max_neg = INT16_MIN; 208d5de7839SBastian Koppelmann int32_t av0, av1; 209d5de7839SBastian Koppelmann 210d5de7839SBastian Koppelmann env->PSW_USB_V = 0; 211d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u; 212d5de7839SBastian Koppelmann if (hw0 > max_pos) { 213d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 214d5de7839SBastian Koppelmann hw0 = max_pos; 215d5de7839SBastian Koppelmann } else if (hw0 < max_neg) { 216d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 217d5de7839SBastian Koppelmann hw0 = max_neg; 218d5de7839SBastian Koppelmann } 219d5de7839SBastian Koppelmann 220d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u; 221d5de7839SBastian Koppelmann if (hw1 > max_pos) { 222d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 223d5de7839SBastian Koppelmann hw1 = max_pos; 224d5de7839SBastian Koppelmann } else if (hw1 < max_neg) { 225d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 226d5de7839SBastian Koppelmann hw1 = max_neg; 227d5de7839SBastian Koppelmann } 228d5de7839SBastian Koppelmann 229d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 230d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16; 231d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 232d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16); 233d5de7839SBastian Koppelmann } 234d5de7839SBastian Koppelmann 235d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1) 236d5de7839SBastian Koppelmann { 237d5de7839SBastian Koppelmann int32_t max_pos = UINT16_MAX; 238d5de7839SBastian Koppelmann int32_t av0, av1; 239d5de7839SBastian Koppelmann 240d5de7839SBastian Koppelmann env->PSW_USB_V = 0; 241d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u; 242d5de7839SBastian Koppelmann if (hw0 > max_pos) { 243d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 244d5de7839SBastian Koppelmann hw0 = max_pos; 245d5de7839SBastian Koppelmann } else if (hw0 < 0) { 246d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 247d5de7839SBastian Koppelmann hw0 = 0; 248d5de7839SBastian Koppelmann } 249d5de7839SBastian Koppelmann 250d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u; 251d5de7839SBastian Koppelmann if (hw1 > max_pos) { 252d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 253d5de7839SBastian Koppelmann hw1 = max_pos; 254d5de7839SBastian Koppelmann } else if (hw1 < 0) { 255d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31); 256d5de7839SBastian Koppelmann hw1 = 0; 257d5de7839SBastian Koppelmann } 258d5de7839SBastian Koppelmann 259d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 260d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16; 261d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 262d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16); 263d5de7839SBastian Koppelmann } 2640974257eSBastian Koppelmann 2652692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1, 2662692802aSBastian Koppelmann target_ulong r2) 2672692802aSBastian Koppelmann { 2682692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 2692692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 2702692802aSBastian Koppelmann int64_t result = t1 + t2; 271e4e39176SBastian Koppelmann return ssov32(env, result); 2722692802aSBastian Koppelmann } 2732692802aSBastian Koppelmann 2742e430e1cSBastian Koppelmann uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 2752e430e1cSBastian Koppelmann { 2762e430e1cSBastian Koppelmann uint64_t result; 2772e430e1cSBastian Koppelmann int64_t ovf; 2782e430e1cSBastian Koppelmann 2792e430e1cSBastian Koppelmann result = r1 + r2; 2802e430e1cSBastian Koppelmann ovf = (result ^ r1) & ~(r1 ^ r2); 2812e430e1cSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 2822e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 2832e430e1cSBastian Koppelmann if (ovf < 0) { 2842e430e1cSBastian Koppelmann env->PSW_USB_V = (1 << 31); 2852e430e1cSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 2862e430e1cSBastian Koppelmann /* ext_ret > MAX_INT */ 2872e430e1cSBastian Koppelmann if ((int64_t)r1 >= 0) { 2882e430e1cSBastian Koppelmann result = INT64_MAX; 2892e430e1cSBastian Koppelmann /* ext_ret < MIN_INT */ 2902e430e1cSBastian Koppelmann } else { 2912e430e1cSBastian Koppelmann result = INT64_MIN; 2922e430e1cSBastian Koppelmann } 2932e430e1cSBastian Koppelmann } else { 2942e430e1cSBastian Koppelmann env->PSW_USB_V = 0; 2952e430e1cSBastian Koppelmann } 2962e430e1cSBastian Koppelmann return result; 2972e430e1cSBastian Koppelmann } 2982e430e1cSBastian Koppelmann 299d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1, 300d5de7839SBastian Koppelmann target_ulong r2) 301d5de7839SBastian Koppelmann { 302d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 303d5de7839SBastian Koppelmann 304d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16); 305d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16); 306d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 307d5de7839SBastian Koppelmann } 308d5de7839SBastian Koppelmann 3092e430e1cSBastian Koppelmann uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 3102e430e1cSBastian Koppelmann uint32_t r2_h) 3112e430e1cSBastian Koppelmann { 3122e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 3132e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 3142e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 3152e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 3162e430e1cSBastian Koppelmann int64_t result0, result1; 3172e430e1cSBastian Koppelmann uint32_t ovf0, ovf1; 3182e430e1cSBastian Koppelmann uint32_t avf0, avf1; 3192e430e1cSBastian Koppelmann 3202e430e1cSBastian Koppelmann ovf0 = ovf1 = 0; 3212e430e1cSBastian Koppelmann 3222e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 3232e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 3242e430e1cSBastian Koppelmann 3252e430e1cSBastian Koppelmann avf0 = result0 * 2u; 3262e430e1cSBastian Koppelmann avf0 = result0 ^ avf0; 3272e430e1cSBastian Koppelmann avf1 = result1 * 2u; 3282e430e1cSBastian Koppelmann avf1 = result1 ^ avf1; 3292e430e1cSBastian Koppelmann 3302e430e1cSBastian Koppelmann if (result0 > INT32_MAX) { 3312e430e1cSBastian Koppelmann ovf0 = (1 << 31); 3322e430e1cSBastian Koppelmann result0 = INT32_MAX; 3332e430e1cSBastian Koppelmann } else if (result0 < INT32_MIN) { 3342e430e1cSBastian Koppelmann ovf0 = (1 << 31); 3352e430e1cSBastian Koppelmann result0 = INT32_MIN; 3362e430e1cSBastian Koppelmann } 3372e430e1cSBastian Koppelmann 3382e430e1cSBastian Koppelmann if (result1 > INT32_MAX) { 3392e430e1cSBastian Koppelmann ovf1 = (1 << 31); 3402e430e1cSBastian Koppelmann result1 = INT32_MAX; 3412e430e1cSBastian Koppelmann } else if (result1 < INT32_MIN) { 3422e430e1cSBastian Koppelmann ovf1 = (1 << 31); 3432e430e1cSBastian Koppelmann result1 = INT32_MIN; 3442e430e1cSBastian Koppelmann } 3452e430e1cSBastian Koppelmann 3462e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 3472e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 3482e430e1cSBastian Koppelmann 3492e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 3502e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 3512e430e1cSBastian Koppelmann 3522e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 3532e430e1cSBastian Koppelmann } 3542e430e1cSBastian Koppelmann 355bebe80fcSBastian Koppelmann uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 356bebe80fcSBastian Koppelmann uint32_t r2_h) 357bebe80fcSBastian Koppelmann { 358bebe80fcSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 359bebe80fcSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 360bebe80fcSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 361bebe80fcSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 362bebe80fcSBastian Koppelmann int64_t result0, result1; 363bebe80fcSBastian Koppelmann uint32_t ovf0, ovf1; 364bebe80fcSBastian Koppelmann uint32_t avf0, avf1; 365bebe80fcSBastian Koppelmann 366bebe80fcSBastian Koppelmann ovf0 = ovf1 = 0; 367bebe80fcSBastian Koppelmann 368bebe80fcSBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 369bebe80fcSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 370bebe80fcSBastian Koppelmann 371bebe80fcSBastian Koppelmann avf0 = result0 * 2u; 372bebe80fcSBastian Koppelmann avf0 = result0 ^ avf0; 373bebe80fcSBastian Koppelmann avf1 = result1 * 2u; 374bebe80fcSBastian Koppelmann avf1 = result1 ^ avf1; 375bebe80fcSBastian Koppelmann 376bebe80fcSBastian Koppelmann if (result0 > INT32_MAX) { 377bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 378bebe80fcSBastian Koppelmann result0 = INT32_MAX; 379bebe80fcSBastian Koppelmann } else if (result0 < INT32_MIN) { 380bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 381bebe80fcSBastian Koppelmann result0 = INT32_MIN; 382bebe80fcSBastian Koppelmann } 383bebe80fcSBastian Koppelmann 384bebe80fcSBastian Koppelmann if (result1 > INT32_MAX) { 385bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 386bebe80fcSBastian Koppelmann result1 = INT32_MAX; 387bebe80fcSBastian Koppelmann } else if (result1 < INT32_MIN) { 388bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 389bebe80fcSBastian Koppelmann result1 = INT32_MIN; 390bebe80fcSBastian Koppelmann } 391bebe80fcSBastian Koppelmann 392bebe80fcSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 393bebe80fcSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 394bebe80fcSBastian Koppelmann 395bebe80fcSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 396bebe80fcSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 397bebe80fcSBastian Koppelmann 398bebe80fcSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 399bebe80fcSBastian Koppelmann } 400bebe80fcSBastian Koppelmann 4012e430e1cSBastian Koppelmann 4020974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1, 4030974257eSBastian Koppelmann target_ulong r2) 4040974257eSBastian Koppelmann { 4050974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 4060974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 4070974257eSBastian Koppelmann int64_t result = t1 + t2; 40885d604afSBastian Koppelmann return suov32_pos(env, result); 4090974257eSBastian Koppelmann } 4100974257eSBastian Koppelmann 411d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1, 412d5de7839SBastian Koppelmann target_ulong r2) 413d5de7839SBastian Koppelmann { 414d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 415d5de7839SBastian Koppelmann 416d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16); 417d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16); 418d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 419d5de7839SBastian Koppelmann } 420d5de7839SBastian Koppelmann 4212692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1, 4222692802aSBastian Koppelmann target_ulong r2) 4232692802aSBastian Koppelmann { 4242692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 4252692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 4262692802aSBastian Koppelmann int64_t result = t1 - t2; 427e4e39176SBastian Koppelmann return ssov32(env, result); 4282692802aSBastian Koppelmann } 4292692802aSBastian Koppelmann 430f4aef476SBastian Koppelmann uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 431f4aef476SBastian Koppelmann { 432f4aef476SBastian Koppelmann uint64_t result; 433f4aef476SBastian Koppelmann int64_t ovf; 434f4aef476SBastian Koppelmann 435f4aef476SBastian Koppelmann result = r1 - r2; 436f4aef476SBastian Koppelmann ovf = (result ^ r1) & (r1 ^ r2); 437f4aef476SBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 438f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 439f4aef476SBastian Koppelmann if (ovf < 0) { 440f4aef476SBastian Koppelmann env->PSW_USB_V = (1 << 31); 441f4aef476SBastian Koppelmann env->PSW_USB_SV = (1 << 31); 442f4aef476SBastian Koppelmann /* ext_ret > MAX_INT */ 443f4aef476SBastian Koppelmann if ((int64_t)r1 >= 0) { 444f4aef476SBastian Koppelmann result = INT64_MAX; 445f4aef476SBastian Koppelmann /* ext_ret < MIN_INT */ 446f4aef476SBastian Koppelmann } else { 447f4aef476SBastian Koppelmann result = INT64_MIN; 448f4aef476SBastian Koppelmann } 449f4aef476SBastian Koppelmann } else { 450f4aef476SBastian Koppelmann env->PSW_USB_V = 0; 451f4aef476SBastian Koppelmann } 452f4aef476SBastian Koppelmann return result; 453f4aef476SBastian Koppelmann } 454f4aef476SBastian Koppelmann 455d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1, 456d5de7839SBastian Koppelmann target_ulong r2) 457d5de7839SBastian Koppelmann { 458d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 459d5de7839SBastian Koppelmann 460d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16); 461d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16); 462d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1); 463d5de7839SBastian Koppelmann } 464d5de7839SBastian Koppelmann 465f4aef476SBastian Koppelmann uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 466f4aef476SBastian Koppelmann uint32_t r2_h) 467f4aef476SBastian Koppelmann { 468f4aef476SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 469f4aef476SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 470f4aef476SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 471f4aef476SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 472f4aef476SBastian Koppelmann int64_t result0, result1; 473f4aef476SBastian Koppelmann uint32_t ovf0, ovf1; 474f4aef476SBastian Koppelmann uint32_t avf0, avf1; 475f4aef476SBastian Koppelmann 476f4aef476SBastian Koppelmann ovf0 = ovf1 = 0; 477f4aef476SBastian Koppelmann 478f4aef476SBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 479f4aef476SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 480f4aef476SBastian Koppelmann 481f4aef476SBastian Koppelmann avf0 = result0 * 2u; 482f4aef476SBastian Koppelmann avf0 = result0 ^ avf0; 483f4aef476SBastian Koppelmann avf1 = result1 * 2u; 484f4aef476SBastian Koppelmann avf1 = result1 ^ avf1; 485f4aef476SBastian Koppelmann 486f4aef476SBastian Koppelmann if (result0 > INT32_MAX) { 487f4aef476SBastian Koppelmann ovf0 = (1 << 31); 488f4aef476SBastian Koppelmann result0 = INT32_MAX; 489f4aef476SBastian Koppelmann } else if (result0 < INT32_MIN) { 490f4aef476SBastian Koppelmann ovf0 = (1 << 31); 491f4aef476SBastian Koppelmann result0 = INT32_MIN; 492f4aef476SBastian Koppelmann } 493f4aef476SBastian Koppelmann 494f4aef476SBastian Koppelmann if (result1 > INT32_MAX) { 495f4aef476SBastian Koppelmann ovf1 = (1 << 31); 496f4aef476SBastian Koppelmann result1 = INT32_MAX; 497f4aef476SBastian Koppelmann } else if (result1 < INT32_MIN) { 498f4aef476SBastian Koppelmann ovf1 = (1 << 31); 499f4aef476SBastian Koppelmann result1 = INT32_MIN; 500f4aef476SBastian Koppelmann } 501f4aef476SBastian Koppelmann 502f4aef476SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 503f4aef476SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 504f4aef476SBastian Koppelmann 505f4aef476SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 506f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 507f4aef476SBastian Koppelmann 508f4aef476SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 509f4aef476SBastian Koppelmann } 510f4aef476SBastian Koppelmann 511068fac77SBastian Koppelmann uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 512068fac77SBastian Koppelmann uint32_t r2_h) 513068fac77SBastian Koppelmann { 514068fac77SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 515068fac77SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 516068fac77SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 517068fac77SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 518068fac77SBastian Koppelmann int64_t result0, result1; 519068fac77SBastian Koppelmann uint32_t ovf0, ovf1; 520068fac77SBastian Koppelmann uint32_t avf0, avf1; 521068fac77SBastian Koppelmann 522068fac77SBastian Koppelmann ovf0 = ovf1 = 0; 523068fac77SBastian Koppelmann 524068fac77SBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 525068fac77SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 526068fac77SBastian Koppelmann 527068fac77SBastian Koppelmann avf0 = result0 * 2u; 528068fac77SBastian Koppelmann avf0 = result0 ^ avf0; 529068fac77SBastian Koppelmann avf1 = result1 * 2u; 530068fac77SBastian Koppelmann avf1 = result1 ^ avf1; 531068fac77SBastian Koppelmann 532068fac77SBastian Koppelmann if (result0 > INT32_MAX) { 533068fac77SBastian Koppelmann ovf0 = (1 << 31); 534068fac77SBastian Koppelmann result0 = INT32_MAX; 535068fac77SBastian Koppelmann } else if (result0 < INT32_MIN) { 536068fac77SBastian Koppelmann ovf0 = (1 << 31); 537068fac77SBastian Koppelmann result0 = INT32_MIN; 538068fac77SBastian Koppelmann } 539068fac77SBastian Koppelmann 540068fac77SBastian Koppelmann if (result1 > INT32_MAX) { 541068fac77SBastian Koppelmann ovf1 = (1 << 31); 542068fac77SBastian Koppelmann result1 = INT32_MAX; 543068fac77SBastian Koppelmann } else if (result1 < INT32_MIN) { 544068fac77SBastian Koppelmann ovf1 = (1 << 31); 545068fac77SBastian Koppelmann result1 = INT32_MIN; 546068fac77SBastian Koppelmann } 547068fac77SBastian Koppelmann 548068fac77SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 549068fac77SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 550068fac77SBastian Koppelmann 551068fac77SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 552068fac77SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 553068fac77SBastian Koppelmann 554068fac77SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 555068fac77SBastian Koppelmann } 556068fac77SBastian Koppelmann 5570974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1, 5580974257eSBastian Koppelmann target_ulong r2) 5590974257eSBastian Koppelmann { 5600974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 5610974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 5620974257eSBastian Koppelmann int64_t result = t1 - t2; 56385d604afSBastian Koppelmann return suov32_neg(env, result); 5640974257eSBastian Koppelmann } 5650974257eSBastian Koppelmann 566d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1, 567d5de7839SBastian Koppelmann target_ulong r2) 568d5de7839SBastian Koppelmann { 569d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1; 570d5de7839SBastian Koppelmann 571d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16); 572d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16); 573d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1); 574d5de7839SBastian Koppelmann } 575d5de7839SBastian Koppelmann 5760974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1, 5770974257eSBastian Koppelmann target_ulong r2) 5780974257eSBastian Koppelmann { 5790974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 5800974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 5810974257eSBastian Koppelmann int64_t result = t1 * t2; 582e4e39176SBastian Koppelmann return ssov32(env, result); 5830974257eSBastian Koppelmann } 5840974257eSBastian Koppelmann 5850974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1, 5860974257eSBastian Koppelmann target_ulong r2) 5870974257eSBastian Koppelmann { 5880974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32); 5890974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32); 5900974257eSBastian Koppelmann int64_t result = t1 * t2; 5915f30046fSBastian Koppelmann 59285d604afSBastian Koppelmann return suov32_pos(env, result); 5930974257eSBastian Koppelmann } 5940974257eSBastian Koppelmann 5950974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1, 5960974257eSBastian Koppelmann target_ulong r2) 5970974257eSBastian Koppelmann { 5980974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 5990974257eSBastian Koppelmann int32_t t2 = sextract64(r2, 0, 6); 6000974257eSBastian Koppelmann int64_t result; 6010974257eSBastian Koppelmann if (t2 == 0) { 6020974257eSBastian Koppelmann result = t1; 6030974257eSBastian Koppelmann } else if (t2 > 0) { 6040974257eSBastian Koppelmann result = t1 << t2; 6050974257eSBastian Koppelmann } else { 6060974257eSBastian Koppelmann result = t1 >> -t2; 6070974257eSBastian Koppelmann } 608e4e39176SBastian Koppelmann return ssov32(env, result); 6090974257eSBastian Koppelmann } 6100974257eSBastian Koppelmann 611d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1) 612d5de7839SBastian Koppelmann { 613d5de7839SBastian Koppelmann target_ulong result; 614d5de7839SBastian Koppelmann result = ((int32_t)r1 >= 0) ? r1 : (0 - r1); 615d5de7839SBastian Koppelmann return ssov32(env, result); 616d5de7839SBastian Koppelmann } 617d5de7839SBastian Koppelmann 618d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1) 619d5de7839SBastian Koppelmann { 620d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 621d5de7839SBastian Koppelmann 622d5de7839SBastian Koppelmann ret_h0 = sextract32(r1, 0, 16); 623d5de7839SBastian Koppelmann ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0); 624d5de7839SBastian Koppelmann 625d5de7839SBastian Koppelmann ret_h1 = sextract32(r1, 16, 16); 626d5de7839SBastian Koppelmann ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1); 627d5de7839SBastian Koppelmann 628d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 629d5de7839SBastian Koppelmann } 630d5de7839SBastian Koppelmann 6310974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1, 6320974257eSBastian Koppelmann target_ulong r2) 6330974257eSBastian Koppelmann { 6340974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 6350974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 6360974257eSBastian Koppelmann int64_t result; 6370974257eSBastian Koppelmann 6380974257eSBastian Koppelmann if (t1 > t2) { 6390974257eSBastian Koppelmann result = t1 - t2; 6400974257eSBastian Koppelmann } else { 6410974257eSBastian Koppelmann result = t2 - t1; 6420974257eSBastian Koppelmann } 643e4e39176SBastian Koppelmann return ssov32(env, result); 6440974257eSBastian Koppelmann } 645328f1f0fSBastian Koppelmann 646d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1, 647d5de7839SBastian Koppelmann target_ulong r2) 648d5de7839SBastian Koppelmann { 649d5de7839SBastian Koppelmann int32_t t1, t2; 650d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1; 651d5de7839SBastian Koppelmann 652d5de7839SBastian Koppelmann t1 = sextract32(r1, 0, 16); 653d5de7839SBastian Koppelmann t2 = sextract32(r2, 0, 16); 654d5de7839SBastian Koppelmann if (t1 > t2) { 655d5de7839SBastian Koppelmann ret_h0 = t1 - t2; 656d5de7839SBastian Koppelmann } else { 657d5de7839SBastian Koppelmann ret_h0 = t2 - t1; 658d5de7839SBastian Koppelmann } 659d5de7839SBastian Koppelmann 660d5de7839SBastian Koppelmann t1 = sextract32(r1, 16, 16); 661d5de7839SBastian Koppelmann t2 = sextract32(r2, 16, 16); 662d5de7839SBastian Koppelmann if (t1 > t2) { 663d5de7839SBastian Koppelmann ret_h1 = t1 - t2; 664d5de7839SBastian Koppelmann } else { 665d5de7839SBastian Koppelmann ret_h1 = t2 - t1; 666d5de7839SBastian Koppelmann } 667d5de7839SBastian Koppelmann 668d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1); 669d5de7839SBastian Koppelmann } 670d5de7839SBastian Koppelmann 671328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1, 672328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 673328f1f0fSBastian Koppelmann { 674328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 675328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 676328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 677328f1f0fSBastian Koppelmann int64_t result; 678328f1f0fSBastian Koppelmann 679328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 680e4e39176SBastian Koppelmann return ssov32(env, result); 681328f1f0fSBastian Koppelmann } 682328f1f0fSBastian Koppelmann 683328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1, 684328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 685328f1f0fSBastian Koppelmann { 686328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 687328f1f0fSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 688328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 689328f1f0fSBastian Koppelmann int64_t result; 690328f1f0fSBastian Koppelmann 691328f1f0fSBastian Koppelmann result = t2 + (t1 * t3); 69285d604afSBastian Koppelmann return suov32_pos(env, result); 693328f1f0fSBastian Koppelmann } 694328f1f0fSBastian Koppelmann 695328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1, 696328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 697328f1f0fSBastian Koppelmann { 698328f1f0fSBastian Koppelmann uint64_t ret, ovf; 699328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 700328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 701328f1f0fSBastian Koppelmann int64_t mul; 702328f1f0fSBastian Koppelmann 703328f1f0fSBastian Koppelmann mul = t1 * t3; 704328f1f0fSBastian Koppelmann ret = mul + r2; 705328f1f0fSBastian Koppelmann ovf = (ret ^ mul) & ~(mul ^ r2); 706328f1f0fSBastian Koppelmann 707811ea608SBastian Koppelmann t1 = ret >> 32; 708811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 709811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 710811ea608SBastian Koppelmann 711328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 712328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 713328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 714328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 715328f1f0fSBastian Koppelmann if (mul >= 0) { 716328f1f0fSBastian Koppelmann ret = INT64_MAX; 717328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 718328f1f0fSBastian Koppelmann } else { 719328f1f0fSBastian Koppelmann ret = INT64_MIN; 720328f1f0fSBastian Koppelmann } 721328f1f0fSBastian Koppelmann } else { 722328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 723328f1f0fSBastian Koppelmann } 724328f1f0fSBastian Koppelmann 725328f1f0fSBastian Koppelmann return ret; 726328f1f0fSBastian Koppelmann } 727328f1f0fSBastian Koppelmann 728b00aa8ecSBastian Koppelmann uint32_t 729b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 730b00aa8ecSBastian Koppelmann { 731b00aa8ecSBastian Koppelmann int64_t result; 732b00aa8ecSBastian Koppelmann 733b00aa8ecSBastian Koppelmann result = (r1 + r2); 734b00aa8ecSBastian Koppelmann 735b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u); 736b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 737b00aa8ecSBastian Koppelmann 738b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 739b00aa8ecSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 740b00aa8ecSBastian Koppelmann case, we flip the saturated value. */ 741b00aa8ecSBastian Koppelmann if (r2 == 0x8000000000000000LL) { 742b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) { 743b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 744b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 745b00aa8ecSBastian Koppelmann result = INT32_MIN; 746b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) { 747b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 748b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 749b00aa8ecSBastian Koppelmann result = INT32_MAX; 750b00aa8ecSBastian Koppelmann } else { 751b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 752b00aa8ecSBastian Koppelmann } 753b00aa8ecSBastian Koppelmann } else { 754b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) { 755b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 756b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 757b00aa8ecSBastian Koppelmann result = INT32_MAX; 758b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) { 759b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 760b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 761b00aa8ecSBastian Koppelmann result = INT32_MIN; 762b00aa8ecSBastian Koppelmann } else { 763b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 764b00aa8ecSBastian Koppelmann } 765b00aa8ecSBastian Koppelmann } 766b00aa8ecSBastian Koppelmann return (uint32_t)result; 767b00aa8ecSBastian Koppelmann } 768b00aa8ecSBastian Koppelmann 769b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 770b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 771b00aa8ecSBastian Koppelmann { 772b00aa8ecSBastian Koppelmann int64_t t1 = (int64_t)r1; 773b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 774b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 775b00aa8ecSBastian Koppelmann int64_t result, mul; 776b00aa8ecSBastian Koppelmann int64_t ovf; 777b00aa8ecSBastian Koppelmann 778b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 779b00aa8ecSBastian Koppelmann result = mul + t1; 780b00aa8ecSBastian Koppelmann 781b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 782b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 783b00aa8ecSBastian Koppelmann 784b00aa8ecSBastian Koppelmann ovf = (result ^ mul) & ~(mul ^ t1); 785b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 786b00aa8ecSBastian Koppelmann if the mul was (0x80000000 * 0x80000000) << 1). If this is the 787b00aa8ecSBastian Koppelmann case, we flip the saturated value. */ 788b00aa8ecSBastian Koppelmann if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) { 789b00aa8ecSBastian Koppelmann if (ovf >= 0) { 790b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 791b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 792b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */ 793b00aa8ecSBastian Koppelmann if (mul < 0) { 794b00aa8ecSBastian Koppelmann result = INT64_MAX; 795b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */ 796b00aa8ecSBastian Koppelmann } else { 797b00aa8ecSBastian Koppelmann result = INT64_MIN; 798b00aa8ecSBastian Koppelmann } 799b00aa8ecSBastian Koppelmann } else { 800b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 801b00aa8ecSBastian Koppelmann } 802b00aa8ecSBastian Koppelmann } else { 803b00aa8ecSBastian Koppelmann if (ovf < 0) { 804b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 805b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 806b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */ 807b00aa8ecSBastian Koppelmann if (mul >= 0) { 808b00aa8ecSBastian Koppelmann result = INT64_MAX; 809b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */ 810b00aa8ecSBastian Koppelmann } else { 811b00aa8ecSBastian Koppelmann result = INT64_MIN; 812b00aa8ecSBastian Koppelmann } 813b00aa8ecSBastian Koppelmann } else { 814b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 815b00aa8ecSBastian Koppelmann } 816b00aa8ecSBastian Koppelmann } 817b00aa8ecSBastian Koppelmann return (uint64_t)result; 818b00aa8ecSBastian Koppelmann } 819b00aa8ecSBastian Koppelmann 820b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 821b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 822b00aa8ecSBastian Koppelmann { 823b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 824b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 825b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 826b00aa8ecSBastian Koppelmann int64_t mul, ret; 827b00aa8ecSBastian Koppelmann 828b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 829b00aa8ecSBastian Koppelmann mul = 0x7fffffff; 830b00aa8ecSBastian Koppelmann } else { 831b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 832b00aa8ecSBastian Koppelmann } 833b00aa8ecSBastian Koppelmann 834b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000; 835b00aa8ecSBastian Koppelmann 836b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 837b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 838b00aa8ecSBastian Koppelmann 839b00aa8ecSBastian Koppelmann if (ret > 0x7fffffffll) { 840b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 841b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 842b00aa8ecSBastian Koppelmann ret = INT32_MAX; 843b00aa8ecSBastian Koppelmann } else if (ret < -0x80000000ll) { 844b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 845b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 846b00aa8ecSBastian Koppelmann ret = INT32_MIN; 847b00aa8ecSBastian Koppelmann } else { 848b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 849b00aa8ecSBastian Koppelmann } 850b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll; 851b00aa8ecSBastian Koppelmann } 852b00aa8ecSBastian Koppelmann 853328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1, 854328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 855328f1f0fSBastian Koppelmann { 856328f1f0fSBastian Koppelmann uint64_t ret, mul; 857328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 858328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 859328f1f0fSBastian Koppelmann 860328f1f0fSBastian Koppelmann mul = t1 * t3; 861328f1f0fSBastian Koppelmann ret = mul + r2; 862328f1f0fSBastian Koppelmann 863811ea608SBastian Koppelmann t1 = ret >> 32; 864811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 865811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 866811ea608SBastian Koppelmann 867328f1f0fSBastian Koppelmann if (ret < r2) { 868328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 869328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 870328f1f0fSBastian Koppelmann /* saturate */ 871328f1f0fSBastian Koppelmann ret = UINT64_MAX; 872328f1f0fSBastian Koppelmann } else { 873328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 874328f1f0fSBastian Koppelmann } 875328f1f0fSBastian Koppelmann return ret; 876328f1f0fSBastian Koppelmann } 877328f1f0fSBastian Koppelmann 878328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1, 879328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 880328f1f0fSBastian Koppelmann { 881328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 882328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 883328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 884328f1f0fSBastian Koppelmann int64_t result; 885328f1f0fSBastian Koppelmann 886328f1f0fSBastian Koppelmann result = t2 - (t1 * t3); 887e4e39176SBastian Koppelmann return ssov32(env, result); 888328f1f0fSBastian Koppelmann } 889328f1f0fSBastian Koppelmann 890328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1, 891328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3) 892328f1f0fSBastian Koppelmann { 8933debbb5aSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 8943debbb5aSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32); 8953debbb5aSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 8963debbb5aSBastian Koppelmann uint64_t result; 8973debbb5aSBastian Koppelmann uint64_t mul; 898328f1f0fSBastian Koppelmann 8993debbb5aSBastian Koppelmann mul = (t1 * t3); 9003debbb5aSBastian Koppelmann result = t2 - mul; 9013debbb5aSBastian Koppelmann 9023debbb5aSBastian Koppelmann env->PSW_USB_AV = result ^ result * 2u; 9033debbb5aSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 9043debbb5aSBastian Koppelmann /* we calculate ovf by hand here, because the multiplication can overflow on 9053debbb5aSBastian Koppelmann the host, which would give false results if we compare to less than 9063debbb5aSBastian Koppelmann zero */ 9073debbb5aSBastian Koppelmann if (mul > t2) { 9083debbb5aSBastian Koppelmann env->PSW_USB_V = (1 << 31); 9093debbb5aSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 9103debbb5aSBastian Koppelmann result = 0; 9113debbb5aSBastian Koppelmann } else { 9123debbb5aSBastian Koppelmann env->PSW_USB_V = 0; 9133debbb5aSBastian Koppelmann } 9143debbb5aSBastian Koppelmann return result; 915328f1f0fSBastian Koppelmann } 916328f1f0fSBastian Koppelmann 917328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1, 918328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 919328f1f0fSBastian Koppelmann { 920328f1f0fSBastian Koppelmann uint64_t ret, ovf; 921328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 922328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 923328f1f0fSBastian Koppelmann int64_t mul; 924328f1f0fSBastian Koppelmann 925328f1f0fSBastian Koppelmann mul = t1 * t3; 926328f1f0fSBastian Koppelmann ret = r2 - mul; 927328f1f0fSBastian Koppelmann ovf = (ret ^ r2) & (mul ^ r2); 928328f1f0fSBastian Koppelmann 929811ea608SBastian Koppelmann t1 = ret >> 32; 930811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 931811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 932811ea608SBastian Koppelmann 933328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) { 934328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 935328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 936328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */ 937328f1f0fSBastian Koppelmann if (mul < 0) { 938328f1f0fSBastian Koppelmann ret = INT64_MAX; 939328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */ 940328f1f0fSBastian Koppelmann } else { 941328f1f0fSBastian Koppelmann ret = INT64_MIN; 942328f1f0fSBastian Koppelmann } 943328f1f0fSBastian Koppelmann } else { 944328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 945328f1f0fSBastian Koppelmann } 946328f1f0fSBastian Koppelmann return ret; 947328f1f0fSBastian Koppelmann } 948328f1f0fSBastian Koppelmann 949328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1, 950328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3) 951328f1f0fSBastian Koppelmann { 952328f1f0fSBastian Koppelmann uint64_t ret, mul; 953328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32); 954328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32); 955328f1f0fSBastian Koppelmann 956328f1f0fSBastian Koppelmann mul = t1 * t3; 957328f1f0fSBastian Koppelmann ret = r2 - mul; 958328f1f0fSBastian Koppelmann 959811ea608SBastian Koppelmann t1 = ret >> 32; 960811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u; 961811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 962811ea608SBastian Koppelmann 963328f1f0fSBastian Koppelmann if (ret > r2) { 964328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31); 965328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 966328f1f0fSBastian Koppelmann /* saturate */ 967328f1f0fSBastian Koppelmann ret = 0; 968328f1f0fSBastian Koppelmann } else { 969328f1f0fSBastian Koppelmann env->PSW_USB_V = 0; 970328f1f0fSBastian Koppelmann } 971328f1f0fSBastian Koppelmann return ret; 972328f1f0fSBastian Koppelmann } 973328f1f0fSBastian Koppelmann 97462e47b2eSBastian Koppelmann uint32_t 97562e47b2eSBastian Koppelmann helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2) 97662e47b2eSBastian Koppelmann { 97762e47b2eSBastian Koppelmann int64_t result; 97862e47b2eSBastian Koppelmann int64_t t1 = (int64_t)r1; 97962e47b2eSBastian Koppelmann int64_t t2 = (int64_t)r2; 98062e47b2eSBastian Koppelmann 98162e47b2eSBastian Koppelmann result = t1 - t2; 98262e47b2eSBastian Koppelmann 98362e47b2eSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u); 98462e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 98562e47b2eSBastian Koppelmann 98662e47b2eSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 98762e47b2eSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 98862e47b2eSBastian Koppelmann case, we flip the saturated value. */ 98962e47b2eSBastian Koppelmann if (r2 == 0x8000000000000000LL) { 99062e47b2eSBastian Koppelmann if (result > 0x7fffffffLL) { 99162e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 99262e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 99362e47b2eSBastian Koppelmann result = INT32_MIN; 99462e47b2eSBastian Koppelmann } else if (result < -0x80000000LL) { 99562e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 99662e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 99762e47b2eSBastian Koppelmann result = INT32_MAX; 99862e47b2eSBastian Koppelmann } else { 99962e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 100062e47b2eSBastian Koppelmann } 100162e47b2eSBastian Koppelmann } else { 100262e47b2eSBastian Koppelmann if (result > 0x7fffffffLL) { 100362e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 100462e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 100562e47b2eSBastian Koppelmann result = INT32_MAX; 100662e47b2eSBastian Koppelmann } else if (result < -0x80000000LL) { 100762e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 100862e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 100962e47b2eSBastian Koppelmann result = INT32_MIN; 101062e47b2eSBastian Koppelmann } else { 101162e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 101262e47b2eSBastian Koppelmann } 101362e47b2eSBastian Koppelmann } 101462e47b2eSBastian Koppelmann return (uint32_t)result; 101562e47b2eSBastian Koppelmann } 101662e47b2eSBastian Koppelmann 101762e47b2eSBastian Koppelmann uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2, 101862e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 101962e47b2eSBastian Koppelmann { 102062e47b2eSBastian Koppelmann int64_t t1 = (int64_t)r1; 102162e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 102262e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 102362e47b2eSBastian Koppelmann int64_t result, mul; 102462e47b2eSBastian Koppelmann int64_t ovf; 102562e47b2eSBastian Koppelmann 102662e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 102762e47b2eSBastian Koppelmann result = t1 - mul; 102862e47b2eSBastian Koppelmann 102962e47b2eSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32; 103062e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 103162e47b2eSBastian Koppelmann 103262e47b2eSBastian Koppelmann ovf = (result ^ t1) & (t1 ^ mul); 103362e47b2eSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host 103462e47b2eSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the 103562e47b2eSBastian Koppelmann case, we flip the saturated value. */ 103662e47b2eSBastian Koppelmann if (mul == 0x8000000000000000LL) { 103762e47b2eSBastian Koppelmann if (ovf >= 0) { 103862e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 103962e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 104062e47b2eSBastian Koppelmann /* ext_ret > MAX_INT */ 104162e47b2eSBastian Koppelmann if (mul >= 0) { 104262e47b2eSBastian Koppelmann result = INT64_MAX; 104362e47b2eSBastian Koppelmann /* ext_ret < MIN_INT */ 104462e47b2eSBastian Koppelmann } else { 104562e47b2eSBastian Koppelmann result = INT64_MIN; 104662e47b2eSBastian Koppelmann } 10479029710bSBastian Koppelmann } else { 10489029710bSBastian Koppelmann env->PSW_USB_V = 0; 104962e47b2eSBastian Koppelmann } 105062e47b2eSBastian Koppelmann } else { 105162e47b2eSBastian Koppelmann if (ovf < 0) { 105262e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 105362e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31); 105462e47b2eSBastian Koppelmann /* ext_ret > MAX_INT */ 105562e47b2eSBastian Koppelmann if (mul < 0) { 105662e47b2eSBastian Koppelmann result = INT64_MAX; 105762e47b2eSBastian Koppelmann /* ext_ret < MIN_INT */ 105862e47b2eSBastian Koppelmann } else { 105962e47b2eSBastian Koppelmann result = INT64_MIN; 106062e47b2eSBastian Koppelmann } 106162e47b2eSBastian Koppelmann } else { 106262e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 106362e47b2eSBastian Koppelmann } 106462e47b2eSBastian Koppelmann } 106562e47b2eSBastian Koppelmann 106662e47b2eSBastian Koppelmann return (uint64_t)result; 106762e47b2eSBastian Koppelmann } 106862e47b2eSBastian Koppelmann 106962e47b2eSBastian Koppelmann uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 107062e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 107162e47b2eSBastian Koppelmann { 107262e47b2eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 107362e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 107462e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 107562e47b2eSBastian Koppelmann int64_t mul, ret; 107662e47b2eSBastian Koppelmann 107762e47b2eSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 107862e47b2eSBastian Koppelmann mul = 0x7fffffff; 107962e47b2eSBastian Koppelmann } else { 108062e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 108162e47b2eSBastian Koppelmann } 108262e47b2eSBastian Koppelmann 108362e47b2eSBastian Koppelmann ret = t1 - mul + 0x8000; 108462e47b2eSBastian Koppelmann 108562e47b2eSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 108662e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 108762e47b2eSBastian Koppelmann 108862e47b2eSBastian Koppelmann if (ret > 0x7fffffffll) { 108962e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 109062e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 109162e47b2eSBastian Koppelmann ret = INT32_MAX; 109262e47b2eSBastian Koppelmann } else if (ret < -0x80000000ll) { 109362e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 109462e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 109562e47b2eSBastian Koppelmann ret = INT32_MIN; 109662e47b2eSBastian Koppelmann } else { 109762e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 109862e47b2eSBastian Koppelmann } 109962e47b2eSBastian Koppelmann return ret & 0xffff0000ll; 110062e47b2eSBastian Koppelmann } 110162e47b2eSBastian Koppelmann 1102d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg) 1103d5de7839SBastian Koppelmann { 1104d5de7839SBastian Koppelmann int32_t b, i; 1105d5de7839SBastian Koppelmann int32_t ovf = 0; 1106d5de7839SBastian Koppelmann int32_t avf = 0; 1107d5de7839SBastian Koppelmann int32_t ret = 0; 1108d5de7839SBastian Koppelmann 1109d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1110d5de7839SBastian Koppelmann b = sextract32(arg, i * 8, 8); 1111d5de7839SBastian Koppelmann b = (b >= 0) ? b : (0 - b); 1112d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 1113d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1114d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 1115d5de7839SBastian Koppelmann } 1116d5de7839SBastian Koppelmann 1117d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1118d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1119d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1120d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1121d5de7839SBastian Koppelmann 1122d5de7839SBastian Koppelmann return ret; 1123d5de7839SBastian Koppelmann } 1124d5de7839SBastian Koppelmann 1125d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg) 1126d5de7839SBastian Koppelmann { 1127d5de7839SBastian Koppelmann int32_t h, i; 1128d5de7839SBastian Koppelmann int32_t ovf = 0; 1129d5de7839SBastian Koppelmann int32_t avf = 0; 1130d5de7839SBastian Koppelmann int32_t ret = 0; 1131d5de7839SBastian Koppelmann 1132d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1133d5de7839SBastian Koppelmann h = sextract32(arg, i * 16, 16); 1134d5de7839SBastian Koppelmann h = (h >= 0) ? h : (0 - h); 1135d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 1136d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1137d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1138d5de7839SBastian Koppelmann } 1139d5de7839SBastian Koppelmann 1140d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1141d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1142d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1143d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1144d5de7839SBastian Koppelmann 1145d5de7839SBastian Koppelmann return ret; 1146d5de7839SBastian Koppelmann } 1147d5de7839SBastian Koppelmann 1148d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1149d5de7839SBastian Koppelmann { 1150d5de7839SBastian Koppelmann int32_t b, i; 1151d5de7839SBastian Koppelmann int32_t extr_r2; 1152d5de7839SBastian Koppelmann int32_t ovf = 0; 1153d5de7839SBastian Koppelmann int32_t avf = 0; 1154d5de7839SBastian Koppelmann int32_t ret = 0; 1155d5de7839SBastian Koppelmann 1156d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1157d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1158d5de7839SBastian Koppelmann b = sextract32(r1, i * 8, 8); 1159d5de7839SBastian Koppelmann b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b); 1160d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80); 1161d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1162d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8); 1163d5de7839SBastian Koppelmann } 1164d5de7839SBastian Koppelmann 1165d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1166d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1167d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1168d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1169d5de7839SBastian Koppelmann return ret; 1170d5de7839SBastian Koppelmann } 1171d5de7839SBastian Koppelmann 1172d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1173d5de7839SBastian Koppelmann { 1174d5de7839SBastian Koppelmann int32_t h, i; 1175d5de7839SBastian Koppelmann int32_t extr_r2; 1176d5de7839SBastian Koppelmann int32_t ovf = 0; 1177d5de7839SBastian Koppelmann int32_t avf = 0; 1178d5de7839SBastian Koppelmann int32_t ret = 0; 1179d5de7839SBastian Koppelmann 1180d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1181d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1182d5de7839SBastian Koppelmann h = sextract32(r1, i * 16, 16); 1183d5de7839SBastian Koppelmann h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h); 1184d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000); 1185d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1186d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1187d5de7839SBastian Koppelmann } 1188d5de7839SBastian Koppelmann 1189d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31; 1190d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1191d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1192d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1193d5de7839SBastian Koppelmann 1194d5de7839SBastian Koppelmann return ret; 1195d5de7839SBastian Koppelmann } 1196d5de7839SBastian Koppelmann 11972e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 11982e430e1cSBastian Koppelmann uint32_t r2_h) 11992e430e1cSBastian Koppelmann { 12002e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 12012e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 12022e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 12032e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 12042e430e1cSBastian Koppelmann int64_t result0, result1; 12052e430e1cSBastian Koppelmann uint32_t ovf0, ovf1; 12062e430e1cSBastian Koppelmann uint32_t avf0, avf1; 12072e430e1cSBastian Koppelmann 12082e430e1cSBastian Koppelmann ovf0 = ovf1 = 0; 12092e430e1cSBastian Koppelmann 12102e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 12112e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 12122e430e1cSBastian Koppelmann 12132e430e1cSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 12142e430e1cSBastian Koppelmann ovf0 = (1 << 31); 12152e430e1cSBastian Koppelmann } 12162e430e1cSBastian Koppelmann 12172e430e1cSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 12182e430e1cSBastian Koppelmann ovf1 = (1 << 31); 12192e430e1cSBastian Koppelmann } 12202e430e1cSBastian Koppelmann 12212e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 12222e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 12232e430e1cSBastian Koppelmann 12242e430e1cSBastian Koppelmann avf0 = result0 * 2u; 12252e430e1cSBastian Koppelmann avf0 = result0 ^ avf0; 12262e430e1cSBastian Koppelmann avf1 = result1 * 2u; 12272e430e1cSBastian Koppelmann avf1 = result1 ^ avf1; 12282e430e1cSBastian Koppelmann 12292e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 12302e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 12312e430e1cSBastian Koppelmann 12322e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 12332e430e1cSBastian Koppelmann } 12342e430e1cSBastian Koppelmann 1235bebe80fcSBastian Koppelmann uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1236bebe80fcSBastian Koppelmann uint32_t r2_h) 1237bebe80fcSBastian Koppelmann { 1238bebe80fcSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1239bebe80fcSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1240bebe80fcSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1241bebe80fcSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1242bebe80fcSBastian Koppelmann int64_t result0, result1; 1243bebe80fcSBastian Koppelmann uint32_t ovf0, ovf1; 1244bebe80fcSBastian Koppelmann uint32_t avf0, avf1; 1245bebe80fcSBastian Koppelmann 1246bebe80fcSBastian Koppelmann ovf0 = ovf1 = 0; 1247bebe80fcSBastian Koppelmann 1248bebe80fcSBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 1249bebe80fcSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000; 1250bebe80fcSBastian Koppelmann 1251bebe80fcSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1252bebe80fcSBastian Koppelmann ovf0 = (1 << 31); 1253bebe80fcSBastian Koppelmann } 1254bebe80fcSBastian Koppelmann 1255bebe80fcSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1256bebe80fcSBastian Koppelmann ovf1 = (1 << 31); 1257bebe80fcSBastian Koppelmann } 1258bebe80fcSBastian Koppelmann 1259bebe80fcSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1260bebe80fcSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1261bebe80fcSBastian Koppelmann 1262bebe80fcSBastian Koppelmann avf0 = result0 * 2u; 1263bebe80fcSBastian Koppelmann avf0 = result0 ^ avf0; 1264bebe80fcSBastian Koppelmann avf1 = result1 * 2u; 1265bebe80fcSBastian Koppelmann avf1 = result1 ^ avf1; 1266bebe80fcSBastian Koppelmann 1267bebe80fcSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1268bebe80fcSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1269bebe80fcSBastian Koppelmann 1270bebe80fcSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1271bebe80fcSBastian Koppelmann } 1272bebe80fcSBastian Koppelmann 1273b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 1274b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n) 1275b00aa8ecSBastian Koppelmann { 1276b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 1277b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 1278b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 1279b00aa8ecSBastian Koppelmann int64_t mul, ret; 1280b00aa8ecSBastian Koppelmann 1281b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 1282b00aa8ecSBastian Koppelmann mul = 0x7fffffff; 1283b00aa8ecSBastian Koppelmann } else { 1284b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n; 1285b00aa8ecSBastian Koppelmann } 1286b00aa8ecSBastian Koppelmann 1287b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000; 1288b00aa8ecSBastian Koppelmann 1289b00aa8ecSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 1290b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31); 1291b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1292b00aa8ecSBastian Koppelmann } else { 1293b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0; 1294b00aa8ecSBastian Koppelmann } 1295b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 1296b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1297b00aa8ecSBastian Koppelmann 1298b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll; 1299b00aa8ecSBastian Koppelmann } 1300b00aa8ecSBastian Koppelmann 1301d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1302d5de7839SBastian Koppelmann { 1303d5de7839SBastian Koppelmann int32_t b, i; 1304d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1305d5de7839SBastian Koppelmann int32_t ovf = 0; 1306d5de7839SBastian Koppelmann int32_t avf = 0; 1307d5de7839SBastian Koppelmann uint32_t ret = 0; 1308d5de7839SBastian Koppelmann 1309d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1310d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 1311d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1312d5de7839SBastian Koppelmann 1313d5de7839SBastian Koppelmann b = extr_r1 + extr_r2; 1314d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 1315d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1316d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 1317d5de7839SBastian Koppelmann } 1318d5de7839SBastian Koppelmann 1319d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1320d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1321d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1322d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1323d5de7839SBastian Koppelmann 1324d5de7839SBastian Koppelmann return ret; 1325d5de7839SBastian Koppelmann } 1326d5de7839SBastian Koppelmann 1327d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1328d5de7839SBastian Koppelmann { 1329d5de7839SBastian Koppelmann int32_t h, i; 1330d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1331d5de7839SBastian Koppelmann int32_t ovf = 0; 1332d5de7839SBastian Koppelmann int32_t avf = 0; 1333d5de7839SBastian Koppelmann int32_t ret = 0; 1334d5de7839SBastian Koppelmann 1335d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1336d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 1337d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1338d5de7839SBastian Koppelmann h = extr_r1 + extr_r2; 1339d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 1340d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1341d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1342d5de7839SBastian Koppelmann } 1343d5de7839SBastian Koppelmann 1344d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1345d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1346d5de7839SBastian Koppelmann env->PSW_USB_AV = (avf << 16); 1347d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1348d5de7839SBastian Koppelmann 1349d5de7839SBastian Koppelmann return ret; 1350d5de7839SBastian Koppelmann } 1351d5de7839SBastian Koppelmann 1352f4aef476SBastian Koppelmann uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1353f4aef476SBastian Koppelmann uint32_t r2_h) 1354f4aef476SBastian Koppelmann { 1355f4aef476SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1356f4aef476SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1357f4aef476SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1358f4aef476SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1359f4aef476SBastian Koppelmann int64_t result0, result1; 1360f4aef476SBastian Koppelmann uint32_t ovf0, ovf1; 1361f4aef476SBastian Koppelmann uint32_t avf0, avf1; 1362f4aef476SBastian Koppelmann 1363f4aef476SBastian Koppelmann ovf0 = ovf1 = 0; 1364f4aef476SBastian Koppelmann 1365f4aef476SBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000; 1366f4aef476SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 1367f4aef476SBastian Koppelmann 1368f4aef476SBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1369f4aef476SBastian Koppelmann ovf0 = (1 << 31); 1370f4aef476SBastian Koppelmann } 1371f4aef476SBastian Koppelmann 1372f4aef476SBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1373f4aef476SBastian Koppelmann ovf1 = (1 << 31); 1374f4aef476SBastian Koppelmann } 1375f4aef476SBastian Koppelmann 1376f4aef476SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1377f4aef476SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1378f4aef476SBastian Koppelmann 1379f4aef476SBastian Koppelmann avf0 = result0 * 2u; 1380f4aef476SBastian Koppelmann avf0 = result0 ^ avf0; 1381f4aef476SBastian Koppelmann avf1 = result1 * 2u; 1382f4aef476SBastian Koppelmann avf1 = result1 ^ avf1; 1383f4aef476SBastian Koppelmann 1384f4aef476SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1385f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1386f4aef476SBastian Koppelmann 1387f4aef476SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1388f4aef476SBastian Koppelmann } 1389f4aef476SBastian Koppelmann 1390068fac77SBastian Koppelmann uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l, 1391068fac77SBastian Koppelmann uint32_t r2_h) 1392068fac77SBastian Koppelmann { 1393068fac77SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32); 1394068fac77SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32); 1395068fac77SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32); 1396068fac77SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32); 1397068fac77SBastian Koppelmann int64_t result0, result1; 1398068fac77SBastian Koppelmann uint32_t ovf0, ovf1; 1399068fac77SBastian Koppelmann uint32_t avf0, avf1; 1400068fac77SBastian Koppelmann 1401068fac77SBastian Koppelmann ovf0 = ovf1 = 0; 1402068fac77SBastian Koppelmann 1403068fac77SBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000; 1404068fac77SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000; 1405068fac77SBastian Koppelmann 1406068fac77SBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) { 1407068fac77SBastian Koppelmann ovf0 = (1 << 31); 1408068fac77SBastian Koppelmann } 1409068fac77SBastian Koppelmann 1410068fac77SBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) { 1411068fac77SBastian Koppelmann ovf1 = (1 << 31); 1412068fac77SBastian Koppelmann } 1413068fac77SBastian Koppelmann 1414068fac77SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1; 1415068fac77SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1416068fac77SBastian Koppelmann 1417068fac77SBastian Koppelmann avf0 = result0 * 2u; 1418068fac77SBastian Koppelmann avf0 = result0 ^ avf0; 1419068fac77SBastian Koppelmann avf1 = result1 * 2u; 1420068fac77SBastian Koppelmann avf1 = result1 ^ avf1; 1421068fac77SBastian Koppelmann 1422068fac77SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1; 1423068fac77SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1424068fac77SBastian Koppelmann 1425068fac77SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL); 1426068fac77SBastian Koppelmann } 1427068fac77SBastian Koppelmann 142862e47b2eSBastian Koppelmann uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2, 142962e47b2eSBastian Koppelmann uint32_t r3, uint32_t n) 143062e47b2eSBastian Koppelmann { 143162e47b2eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32); 143262e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32); 143362e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32); 143462e47b2eSBastian Koppelmann int64_t mul, ret; 143562e47b2eSBastian Koppelmann 143662e47b2eSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) { 143762e47b2eSBastian Koppelmann mul = 0x7fffffff; 143862e47b2eSBastian Koppelmann } else { 143962e47b2eSBastian Koppelmann mul = (t2 * t3) << n; 144062e47b2eSBastian Koppelmann } 144162e47b2eSBastian Koppelmann 144262e47b2eSBastian Koppelmann ret = t1 - mul + 0x8000; 144362e47b2eSBastian Koppelmann 144462e47b2eSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) { 144562e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31); 144662e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 144762e47b2eSBastian Koppelmann } else { 144862e47b2eSBastian Koppelmann env->PSW_USB_V = 0; 144962e47b2eSBastian Koppelmann } 145062e47b2eSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 145162e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 145262e47b2eSBastian Koppelmann 145362e47b2eSBastian Koppelmann return ret & 0xffff0000ll; 145462e47b2eSBastian Koppelmann } 145562e47b2eSBastian Koppelmann 1456d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1457d5de7839SBastian Koppelmann { 1458d5de7839SBastian Koppelmann int32_t b, i; 1459d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1460d5de7839SBastian Koppelmann int32_t ovf = 0; 1461d5de7839SBastian Koppelmann int32_t avf = 0; 1462d5de7839SBastian Koppelmann uint32_t ret = 0; 1463d5de7839SBastian Koppelmann 1464d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1465d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); 1466d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); 1467d5de7839SBastian Koppelmann 1468d5de7839SBastian Koppelmann b = extr_r1 - extr_r2; 1469d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80)); 1470d5de7839SBastian Koppelmann avf |= b ^ b * 2u; 1471d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8)); 1472d5de7839SBastian Koppelmann } 1473d5de7839SBastian Koppelmann 1474d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1475d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1476d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24; 1477d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1478d5de7839SBastian Koppelmann 1479d5de7839SBastian Koppelmann return ret; 1480d5de7839SBastian Koppelmann } 1481d5de7839SBastian Koppelmann 1482d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 1483d5de7839SBastian Koppelmann { 1484d5de7839SBastian Koppelmann int32_t h, i; 1485d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; 1486d5de7839SBastian Koppelmann int32_t ovf = 0; 1487d5de7839SBastian Koppelmann int32_t avf = 0; 1488d5de7839SBastian Koppelmann int32_t ret = 0; 1489d5de7839SBastian Koppelmann 1490d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) { 1491d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16); 1492d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16); 1493d5de7839SBastian Koppelmann h = extr_r1 - extr_r2; 1494d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000)); 1495d5de7839SBastian Koppelmann avf |= h ^ h * 2u; 1496d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16); 1497d5de7839SBastian Koppelmann } 1498d5de7839SBastian Koppelmann 1499d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31); 1500d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 1501d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16; 1502d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 1503d5de7839SBastian Koppelmann 1504d5de7839SBastian Koppelmann return ret; 1505d5de7839SBastian Koppelmann } 1506d5de7839SBastian Koppelmann 1507d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2) 1508d5de7839SBastian Koppelmann { 1509d5de7839SBastian Koppelmann int32_t ret; 1510d5de7839SBastian Koppelmann int32_t i, msk; 1511d5de7839SBastian Koppelmann 1512d5de7839SBastian Koppelmann ret = 0; 1513d5de7839SBastian Koppelmann msk = 0xff; 1514d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1515d5de7839SBastian Koppelmann if ((r1 & msk) == (r2 & msk)) { 1516d5de7839SBastian Koppelmann ret |= msk; 1517d5de7839SBastian Koppelmann } 1518d5de7839SBastian Koppelmann msk = msk << 8; 1519d5de7839SBastian Koppelmann } 1520d5de7839SBastian Koppelmann 1521d5de7839SBastian Koppelmann return ret; 1522d5de7839SBastian Koppelmann } 1523d5de7839SBastian Koppelmann 1524d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2) 1525d5de7839SBastian Koppelmann { 1526d5de7839SBastian Koppelmann int32_t ret = 0; 1527d5de7839SBastian Koppelmann 1528d5de7839SBastian Koppelmann if ((r1 & 0xffff) == (r2 & 0xffff)) { 1529d5de7839SBastian Koppelmann ret = 0xffff; 1530d5de7839SBastian Koppelmann } 1531d5de7839SBastian Koppelmann 1532d5de7839SBastian Koppelmann if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) { 1533d5de7839SBastian Koppelmann ret |= 0xffff0000; 1534d5de7839SBastian Koppelmann } 1535d5de7839SBastian Koppelmann 1536d5de7839SBastian Koppelmann return ret; 1537d5de7839SBastian Koppelmann } 1538d5de7839SBastian Koppelmann 1539d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2) 1540d5de7839SBastian Koppelmann { 1541d5de7839SBastian Koppelmann int32_t i; 1542d5de7839SBastian Koppelmann uint32_t ret = 0; 1543d5de7839SBastian Koppelmann 1544d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1545d5de7839SBastian Koppelmann ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8)); 1546d5de7839SBastian Koppelmann } 1547d5de7839SBastian Koppelmann 1548d5de7839SBastian Koppelmann return ret; 1549d5de7839SBastian Koppelmann } 1550d5de7839SBastian Koppelmann 1551d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2) 1552d5de7839SBastian Koppelmann { 1553d5de7839SBastian Koppelmann uint32_t ret; 1554d5de7839SBastian Koppelmann 1555d5de7839SBastian Koppelmann ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16)); 1556d5de7839SBastian Koppelmann ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16)); 1557d5de7839SBastian Koppelmann 1558d5de7839SBastian Koppelmann return ret; 1559d5de7839SBastian Koppelmann } 1560d5de7839SBastian Koppelmann 1561d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2) 1562d5de7839SBastian Koppelmann { 1563d5de7839SBastian Koppelmann int32_t i; 1564d5de7839SBastian Koppelmann uint32_t ret = 0; 1565d5de7839SBastian Koppelmann 1566d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1567d5de7839SBastian Koppelmann if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) { 1568d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 1569d5de7839SBastian Koppelmann } 1570d5de7839SBastian Koppelmann } 1571d5de7839SBastian Koppelmann 1572d5de7839SBastian Koppelmann return ret; 1573d5de7839SBastian Koppelmann } 1574d5de7839SBastian Koppelmann 1575d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2) 1576d5de7839SBastian Koppelmann { 1577d5de7839SBastian Koppelmann int32_t i; 1578d5de7839SBastian Koppelmann uint32_t ret = 0; 1579d5de7839SBastian Koppelmann 1580d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { 1581d5de7839SBastian Koppelmann if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) { 1582d5de7839SBastian Koppelmann ret |= (0xff << (i * 8)); 1583d5de7839SBastian Koppelmann } 1584d5de7839SBastian Koppelmann } 1585d5de7839SBastian Koppelmann 1586d5de7839SBastian Koppelmann return ret; 1587d5de7839SBastian Koppelmann } 1588d5de7839SBastian Koppelmann 1589d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2) 1590d5de7839SBastian Koppelmann { 1591d5de7839SBastian Koppelmann uint32_t ret = 0; 1592d5de7839SBastian Koppelmann 1593d5de7839SBastian Koppelmann if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) { 1594d5de7839SBastian Koppelmann ret |= 0xffff; 1595d5de7839SBastian Koppelmann } 1596d5de7839SBastian Koppelmann 1597d5de7839SBastian Koppelmann if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) { 1598d5de7839SBastian Koppelmann ret |= 0xffff0000; 1599d5de7839SBastian Koppelmann } 1600d5de7839SBastian Koppelmann 1601d5de7839SBastian Koppelmann return ret; 1602d5de7839SBastian Koppelmann } 1603d5de7839SBastian Koppelmann 1604d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2) 1605d5de7839SBastian Koppelmann { 1606d5de7839SBastian Koppelmann uint32_t ret = 0; 1607d5de7839SBastian Koppelmann 1608d5de7839SBastian Koppelmann if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) { 1609d5de7839SBastian Koppelmann ret |= 0xffff; 1610d5de7839SBastian Koppelmann } 1611d5de7839SBastian Koppelmann 1612d5de7839SBastian Koppelmann if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) { 1613d5de7839SBastian Koppelmann ret |= 0xffff0000; 1614d5de7839SBastian Koppelmann } 1615d5de7839SBastian Koppelmann 1616d5de7839SBastian Koppelmann return ret; 1617d5de7839SBastian Koppelmann } 1618d5de7839SBastian Koppelmann 1619d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op) \ 1620d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \ 1621d5de7839SBastian Koppelmann { \ 1622d5de7839SBastian Koppelmann int32_t i, extr_r1, extr_r2; \ 1623d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1624d5de7839SBastian Koppelmann \ 1625d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 1626d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); \ 1627d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); \ 1628d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1629d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 1630d5de7839SBastian Koppelmann } \ 1631d5de7839SBastian Koppelmann return ret; \ 1632d5de7839SBastian Koppelmann } \ 1633d5de7839SBastian Koppelmann \ 1634d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\ 1635d5de7839SBastian Koppelmann { \ 1636d5de7839SBastian Koppelmann int32_t i; \ 1637d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 1638d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1639d5de7839SBastian Koppelmann \ 1640d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \ 1641d5de7839SBastian Koppelmann extr_r1 = extract32(r1, i * 8, 8); \ 1642d5de7839SBastian Koppelmann extr_r2 = extract32(r2, i * 8, 8); \ 1643d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1644d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \ 1645d5de7839SBastian Koppelmann } \ 1646d5de7839SBastian Koppelmann return ret; \ 1647d5de7839SBastian Koppelmann } \ 1648d5de7839SBastian Koppelmann \ 1649d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \ 1650d5de7839SBastian Koppelmann { \ 1651d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; \ 1652d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1653d5de7839SBastian Koppelmann \ 1654d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 0, 16); \ 1655d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 0, 16); \ 1656d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1657d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 1658d5de7839SBastian Koppelmann \ 1659d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 16, 16); \ 1660d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 16, 16); \ 1661d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1662d5de7839SBastian Koppelmann ret |= extr_r1 << 16; \ 1663d5de7839SBastian Koppelmann \ 1664d5de7839SBastian Koppelmann return ret; \ 1665d5de7839SBastian Koppelmann } \ 1666d5de7839SBastian Koppelmann \ 1667d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\ 1668d5de7839SBastian Koppelmann { \ 1669d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \ 1670d5de7839SBastian Koppelmann uint32_t ret = 0; \ 1671d5de7839SBastian Koppelmann \ 1672d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 0, 16); \ 1673d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 0, 16); \ 1674d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1675d5de7839SBastian Koppelmann ret = ret & 0xffff; \ 1676d5de7839SBastian Koppelmann \ 1677d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 16, 16); \ 1678d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 16, 16); \ 1679d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \ 1680d5de7839SBastian Koppelmann ret |= extr_r1 << (16); \ 1681d5de7839SBastian Koppelmann \ 1682d5de7839SBastian Koppelmann return ret; \ 1683d5de7839SBastian Koppelmann } \ 168409532255SBastian Koppelmann \ 168509532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2) \ 168609532255SBastian Koppelmann { \ 168709532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \ 168809532255SBastian Koppelmann uint64_t ret = 0; \ 168909532255SBastian Koppelmann \ 169009532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \ 169109532255SBastian Koppelmann r2l = sextract64(r2, 0, 16); \ 169209532255SBastian Koppelmann r2h = sextract64(r2, 16, 16); \ 169309532255SBastian Koppelmann r1hl = sextract64(r1, 32, 16); \ 169409532255SBastian Koppelmann \ 169509532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 169609532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \ 169709532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \ 169809532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \ 169909532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \ 170009532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \ 170109532255SBastian Koppelmann } else { \ 170209532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \ 170309532255SBastian Koppelmann } \ 170409532255SBastian Koppelmann return ret; \ 170509532255SBastian Koppelmann } \ 170609532255SBastian Koppelmann \ 170709532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2) \ 170809532255SBastian Koppelmann { \ 170909532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \ 171009532255SBastian Koppelmann uint64_t ret = 0; \ 171109532255SBastian Koppelmann \ 171209532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \ 171309532255SBastian Koppelmann r2l = extract64(r2, 0, 16); \ 171409532255SBastian Koppelmann r2h = extract64(r2, 16, 16); \ 171509532255SBastian Koppelmann r1hl = extract64(r1, 32, 16); \ 171609532255SBastian Koppelmann \ 171709532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \ 171809532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \ 171909532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \ 172009532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \ 172109532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \ 172209532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \ 172309532255SBastian Koppelmann } else { \ 172409532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \ 172509532255SBastian Koppelmann } \ 172609532255SBastian Koppelmann return ret; \ 172709532255SBastian Koppelmann } 1728d5de7839SBastian Koppelmann 1729d5de7839SBastian Koppelmann EXTREMA_H_B(max, >) 1730d5de7839SBastian Koppelmann EXTREMA_H_B(min, <) 1731d5de7839SBastian Koppelmann 1732d5de7839SBastian Koppelmann #undef EXTREMA_H_B 1733d5de7839SBastian Koppelmann 17340b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1) 17350b79a781SBastian Koppelmann { 17360b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 17370b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 17380b79a781SBastian Koppelmann 17390b79a781SBastian Koppelmann ret_hw0 = clo32(ret_hw0 << 16); 17400b79a781SBastian Koppelmann ret_hw1 = clo32(ret_hw1 << 16); 17410b79a781SBastian Koppelmann 17420b79a781SBastian Koppelmann if (ret_hw0 > 16) { 17430b79a781SBastian Koppelmann ret_hw0 = 16; 17440b79a781SBastian Koppelmann } 17450b79a781SBastian Koppelmann if (ret_hw1 > 16) { 17460b79a781SBastian Koppelmann ret_hw1 = 16; 17470b79a781SBastian Koppelmann } 17480b79a781SBastian Koppelmann 17490b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 17500b79a781SBastian Koppelmann } 17510b79a781SBastian Koppelmann 17520b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1) 17530b79a781SBastian Koppelmann { 17540b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 17550b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 17560b79a781SBastian Koppelmann 17570b79a781SBastian Koppelmann ret_hw0 = clz32(ret_hw0 << 16); 17580b79a781SBastian Koppelmann ret_hw1 = clz32(ret_hw1 << 16); 17590b79a781SBastian Koppelmann 17600b79a781SBastian Koppelmann if (ret_hw0 > 16) { 17610b79a781SBastian Koppelmann ret_hw0 = 16; 17620b79a781SBastian Koppelmann } 17630b79a781SBastian Koppelmann if (ret_hw1 > 16) { 17640b79a781SBastian Koppelmann ret_hw1 = 16; 17650b79a781SBastian Koppelmann } 17660b79a781SBastian Koppelmann 17670b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 17680b79a781SBastian Koppelmann } 17690b79a781SBastian Koppelmann 17700b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1) 17710b79a781SBastian Koppelmann { 17720b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16); 17730b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16); 17740b79a781SBastian Koppelmann 17750b79a781SBastian Koppelmann ret_hw0 = clrsb32(ret_hw0 << 16); 17760b79a781SBastian Koppelmann ret_hw1 = clrsb32(ret_hw1 << 16); 17770b79a781SBastian Koppelmann 17780b79a781SBastian Koppelmann if (ret_hw0 > 15) { 17790b79a781SBastian Koppelmann ret_hw0 = 15; 17800b79a781SBastian Koppelmann } 17810b79a781SBastian Koppelmann if (ret_hw1 > 15) { 17820b79a781SBastian Koppelmann ret_hw1 = 15; 17830b79a781SBastian Koppelmann } 17840b79a781SBastian Koppelmann 17850b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16); 17860b79a781SBastian Koppelmann } 17870b79a781SBastian Koppelmann 17880b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2) 17890b79a781SBastian Koppelmann { 17900b79a781SBastian Koppelmann int32_t shift_count = sextract32(r2, 0, 6); 17910b79a781SBastian Koppelmann 17920b79a781SBastian Koppelmann if (shift_count == -32) { 17930b79a781SBastian Koppelmann return 0; 17940b79a781SBastian Koppelmann } else if (shift_count < 0) { 17950b79a781SBastian Koppelmann return r1 >> -shift_count; 17960b79a781SBastian Koppelmann } else { 17970b79a781SBastian Koppelmann return r1 << shift_count; 17980b79a781SBastian Koppelmann } 17990b79a781SBastian Koppelmann } 18000b79a781SBastian Koppelmann 18010b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2) 18020b79a781SBastian Koppelmann { 18030b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 18040b79a781SBastian Koppelmann int32_t shift_count; 18050b79a781SBastian Koppelmann 18060b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 18070b79a781SBastian Koppelmann 18080b79a781SBastian Koppelmann if (shift_count == -16) { 18090b79a781SBastian Koppelmann return 0; 18100b79a781SBastian Koppelmann } else if (shift_count < 0) { 18110b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) >> -shift_count; 18120b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) >> -shift_count; 18130b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 18140b79a781SBastian Koppelmann } else { 18150b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) << shift_count; 18160b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) << shift_count; 18170b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 18180b79a781SBastian Koppelmann } 18190b79a781SBastian Koppelmann } 18200b79a781SBastian Koppelmann 18210b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2) 18220b79a781SBastian Koppelmann { 18230b79a781SBastian Koppelmann int32_t shift_count; 18240b79a781SBastian Koppelmann int64_t result, t1; 18250b79a781SBastian Koppelmann uint32_t ret; 18260b79a781SBastian Koppelmann 18270b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 6); 18280b79a781SBastian Koppelmann t1 = sextract32(r1, 0, 32); 18290b79a781SBastian Koppelmann 18300b79a781SBastian Koppelmann if (shift_count == 0) { 18310b79a781SBastian Koppelmann env->PSW_USB_C = env->PSW_USB_V = 0; 18320b79a781SBastian Koppelmann ret = r1; 18330b79a781SBastian Koppelmann } else if (shift_count == -32) { 18340b79a781SBastian Koppelmann env->PSW_USB_C = r1; 18350b79a781SBastian Koppelmann env->PSW_USB_V = 0; 18360b79a781SBastian Koppelmann ret = t1 >> 31; 18370b79a781SBastian Koppelmann } else if (shift_count > 0) { 18380b79a781SBastian Koppelmann result = t1 << shift_count; 18390b79a781SBastian Koppelmann /* calc carry */ 1840452e3d49SPeter Maydell env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0); 18410b79a781SBastian Koppelmann /* calc v */ 18420b79a781SBastian Koppelmann env->PSW_USB_V = (((result > 0x7fffffffLL) || 18430b79a781SBastian Koppelmann (result < -0x80000000LL)) << 31); 18440b79a781SBastian Koppelmann /* calc sv */ 18450b79a781SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 18460b79a781SBastian Koppelmann ret = (uint32_t)result; 18470b79a781SBastian Koppelmann } else { 18480b79a781SBastian Koppelmann env->PSW_USB_V = 0; 18490b79a781SBastian Koppelmann env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1)); 18500b79a781SBastian Koppelmann ret = t1 >> -shift_count; 18510b79a781SBastian Koppelmann } 18520b79a781SBastian Koppelmann 18530b79a781SBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u; 18540b79a781SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV; 18550b79a781SBastian Koppelmann 18560b79a781SBastian Koppelmann return ret; 18570b79a781SBastian Koppelmann } 18580b79a781SBastian Koppelmann 18590b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2) 18600b79a781SBastian Koppelmann { 18610b79a781SBastian Koppelmann int32_t shift_count; 18620b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1; 18630b79a781SBastian Koppelmann 18640b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5); 18650b79a781SBastian Koppelmann 18660b79a781SBastian Koppelmann if (shift_count == 0) { 18670b79a781SBastian Koppelmann return r1; 18680b79a781SBastian Koppelmann } else if (shift_count < 0) { 18690b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) >> -shift_count; 18700b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) >> -shift_count; 18710b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 18720b79a781SBastian Koppelmann } else { 18730b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) << shift_count; 18740b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) << shift_count; 18750b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16); 18760b79a781SBastian Koppelmann } 18770b79a781SBastian Koppelmann } 18780b79a781SBastian Koppelmann 1879e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2) 1880e2bed107SBastian Koppelmann { 1881e2bed107SBastian Koppelmann uint32_t i, ret; 1882e2bed107SBastian Koppelmann 1883e2bed107SBastian Koppelmann ret = 0; 1884e2bed107SBastian Koppelmann for (i = 0; i < 16; i++) { 1885e2bed107SBastian Koppelmann ret |= (r1 & 1) << (2 * i + 1); 1886e2bed107SBastian Koppelmann ret |= (r2 & 1) << (2 * i); 1887e2bed107SBastian Koppelmann r1 = r1 >> 1; 1888e2bed107SBastian Koppelmann r2 = r2 >> 1; 1889e2bed107SBastian Koppelmann } 1890e2bed107SBastian Koppelmann return ret; 1891e2bed107SBastian Koppelmann } 1892e2bed107SBastian Koppelmann 1893e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1) 1894e2bed107SBastian Koppelmann { 1895e2bed107SBastian Koppelmann int32_t i; 1896e2bed107SBastian Koppelmann uint64_t ret; 1897e2bed107SBastian Koppelmann 1898e2bed107SBastian Koppelmann ret = 0; 1899e2bed107SBastian Koppelmann for (i = 0; i < 32; i = i + 2) { 1900e2bed107SBastian Koppelmann /* even */ 1901e2bed107SBastian Koppelmann ret |= (r1 & 1) << (i/2); 1902e2bed107SBastian Koppelmann r1 = r1 >> 1; 1903e2bed107SBastian Koppelmann /* odd */ 1904e2bed107SBastian Koppelmann ret |= (uint64_t)(r1 & 1) << (i/2 + 32); 1905e2bed107SBastian Koppelmann r1 = r1 >> 1; 1906e2bed107SBastian Koppelmann } 1907e2bed107SBastian Koppelmann return ret; 1908e2bed107SBastian Koppelmann } 1909e2bed107SBastian Koppelmann 1910e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1) 1911e2bed107SBastian Koppelmann { 1912e2bed107SBastian Koppelmann uint32_t ret; 1913e2bed107SBastian Koppelmann uint32_t nOnes, i; 1914e2bed107SBastian Koppelmann 1915e2bed107SBastian Koppelmann ret = 0; 1916e2bed107SBastian Koppelmann nOnes = 0; 1917e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1918e2bed107SBastian Koppelmann ret ^= (r1 & 1); 1919e2bed107SBastian Koppelmann r1 = r1 >> 1; 1920e2bed107SBastian Koppelmann } 1921e2bed107SBastian Koppelmann /* second byte */ 1922e2bed107SBastian Koppelmann nOnes = 0; 1923e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1924e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1925e2bed107SBastian Koppelmann r1 = r1 >> 1; 1926e2bed107SBastian Koppelmann } 1927e2bed107SBastian Koppelmann ret |= nOnes << 8; 1928e2bed107SBastian Koppelmann /* third byte */ 1929e2bed107SBastian Koppelmann nOnes = 0; 1930e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1931e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1932e2bed107SBastian Koppelmann r1 = r1 >> 1; 1933e2bed107SBastian Koppelmann } 1934e2bed107SBastian Koppelmann ret |= nOnes << 16; 1935e2bed107SBastian Koppelmann /* fourth byte */ 1936e2bed107SBastian Koppelmann nOnes = 0; 1937e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) { 1938e2bed107SBastian Koppelmann nOnes ^= (r1 & 1); 1939e2bed107SBastian Koppelmann r1 = r1 >> 1; 1940e2bed107SBastian Koppelmann } 1941e2bed107SBastian Koppelmann ret |= nOnes << 24; 1942e2bed107SBastian Koppelmann 1943e2bed107SBastian Koppelmann return ret; 1944e2bed107SBastian Koppelmann } 1945e2bed107SBastian Koppelmann 194609532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high, 194709532255SBastian Koppelmann target_ulong r2) 194809532255SBastian Koppelmann { 194909532255SBastian Koppelmann uint32_t ret; 195009532255SBastian Koppelmann int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac; 195109532255SBastian Koppelmann int32_t int_exp = r1_high; 195209532255SBastian Koppelmann int32_t int_mant = r1_low; 195309532255SBastian Koppelmann uint32_t flag_rnd = (int_mant & (1 << 7)) && ( 195409532255SBastian Koppelmann (int_mant & (1 << 8)) || 195509532255SBastian Koppelmann (int_mant & 0x7f) || 195609532255SBastian Koppelmann (carry != 0)); 195709532255SBastian Koppelmann if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) { 195809532255SBastian Koppelmann fp_exp = 255; 195909532255SBastian Koppelmann fp_frac = extract32(int_mant, 8, 23); 196009532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp >= 127)) { 196109532255SBastian Koppelmann fp_exp = 255; 196209532255SBastian Koppelmann fp_frac = 0; 196309532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp <= -128)) { 196409532255SBastian Koppelmann fp_exp = 0; 196509532255SBastian Koppelmann fp_frac = 0; 196609532255SBastian Koppelmann } else if (int_mant == 0) { 196709532255SBastian Koppelmann fp_exp = 0; 196809532255SBastian Koppelmann fp_frac = 0; 196909532255SBastian Koppelmann } else { 197009532255SBastian Koppelmann if (((int_mant & (1 << 31)) == 0)) { 197109532255SBastian Koppelmann temp_exp = 0; 197209532255SBastian Koppelmann } else { 197309532255SBastian Koppelmann temp_exp = int_exp + 128; 197409532255SBastian Koppelmann } 197509532255SBastian Koppelmann fp_exp_frac = (((temp_exp & 0xff) << 23) | 197609532255SBastian Koppelmann extract32(int_mant, 8, 23)) 197709532255SBastian Koppelmann + flag_rnd; 197809532255SBastian Koppelmann fp_exp = extract32(fp_exp_frac, 23, 8); 197909532255SBastian Koppelmann fp_frac = extract32(fp_exp_frac, 0, 23); 198009532255SBastian Koppelmann } 198109532255SBastian Koppelmann ret = r2 & (1 << 31); 198209532255SBastian Koppelmann ret = ret + (fp_exp << 23); 198309532255SBastian Koppelmann ret = ret + (fp_frac & 0x7fffff); 198409532255SBastian Koppelmann 198509532255SBastian Koppelmann return ret; 198609532255SBastian Koppelmann } 198709532255SBastian Koppelmann 1988e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1) 1989e2bed107SBastian Koppelmann { 1990e2bed107SBastian Koppelmann int32_t fp_exp = extract32(arg1, 23, 8); 1991e2bed107SBastian Koppelmann int32_t fp_frac = extract32(arg1, 0, 23); 1992e2bed107SBastian Koppelmann uint64_t ret; 1993e2bed107SBastian Koppelmann int32_t int_exp, int_mant; 1994e2bed107SBastian Koppelmann 1995e2bed107SBastian Koppelmann if (fp_exp == 255) { 1996e2bed107SBastian Koppelmann int_exp = 255; 1997e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 1998e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac == 0)) { 1999e2bed107SBastian Koppelmann int_exp = -127; 2000e2bed107SBastian Koppelmann int_mant = 0; 2001e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac != 0)) { 2002e2bed107SBastian Koppelmann int_exp = -126; 2003e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 2004e2bed107SBastian Koppelmann } else { 2005e2bed107SBastian Koppelmann int_exp = fp_exp - 127; 2006e2bed107SBastian Koppelmann int_mant = (fp_frac << 7); 2007e2bed107SBastian Koppelmann int_mant |= (1 << 30); 2008e2bed107SBastian Koppelmann } 2009e2bed107SBastian Koppelmann ret = int_exp; 2010e2bed107SBastian Koppelmann ret = ret << 32; 2011e2bed107SBastian Koppelmann ret |= int_mant; 2012e2bed107SBastian Koppelmann 2013e2bed107SBastian Koppelmann return ret; 2014e2bed107SBastian Koppelmann } 2015e2bed107SBastian Koppelmann 2016e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2017e2bed107SBastian Koppelmann { 2018e2bed107SBastian Koppelmann uint64_t ret; 2019f69c24e4SBastian Koppelmann int32_t abs_sig_dividend, abs_divisor; 2020e2bed107SBastian Koppelmann 2021e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 2022e2bed107SBastian Koppelmann ret = ret << 24; 2023e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2024e2bed107SBastian Koppelmann ret |= 0xffffff; 2025e2bed107SBastian Koppelmann } 2026e2bed107SBastian Koppelmann 2027f69c24e4SBastian Koppelmann abs_sig_dividend = abs((int32_t)r1) >> 8; 202830a0d72fSStefan Weil abs_divisor = abs((int32_t)r2); 2029f69c24e4SBastian Koppelmann /* calc overflow 2030f69c24e4SBastian Koppelmann ofv if (a/b >= 255) <=> (a/255 >= b) */ 2031f69c24e4SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; 2032e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 2033e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2034e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 2035e2bed107SBastian Koppelmann 2036e2bed107SBastian Koppelmann return ret; 2037e2bed107SBastian Koppelmann } 2038e2bed107SBastian Koppelmann 2039e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2040e2bed107SBastian Koppelmann { 2041e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 2042e2bed107SBastian Koppelmann 2043e2bed107SBastian Koppelmann ret = ret << 24; 2044e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2045e2bed107SBastian Koppelmann ret |= 0xffffff; 2046e2bed107SBastian Koppelmann } 2047e2bed107SBastian Koppelmann /* calc overflow */ 2048e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80))); 2049e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 2050e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2051e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 2052e2bed107SBastian Koppelmann 2053e2bed107SBastian Koppelmann return ret; 2054e2bed107SBastian Koppelmann } 2055e2bed107SBastian Koppelmann 2056e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2057e2bed107SBastian Koppelmann { 2058e2bed107SBastian Koppelmann uint64_t ret; 2059f69c24e4SBastian Koppelmann int32_t abs_sig_dividend, abs_divisor; 2060e2bed107SBastian Koppelmann 2061e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32); 2062e2bed107SBastian Koppelmann ret = ret << 16; 2063e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2064e2bed107SBastian Koppelmann ret |= 0xffff; 2065e2bed107SBastian Koppelmann } 2066e2bed107SBastian Koppelmann 2067f69c24e4SBastian Koppelmann abs_sig_dividend = abs((int32_t)r1) >> 16; 206830a0d72fSStefan Weil abs_divisor = abs((int32_t)r2); 2069f69c24e4SBastian Koppelmann /* calc overflow 2070f69c24e4SBastian Koppelmann ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */ 2071f69c24e4SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31; 2072e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 2073e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2074e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 2075e2bed107SBastian Koppelmann 2076e2bed107SBastian Koppelmann return ret; 2077e2bed107SBastian Koppelmann } 2078e2bed107SBastian Koppelmann 2079e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 2080e2bed107SBastian Koppelmann { 2081e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32); 2082e2bed107SBastian Koppelmann 2083e2bed107SBastian Koppelmann ret = ret << 16; 2084e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) { 2085e2bed107SBastian Koppelmann ret |= 0xffff; 2086e2bed107SBastian Koppelmann } 2087e2bed107SBastian Koppelmann /* calc overflow */ 2088e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000))); 2089e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31; 2090e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 2091e2bed107SBastian Koppelmann env->PSW_USB_AV = 0; 2092e2bed107SBastian Koppelmann 2093e2bed107SBastian Koppelmann return ret; 2094e2bed107SBastian Koppelmann } 2095e2bed107SBastian Koppelmann 209609532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2) 209709532255SBastian Koppelmann { 209809532255SBastian Koppelmann int32_t x_sign = (r1 >> 63); 209909532255SBastian Koppelmann int32_t q_sign = x_sign ^ (r2 >> 31); 210009532255SBastian Koppelmann int32_t eq_pos = x_sign & ((r1 >> 32) == r2); 210109532255SBastian Koppelmann int32_t eq_neg = x_sign & ((r1 >> 32) == -r2); 210209532255SBastian Koppelmann uint32_t quotient; 21039be38598SEduardo Habkost uint64_t remainder; 210409532255SBastian Koppelmann 210509532255SBastian Koppelmann if ((q_sign & ~eq_neg) | eq_pos) { 210609532255SBastian Koppelmann quotient = (r1 + 1) & 0xffffffff; 210709532255SBastian Koppelmann } else { 210809532255SBastian Koppelmann quotient = r1 & 0xffffffff; 210909532255SBastian Koppelmann } 211009532255SBastian Koppelmann 211109532255SBastian Koppelmann if (eq_pos | eq_neg) { 211209532255SBastian Koppelmann remainder = 0; 211309532255SBastian Koppelmann } else { 211409532255SBastian Koppelmann remainder = (r1 & 0xffffffff00000000ull); 211509532255SBastian Koppelmann } 21169be38598SEduardo Habkost return remainder | quotient; 211709532255SBastian Koppelmann } 211809532255SBastian Koppelmann 211909532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2) 212009532255SBastian Koppelmann { 212109532255SBastian Koppelmann int32_t dividend_sign = extract64(r1, 63, 1); 212209532255SBastian Koppelmann int32_t divisor_sign = extract32(r2, 31, 1); 212309532255SBastian Koppelmann int32_t quotient_sign = (dividend_sign != divisor_sign); 212409532255SBastian Koppelmann int32_t addend, dividend_quotient, remainder; 212509532255SBastian Koppelmann int32_t i, temp; 212609532255SBastian Koppelmann 212709532255SBastian Koppelmann if (quotient_sign) { 212809532255SBastian Koppelmann addend = r2; 212909532255SBastian Koppelmann } else { 213009532255SBastian Koppelmann addend = -r2; 213109532255SBastian Koppelmann } 213209532255SBastian Koppelmann dividend_quotient = (int32_t)r1; 213309532255SBastian Koppelmann remainder = (int32_t)(r1 >> 32); 213409532255SBastian Koppelmann 213509532255SBastian Koppelmann for (i = 0; i < 8; i++) { 213609532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 213709532255SBastian Koppelmann dividend_quotient <<= 1; 213809532255SBastian Koppelmann temp = remainder + addend; 213909532255SBastian Koppelmann if ((temp < 0) == dividend_sign) { 214009532255SBastian Koppelmann remainder = temp; 214109532255SBastian Koppelmann } 214209532255SBastian Koppelmann if (((temp < 0) == dividend_sign)) { 214309532255SBastian Koppelmann dividend_quotient = dividend_quotient | !quotient_sign; 214409532255SBastian Koppelmann } else { 214509532255SBastian Koppelmann dividend_quotient = dividend_quotient | quotient_sign; 214609532255SBastian Koppelmann } 214709532255SBastian Koppelmann } 214809532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 214909532255SBastian Koppelmann } 215009532255SBastian Koppelmann 215109532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2) 215209532255SBastian Koppelmann { 215309532255SBastian Koppelmann int32_t dividend_quotient = extract64(r1, 0, 32); 215409532255SBastian Koppelmann int64_t remainder = extract64(r1, 32, 32); 215509532255SBastian Koppelmann int32_t i; 215609532255SBastian Koppelmann int64_t temp; 215709532255SBastian Koppelmann for (i = 0; i < 8; i++) { 215809532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1); 215909532255SBastian Koppelmann dividend_quotient <<= 1; 216009532255SBastian Koppelmann temp = (remainder & 0xffffffff) - r2; 216109532255SBastian Koppelmann if (temp >= 0) { 216209532255SBastian Koppelmann remainder = temp; 216309532255SBastian Koppelmann } 216409532255SBastian Koppelmann dividend_quotient = dividend_quotient | !(temp < 0); 216509532255SBastian Koppelmann } 216609532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient; 216709532255SBastian Koppelmann } 216809532255SBastian Koppelmann 216993715571SBastian Koppelmann uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 217093715571SBastian Koppelmann { 217193715571SBastian Koppelmann int32_t quotient, remainder; 217293715571SBastian Koppelmann int32_t dividend = (int32_t)r1; 217393715571SBastian Koppelmann int32_t divisor = (int32_t)r2; 217493715571SBastian Koppelmann 217593715571SBastian Koppelmann if (divisor == 0) { 217693715571SBastian Koppelmann if (dividend >= 0) { 217793715571SBastian Koppelmann quotient = 0x7fffffff; 217893715571SBastian Koppelmann remainder = 0; 217993715571SBastian Koppelmann } else { 218093715571SBastian Koppelmann quotient = 0x80000000; 218193715571SBastian Koppelmann remainder = 0; 218293715571SBastian Koppelmann } 218393715571SBastian Koppelmann env->PSW_USB_V = (1 << 31); 218493715571SBastian Koppelmann } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) { 218593715571SBastian Koppelmann quotient = 0x7fffffff; 218693715571SBastian Koppelmann remainder = 0; 218793715571SBastian Koppelmann env->PSW_USB_V = (1 << 31); 218893715571SBastian Koppelmann } else { 218993715571SBastian Koppelmann remainder = dividend % divisor; 219093715571SBastian Koppelmann quotient = (dividend - remainder)/divisor; 219193715571SBastian Koppelmann env->PSW_USB_V = 0; 219293715571SBastian Koppelmann } 219393715571SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 219493715571SBastian Koppelmann env->PSW_USB_AV = 0; 219593715571SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)quotient; 219693715571SBastian Koppelmann } 219793715571SBastian Koppelmann 219893715571SBastian Koppelmann uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2) 219993715571SBastian Koppelmann { 220093715571SBastian Koppelmann uint32_t quotient, remainder; 220193715571SBastian Koppelmann uint32_t dividend = r1; 220293715571SBastian Koppelmann uint32_t divisor = r2; 220393715571SBastian Koppelmann 220493715571SBastian Koppelmann if (divisor == 0) { 220593715571SBastian Koppelmann quotient = 0xffffffff; 220693715571SBastian Koppelmann remainder = 0; 220793715571SBastian Koppelmann env->PSW_USB_V = (1 << 31); 220893715571SBastian Koppelmann } else { 220993715571SBastian Koppelmann remainder = dividend % divisor; 221093715571SBastian Koppelmann quotient = (dividend - remainder)/divisor; 221193715571SBastian Koppelmann env->PSW_USB_V = 0; 221293715571SBastian Koppelmann } 221393715571SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V; 221493715571SBastian Koppelmann env->PSW_USB_AV = 0; 221593715571SBastian Koppelmann return ((uint64_t)remainder << 32) | quotient; 221693715571SBastian Koppelmann } 221793715571SBastian Koppelmann 22189655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01, 22199655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 22209655b932SBastian Koppelmann { 22219655b932SBastian Koppelmann uint32_t result0, result1; 22229655b932SBastian Koppelmann 22239655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 22249655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 22259655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 22269655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 22279655b932SBastian Koppelmann if (sc1) { 22289655b932SBastian Koppelmann result1 = 0x7fffffff; 22299655b932SBastian Koppelmann } else { 22309655b932SBastian Koppelmann result1 = (((uint32_t)(arg00 * arg10)) << n); 22319655b932SBastian Koppelmann } 22329655b932SBastian Koppelmann if (sc0) { 22339655b932SBastian Koppelmann result0 = 0x7fffffff; 22349655b932SBastian Koppelmann } else { 22359655b932SBastian Koppelmann result0 = (((uint32_t)(arg01 * arg11)) << n); 22369655b932SBastian Koppelmann } 22379be38598SEduardo Habkost return (((uint64_t)result1 << 32)) | result0; 22389655b932SBastian Koppelmann } 22399655b932SBastian Koppelmann 22409655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01, 22419655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 22429655b932SBastian Koppelmann { 22439655b932SBastian Koppelmann uint64_t ret; 22449655b932SBastian Koppelmann int64_t result0, result1; 22459655b932SBastian Koppelmann 22469655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 22479655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 22489655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 22499655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 22509655b932SBastian Koppelmann 22519655b932SBastian Koppelmann if (sc1) { 22529655b932SBastian Koppelmann result1 = 0x7fffffff; 22539655b932SBastian Koppelmann } else { 22549655b932SBastian Koppelmann result1 = (((int32_t)arg00 * (int32_t)arg10) << n); 22559655b932SBastian Koppelmann } 22569655b932SBastian Koppelmann if (sc0) { 22579655b932SBastian Koppelmann result0 = 0x7fffffff; 22589655b932SBastian Koppelmann } else { 22599655b932SBastian Koppelmann result0 = (((int32_t)arg01 * (int32_t)arg11) << n); 22609655b932SBastian Koppelmann } 22619655b932SBastian Koppelmann ret = (result1 + result0); 22629655b932SBastian Koppelmann ret = ret << 16; 22639655b932SBastian Koppelmann return ret; 22649655b932SBastian Koppelmann } 22659655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01, 22669655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n) 22679655b932SBastian Koppelmann { 22689655b932SBastian Koppelmann uint32_t result0, result1; 22699655b932SBastian Koppelmann 22709655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) && 22719655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1); 22729655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) && 22739655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1); 22749655b932SBastian Koppelmann 22759655b932SBastian Koppelmann if (sc1) { 22769655b932SBastian Koppelmann result1 = 0x7fffffff; 22779655b932SBastian Koppelmann } else { 22789655b932SBastian Koppelmann result1 = ((arg00 * arg10) << n) + 0x8000; 22799655b932SBastian Koppelmann } 22809655b932SBastian Koppelmann if (sc0) { 22819655b932SBastian Koppelmann result0 = 0x7fffffff; 22829655b932SBastian Koppelmann } else { 22839655b932SBastian Koppelmann result0 = ((arg01 * arg11) << n) + 0x8000; 22849655b932SBastian Koppelmann } 22859655b932SBastian Koppelmann return (result1 & 0xffff0000) | (result0 >> 16); 22869655b932SBastian Koppelmann } 22879655b932SBastian Koppelmann 2288e5c96c82SBastian Koppelmann uint32_t helper_crc32(uint32_t arg0, uint32_t arg1) 2289e5c96c82SBastian Koppelmann { 2290e5c96c82SBastian Koppelmann uint8_t buf[4]; 2291e5c96c82SBastian Koppelmann stl_be_p(buf, arg0); 2292e5c96c82SBastian Koppelmann 22939be38598SEduardo Habkost return crc32(arg1, buf, 4); 2294e5c96c82SBastian Koppelmann } 2295e5c96c82SBastian Koppelmann 22969a31922bSBastian Koppelmann /* context save area (CSA) related helpers */ 22979a31922bSBastian Koppelmann 22989a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw) 22999a31922bSBastian Koppelmann { 23009a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 23019a31922bSBastian Koppelmann return 0; 23029a31922bSBastian Koppelmann } 23039a31922bSBastian Koppelmann 23049a31922bSBastian Koppelmann (*psw)++; 23059a31922bSBastian Koppelmann /* check for overflow */ 23069a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 23079a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 23089a31922bSBastian Koppelmann int count = *psw & mask; 23099a31922bSBastian Koppelmann if (count == 0) { 23109a31922bSBastian Koppelmann (*psw)--; 23119a31922bSBastian Koppelmann return 1; 23129a31922bSBastian Koppelmann } 23139a31922bSBastian Koppelmann return 0; 23149a31922bSBastian Koppelmann } 23159a31922bSBastian Koppelmann 23169a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw) 23179a31922bSBastian Koppelmann { 23189a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) { 23199a31922bSBastian Koppelmann return 0; 23209a31922bSBastian Koppelmann } 23219a31922bSBastian Koppelmann /* check for underflow */ 23229a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 23239a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 23249a31922bSBastian Koppelmann int count = *psw & mask; 23259a31922bSBastian Koppelmann if (count == 0) { 23269a31922bSBastian Koppelmann return 1; 23279a31922bSBastian Koppelmann } 23289a31922bSBastian Koppelmann (*psw)--; 23299a31922bSBastian Koppelmann return 0; 23309a31922bSBastian Koppelmann } 23319a31922bSBastian Koppelmann 233244ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw) 233344ea3430SBastian Koppelmann { 233444ea3430SBastian Koppelmann int cdc = *psw & MASK_PSW_CDC; 233544ea3430SBastian Koppelmann /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC == 233644ea3430SBastian Koppelmann 7'b1111111, otherwise returns FALSE. */ 233744ea3430SBastian Koppelmann if (cdc == 0x7f) { 233844ea3430SBastian Koppelmann return true; 233944ea3430SBastian Koppelmann } 234044ea3430SBastian Koppelmann /* find CDC.COUNT */ 234144ea3430SBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7)); 234244ea3430SBastian Koppelmann int mask = (1u << (7 - lo)) - 1; 234344ea3430SBastian Koppelmann int count = *psw & mask; 234444ea3430SBastian Koppelmann return count == 0; 234544ea3430SBastian Koppelmann } 234644ea3430SBastian Koppelmann 2347030c58dfSBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, int ea) 23489a31922bSBastian Koppelmann { 23499a31922bSBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 235072373357SBastian Koppelmann cpu_stl_data(env, ea+4, psw_read(env)); 23519a31922bSBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[10]); 23529a31922bSBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[11]); 23539a31922bSBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[8]); 23549a31922bSBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[9]); 23559a31922bSBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[10]); 23569a31922bSBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[11]); 23579a31922bSBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[12]); 23589a31922bSBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[13]); 23599a31922bSBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[14]); 23609a31922bSBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[15]); 23619a31922bSBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[12]); 23629a31922bSBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[13]); 23639a31922bSBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[14]); 23649a31922bSBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[15]); 23659a31922bSBastian Koppelmann } 23669a31922bSBastian Koppelmann 2367030c58dfSBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, int ea) 23685de93515SBastian Koppelmann { 23695de93515SBastian Koppelmann cpu_stl_data(env, ea, env->PCXI); 2370030c58dfSBastian Koppelmann cpu_stl_data(env, ea+4, env->gpr_a[11]); 23715de93515SBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[2]); 23725de93515SBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[3]); 23735de93515SBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[0]); 23745de93515SBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[1]); 23755de93515SBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[2]); 23765de93515SBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[3]); 23775de93515SBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[4]); 23785de93515SBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[5]); 23795de93515SBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[6]); 23805de93515SBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[7]); 23815de93515SBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[4]); 23825de93515SBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[5]); 23835de93515SBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[6]); 23845de93515SBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[7]); 23855de93515SBastian Koppelmann } 23865de93515SBastian Koppelmann 23879a31922bSBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, int ea, 23889a31922bSBastian Koppelmann target_ulong *new_PCXI, target_ulong *new_PSW) 23899a31922bSBastian Koppelmann { 23909a31922bSBastian Koppelmann *new_PCXI = cpu_ldl_data(env, ea); 23919a31922bSBastian Koppelmann *new_PSW = cpu_ldl_data(env, ea+4); 23929a31922bSBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, ea+8); 23939a31922bSBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, ea+12); 23949a31922bSBastian Koppelmann env->gpr_d[8] = cpu_ldl_data(env, ea+16); 23959a31922bSBastian Koppelmann env->gpr_d[9] = cpu_ldl_data(env, ea+20); 23969a31922bSBastian Koppelmann env->gpr_d[10] = cpu_ldl_data(env, ea+24); 23979a31922bSBastian Koppelmann env->gpr_d[11] = cpu_ldl_data(env, ea+28); 23989a31922bSBastian Koppelmann env->gpr_a[12] = cpu_ldl_data(env, ea+32); 23999a31922bSBastian Koppelmann env->gpr_a[13] = cpu_ldl_data(env, ea+36); 24009a31922bSBastian Koppelmann env->gpr_a[14] = cpu_ldl_data(env, ea+40); 24019a31922bSBastian Koppelmann env->gpr_a[15] = cpu_ldl_data(env, ea+44); 24029a31922bSBastian Koppelmann env->gpr_d[12] = cpu_ldl_data(env, ea+48); 24039a31922bSBastian Koppelmann env->gpr_d[13] = cpu_ldl_data(env, ea+52); 24049a31922bSBastian Koppelmann env->gpr_d[14] = cpu_ldl_data(env, ea+56); 24059a31922bSBastian Koppelmann env->gpr_d[15] = cpu_ldl_data(env, ea+60); 24069a31922bSBastian Koppelmann } 24079a31922bSBastian Koppelmann 240859543d4eSBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, int ea, 240959543d4eSBastian Koppelmann target_ulong *ra, target_ulong *pcxi) 241059543d4eSBastian Koppelmann { 241159543d4eSBastian Koppelmann *pcxi = cpu_ldl_data(env, ea); 241259543d4eSBastian Koppelmann *ra = cpu_ldl_data(env, ea+4); 241359543d4eSBastian Koppelmann env->gpr_a[2] = cpu_ldl_data(env, ea+8); 241459543d4eSBastian Koppelmann env->gpr_a[3] = cpu_ldl_data(env, ea+12); 241559543d4eSBastian Koppelmann env->gpr_d[0] = cpu_ldl_data(env, ea+16); 241659543d4eSBastian Koppelmann env->gpr_d[1] = cpu_ldl_data(env, ea+20); 241759543d4eSBastian Koppelmann env->gpr_d[2] = cpu_ldl_data(env, ea+24); 241859543d4eSBastian Koppelmann env->gpr_d[3] = cpu_ldl_data(env, ea+28); 241959543d4eSBastian Koppelmann env->gpr_a[4] = cpu_ldl_data(env, ea+32); 242059543d4eSBastian Koppelmann env->gpr_a[5] = cpu_ldl_data(env, ea+36); 242159543d4eSBastian Koppelmann env->gpr_a[6] = cpu_ldl_data(env, ea+40); 242259543d4eSBastian Koppelmann env->gpr_a[7] = cpu_ldl_data(env, ea+44); 242359543d4eSBastian Koppelmann env->gpr_d[4] = cpu_ldl_data(env, ea+48); 242459543d4eSBastian Koppelmann env->gpr_d[5] = cpu_ldl_data(env, ea+52); 242559543d4eSBastian Koppelmann env->gpr_d[6] = cpu_ldl_data(env, ea+56); 242659543d4eSBastian Koppelmann env->gpr_d[7] = cpu_ldl_data(env, ea+60); 242759543d4eSBastian Koppelmann } 242859543d4eSBastian Koppelmann 24299a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc) 24309a31922bSBastian Koppelmann { 24319a31922bSBastian Koppelmann target_ulong tmp_FCX; 24329a31922bSBastian Koppelmann target_ulong ea; 24339a31922bSBastian Koppelmann target_ulong new_FCX; 24349a31922bSBastian Koppelmann target_ulong psw; 24359a31922bSBastian Koppelmann 24369a31922bSBastian Koppelmann psw = psw_read(env); 24379a31922bSBastian Koppelmann /* if (FCX == 0) trap(FCU); */ 24389a31922bSBastian Koppelmann if (env->FCX == 0) { 24399a31922bSBastian Koppelmann /* FCU trap */ 24403292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); 24419a31922bSBastian Koppelmann } 24429a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */ 24439a31922bSBastian Koppelmann if (psw & MASK_PSW_CDE) { 24449a31922bSBastian Koppelmann if (cdc_increment(&psw)) { 24459a31922bSBastian Koppelmann /* CDO trap */ 24463292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC()); 24479a31922bSBastian Koppelmann } 24489a31922bSBastian Koppelmann } 24499a31922bSBastian Koppelmann /* PSW.CDE = 1;*/ 24509a31922bSBastian Koppelmann psw |= MASK_PSW_CDE; 24519a31922bSBastian Koppelmann /* tmp_FCX = FCX; */ 24529a31922bSBastian Koppelmann tmp_FCX = env->FCX; 24539a31922bSBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 24549a31922bSBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 24559a31922bSBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 2456030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 2457030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2458030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 24599a31922bSBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 24609a31922bSBastian Koppelmann D[15]}; */ 2461030c58dfSBastian Koppelmann save_context_upper(env, ea); 24629a31922bSBastian Koppelmann 24639a31922bSBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 24649a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 24659a31922bSBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 24669a31922bSBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 2467ce46335cSDavid Brenken env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 2468d1cbc28aSDavid Brenken ((env->ICR & MASK_ICR_IE_1_3) << 15)); 24699a31922bSBastian Koppelmann /* PCXI.UL = 1; */ 24709a31922bSBastian Koppelmann env->PCXI |= MASK_PCXI_UL; 24719a31922bSBastian Koppelmann 24729a31922bSBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 24739a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 24749a31922bSBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 24759a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 24769a31922bSBastian Koppelmann /* A[11] = next_pc[31: 0]; */ 24779a31922bSBastian Koppelmann env->gpr_a[11] = next_pc; 24789a31922bSBastian Koppelmann 24799a31922bSBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 24809a31922bSBastian Koppelmann if (tmp_FCX == env->LCX) { 24819a31922bSBastian Koppelmann /* FCD trap */ 24823292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); 24839a31922bSBastian Koppelmann } 24849a31922bSBastian Koppelmann psw_write(env, psw); 24859a31922bSBastian Koppelmann } 24869a31922bSBastian Koppelmann 24879a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env) 24889a31922bSBastian Koppelmann { 24899a31922bSBastian Koppelmann target_ulong ea; 24909a31922bSBastian Koppelmann target_ulong new_PCXI; 24919a31922bSBastian Koppelmann target_ulong new_PSW, psw; 24929a31922bSBastian Koppelmann 24939a31922bSBastian Koppelmann psw = psw_read(env); 24949a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/ 24953292b447SBastian Koppelmann if (psw & MASK_PSW_CDE) { 24963292b447SBastian Koppelmann if (cdc_decrement(&psw)) { 24979a31922bSBastian Koppelmann /* CDU trap */ 24983292b447SBastian Koppelmann psw_write(env, psw); 24993292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC()); 25009a31922bSBastian Koppelmann } 25019a31922bSBastian Koppelmann } 25029a31922bSBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 25039a31922bSBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 25049a31922bSBastian Koppelmann /* CSU trap */ 25053292b447SBastian Koppelmann psw_write(env, psw); 25063292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC()); 25079a31922bSBastian Koppelmann } 25089a31922bSBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 25099a31922bSBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 25109a31922bSBastian Koppelmann /* CTYP trap */ 25113292b447SBastian Koppelmann cdc_increment(&psw); /* restore to the start of helper */ 25123292b447SBastian Koppelmann psw_write(env, psw); 25133292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC()); 25149a31922bSBastian Koppelmann } 25159a31922bSBastian Koppelmann /* PC = {A11 [31: 1], 1’b0}; */ 25169a31922bSBastian Koppelmann env->PC = env->gpr_a[11] & 0xfffffffe; 25179a31922bSBastian Koppelmann 25189a31922bSBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 25199a31922bSBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 25209a31922bSBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 25219a31922bSBastian Koppelmann /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2522030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 25239a31922bSBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2524030c58dfSBastian Koppelmann /* M(EA, word) = FCX; */ 2525030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 25269a31922bSBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 25279a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 25289a31922bSBastian Koppelmann /* PCXI = new_PCXI; */ 25299a31922bSBastian Koppelmann env->PCXI = new_PCXI; 25309a31922bSBastian Koppelmann 25319a31922bSBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_13)) { 25329a31922bSBastian Koppelmann /* PSW = new_PSW */ 25339a31922bSBastian Koppelmann psw_write(env, new_PSW); 25349a31922bSBastian Koppelmann } else { 25359a31922bSBastian Koppelmann /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */ 25369a31922bSBastian Koppelmann psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000))); 25379a31922bSBastian Koppelmann } 25389a31922bSBastian Koppelmann } 25399a31922bSBastian Koppelmann 25405de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9) 25415de93515SBastian Koppelmann { 25425de93515SBastian Koppelmann target_ulong tmp_FCX; 25435de93515SBastian Koppelmann target_ulong ea; 25445de93515SBastian Koppelmann target_ulong new_FCX; 25455de93515SBastian Koppelmann 25465de93515SBastian Koppelmann if (env->FCX == 0) { 25475de93515SBastian Koppelmann /* FCU trap */ 25483292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); 25495de93515SBastian Koppelmann } 25505de93515SBastian Koppelmann 25515de93515SBastian Koppelmann tmp_FCX = env->FCX; 25525de93515SBastian Koppelmann ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6); 25535de93515SBastian Koppelmann 2554030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */ 2555030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2556030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4] 2557030c58dfSBastian Koppelmann , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */ 2558030c58dfSBastian Koppelmann save_context_lower(env, ea); 2559030c58dfSBastian Koppelmann 25605de93515SBastian Koppelmann 25615de93515SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */ 25625de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 25635de93515SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 25645de93515SBastian Koppelmann /* PCXI.PIE = ICR.IE */ 2565ce46335cSDavid Brenken env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 2566d1cbc28aSDavid Brenken ((env->ICR & MASK_ICR_IE_1_3) << 15)); 25675de93515SBastian Koppelmann /* PCXI.UL = 0 */ 25685de93515SBastian Koppelmann env->PCXI &= ~(MASK_PCXI_UL); 25695de93515SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0] */ 25705de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 25715de93515SBastian Koppelmann /* FXC[19: 0] = new_FCX[19: 0] */ 25725de93515SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 25735de93515SBastian Koppelmann /* ICR.IE = 1 */ 2574d1cbc28aSDavid Brenken env->ICR |= MASK_ICR_IE_1_3; 25755de93515SBastian Koppelmann 25765de93515SBastian Koppelmann env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/ 25775de93515SBastian Koppelmann 25785de93515SBastian Koppelmann if (tmp_FCX == env->LCX) { 25795de93515SBastian Koppelmann /* FCD trap */ 25803292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); 25815de93515SBastian Koppelmann } 25825de93515SBastian Koppelmann } 25835de93515SBastian Koppelmann 258444ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env) 258544ea3430SBastian Koppelmann { 258644ea3430SBastian Koppelmann target_ulong ea; 258744ea3430SBastian Koppelmann target_ulong new_PCXI; 258844ea3430SBastian Koppelmann target_ulong new_PSW; 258944ea3430SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 259044ea3430SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 259144ea3430SBastian Koppelmann /* raise csu trap */ 25923292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC()); 259344ea3430SBastian Koppelmann } 259444ea3430SBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */ 259544ea3430SBastian Koppelmann if ((env->PCXI & MASK_PCXI_UL) == 0) { 259644ea3430SBastian Koppelmann /* raise CTYP trap */ 25973292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC()); 259844ea3430SBastian Koppelmann } 259944ea3430SBastian Koppelmann /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */ 260044ea3430SBastian Koppelmann if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) { 26013292b447SBastian Koppelmann /* raise NEST trap */ 26023292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC()); 260344ea3430SBastian Koppelmann } 26043446a111SBastian Koppelmann env->PC = env->gpr_a[11] & ~0x1; 260544ea3430SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 2606d1cbc28aSDavid Brenken env->ICR = (env->ICR & ~MASK_ICR_IE_1_3) 2607ce46335cSDavid Brenken + ((env->PCXI & MASK_PCXI_PIE_1_3) >> 15); 260844ea3430SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 260944ea3430SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) + 261044ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCPN) >> 24); 261144ea3430SBastian Koppelmann /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/ 261244ea3430SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 261344ea3430SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 261444ea3430SBastian Koppelmann /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2615030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 261644ea3430SBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW); 2617030c58dfSBastian Koppelmann /* M(EA, word) = FCX;*/ 2618030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 261944ea3430SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 262044ea3430SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 262144ea3430SBastian Koppelmann /* PCXI = new_PCXI; */ 262244ea3430SBastian Koppelmann env->PCXI = new_PCXI; 262344ea3430SBastian Koppelmann /* write psw */ 262444ea3430SBastian Koppelmann psw_write(env, new_PSW); 262544ea3430SBastian Koppelmann } 262644ea3430SBastian Koppelmann 2627b724b012SBastian Koppelmann void helper_rfm(CPUTriCoreState *env) 2628b724b012SBastian Koppelmann { 2629b724b012SBastian Koppelmann env->PC = (env->gpr_a[11] & ~0x1); 2630b724b012SBastian Koppelmann /* ICR.IE = PCXI.PIE; */ 2631ce46335cSDavid Brenken env->ICR = (env->ICR & ~MASK_ICR_IE_1_3) 2632ce46335cSDavid Brenken | ((env->PCXI & MASK_PCXI_PIE_1_3) >> 15); 2633b724b012SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */ 2634b724b012SBastian Koppelmann env->ICR = (env->ICR & ~MASK_ICR_CCPN) | 26355f37fd8eSPaolo Bonzini ((env->PCXI & MASK_PCXI_PCPN) >> 24); 2636b724b012SBastian Koppelmann /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */ 2637b724b012SBastian Koppelmann env->PCXI = cpu_ldl_data(env, env->DCX); 2638b724b012SBastian Koppelmann psw_write(env, cpu_ldl_data(env, env->DCX+4)); 2639b724b012SBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8); 2640b724b012SBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12); 2641b724b012SBastian Koppelmann 2642b724b012SBastian Koppelmann if (tricore_feature(env, TRICORE_FEATURE_131)) { 2643b724b012SBastian Koppelmann env->DBGTCR = 0; 2644b724b012SBastian Koppelmann } 2645b724b012SBastian Koppelmann } 2646b724b012SBastian Koppelmann 264759543d4eSBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, uint32_t ea) 264859543d4eSBastian Koppelmann { 264959543d4eSBastian Koppelmann uint32_t dummy; 265059543d4eSBastian Koppelmann /* insn doesn't load PCXI and RA */ 265159543d4eSBastian Koppelmann restore_context_lower(env, ea, &dummy, &dummy); 265259543d4eSBastian Koppelmann } 265359543d4eSBastian Koppelmann 265459543d4eSBastian Koppelmann void helper_lducx(CPUTriCoreState *env, uint32_t ea) 265559543d4eSBastian Koppelmann { 265659543d4eSBastian Koppelmann uint32_t dummy; 265759543d4eSBastian Koppelmann /* insn doesn't load PCXI and PSW */ 265859543d4eSBastian Koppelmann restore_context_upper(env, ea, &dummy, &dummy); 265959543d4eSBastian Koppelmann } 266059543d4eSBastian Koppelmann 266159543d4eSBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, uint32_t ea) 266259543d4eSBastian Koppelmann { 266359543d4eSBastian Koppelmann save_context_lower(env, ea); 266459543d4eSBastian Koppelmann } 266559543d4eSBastian Koppelmann 266659543d4eSBastian Koppelmann void helper_stucx(CPUTriCoreState *env, uint32_t ea) 266759543d4eSBastian Koppelmann { 266859543d4eSBastian Koppelmann save_context_upper(env, ea); 266959543d4eSBastian Koppelmann } 267059543d4eSBastian Koppelmann 2671b724b012SBastian Koppelmann void helper_svlcx(CPUTriCoreState *env) 2672b724b012SBastian Koppelmann { 2673b724b012SBastian Koppelmann target_ulong tmp_FCX; 2674b724b012SBastian Koppelmann target_ulong ea; 2675b724b012SBastian Koppelmann target_ulong new_FCX; 2676b724b012SBastian Koppelmann 2677b724b012SBastian Koppelmann if (env->FCX == 0) { 2678b724b012SBastian Koppelmann /* FCU trap */ 26793292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); 2680b724b012SBastian Koppelmann } 2681b724b012SBastian Koppelmann /* tmp_FCX = FCX; */ 2682b724b012SBastian Koppelmann tmp_FCX = env->FCX; 2683b724b012SBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 2684b724b012SBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 2685b724b012SBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 2686b724b012SBastian Koppelmann /* new_FCX = M(EA, word); */ 2687b724b012SBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2688b724b012SBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 2689b724b012SBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 2690b724b012SBastian Koppelmann D[15]}; */ 2691b724b012SBastian Koppelmann save_context_lower(env, ea); 2692b724b012SBastian Koppelmann 2693b724b012SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 2694b724b012SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 2695b724b012SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 2696b724b012SBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 2697ce46335cSDavid Brenken env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 2698d1cbc28aSDavid Brenken ((env->ICR & MASK_ICR_IE_1_3) << 15)); 2699b724b012SBastian Koppelmann /* PCXI.UL = 0; */ 2700b724b012SBastian Koppelmann env->PCXI &= ~MASK_PCXI_UL; 2701b724b012SBastian Koppelmann 2702b724b012SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 2703b724b012SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 2704b724b012SBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 2705b724b012SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 2706b724b012SBastian Koppelmann 2707b724b012SBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 2708b724b012SBastian Koppelmann if (tmp_FCX == env->LCX) { 2709b724b012SBastian Koppelmann /* FCD trap */ 27103292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); 2711b724b012SBastian Koppelmann } 2712b724b012SBastian Koppelmann } 2713b724b012SBastian Koppelmann 2714518d7fd2SBastian Koppelmann void helper_svucx(CPUTriCoreState *env) 2715518d7fd2SBastian Koppelmann { 2716518d7fd2SBastian Koppelmann target_ulong tmp_FCX; 2717518d7fd2SBastian Koppelmann target_ulong ea; 2718518d7fd2SBastian Koppelmann target_ulong new_FCX; 2719518d7fd2SBastian Koppelmann 2720518d7fd2SBastian Koppelmann if (env->FCX == 0) { 2721518d7fd2SBastian Koppelmann /* FCU trap */ 27223292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC()); 2723518d7fd2SBastian Koppelmann } 2724518d7fd2SBastian Koppelmann /* tmp_FCX = FCX; */ 2725518d7fd2SBastian Koppelmann tmp_FCX = env->FCX; 2726518d7fd2SBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */ 2727518d7fd2SBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) + 2728518d7fd2SBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6); 2729518d7fd2SBastian Koppelmann /* new_FCX = M(EA, word); */ 2730518d7fd2SBastian Koppelmann new_FCX = cpu_ldl_data(env, ea); 2731518d7fd2SBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], 2732518d7fd2SBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14], 2733518d7fd2SBastian Koppelmann D[15]}; */ 2734518d7fd2SBastian Koppelmann save_context_upper(env, ea); 2735518d7fd2SBastian Koppelmann 2736518d7fd2SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */ 2737518d7fd2SBastian Koppelmann env->PCXI = (env->PCXI & 0xffffff) + 2738518d7fd2SBastian Koppelmann ((env->ICR & MASK_ICR_CCPN) << 24); 2739518d7fd2SBastian Koppelmann /* PCXI.PIE = ICR.IE; */ 2740ce46335cSDavid Brenken env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE_1_3) + 2741d1cbc28aSDavid Brenken ((env->ICR & MASK_ICR_IE_1_3) << 15)); 2742518d7fd2SBastian Koppelmann /* PCXI.UL = 1; */ 2743518d7fd2SBastian Koppelmann env->PCXI |= MASK_PCXI_UL; 2744518d7fd2SBastian Koppelmann 2745518d7fd2SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */ 2746518d7fd2SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff); 2747518d7fd2SBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */ 2748518d7fd2SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff); 2749518d7fd2SBastian Koppelmann 2750518d7fd2SBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/ 2751518d7fd2SBastian Koppelmann if (tmp_FCX == env->LCX) { 2752518d7fd2SBastian Koppelmann /* FCD trap */ 27533292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC()); 2754518d7fd2SBastian Koppelmann } 2755518d7fd2SBastian Koppelmann } 2756518d7fd2SBastian Koppelmann 2757b724b012SBastian Koppelmann void helper_rslcx(CPUTriCoreState *env) 2758b724b012SBastian Koppelmann { 2759b724b012SBastian Koppelmann target_ulong ea; 2760b724b012SBastian Koppelmann target_ulong new_PCXI; 2761b724b012SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */ 2762b724b012SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) { 2763b724b012SBastian Koppelmann /* CSU trap */ 27643292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC()); 2765b724b012SBastian Koppelmann } 2766b724b012SBastian Koppelmann /* if (PCXI.UL == 1) then trap(CTYP); */ 27677b4b0b57SStefan Weil if ((env->PCXI & MASK_PCXI_UL) != 0) { 2768b724b012SBastian Koppelmann /* CTYP trap */ 27693292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC()); 2770b724b012SBastian Koppelmann } 2771b724b012SBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */ 2772b724b012SBastian Koppelmann ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) + 2773b724b012SBastian Koppelmann ((env->PCXI & MASK_PCXI_PCXO) << 6); 2774b724b012SBastian Koppelmann /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12], 2775b724b012SBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */ 2776bc72f8aaSBastian Koppelmann restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI); 2777b724b012SBastian Koppelmann /* M(EA, word) = FCX; */ 2778b724b012SBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 2779b724b012SBastian Koppelmann /* M(EA, word) = FCX; */ 2780b724b012SBastian Koppelmann cpu_stl_data(env, ea, env->FCX); 2781b724b012SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */ 2782b724b012SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff); 2783b724b012SBastian Koppelmann /* PCXI = new_PCXI; */ 2784b724b012SBastian Koppelmann env->PCXI = new_PCXI; 2785b724b012SBastian Koppelmann } 2786b724b012SBastian Koppelmann 27872b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg) 27882b2f7d97SBastian Koppelmann { 27892b2f7d97SBastian Koppelmann psw_write(env, arg); 27902b2f7d97SBastian Koppelmann } 27912b2f7d97SBastian Koppelmann 27922b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env) 27932b2f7d97SBastian Koppelmann { 27942b2f7d97SBastian Koppelmann return psw_read(env); 27952b2f7d97SBastian Koppelmann } 2796