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"
21*42fa9665SPhilippe Mathieu-Daudé #include "accel/tcg/cpu-ldst.h"
22e5c96c82SBastian Koppelmann #include <zlib.h> /* for crc32 */
2348e06fe0SBastian Koppelmann
24518d7fd2SBastian Koppelmann
25518d7fd2SBastian Koppelmann /* Exception helpers */
26518d7fd2SBastian Koppelmann
278905770bSMarc-André Lureau static G_NORETURN
raise_exception_sync_internal(CPUTriCoreState * env,uint32_t class,int tin,uintptr_t pc,uint32_t fcd_pc)288905770bSMarc-André Lureau void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin,
29518d7fd2SBastian Koppelmann uintptr_t pc, uint32_t fcd_pc)
30518d7fd2SBastian Koppelmann {
3106eb2e29SRichard Henderson CPUState *cs = env_cpu(env);
32518d7fd2SBastian Koppelmann /* in case we come from a helper-call we need to restore the PC */
333d419a4dSRichard Henderson cpu_restore_state(cs, pc);
34518d7fd2SBastian Koppelmann
35518d7fd2SBastian Koppelmann /* Tin is loaded into d[15] */
36518d7fd2SBastian Koppelmann env->gpr_d[15] = tin;
37518d7fd2SBastian Koppelmann
38518d7fd2SBastian Koppelmann if (class == TRAPC_CTX_MNG && tin == TIN3_FCU) {
39518d7fd2SBastian Koppelmann /* upper context cannot be saved, if the context list is empty */
40518d7fd2SBastian Koppelmann } else {
41518d7fd2SBastian Koppelmann helper_svucx(env);
42518d7fd2SBastian Koppelmann }
43518d7fd2SBastian Koppelmann
44518d7fd2SBastian Koppelmann /* The return address in a[11] is updated */
45518d7fd2SBastian Koppelmann if (class == TRAPC_CTX_MNG && tin == TIN3_FCD) {
46518d7fd2SBastian Koppelmann env->SYSCON |= MASK_SYSCON_FCD_SF;
47518d7fd2SBastian Koppelmann /* when we run out of CSAs after saving a context a FCD trap is taken
48518d7fd2SBastian Koppelmann and the return address is the start of the trap handler which used
49518d7fd2SBastian Koppelmann the last CSA */
50518d7fd2SBastian Koppelmann env->gpr_a[11] = fcd_pc;
51518d7fd2SBastian Koppelmann } else if (class == TRAPC_SYSCALL) {
52518d7fd2SBastian Koppelmann env->gpr_a[11] = env->PC + 4;
53518d7fd2SBastian Koppelmann } else {
54518d7fd2SBastian Koppelmann env->gpr_a[11] = env->PC;
55518d7fd2SBastian Koppelmann }
56518d7fd2SBastian Koppelmann /* The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP)
57518d7fd2SBastian Koppelmann when the processor was not previously using the interrupt stack
58518d7fd2SBastian Koppelmann (in case of PSW.IS = 0). The stack pointer bit is set for using the
59518d7fd2SBastian Koppelmann interrupt stack: PSW.IS = 1. */
60518d7fd2SBastian Koppelmann if ((env->PSW & MASK_PSW_IS) == 0) {
61518d7fd2SBastian Koppelmann env->gpr_a[10] = env->ISP;
62518d7fd2SBastian Koppelmann }
63518d7fd2SBastian Koppelmann env->PSW |= MASK_PSW_IS;
64518d7fd2SBastian Koppelmann /* The I/O mode is set to Supervisor mode, which means all permissions
65518d7fd2SBastian Koppelmann are enabled: PSW.IO = 10 B .*/
66518d7fd2SBastian Koppelmann env->PSW |= (2 << 10);
67518d7fd2SBastian Koppelmann
68518d7fd2SBastian Koppelmann /*The current Protection Register Set is set to 0: PSW.PRS = 00 B .*/
69518d7fd2SBastian Koppelmann env->PSW &= ~MASK_PSW_PRS;
70518d7fd2SBastian Koppelmann
71518d7fd2SBastian Koppelmann /* The Call Depth Counter (CDC) is cleared, and the call depth limit is
72518d7fd2SBastian Koppelmann set for 64: PSW.CDC = 0000000 B .*/
73518d7fd2SBastian Koppelmann env->PSW &= ~MASK_PSW_CDC;
74518d7fd2SBastian Koppelmann
75518d7fd2SBastian Koppelmann /* Call Depth Counter is enabled, PSW.CDE = 1. */
76518d7fd2SBastian Koppelmann env->PSW |= MASK_PSW_CDE;
77518d7fd2SBastian Koppelmann
78518d7fd2SBastian Koppelmann /* Write permission to global registers A[0], A[1], A[8], A[9] is
79518d7fd2SBastian Koppelmann disabled: PSW.GW = 0. */
80518d7fd2SBastian Koppelmann env->PSW &= ~MASK_PSW_GW;
81518d7fd2SBastian Koppelmann
82518d7fd2SBastian Koppelmann /*The interrupt system is globally disabled: ICR.IE = 0. The ‘old’
83518d7fd2SBastian Koppelmann ICR.IE and ICR.CCPN are saved */
84518d7fd2SBastian Koppelmann
85518d7fd2SBastian Koppelmann /* PCXI.PIE = ICR.IE */
86343cdf2cSBastian Koppelmann pcxi_set_pie(env, icr_get_ie(env));
87343cdf2cSBastian Koppelmann
88518d7fd2SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */
89343cdf2cSBastian Koppelmann pcxi_set_pcpn(env, icr_get_ccpn(env));
90518d7fd2SBastian Koppelmann /* Update PC using the trap vector table */
91518d7fd2SBastian Koppelmann env->PC = env->BTV | (class << 5);
92518d7fd2SBastian Koppelmann
93518d7fd2SBastian Koppelmann cpu_loop_exit(cs);
94518d7fd2SBastian Koppelmann }
95518d7fd2SBastian Koppelmann
helper_raise_exception_sync(CPUTriCoreState * env,uint32_t class,uint32_t tin)96518d7fd2SBastian Koppelmann void helper_raise_exception_sync(CPUTriCoreState *env, uint32_t class,
97518d7fd2SBastian Koppelmann uint32_t tin)
98518d7fd2SBastian Koppelmann {
99518d7fd2SBastian Koppelmann raise_exception_sync_internal(env, class, tin, 0, 0);
100518d7fd2SBastian Koppelmann }
101518d7fd2SBastian Koppelmann
raise_exception_sync_helper(CPUTriCoreState * env,uint32_t class,uint32_t tin,uintptr_t pc)1023292b447SBastian Koppelmann static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class,
1033292b447SBastian Koppelmann uint32_t tin, uintptr_t pc)
1043292b447SBastian Koppelmann {
1053292b447SBastian Koppelmann raise_exception_sync_internal(env, class, tin, pc, 0);
1063292b447SBastian Koppelmann }
1073292b447SBastian Koppelmann
1083a16ecb0SBastian Koppelmann /* Addressing mode helper */
1093a16ecb0SBastian Koppelmann
reverse16(uint16_t val)1103a16ecb0SBastian Koppelmann static uint16_t reverse16(uint16_t val)
1113a16ecb0SBastian Koppelmann {
1123a16ecb0SBastian Koppelmann uint8_t high = (uint8_t)(val >> 8);
1133a16ecb0SBastian Koppelmann uint8_t low = (uint8_t)(val & 0xff);
1143a16ecb0SBastian Koppelmann
1153a16ecb0SBastian Koppelmann uint16_t rh, rl;
1163a16ecb0SBastian Koppelmann
1173a16ecb0SBastian Koppelmann rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
1183a16ecb0SBastian Koppelmann rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
1193a16ecb0SBastian Koppelmann
1203a16ecb0SBastian Koppelmann return (rh << 8) | rl;
1213a16ecb0SBastian Koppelmann }
1223a16ecb0SBastian Koppelmann
helper_br_update(uint32_t reg)1233a16ecb0SBastian Koppelmann uint32_t helper_br_update(uint32_t reg)
1243a16ecb0SBastian Koppelmann {
1253a16ecb0SBastian Koppelmann uint32_t index = reg & 0xffff;
1263a16ecb0SBastian Koppelmann uint32_t incr = reg >> 16;
1273a16ecb0SBastian Koppelmann uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
1283a16ecb0SBastian Koppelmann return reg - index + new_index;
1293a16ecb0SBastian Koppelmann }
1303a16ecb0SBastian Koppelmann
helper_circ_update(uint32_t reg,uint32_t off)1313a16ecb0SBastian Koppelmann uint32_t helper_circ_update(uint32_t reg, uint32_t off)
1323a16ecb0SBastian Koppelmann {
1333a16ecb0SBastian Koppelmann uint32_t index = reg & 0xffff;
1343a16ecb0SBastian Koppelmann uint32_t length = reg >> 16;
1353a16ecb0SBastian Koppelmann int32_t new_index = index + off;
1363a16ecb0SBastian Koppelmann if (new_index < 0) {
1373a16ecb0SBastian Koppelmann new_index += length;
1383a16ecb0SBastian Koppelmann } else {
1393a16ecb0SBastian Koppelmann new_index %= length;
1403a16ecb0SBastian Koppelmann }
1413a16ecb0SBastian Koppelmann return reg - index + new_index;
1423a16ecb0SBastian Koppelmann }
1433a16ecb0SBastian Koppelmann
ssov32(CPUTriCoreState * env,int64_t arg)144e4e39176SBastian Koppelmann static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
145e4e39176SBastian Koppelmann {
146e4e39176SBastian Koppelmann uint32_t ret;
147e4e39176SBastian Koppelmann int64_t max_pos = INT32_MAX;
148e4e39176SBastian Koppelmann int64_t max_neg = INT32_MIN;
149e4e39176SBastian Koppelmann if (arg > max_pos) {
150e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31);
151e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31);
152e4e39176SBastian Koppelmann ret = (target_ulong)max_pos;
153e4e39176SBastian Koppelmann } else {
154e4e39176SBastian Koppelmann if (arg < max_neg) {
155e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31);
156e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31);
157e4e39176SBastian Koppelmann ret = (target_ulong)max_neg;
158e4e39176SBastian Koppelmann } else {
159e4e39176SBastian Koppelmann env->PSW_USB_V = 0;
160e4e39176SBastian Koppelmann ret = (target_ulong)arg;
161e4e39176SBastian Koppelmann }
162e4e39176SBastian Koppelmann }
163e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u;
164e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
165e4e39176SBastian Koppelmann return ret;
166e4e39176SBastian Koppelmann }
1672692802aSBastian Koppelmann
suov32_pos(CPUTriCoreState * env,uint64_t arg)16885d604afSBastian Koppelmann static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg)
169e4e39176SBastian Koppelmann {
170e4e39176SBastian Koppelmann uint32_t ret;
17185d604afSBastian Koppelmann uint64_t max_pos = UINT32_MAX;
172e4e39176SBastian Koppelmann if (arg > max_pos) {
173e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31);
174e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31);
175e4e39176SBastian Koppelmann ret = (target_ulong)max_pos;
176e4e39176SBastian Koppelmann } else {
17785d604afSBastian Koppelmann env->PSW_USB_V = 0;
17885d604afSBastian Koppelmann ret = (target_ulong)arg;
17985d604afSBastian Koppelmann }
18085d604afSBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u;
18185d604afSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
18285d604afSBastian Koppelmann return ret;
18385d604afSBastian Koppelmann }
18485d604afSBastian Koppelmann
suov32_neg(CPUTriCoreState * env,int64_t arg)18585d604afSBastian Koppelmann static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg)
18685d604afSBastian Koppelmann {
18785d604afSBastian Koppelmann uint32_t ret;
18885d604afSBastian Koppelmann
189e4e39176SBastian Koppelmann if (arg < 0) {
190e4e39176SBastian Koppelmann env->PSW_USB_V = (1 << 31);
191e4e39176SBastian Koppelmann env->PSW_USB_SV = (1 << 31);
192e4e39176SBastian Koppelmann ret = 0;
193e4e39176SBastian Koppelmann } else {
194e4e39176SBastian Koppelmann env->PSW_USB_V = 0;
195e4e39176SBastian Koppelmann ret = (target_ulong)arg;
196e4e39176SBastian Koppelmann }
197e4e39176SBastian Koppelmann env->PSW_USB_AV = arg ^ arg * 2u;
198e4e39176SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
199e4e39176SBastian Koppelmann return ret;
200e4e39176SBastian Koppelmann }
2010974257eSBastian Koppelmann
ssov16(CPUTriCoreState * env,int32_t hw0,int32_t hw1)202d5de7839SBastian Koppelmann static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
203d5de7839SBastian Koppelmann {
204d5de7839SBastian Koppelmann int32_t max_pos = INT16_MAX;
205d5de7839SBastian Koppelmann int32_t max_neg = INT16_MIN;
206d5de7839SBastian Koppelmann int32_t av0, av1;
207d5de7839SBastian Koppelmann
208d5de7839SBastian Koppelmann env->PSW_USB_V = 0;
209d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u;
210d5de7839SBastian Koppelmann if (hw0 > max_pos) {
211d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31);
212d5de7839SBastian Koppelmann hw0 = max_pos;
213d5de7839SBastian Koppelmann } else if (hw0 < max_neg) {
214d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31);
215d5de7839SBastian Koppelmann hw0 = max_neg;
216d5de7839SBastian Koppelmann }
217d5de7839SBastian Koppelmann
218d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u;
219d5de7839SBastian Koppelmann if (hw1 > max_pos) {
220d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31);
221d5de7839SBastian Koppelmann hw1 = max_pos;
222d5de7839SBastian Koppelmann } else if (hw1 < max_neg) {
223d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31);
224d5de7839SBastian Koppelmann hw1 = max_neg;
225d5de7839SBastian Koppelmann }
226d5de7839SBastian Koppelmann
227d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
228d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16;
229d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
230d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16);
231d5de7839SBastian Koppelmann }
232d5de7839SBastian Koppelmann
suov16(CPUTriCoreState * env,int32_t hw0,int32_t hw1)233d5de7839SBastian Koppelmann static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
234d5de7839SBastian Koppelmann {
235d5de7839SBastian Koppelmann int32_t max_pos = UINT16_MAX;
236d5de7839SBastian Koppelmann int32_t av0, av1;
237d5de7839SBastian Koppelmann
238d5de7839SBastian Koppelmann env->PSW_USB_V = 0;
239d5de7839SBastian Koppelmann av0 = hw0 ^ hw0 * 2u;
240d5de7839SBastian Koppelmann if (hw0 > max_pos) {
241d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31);
242d5de7839SBastian Koppelmann hw0 = max_pos;
243d5de7839SBastian Koppelmann } else if (hw0 < 0) {
244d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31);
245d5de7839SBastian Koppelmann hw0 = 0;
246d5de7839SBastian Koppelmann }
247d5de7839SBastian Koppelmann
248d5de7839SBastian Koppelmann av1 = hw1 ^ hw1 * 2u;
249d5de7839SBastian Koppelmann if (hw1 > max_pos) {
250d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31);
251d5de7839SBastian Koppelmann hw1 = max_pos;
252d5de7839SBastian Koppelmann } else if (hw1 < 0) {
253d5de7839SBastian Koppelmann env->PSW_USB_V = (1 << 31);
254d5de7839SBastian Koppelmann hw1 = 0;
255d5de7839SBastian Koppelmann }
256d5de7839SBastian Koppelmann
257d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
258d5de7839SBastian Koppelmann env->PSW_USB_AV = (av0 | av1) << 16;
259d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
260d5de7839SBastian Koppelmann return (hw0 & 0xffff) | (hw1 << 16);
261d5de7839SBastian Koppelmann }
2620974257eSBastian Koppelmann
helper_add_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)2632692802aSBastian Koppelmann target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
2642692802aSBastian Koppelmann target_ulong r2)
2652692802aSBastian Koppelmann {
2662692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
2672692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
2682692802aSBastian Koppelmann int64_t result = t1 + t2;
269e4e39176SBastian Koppelmann return ssov32(env, result);
2702692802aSBastian Koppelmann }
2712692802aSBastian Koppelmann
helper_add64_ssov(CPUTriCoreState * env,uint64_t r1,uint64_t r2)2722e430e1cSBastian Koppelmann uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
2732e430e1cSBastian Koppelmann {
2742e430e1cSBastian Koppelmann uint64_t result;
2752e430e1cSBastian Koppelmann int64_t ovf;
2762e430e1cSBastian Koppelmann
2772e430e1cSBastian Koppelmann result = r1 + r2;
2782e430e1cSBastian Koppelmann ovf = (result ^ r1) & ~(r1 ^ r2);
2792e430e1cSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32;
2802e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
2812e430e1cSBastian Koppelmann if (ovf < 0) {
2822e430e1cSBastian Koppelmann env->PSW_USB_V = (1 << 31);
2832e430e1cSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
2842e430e1cSBastian Koppelmann /* ext_ret > MAX_INT */
2852e430e1cSBastian Koppelmann if ((int64_t)r1 >= 0) {
2862e430e1cSBastian Koppelmann result = INT64_MAX;
2872e430e1cSBastian Koppelmann /* ext_ret < MIN_INT */
2882e430e1cSBastian Koppelmann } else {
2892e430e1cSBastian Koppelmann result = INT64_MIN;
2902e430e1cSBastian Koppelmann }
2912e430e1cSBastian Koppelmann } else {
2922e430e1cSBastian Koppelmann env->PSW_USB_V = 0;
2932e430e1cSBastian Koppelmann }
2942e430e1cSBastian Koppelmann return result;
2952e430e1cSBastian Koppelmann }
2962e430e1cSBastian Koppelmann
helper_add_h_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)297d5de7839SBastian Koppelmann target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
298d5de7839SBastian Koppelmann target_ulong r2)
299d5de7839SBastian Koppelmann {
300d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1;
301d5de7839SBastian Koppelmann
302d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
303d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
304d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1);
305d5de7839SBastian Koppelmann }
306d5de7839SBastian Koppelmann
helper_addr_h_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)3072e430e1cSBastian Koppelmann uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
3082e430e1cSBastian Koppelmann uint32_t r2_h)
3092e430e1cSBastian Koppelmann {
3102e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32);
3112e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32);
3122e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32);
3132e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32);
3142e430e1cSBastian Koppelmann int64_t result0, result1;
3152e430e1cSBastian Koppelmann uint32_t ovf0, ovf1;
3162e430e1cSBastian Koppelmann uint32_t avf0, avf1;
3172e430e1cSBastian Koppelmann
3182e430e1cSBastian Koppelmann ovf0 = ovf1 = 0;
3192e430e1cSBastian Koppelmann
3202e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000;
3212e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000;
3222e430e1cSBastian Koppelmann
3232e430e1cSBastian Koppelmann avf0 = result0 * 2u;
3242e430e1cSBastian Koppelmann avf0 = result0 ^ avf0;
3252e430e1cSBastian Koppelmann avf1 = result1 * 2u;
3262e430e1cSBastian Koppelmann avf1 = result1 ^ avf1;
3272e430e1cSBastian Koppelmann
3282e430e1cSBastian Koppelmann if (result0 > INT32_MAX) {
3292e430e1cSBastian Koppelmann ovf0 = (1 << 31);
3302e430e1cSBastian Koppelmann result0 = INT32_MAX;
3312e430e1cSBastian Koppelmann } else if (result0 < INT32_MIN) {
3322e430e1cSBastian Koppelmann ovf0 = (1 << 31);
3332e430e1cSBastian Koppelmann result0 = INT32_MIN;
3342e430e1cSBastian Koppelmann }
3352e430e1cSBastian Koppelmann
3362e430e1cSBastian Koppelmann if (result1 > INT32_MAX) {
3372e430e1cSBastian Koppelmann ovf1 = (1 << 31);
3382e430e1cSBastian Koppelmann result1 = INT32_MAX;
3392e430e1cSBastian Koppelmann } else if (result1 < INT32_MIN) {
3402e430e1cSBastian Koppelmann ovf1 = (1 << 31);
3412e430e1cSBastian Koppelmann result1 = INT32_MIN;
3422e430e1cSBastian Koppelmann }
3432e430e1cSBastian Koppelmann
3442e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1;
3452e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
3462e430e1cSBastian Koppelmann
3472e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1;
3482e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
3492e430e1cSBastian Koppelmann
3502e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
3512e430e1cSBastian Koppelmann }
3522e430e1cSBastian Koppelmann
helper_addsur_h_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)353bebe80fcSBastian Koppelmann uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
354bebe80fcSBastian Koppelmann uint32_t r2_h)
355bebe80fcSBastian Koppelmann {
356bebe80fcSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32);
357bebe80fcSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32);
358bebe80fcSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32);
359bebe80fcSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32);
360bebe80fcSBastian Koppelmann int64_t result0, result1;
361bebe80fcSBastian Koppelmann uint32_t ovf0, ovf1;
362bebe80fcSBastian Koppelmann uint32_t avf0, avf1;
363bebe80fcSBastian Koppelmann
364bebe80fcSBastian Koppelmann ovf0 = ovf1 = 0;
365bebe80fcSBastian Koppelmann
366bebe80fcSBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000;
367bebe80fcSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000;
368bebe80fcSBastian Koppelmann
369bebe80fcSBastian Koppelmann avf0 = result0 * 2u;
370bebe80fcSBastian Koppelmann avf0 = result0 ^ avf0;
371bebe80fcSBastian Koppelmann avf1 = result1 * 2u;
372bebe80fcSBastian Koppelmann avf1 = result1 ^ avf1;
373bebe80fcSBastian Koppelmann
374bebe80fcSBastian Koppelmann if (result0 > INT32_MAX) {
375bebe80fcSBastian Koppelmann ovf0 = (1 << 31);
376bebe80fcSBastian Koppelmann result0 = INT32_MAX;
377bebe80fcSBastian Koppelmann } else if (result0 < INT32_MIN) {
378bebe80fcSBastian Koppelmann ovf0 = (1 << 31);
379bebe80fcSBastian Koppelmann result0 = INT32_MIN;
380bebe80fcSBastian Koppelmann }
381bebe80fcSBastian Koppelmann
382bebe80fcSBastian Koppelmann if (result1 > INT32_MAX) {
383bebe80fcSBastian Koppelmann ovf1 = (1 << 31);
384bebe80fcSBastian Koppelmann result1 = INT32_MAX;
385bebe80fcSBastian Koppelmann } else if (result1 < INT32_MIN) {
386bebe80fcSBastian Koppelmann ovf1 = (1 << 31);
387bebe80fcSBastian Koppelmann result1 = INT32_MIN;
388bebe80fcSBastian Koppelmann }
389bebe80fcSBastian Koppelmann
390bebe80fcSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1;
391bebe80fcSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
392bebe80fcSBastian Koppelmann
393bebe80fcSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1;
394bebe80fcSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
395bebe80fcSBastian Koppelmann
396bebe80fcSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
397bebe80fcSBastian Koppelmann }
398bebe80fcSBastian Koppelmann
3992e430e1cSBastian Koppelmann
helper_add_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)4000974257eSBastian Koppelmann target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
4010974257eSBastian Koppelmann target_ulong r2)
4020974257eSBastian Koppelmann {
4030974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32);
4040974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32);
4050974257eSBastian Koppelmann int64_t result = t1 + t2;
40685d604afSBastian Koppelmann return suov32_pos(env, result);
4070974257eSBastian Koppelmann }
4080974257eSBastian Koppelmann
helper_add_h_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)409d5de7839SBastian Koppelmann target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
410d5de7839SBastian Koppelmann target_ulong r2)
411d5de7839SBastian Koppelmann {
412d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1;
413d5de7839SBastian Koppelmann
414d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
415d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
416d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1);
417d5de7839SBastian Koppelmann }
418d5de7839SBastian Koppelmann
helper_sub_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)4192692802aSBastian Koppelmann target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
4202692802aSBastian Koppelmann target_ulong r2)
4212692802aSBastian Koppelmann {
4222692802aSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
4232692802aSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
4242692802aSBastian Koppelmann int64_t result = t1 - t2;
425e4e39176SBastian Koppelmann return ssov32(env, result);
4262692802aSBastian Koppelmann }
4272692802aSBastian Koppelmann
helper_sub64_ssov(CPUTriCoreState * env,uint64_t r1,uint64_t r2)428f4aef476SBastian Koppelmann uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
429f4aef476SBastian Koppelmann {
430f4aef476SBastian Koppelmann uint64_t result;
431f4aef476SBastian Koppelmann int64_t ovf;
432f4aef476SBastian Koppelmann
433f4aef476SBastian Koppelmann result = r1 - r2;
434f4aef476SBastian Koppelmann ovf = (result ^ r1) & (r1 ^ r2);
435f4aef476SBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32;
436f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
437f4aef476SBastian Koppelmann if (ovf < 0) {
438f4aef476SBastian Koppelmann env->PSW_USB_V = (1 << 31);
439f4aef476SBastian Koppelmann env->PSW_USB_SV = (1 << 31);
440f4aef476SBastian Koppelmann /* ext_ret > MAX_INT */
441f4aef476SBastian Koppelmann if ((int64_t)r1 >= 0) {
442f4aef476SBastian Koppelmann result = INT64_MAX;
443f4aef476SBastian Koppelmann /* ext_ret < MIN_INT */
444f4aef476SBastian Koppelmann } else {
445f4aef476SBastian Koppelmann result = INT64_MIN;
446f4aef476SBastian Koppelmann }
447f4aef476SBastian Koppelmann } else {
448f4aef476SBastian Koppelmann env->PSW_USB_V = 0;
449f4aef476SBastian Koppelmann }
450f4aef476SBastian Koppelmann return result;
451f4aef476SBastian Koppelmann }
452f4aef476SBastian Koppelmann
helper_sub_h_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)453d5de7839SBastian Koppelmann target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
454d5de7839SBastian Koppelmann target_ulong r2)
455d5de7839SBastian Koppelmann {
456d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1;
457d5de7839SBastian Koppelmann
458d5de7839SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
459d5de7839SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
460d5de7839SBastian Koppelmann return ssov16(env, ret_hw0, ret_hw1);
461d5de7839SBastian Koppelmann }
462d5de7839SBastian Koppelmann
helper_subr_h_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)463f4aef476SBastian Koppelmann uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
464f4aef476SBastian Koppelmann uint32_t r2_h)
465f4aef476SBastian Koppelmann {
466f4aef476SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32);
467f4aef476SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32);
468f4aef476SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32);
469f4aef476SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32);
470f4aef476SBastian Koppelmann int64_t result0, result1;
471f4aef476SBastian Koppelmann uint32_t ovf0, ovf1;
472f4aef476SBastian Koppelmann uint32_t avf0, avf1;
473f4aef476SBastian Koppelmann
474f4aef476SBastian Koppelmann ovf0 = ovf1 = 0;
475f4aef476SBastian Koppelmann
476f4aef476SBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000;
477f4aef476SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000;
478f4aef476SBastian Koppelmann
479f4aef476SBastian Koppelmann avf0 = result0 * 2u;
480f4aef476SBastian Koppelmann avf0 = result0 ^ avf0;
481f4aef476SBastian Koppelmann avf1 = result1 * 2u;
482f4aef476SBastian Koppelmann avf1 = result1 ^ avf1;
483f4aef476SBastian Koppelmann
484f4aef476SBastian Koppelmann if (result0 > INT32_MAX) {
485f4aef476SBastian Koppelmann ovf0 = (1 << 31);
486f4aef476SBastian Koppelmann result0 = INT32_MAX;
487f4aef476SBastian Koppelmann } else if (result0 < INT32_MIN) {
488f4aef476SBastian Koppelmann ovf0 = (1 << 31);
489f4aef476SBastian Koppelmann result0 = INT32_MIN;
490f4aef476SBastian Koppelmann }
491f4aef476SBastian Koppelmann
492f4aef476SBastian Koppelmann if (result1 > INT32_MAX) {
493f4aef476SBastian Koppelmann ovf1 = (1 << 31);
494f4aef476SBastian Koppelmann result1 = INT32_MAX;
495f4aef476SBastian Koppelmann } else if (result1 < INT32_MIN) {
496f4aef476SBastian Koppelmann ovf1 = (1 << 31);
497f4aef476SBastian Koppelmann result1 = INT32_MIN;
498f4aef476SBastian Koppelmann }
499f4aef476SBastian Koppelmann
500f4aef476SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1;
501f4aef476SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
502f4aef476SBastian Koppelmann
503f4aef476SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1;
504f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
505f4aef476SBastian Koppelmann
506f4aef476SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
507f4aef476SBastian Koppelmann }
508f4aef476SBastian Koppelmann
helper_subadr_h_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)509068fac77SBastian Koppelmann uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
510068fac77SBastian Koppelmann uint32_t r2_h)
511068fac77SBastian Koppelmann {
512068fac77SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32);
513068fac77SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32);
514068fac77SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32);
515068fac77SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32);
516068fac77SBastian Koppelmann int64_t result0, result1;
517068fac77SBastian Koppelmann uint32_t ovf0, ovf1;
518068fac77SBastian Koppelmann uint32_t avf0, avf1;
519068fac77SBastian Koppelmann
520068fac77SBastian Koppelmann ovf0 = ovf1 = 0;
521068fac77SBastian Koppelmann
522068fac77SBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000;
523068fac77SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000;
524068fac77SBastian Koppelmann
525068fac77SBastian Koppelmann avf0 = result0 * 2u;
526068fac77SBastian Koppelmann avf0 = result0 ^ avf0;
527068fac77SBastian Koppelmann avf1 = result1 * 2u;
528068fac77SBastian Koppelmann avf1 = result1 ^ avf1;
529068fac77SBastian Koppelmann
530068fac77SBastian Koppelmann if (result0 > INT32_MAX) {
531068fac77SBastian Koppelmann ovf0 = (1 << 31);
532068fac77SBastian Koppelmann result0 = INT32_MAX;
533068fac77SBastian Koppelmann } else if (result0 < INT32_MIN) {
534068fac77SBastian Koppelmann ovf0 = (1 << 31);
535068fac77SBastian Koppelmann result0 = INT32_MIN;
536068fac77SBastian Koppelmann }
537068fac77SBastian Koppelmann
538068fac77SBastian Koppelmann if (result1 > INT32_MAX) {
539068fac77SBastian Koppelmann ovf1 = (1 << 31);
540068fac77SBastian Koppelmann result1 = INT32_MAX;
541068fac77SBastian Koppelmann } else if (result1 < INT32_MIN) {
542068fac77SBastian Koppelmann ovf1 = (1 << 31);
543068fac77SBastian Koppelmann result1 = INT32_MIN;
544068fac77SBastian Koppelmann }
545068fac77SBastian Koppelmann
546068fac77SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1;
547068fac77SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
548068fac77SBastian Koppelmann
549068fac77SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1;
550068fac77SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
551068fac77SBastian Koppelmann
552068fac77SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
553068fac77SBastian Koppelmann }
554068fac77SBastian Koppelmann
helper_sub_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)5550974257eSBastian Koppelmann target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
5560974257eSBastian Koppelmann target_ulong r2)
5570974257eSBastian Koppelmann {
5580974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32);
5590974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32);
5600974257eSBastian Koppelmann int64_t result = t1 - t2;
56185d604afSBastian Koppelmann return suov32_neg(env, result);
5620974257eSBastian Koppelmann }
5630974257eSBastian Koppelmann
helper_sub_h_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)564d5de7839SBastian Koppelmann target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
565d5de7839SBastian Koppelmann target_ulong r2)
566d5de7839SBastian Koppelmann {
567d5de7839SBastian Koppelmann int32_t ret_hw0, ret_hw1;
568d5de7839SBastian Koppelmann
569d5de7839SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
570d5de7839SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
571d5de7839SBastian Koppelmann return suov16(env, ret_hw0, ret_hw1);
572d5de7839SBastian Koppelmann }
573d5de7839SBastian Koppelmann
helper_mul_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)5740974257eSBastian Koppelmann target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
5750974257eSBastian Koppelmann target_ulong r2)
5760974257eSBastian Koppelmann {
5770974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
5780974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
5790974257eSBastian Koppelmann int64_t result = t1 * t2;
580e4e39176SBastian Koppelmann return ssov32(env, result);
5810974257eSBastian Koppelmann }
5820974257eSBastian Koppelmann
helper_mul_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)5830974257eSBastian Koppelmann target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
5840974257eSBastian Koppelmann target_ulong r2)
5850974257eSBastian Koppelmann {
5860974257eSBastian Koppelmann int64_t t1 = extract64(r1, 0, 32);
5870974257eSBastian Koppelmann int64_t t2 = extract64(r2, 0, 32);
5880974257eSBastian Koppelmann int64_t result = t1 * t2;
5895f30046fSBastian Koppelmann
59085d604afSBastian Koppelmann return suov32_pos(env, result);
5910974257eSBastian Koppelmann }
5920974257eSBastian Koppelmann
helper_sha_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)5930974257eSBastian Koppelmann target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
5940974257eSBastian Koppelmann target_ulong r2)
5950974257eSBastian Koppelmann {
5960974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
5970974257eSBastian Koppelmann int32_t t2 = sextract64(r2, 0, 6);
5980974257eSBastian Koppelmann int64_t result;
5990974257eSBastian Koppelmann if (t2 == 0) {
6000974257eSBastian Koppelmann result = t1;
6010974257eSBastian Koppelmann } else if (t2 > 0) {
6020974257eSBastian Koppelmann result = t1 << t2;
6030974257eSBastian Koppelmann } else {
6040974257eSBastian Koppelmann result = t1 >> -t2;
6050974257eSBastian Koppelmann }
606e4e39176SBastian Koppelmann return ssov32(env, result);
6070974257eSBastian Koppelmann }
6080974257eSBastian Koppelmann
helper_abs_ssov(CPUTriCoreState * env,target_ulong r1)609d5de7839SBastian Koppelmann uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
610d5de7839SBastian Koppelmann {
611d5de7839SBastian Koppelmann target_ulong result;
612d5de7839SBastian Koppelmann result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
613d5de7839SBastian Koppelmann return ssov32(env, result);
614d5de7839SBastian Koppelmann }
615d5de7839SBastian Koppelmann
helper_abs_h_ssov(CPUTriCoreState * env,target_ulong r1)616d5de7839SBastian Koppelmann uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
617d5de7839SBastian Koppelmann {
618d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1;
619d5de7839SBastian Koppelmann
620d5de7839SBastian Koppelmann ret_h0 = sextract32(r1, 0, 16);
621d5de7839SBastian Koppelmann ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
622d5de7839SBastian Koppelmann
623d5de7839SBastian Koppelmann ret_h1 = sextract32(r1, 16, 16);
624d5de7839SBastian Koppelmann ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
625d5de7839SBastian Koppelmann
626d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1);
627d5de7839SBastian Koppelmann }
628d5de7839SBastian Koppelmann
helper_absdif_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)6290974257eSBastian Koppelmann target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
6300974257eSBastian Koppelmann target_ulong r2)
6310974257eSBastian Koppelmann {
6320974257eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
6330974257eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
6340974257eSBastian Koppelmann int64_t result;
6350974257eSBastian Koppelmann
6360974257eSBastian Koppelmann if (t1 > t2) {
6370974257eSBastian Koppelmann result = t1 - t2;
6380974257eSBastian Koppelmann } else {
6390974257eSBastian Koppelmann result = t2 - t1;
6400974257eSBastian Koppelmann }
641e4e39176SBastian Koppelmann return ssov32(env, result);
6420974257eSBastian Koppelmann }
643328f1f0fSBastian Koppelmann
helper_absdif_h_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)644d5de7839SBastian Koppelmann uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
645d5de7839SBastian Koppelmann target_ulong r2)
646d5de7839SBastian Koppelmann {
647d5de7839SBastian Koppelmann int32_t t1, t2;
648d5de7839SBastian Koppelmann int32_t ret_h0, ret_h1;
649d5de7839SBastian Koppelmann
650d5de7839SBastian Koppelmann t1 = sextract32(r1, 0, 16);
651d5de7839SBastian Koppelmann t2 = sextract32(r2, 0, 16);
652d5de7839SBastian Koppelmann if (t1 > t2) {
653d5de7839SBastian Koppelmann ret_h0 = t1 - t2;
654d5de7839SBastian Koppelmann } else {
655d5de7839SBastian Koppelmann ret_h0 = t2 - t1;
656d5de7839SBastian Koppelmann }
657d5de7839SBastian Koppelmann
658d5de7839SBastian Koppelmann t1 = sextract32(r1, 16, 16);
659d5de7839SBastian Koppelmann t2 = sextract32(r2, 16, 16);
660d5de7839SBastian Koppelmann if (t1 > t2) {
661d5de7839SBastian Koppelmann ret_h1 = t1 - t2;
662d5de7839SBastian Koppelmann } else {
663d5de7839SBastian Koppelmann ret_h1 = t2 - t1;
664d5de7839SBastian Koppelmann }
665d5de7839SBastian Koppelmann
666d5de7839SBastian Koppelmann return ssov16(env, ret_h0, ret_h1);
667d5de7839SBastian Koppelmann }
668d5de7839SBastian Koppelmann
helper_madd32_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2,target_ulong r3)669328f1f0fSBastian Koppelmann target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
670328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3)
671328f1f0fSBastian Koppelmann {
672328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
673328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
674328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
675328f1f0fSBastian Koppelmann int64_t result;
676328f1f0fSBastian Koppelmann
677328f1f0fSBastian Koppelmann result = t2 + (t1 * t3);
678e4e39176SBastian Koppelmann return ssov32(env, result);
679328f1f0fSBastian Koppelmann }
680328f1f0fSBastian Koppelmann
helper_madd32_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2,target_ulong r3)681328f1f0fSBastian Koppelmann target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
682328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3)
683328f1f0fSBastian Koppelmann {
684328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32);
685328f1f0fSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32);
686328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32);
687328f1f0fSBastian Koppelmann int64_t result;
688328f1f0fSBastian Koppelmann
689328f1f0fSBastian Koppelmann result = t2 + (t1 * t3);
69085d604afSBastian Koppelmann return suov32_pos(env, result);
691328f1f0fSBastian Koppelmann }
692328f1f0fSBastian Koppelmann
helper_madd64_ssov(CPUTriCoreState * env,target_ulong r1,uint64_t r2,target_ulong r3)693328f1f0fSBastian Koppelmann uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
694328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3)
695328f1f0fSBastian Koppelmann {
696328f1f0fSBastian Koppelmann uint64_t ret, ovf;
697328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
698328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
699328f1f0fSBastian Koppelmann int64_t mul;
700328f1f0fSBastian Koppelmann
701328f1f0fSBastian Koppelmann mul = t1 * t3;
702328f1f0fSBastian Koppelmann ret = mul + r2;
703328f1f0fSBastian Koppelmann ovf = (ret ^ mul) & ~(mul ^ r2);
704328f1f0fSBastian Koppelmann
705811ea608SBastian Koppelmann t1 = ret >> 32;
706811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u;
707811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
708811ea608SBastian Koppelmann
709328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) {
710328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31);
711328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
712328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */
713328f1f0fSBastian Koppelmann if (mul >= 0) {
714328f1f0fSBastian Koppelmann ret = INT64_MAX;
715328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */
716328f1f0fSBastian Koppelmann } else {
717328f1f0fSBastian Koppelmann ret = INT64_MIN;
718328f1f0fSBastian Koppelmann }
719328f1f0fSBastian Koppelmann } else {
720328f1f0fSBastian Koppelmann env->PSW_USB_V = 0;
721328f1f0fSBastian Koppelmann }
722328f1f0fSBastian Koppelmann
723328f1f0fSBastian Koppelmann return ret;
724328f1f0fSBastian Koppelmann }
725328f1f0fSBastian Koppelmann
726b00aa8ecSBastian Koppelmann uint32_t
helper_madd32_q_add_ssov(CPUTriCoreState * env,uint64_t r1,uint64_t r2)727b00aa8ecSBastian Koppelmann helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
728b00aa8ecSBastian Koppelmann {
729b00aa8ecSBastian Koppelmann int64_t result;
730b00aa8ecSBastian Koppelmann
731b00aa8ecSBastian Koppelmann result = (r1 + r2);
732b00aa8ecSBastian Koppelmann
733b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u);
734b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
735b00aa8ecSBastian Koppelmann
736b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host
737b00aa8ecSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
738b00aa8ecSBastian Koppelmann case, we flip the saturated value. */
739b00aa8ecSBastian Koppelmann if (r2 == 0x8000000000000000LL) {
740b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) {
741b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
742b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
743b00aa8ecSBastian Koppelmann result = INT32_MIN;
744b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) {
745b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
746b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
747b00aa8ecSBastian Koppelmann result = INT32_MAX;
748b00aa8ecSBastian Koppelmann } else {
749b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0;
750b00aa8ecSBastian Koppelmann }
751b00aa8ecSBastian Koppelmann } else {
752b00aa8ecSBastian Koppelmann if (result > 0x7fffffffLL) {
753b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
754b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
755b00aa8ecSBastian Koppelmann result = INT32_MAX;
756b00aa8ecSBastian Koppelmann } else if (result < -0x80000000LL) {
757b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
758b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
759b00aa8ecSBastian Koppelmann result = INT32_MIN;
760b00aa8ecSBastian Koppelmann } else {
761b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0;
762b00aa8ecSBastian Koppelmann }
763b00aa8ecSBastian Koppelmann }
764b00aa8ecSBastian Koppelmann return (uint32_t)result;
765b00aa8ecSBastian Koppelmann }
766b00aa8ecSBastian Koppelmann
helper_madd64_q_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2,uint32_t r3,uint32_t n)767b00aa8ecSBastian Koppelmann uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
768b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n)
769b00aa8ecSBastian Koppelmann {
770b00aa8ecSBastian Koppelmann int64_t t1 = (int64_t)r1;
771b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
772b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
773b00aa8ecSBastian Koppelmann int64_t result, mul;
774b00aa8ecSBastian Koppelmann int64_t ovf;
775b00aa8ecSBastian Koppelmann
776b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n;
777b00aa8ecSBastian Koppelmann result = mul + t1;
778b00aa8ecSBastian Koppelmann
779b00aa8ecSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32;
780b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
781b00aa8ecSBastian Koppelmann
782b00aa8ecSBastian Koppelmann ovf = (result ^ mul) & ~(mul ^ t1);
783b00aa8ecSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host
784b00aa8ecSBastian Koppelmann if the mul was (0x80000000 * 0x80000000) << 1). If this is the
785b00aa8ecSBastian Koppelmann case, we flip the saturated value. */
786b00aa8ecSBastian Koppelmann if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) {
787b00aa8ecSBastian Koppelmann if (ovf >= 0) {
788b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
789b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
790b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */
791b00aa8ecSBastian Koppelmann if (mul < 0) {
792b00aa8ecSBastian Koppelmann result = INT64_MAX;
793b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */
794b00aa8ecSBastian Koppelmann } else {
795b00aa8ecSBastian Koppelmann result = INT64_MIN;
796b00aa8ecSBastian Koppelmann }
797b00aa8ecSBastian Koppelmann } else {
798b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0;
799b00aa8ecSBastian Koppelmann }
800b00aa8ecSBastian Koppelmann } else {
801b00aa8ecSBastian Koppelmann if (ovf < 0) {
802b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
803b00aa8ecSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
804b00aa8ecSBastian Koppelmann /* ext_ret > MAX_INT */
805b00aa8ecSBastian Koppelmann if (mul >= 0) {
806b00aa8ecSBastian Koppelmann result = INT64_MAX;
807b00aa8ecSBastian Koppelmann /* ext_ret < MIN_INT */
808b00aa8ecSBastian Koppelmann } else {
809b00aa8ecSBastian Koppelmann result = INT64_MIN;
810b00aa8ecSBastian Koppelmann }
811b00aa8ecSBastian Koppelmann } else {
812b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0;
813b00aa8ecSBastian Koppelmann }
814b00aa8ecSBastian Koppelmann }
815b00aa8ecSBastian Koppelmann return (uint64_t)result;
816b00aa8ecSBastian Koppelmann }
817b00aa8ecSBastian Koppelmann
helper_maddr_q_ssov(CPUTriCoreState * env,uint32_t r1,uint32_t r2,uint32_t r3,uint32_t n)818b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
819b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n)
820b00aa8ecSBastian Koppelmann {
821b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
822b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
823b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
824b00aa8ecSBastian Koppelmann int64_t mul, ret;
825b00aa8ecSBastian Koppelmann
826b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
827b00aa8ecSBastian Koppelmann mul = 0x7fffffff;
828b00aa8ecSBastian Koppelmann } else {
829b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n;
830b00aa8ecSBastian Koppelmann }
831b00aa8ecSBastian Koppelmann
832b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000;
833b00aa8ecSBastian Koppelmann
834b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u;
835b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
836b00aa8ecSBastian Koppelmann
837b00aa8ecSBastian Koppelmann if (ret > 0x7fffffffll) {
838b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
839b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
840b00aa8ecSBastian Koppelmann ret = INT32_MAX;
841b00aa8ecSBastian Koppelmann } else if (ret < -0x80000000ll) {
842b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
843b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
844b00aa8ecSBastian Koppelmann ret = INT32_MIN;
845b00aa8ecSBastian Koppelmann } else {
846b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0;
847b00aa8ecSBastian Koppelmann }
848b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll;
849b00aa8ecSBastian Koppelmann }
850b00aa8ecSBastian Koppelmann
helper_madd64_suov(CPUTriCoreState * env,target_ulong r1,uint64_t r2,target_ulong r3)851328f1f0fSBastian Koppelmann uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
852328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3)
853328f1f0fSBastian Koppelmann {
854328f1f0fSBastian Koppelmann uint64_t ret, mul;
855328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32);
856328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32);
857328f1f0fSBastian Koppelmann
858328f1f0fSBastian Koppelmann mul = t1 * t3;
859328f1f0fSBastian Koppelmann ret = mul + r2;
860328f1f0fSBastian Koppelmann
861811ea608SBastian Koppelmann t1 = ret >> 32;
862811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u;
863811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
864811ea608SBastian Koppelmann
865328f1f0fSBastian Koppelmann if (ret < r2) {
866328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31);
867328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
868328f1f0fSBastian Koppelmann /* saturate */
869328f1f0fSBastian Koppelmann ret = UINT64_MAX;
870328f1f0fSBastian Koppelmann } else {
871328f1f0fSBastian Koppelmann env->PSW_USB_V = 0;
872328f1f0fSBastian Koppelmann }
873328f1f0fSBastian Koppelmann return ret;
874328f1f0fSBastian Koppelmann }
875328f1f0fSBastian Koppelmann
helper_msub32_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2,target_ulong r3)876328f1f0fSBastian Koppelmann target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
877328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3)
878328f1f0fSBastian Koppelmann {
879328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
880328f1f0fSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
881328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
882328f1f0fSBastian Koppelmann int64_t result;
883328f1f0fSBastian Koppelmann
884328f1f0fSBastian Koppelmann result = t2 - (t1 * t3);
885e4e39176SBastian Koppelmann return ssov32(env, result);
886328f1f0fSBastian Koppelmann }
887328f1f0fSBastian Koppelmann
helper_msub32_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2,target_ulong r3)888328f1f0fSBastian Koppelmann target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
889328f1f0fSBastian Koppelmann target_ulong r2, target_ulong r3)
890328f1f0fSBastian Koppelmann {
8913debbb5aSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32);
8923debbb5aSBastian Koppelmann uint64_t t2 = extract64(r2, 0, 32);
8933debbb5aSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32);
8943debbb5aSBastian Koppelmann uint64_t result;
8953debbb5aSBastian Koppelmann uint64_t mul;
896328f1f0fSBastian Koppelmann
8973debbb5aSBastian Koppelmann mul = (t1 * t3);
8983debbb5aSBastian Koppelmann result = t2 - mul;
8993debbb5aSBastian Koppelmann
9003debbb5aSBastian Koppelmann env->PSW_USB_AV = result ^ result * 2u;
9013debbb5aSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
9023debbb5aSBastian Koppelmann /* we calculate ovf by hand here, because the multiplication can overflow on
9033debbb5aSBastian Koppelmann the host, which would give false results if we compare to less than
9043debbb5aSBastian Koppelmann zero */
9053debbb5aSBastian Koppelmann if (mul > t2) {
9063debbb5aSBastian Koppelmann env->PSW_USB_V = (1 << 31);
9073debbb5aSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
9083debbb5aSBastian Koppelmann result = 0;
9093debbb5aSBastian Koppelmann } else {
9103debbb5aSBastian Koppelmann env->PSW_USB_V = 0;
9113debbb5aSBastian Koppelmann }
9123debbb5aSBastian Koppelmann return result;
913328f1f0fSBastian Koppelmann }
914328f1f0fSBastian Koppelmann
helper_msub64_ssov(CPUTriCoreState * env,target_ulong r1,uint64_t r2,target_ulong r3)915328f1f0fSBastian Koppelmann uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
916328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3)
917328f1f0fSBastian Koppelmann {
918328f1f0fSBastian Koppelmann uint64_t ret, ovf;
919328f1f0fSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
920328f1f0fSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
921328f1f0fSBastian Koppelmann int64_t mul;
922328f1f0fSBastian Koppelmann
923328f1f0fSBastian Koppelmann mul = t1 * t3;
924328f1f0fSBastian Koppelmann ret = r2 - mul;
925328f1f0fSBastian Koppelmann ovf = (ret ^ r2) & (mul ^ r2);
926328f1f0fSBastian Koppelmann
927811ea608SBastian Koppelmann t1 = ret >> 32;
928811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u;
929811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
930811ea608SBastian Koppelmann
931328f1f0fSBastian Koppelmann if ((int64_t)ovf < 0) {
932328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31);
933328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
934328f1f0fSBastian Koppelmann /* ext_ret > MAX_INT */
935328f1f0fSBastian Koppelmann if (mul < 0) {
936328f1f0fSBastian Koppelmann ret = INT64_MAX;
937328f1f0fSBastian Koppelmann /* ext_ret < MIN_INT */
938328f1f0fSBastian Koppelmann } else {
939328f1f0fSBastian Koppelmann ret = INT64_MIN;
940328f1f0fSBastian Koppelmann }
941328f1f0fSBastian Koppelmann } else {
942328f1f0fSBastian Koppelmann env->PSW_USB_V = 0;
943328f1f0fSBastian Koppelmann }
944328f1f0fSBastian Koppelmann return ret;
945328f1f0fSBastian Koppelmann }
946328f1f0fSBastian Koppelmann
helper_msub64_suov(CPUTriCoreState * env,target_ulong r1,uint64_t r2,target_ulong r3)947328f1f0fSBastian Koppelmann uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
948328f1f0fSBastian Koppelmann uint64_t r2, target_ulong r3)
949328f1f0fSBastian Koppelmann {
950328f1f0fSBastian Koppelmann uint64_t ret, mul;
951328f1f0fSBastian Koppelmann uint64_t t1 = extract64(r1, 0, 32);
952328f1f0fSBastian Koppelmann uint64_t t3 = extract64(r3, 0, 32);
953328f1f0fSBastian Koppelmann
954328f1f0fSBastian Koppelmann mul = t1 * t3;
955328f1f0fSBastian Koppelmann ret = r2 - mul;
956328f1f0fSBastian Koppelmann
957811ea608SBastian Koppelmann t1 = ret >> 32;
958811ea608SBastian Koppelmann env->PSW_USB_AV = t1 ^ t1 * 2u;
959811ea608SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
960811ea608SBastian Koppelmann
961328f1f0fSBastian Koppelmann if (ret > r2) {
962328f1f0fSBastian Koppelmann env->PSW_USB_V = (1 << 31);
963328f1f0fSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
964328f1f0fSBastian Koppelmann /* saturate */
965328f1f0fSBastian Koppelmann ret = 0;
966328f1f0fSBastian Koppelmann } else {
967328f1f0fSBastian Koppelmann env->PSW_USB_V = 0;
968328f1f0fSBastian Koppelmann }
969328f1f0fSBastian Koppelmann return ret;
970328f1f0fSBastian Koppelmann }
971328f1f0fSBastian Koppelmann
97262e47b2eSBastian Koppelmann uint32_t
helper_msub32_q_sub_ssov(CPUTriCoreState * env,uint64_t r1,uint64_t r2)97362e47b2eSBastian Koppelmann helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
97462e47b2eSBastian Koppelmann {
97562e47b2eSBastian Koppelmann int64_t result;
97662e47b2eSBastian Koppelmann int64_t t1 = (int64_t)r1;
97762e47b2eSBastian Koppelmann int64_t t2 = (int64_t)r2;
97862e47b2eSBastian Koppelmann
97962e47b2eSBastian Koppelmann result = t1 - t2;
98062e47b2eSBastian Koppelmann
98162e47b2eSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u);
98262e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
98362e47b2eSBastian Koppelmann
98462e47b2eSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host
98562e47b2eSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
98662e47b2eSBastian Koppelmann case, we flip the saturated value. */
98762e47b2eSBastian Koppelmann if (r2 == 0x8000000000000000LL) {
98862e47b2eSBastian Koppelmann if (result > 0x7fffffffLL) {
98962e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
99062e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
99162e47b2eSBastian Koppelmann result = INT32_MIN;
99262e47b2eSBastian Koppelmann } else if (result < -0x80000000LL) {
99362e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
99462e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
99562e47b2eSBastian Koppelmann result = INT32_MAX;
99662e47b2eSBastian Koppelmann } else {
99762e47b2eSBastian Koppelmann env->PSW_USB_V = 0;
99862e47b2eSBastian Koppelmann }
99962e47b2eSBastian Koppelmann } else {
100062e47b2eSBastian Koppelmann if (result > 0x7fffffffLL) {
100162e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
100262e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
100362e47b2eSBastian Koppelmann result = INT32_MAX;
100462e47b2eSBastian Koppelmann } else if (result < -0x80000000LL) {
100562e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
100662e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
100762e47b2eSBastian Koppelmann result = INT32_MIN;
100862e47b2eSBastian Koppelmann } else {
100962e47b2eSBastian Koppelmann env->PSW_USB_V = 0;
101062e47b2eSBastian Koppelmann }
101162e47b2eSBastian Koppelmann }
101262e47b2eSBastian Koppelmann return (uint32_t)result;
101362e47b2eSBastian Koppelmann }
101462e47b2eSBastian Koppelmann
helper_msub64_q_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2,uint32_t r3,uint32_t n)101562e47b2eSBastian Koppelmann uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
101662e47b2eSBastian Koppelmann uint32_t r3, uint32_t n)
101762e47b2eSBastian Koppelmann {
101862e47b2eSBastian Koppelmann int64_t t1 = (int64_t)r1;
101962e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
102062e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
102162e47b2eSBastian Koppelmann int64_t result, mul;
102262e47b2eSBastian Koppelmann int64_t ovf;
102362e47b2eSBastian Koppelmann
102462e47b2eSBastian Koppelmann mul = (t2 * t3) << n;
102562e47b2eSBastian Koppelmann result = t1 - mul;
102662e47b2eSBastian Koppelmann
102762e47b2eSBastian Koppelmann env->PSW_USB_AV = (result ^ result * 2u) >> 32;
102862e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
102962e47b2eSBastian Koppelmann
103062e47b2eSBastian Koppelmann ovf = (result ^ t1) & (t1 ^ mul);
103162e47b2eSBastian Koppelmann /* we do the saturation by hand, since we produce an overflow on the host
103262e47b2eSBastian Koppelmann if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
103362e47b2eSBastian Koppelmann case, we flip the saturated value. */
103462e47b2eSBastian Koppelmann if (mul == 0x8000000000000000LL) {
103562e47b2eSBastian Koppelmann if (ovf >= 0) {
103662e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
103762e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
103862e47b2eSBastian Koppelmann /* ext_ret > MAX_INT */
103962e47b2eSBastian Koppelmann if (mul >= 0) {
104062e47b2eSBastian Koppelmann result = INT64_MAX;
104162e47b2eSBastian Koppelmann /* ext_ret < MIN_INT */
104262e47b2eSBastian Koppelmann } else {
104362e47b2eSBastian Koppelmann result = INT64_MIN;
104462e47b2eSBastian Koppelmann }
10459029710bSBastian Koppelmann } else {
10469029710bSBastian Koppelmann env->PSW_USB_V = 0;
104762e47b2eSBastian Koppelmann }
104862e47b2eSBastian Koppelmann } else {
104962e47b2eSBastian Koppelmann if (ovf < 0) {
105062e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
105162e47b2eSBastian Koppelmann env->PSW_USB_SV = (1 << 31);
105262e47b2eSBastian Koppelmann /* ext_ret > MAX_INT */
105362e47b2eSBastian Koppelmann if (mul < 0) {
105462e47b2eSBastian Koppelmann result = INT64_MAX;
105562e47b2eSBastian Koppelmann /* ext_ret < MIN_INT */
105662e47b2eSBastian Koppelmann } else {
105762e47b2eSBastian Koppelmann result = INT64_MIN;
105862e47b2eSBastian Koppelmann }
105962e47b2eSBastian Koppelmann } else {
106062e47b2eSBastian Koppelmann env->PSW_USB_V = 0;
106162e47b2eSBastian Koppelmann }
106262e47b2eSBastian Koppelmann }
106362e47b2eSBastian Koppelmann
106462e47b2eSBastian Koppelmann return (uint64_t)result;
106562e47b2eSBastian Koppelmann }
106662e47b2eSBastian Koppelmann
helper_msubr_q_ssov(CPUTriCoreState * env,uint32_t r1,uint32_t r2,uint32_t r3,uint32_t n)106762e47b2eSBastian Koppelmann uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
106862e47b2eSBastian Koppelmann uint32_t r3, uint32_t n)
106962e47b2eSBastian Koppelmann {
107062e47b2eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
107162e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
107262e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
107362e47b2eSBastian Koppelmann int64_t mul, ret;
107462e47b2eSBastian Koppelmann
107562e47b2eSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
107662e47b2eSBastian Koppelmann mul = 0x7fffffff;
107762e47b2eSBastian Koppelmann } else {
107862e47b2eSBastian Koppelmann mul = (t2 * t3) << n;
107962e47b2eSBastian Koppelmann }
108062e47b2eSBastian Koppelmann
108162e47b2eSBastian Koppelmann ret = t1 - mul + 0x8000;
108262e47b2eSBastian Koppelmann
108362e47b2eSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u;
108462e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
108562e47b2eSBastian Koppelmann
108662e47b2eSBastian Koppelmann if (ret > 0x7fffffffll) {
108762e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
108862e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
108962e47b2eSBastian Koppelmann ret = INT32_MAX;
109062e47b2eSBastian Koppelmann } else if (ret < -0x80000000ll) {
109162e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
109262e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
109362e47b2eSBastian Koppelmann ret = INT32_MIN;
109462e47b2eSBastian Koppelmann } else {
109562e47b2eSBastian Koppelmann env->PSW_USB_V = 0;
109662e47b2eSBastian Koppelmann }
109762e47b2eSBastian Koppelmann return ret & 0xffff0000ll;
109862e47b2eSBastian Koppelmann }
109962e47b2eSBastian Koppelmann
helper_abs_b(CPUTriCoreState * env,target_ulong arg)1100d5de7839SBastian Koppelmann uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
1101d5de7839SBastian Koppelmann {
1102d5de7839SBastian Koppelmann int32_t b, i;
1103d5de7839SBastian Koppelmann int32_t ovf = 0;
1104d5de7839SBastian Koppelmann int32_t avf = 0;
1105d5de7839SBastian Koppelmann int32_t ret = 0;
1106d5de7839SBastian Koppelmann
1107d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) {
1108d5de7839SBastian Koppelmann b = sextract32(arg, i * 8, 8);
1109d5de7839SBastian Koppelmann b = (b >= 0) ? b : (0 - b);
1110d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80);
1111d5de7839SBastian Koppelmann avf |= b ^ b * 2u;
1112d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8);
1113d5de7839SBastian Koppelmann }
1114d5de7839SBastian Koppelmann
1115d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31;
1116d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1117d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24;
1118d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1119d5de7839SBastian Koppelmann
1120d5de7839SBastian Koppelmann return ret;
1121d5de7839SBastian Koppelmann }
1122d5de7839SBastian Koppelmann
helper_abs_h(CPUTriCoreState * env,target_ulong arg)1123d5de7839SBastian Koppelmann uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
1124d5de7839SBastian Koppelmann {
1125d5de7839SBastian Koppelmann int32_t h, i;
1126d5de7839SBastian Koppelmann int32_t ovf = 0;
1127d5de7839SBastian Koppelmann int32_t avf = 0;
1128d5de7839SBastian Koppelmann int32_t ret = 0;
1129d5de7839SBastian Koppelmann
1130d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) {
1131d5de7839SBastian Koppelmann h = sextract32(arg, i * 16, 16);
1132d5de7839SBastian Koppelmann h = (h >= 0) ? h : (0 - h);
1133d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000);
1134d5de7839SBastian Koppelmann avf |= h ^ h * 2u;
1135d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16);
1136d5de7839SBastian Koppelmann }
1137d5de7839SBastian Koppelmann
1138d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31;
1139d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1140d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16;
1141d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1142d5de7839SBastian Koppelmann
1143d5de7839SBastian Koppelmann return ret;
1144d5de7839SBastian Koppelmann }
1145d5de7839SBastian Koppelmann
helper_absdif_b(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1146d5de7839SBastian Koppelmann uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1147d5de7839SBastian Koppelmann {
1148d5de7839SBastian Koppelmann int32_t b, i;
1149d5de7839SBastian Koppelmann int32_t extr_r2;
1150d5de7839SBastian Koppelmann int32_t ovf = 0;
1151d5de7839SBastian Koppelmann int32_t avf = 0;
1152d5de7839SBastian Koppelmann int32_t ret = 0;
1153d5de7839SBastian Koppelmann
1154d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) {
1155d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8);
1156d5de7839SBastian Koppelmann b = sextract32(r1, i * 8, 8);
1157d5de7839SBastian Koppelmann b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
1158d5de7839SBastian Koppelmann ovf |= (b > 0x7F) || (b < -0x80);
1159d5de7839SBastian Koppelmann avf |= b ^ b * 2u;
1160d5de7839SBastian Koppelmann ret |= (b & 0xff) << (i * 8);
1161d5de7839SBastian Koppelmann }
1162d5de7839SBastian Koppelmann
1163d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31;
1164d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1165d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24;
1166d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1167d5de7839SBastian Koppelmann return ret;
1168d5de7839SBastian Koppelmann }
1169d5de7839SBastian Koppelmann
helper_absdif_h(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1170d5de7839SBastian Koppelmann uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1171d5de7839SBastian Koppelmann {
1172d5de7839SBastian Koppelmann int32_t h, i;
1173d5de7839SBastian Koppelmann int32_t extr_r2;
1174d5de7839SBastian Koppelmann int32_t ovf = 0;
1175d5de7839SBastian Koppelmann int32_t avf = 0;
1176d5de7839SBastian Koppelmann int32_t ret = 0;
1177d5de7839SBastian Koppelmann
1178d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) {
1179d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16);
1180d5de7839SBastian Koppelmann h = sextract32(r1, i * 16, 16);
1181d5de7839SBastian Koppelmann h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
1182d5de7839SBastian Koppelmann ovf |= (h > 0x7FFF) || (h < -0x8000);
1183d5de7839SBastian Koppelmann avf |= h ^ h * 2u;
1184d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16);
1185d5de7839SBastian Koppelmann }
1186d5de7839SBastian Koppelmann
1187d5de7839SBastian Koppelmann env->PSW_USB_V = ovf << 31;
1188d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1189d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16;
1190d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1191d5de7839SBastian Koppelmann
1192d5de7839SBastian Koppelmann return ret;
1193d5de7839SBastian Koppelmann }
1194d5de7839SBastian Koppelmann
helper_addr_h(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)11952e430e1cSBastian Koppelmann uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
11962e430e1cSBastian Koppelmann uint32_t r2_h)
11972e430e1cSBastian Koppelmann {
11982e430e1cSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32);
11992e430e1cSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32);
12002e430e1cSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32);
12012e430e1cSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32);
12022e430e1cSBastian Koppelmann int64_t result0, result1;
12032e430e1cSBastian Koppelmann uint32_t ovf0, ovf1;
12042e430e1cSBastian Koppelmann uint32_t avf0, avf1;
12052e430e1cSBastian Koppelmann
12062e430e1cSBastian Koppelmann ovf0 = ovf1 = 0;
12072e430e1cSBastian Koppelmann
12082e430e1cSBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000;
12092e430e1cSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000;
12102e430e1cSBastian Koppelmann
12112e430e1cSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
12122e430e1cSBastian Koppelmann ovf0 = (1 << 31);
12132e430e1cSBastian Koppelmann }
12142e430e1cSBastian Koppelmann
12152e430e1cSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
12162e430e1cSBastian Koppelmann ovf1 = (1 << 31);
12172e430e1cSBastian Koppelmann }
12182e430e1cSBastian Koppelmann
12192e430e1cSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1;
12202e430e1cSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
12212e430e1cSBastian Koppelmann
12222e430e1cSBastian Koppelmann avf0 = result0 * 2u;
12232e430e1cSBastian Koppelmann avf0 = result0 ^ avf0;
12242e430e1cSBastian Koppelmann avf1 = result1 * 2u;
12252e430e1cSBastian Koppelmann avf1 = result1 ^ avf1;
12262e430e1cSBastian Koppelmann
12272e430e1cSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1;
12282e430e1cSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
12292e430e1cSBastian Koppelmann
12302e430e1cSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
12312e430e1cSBastian Koppelmann }
12322e430e1cSBastian Koppelmann
helper_addsur_h(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)1233bebe80fcSBastian Koppelmann uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1234bebe80fcSBastian Koppelmann uint32_t r2_h)
1235bebe80fcSBastian Koppelmann {
1236bebe80fcSBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32);
1237bebe80fcSBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32);
1238bebe80fcSBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32);
1239bebe80fcSBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32);
1240bebe80fcSBastian Koppelmann int64_t result0, result1;
1241bebe80fcSBastian Koppelmann uint32_t ovf0, ovf1;
1242bebe80fcSBastian Koppelmann uint32_t avf0, avf1;
1243bebe80fcSBastian Koppelmann
1244bebe80fcSBastian Koppelmann ovf0 = ovf1 = 0;
1245bebe80fcSBastian Koppelmann
1246bebe80fcSBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000;
1247bebe80fcSBastian Koppelmann result1 = r2_high + mul_res1 + 0x8000;
1248bebe80fcSBastian Koppelmann
1249bebe80fcSBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1250bebe80fcSBastian Koppelmann ovf0 = (1 << 31);
1251bebe80fcSBastian Koppelmann }
1252bebe80fcSBastian Koppelmann
1253bebe80fcSBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1254bebe80fcSBastian Koppelmann ovf1 = (1 << 31);
1255bebe80fcSBastian Koppelmann }
1256bebe80fcSBastian Koppelmann
1257bebe80fcSBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1;
1258bebe80fcSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1259bebe80fcSBastian Koppelmann
1260bebe80fcSBastian Koppelmann avf0 = result0 * 2u;
1261bebe80fcSBastian Koppelmann avf0 = result0 ^ avf0;
1262bebe80fcSBastian Koppelmann avf1 = result1 * 2u;
1263bebe80fcSBastian Koppelmann avf1 = result1 ^ avf1;
1264bebe80fcSBastian Koppelmann
1265bebe80fcSBastian Koppelmann env->PSW_USB_AV = avf0 | avf1;
1266bebe80fcSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1267bebe80fcSBastian Koppelmann
1268bebe80fcSBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1269bebe80fcSBastian Koppelmann }
1270bebe80fcSBastian Koppelmann
helper_maddr_q(CPUTriCoreState * env,uint32_t r1,uint32_t r2,uint32_t r3,uint32_t n)1271b00aa8ecSBastian Koppelmann uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1272b00aa8ecSBastian Koppelmann uint32_t r3, uint32_t n)
1273b00aa8ecSBastian Koppelmann {
1274b00aa8ecSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
1275b00aa8ecSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
1276b00aa8ecSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
1277b00aa8ecSBastian Koppelmann int64_t mul, ret;
1278b00aa8ecSBastian Koppelmann
1279b00aa8ecSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1280b00aa8ecSBastian Koppelmann mul = 0x7fffffff;
1281b00aa8ecSBastian Koppelmann } else {
1282b00aa8ecSBastian Koppelmann mul = (t2 * t3) << n;
1283b00aa8ecSBastian Koppelmann }
1284b00aa8ecSBastian Koppelmann
1285b00aa8ecSBastian Koppelmann ret = t1 + mul + 0x8000;
1286b00aa8ecSBastian Koppelmann
1287b00aa8ecSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1288b00aa8ecSBastian Koppelmann env->PSW_USB_V = (1 << 31);
1289b00aa8ecSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1290b00aa8ecSBastian Koppelmann } else {
1291b00aa8ecSBastian Koppelmann env->PSW_USB_V = 0;
1292b00aa8ecSBastian Koppelmann }
1293b00aa8ecSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u;
1294b00aa8ecSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1295b00aa8ecSBastian Koppelmann
1296b00aa8ecSBastian Koppelmann return ret & 0xffff0000ll;
1297b00aa8ecSBastian Koppelmann }
1298b00aa8ecSBastian Koppelmann
helper_add_b(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1299d5de7839SBastian Koppelmann uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1300d5de7839SBastian Koppelmann {
1301d5de7839SBastian Koppelmann int32_t b, i;
1302d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2;
1303d5de7839SBastian Koppelmann int32_t ovf = 0;
1304d5de7839SBastian Koppelmann int32_t avf = 0;
1305d5de7839SBastian Koppelmann uint32_t ret = 0;
1306d5de7839SBastian Koppelmann
1307d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) {
1308d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8);
1309d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8);
1310d5de7839SBastian Koppelmann
1311d5de7839SBastian Koppelmann b = extr_r1 + extr_r2;
1312d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80));
1313d5de7839SBastian Koppelmann avf |= b ^ b * 2u;
1314d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8));
1315d5de7839SBastian Koppelmann }
1316d5de7839SBastian Koppelmann
1317d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31);
1318d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1319d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24;
1320d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1321d5de7839SBastian Koppelmann
1322d5de7839SBastian Koppelmann return ret;
1323d5de7839SBastian Koppelmann }
1324d5de7839SBastian Koppelmann
helper_add_h(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1325d5de7839SBastian Koppelmann uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1326d5de7839SBastian Koppelmann {
1327d5de7839SBastian Koppelmann int32_t h, i;
1328d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2;
1329d5de7839SBastian Koppelmann int32_t ovf = 0;
1330d5de7839SBastian Koppelmann int32_t avf = 0;
1331d5de7839SBastian Koppelmann int32_t ret = 0;
1332d5de7839SBastian Koppelmann
1333d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) {
1334d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16);
1335d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16);
1336d5de7839SBastian Koppelmann h = extr_r1 + extr_r2;
1337d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000));
1338d5de7839SBastian Koppelmann avf |= h ^ h * 2u;
1339d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16);
1340d5de7839SBastian Koppelmann }
1341d5de7839SBastian Koppelmann
1342d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31);
1343d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1344d5de7839SBastian Koppelmann env->PSW_USB_AV = (avf << 16);
1345d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1346d5de7839SBastian Koppelmann
1347d5de7839SBastian Koppelmann return ret;
1348d5de7839SBastian Koppelmann }
1349d5de7839SBastian Koppelmann
helper_subr_h(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)1350f4aef476SBastian Koppelmann uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1351f4aef476SBastian Koppelmann uint32_t r2_h)
1352f4aef476SBastian Koppelmann {
1353f4aef476SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32);
1354f4aef476SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32);
1355f4aef476SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32);
1356f4aef476SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32);
1357f4aef476SBastian Koppelmann int64_t result0, result1;
1358f4aef476SBastian Koppelmann uint32_t ovf0, ovf1;
1359f4aef476SBastian Koppelmann uint32_t avf0, avf1;
1360f4aef476SBastian Koppelmann
1361f4aef476SBastian Koppelmann ovf0 = ovf1 = 0;
1362f4aef476SBastian Koppelmann
1363f4aef476SBastian Koppelmann result0 = r2_low - mul_res0 + 0x8000;
1364f4aef476SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000;
1365f4aef476SBastian Koppelmann
1366f4aef476SBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1367f4aef476SBastian Koppelmann ovf0 = (1 << 31);
1368f4aef476SBastian Koppelmann }
1369f4aef476SBastian Koppelmann
1370f4aef476SBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1371f4aef476SBastian Koppelmann ovf1 = (1 << 31);
1372f4aef476SBastian Koppelmann }
1373f4aef476SBastian Koppelmann
1374f4aef476SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1;
1375f4aef476SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1376f4aef476SBastian Koppelmann
1377f4aef476SBastian Koppelmann avf0 = result0 * 2u;
1378f4aef476SBastian Koppelmann avf0 = result0 ^ avf0;
1379f4aef476SBastian Koppelmann avf1 = result1 * 2u;
1380f4aef476SBastian Koppelmann avf1 = result1 ^ avf1;
1381f4aef476SBastian Koppelmann
1382f4aef476SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1;
1383f4aef476SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1384f4aef476SBastian Koppelmann
1385f4aef476SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1386f4aef476SBastian Koppelmann }
1387f4aef476SBastian Koppelmann
helper_subadr_h(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)1388068fac77SBastian Koppelmann uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1389068fac77SBastian Koppelmann uint32_t r2_h)
1390068fac77SBastian Koppelmann {
1391068fac77SBastian Koppelmann int64_t mul_res0 = sextract64(r1, 0, 32);
1392068fac77SBastian Koppelmann int64_t mul_res1 = sextract64(r1, 32, 32);
1393068fac77SBastian Koppelmann int64_t r2_low = sextract64(r2_l, 0, 32);
1394068fac77SBastian Koppelmann int64_t r2_high = sextract64(r2_h, 0, 32);
1395068fac77SBastian Koppelmann int64_t result0, result1;
1396068fac77SBastian Koppelmann uint32_t ovf0, ovf1;
1397068fac77SBastian Koppelmann uint32_t avf0, avf1;
1398068fac77SBastian Koppelmann
1399068fac77SBastian Koppelmann ovf0 = ovf1 = 0;
1400068fac77SBastian Koppelmann
1401068fac77SBastian Koppelmann result0 = r2_low + mul_res0 + 0x8000;
1402068fac77SBastian Koppelmann result1 = r2_high - mul_res1 + 0x8000;
1403068fac77SBastian Koppelmann
1404068fac77SBastian Koppelmann if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1405068fac77SBastian Koppelmann ovf0 = (1 << 31);
1406068fac77SBastian Koppelmann }
1407068fac77SBastian Koppelmann
1408068fac77SBastian Koppelmann if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1409068fac77SBastian Koppelmann ovf1 = (1 << 31);
1410068fac77SBastian Koppelmann }
1411068fac77SBastian Koppelmann
1412068fac77SBastian Koppelmann env->PSW_USB_V = ovf0 | ovf1;
1413068fac77SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1414068fac77SBastian Koppelmann
1415068fac77SBastian Koppelmann avf0 = result0 * 2u;
1416068fac77SBastian Koppelmann avf0 = result0 ^ avf0;
1417068fac77SBastian Koppelmann avf1 = result1 * 2u;
1418068fac77SBastian Koppelmann avf1 = result1 ^ avf1;
1419068fac77SBastian Koppelmann
1420068fac77SBastian Koppelmann env->PSW_USB_AV = avf0 | avf1;
1421068fac77SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1422068fac77SBastian Koppelmann
1423068fac77SBastian Koppelmann return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1424068fac77SBastian Koppelmann }
1425068fac77SBastian Koppelmann
helper_msubr_q(CPUTriCoreState * env,uint32_t r1,uint32_t r2,uint32_t r3,uint32_t n)142662e47b2eSBastian Koppelmann uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
142762e47b2eSBastian Koppelmann uint32_t r3, uint32_t n)
142862e47b2eSBastian Koppelmann {
142962e47b2eSBastian Koppelmann int64_t t1 = sextract64(r1, 0, 32);
143062e47b2eSBastian Koppelmann int64_t t2 = sextract64(r2, 0, 32);
143162e47b2eSBastian Koppelmann int64_t t3 = sextract64(r3, 0, 32);
143262e47b2eSBastian Koppelmann int64_t mul, ret;
143362e47b2eSBastian Koppelmann
143462e47b2eSBastian Koppelmann if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
143562e47b2eSBastian Koppelmann mul = 0x7fffffff;
143662e47b2eSBastian Koppelmann } else {
143762e47b2eSBastian Koppelmann mul = (t2 * t3) << n;
143862e47b2eSBastian Koppelmann }
143962e47b2eSBastian Koppelmann
144062e47b2eSBastian Koppelmann ret = t1 - mul + 0x8000;
144162e47b2eSBastian Koppelmann
144262e47b2eSBastian Koppelmann if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
144362e47b2eSBastian Koppelmann env->PSW_USB_V = (1 << 31);
144462e47b2eSBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
144562e47b2eSBastian Koppelmann } else {
144662e47b2eSBastian Koppelmann env->PSW_USB_V = 0;
144762e47b2eSBastian Koppelmann }
144862e47b2eSBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u;
144962e47b2eSBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
145062e47b2eSBastian Koppelmann
145162e47b2eSBastian Koppelmann return ret & 0xffff0000ll;
145262e47b2eSBastian Koppelmann }
145362e47b2eSBastian Koppelmann
helper_sub_b(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1454d5de7839SBastian Koppelmann uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1455d5de7839SBastian Koppelmann {
1456d5de7839SBastian Koppelmann int32_t b, i;
1457d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2;
1458d5de7839SBastian Koppelmann int32_t ovf = 0;
1459d5de7839SBastian Koppelmann int32_t avf = 0;
1460d5de7839SBastian Koppelmann uint32_t ret = 0;
1461d5de7839SBastian Koppelmann
1462d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) {
1463d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8);
1464d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8);
1465d5de7839SBastian Koppelmann
1466d5de7839SBastian Koppelmann b = extr_r1 - extr_r2;
1467d5de7839SBastian Koppelmann ovf |= ((b > 0x7f) || (b < -0x80));
1468d5de7839SBastian Koppelmann avf |= b ^ b * 2u;
1469d5de7839SBastian Koppelmann ret |= ((b & 0xff) << (i*8));
1470d5de7839SBastian Koppelmann }
1471d5de7839SBastian Koppelmann
1472d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31);
1473d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1474d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 24;
1475d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1476d5de7839SBastian Koppelmann
1477d5de7839SBastian Koppelmann return ret;
1478d5de7839SBastian Koppelmann }
1479d5de7839SBastian Koppelmann
helper_sub_h(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1480d5de7839SBastian Koppelmann uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1481d5de7839SBastian Koppelmann {
1482d5de7839SBastian Koppelmann int32_t h, i;
1483d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2;
1484d5de7839SBastian Koppelmann int32_t ovf = 0;
1485d5de7839SBastian Koppelmann int32_t avf = 0;
1486d5de7839SBastian Koppelmann int32_t ret = 0;
1487d5de7839SBastian Koppelmann
1488d5de7839SBastian Koppelmann for (i = 0; i < 2; i++) {
1489d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 16, 16);
1490d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 16, 16);
1491d5de7839SBastian Koppelmann h = extr_r1 - extr_r2;
1492d5de7839SBastian Koppelmann ovf |= ((h > 0x7fff) || (h < -0x8000));
1493d5de7839SBastian Koppelmann avf |= h ^ h * 2u;
1494d5de7839SBastian Koppelmann ret |= (h & 0xffff) << (i * 16);
1495d5de7839SBastian Koppelmann }
1496d5de7839SBastian Koppelmann
1497d5de7839SBastian Koppelmann env->PSW_USB_V = (ovf << 31);
1498d5de7839SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
1499d5de7839SBastian Koppelmann env->PSW_USB_AV = avf << 16;
1500d5de7839SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
1501d5de7839SBastian Koppelmann
1502d5de7839SBastian Koppelmann return ret;
1503d5de7839SBastian Koppelmann }
1504d5de7839SBastian Koppelmann
helper_eq_b(target_ulong r1,target_ulong r2)1505d5de7839SBastian Koppelmann uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
1506d5de7839SBastian Koppelmann {
1507b69c95e7SPeter Maydell uint32_t ret, msk;
1508b69c95e7SPeter Maydell int32_t i;
1509d5de7839SBastian Koppelmann
1510d5de7839SBastian Koppelmann ret = 0;
1511d5de7839SBastian Koppelmann msk = 0xff;
1512d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) {
1513d5de7839SBastian Koppelmann if ((r1 & msk) == (r2 & msk)) {
1514d5de7839SBastian Koppelmann ret |= msk;
1515d5de7839SBastian Koppelmann }
1516d5de7839SBastian Koppelmann msk = msk << 8;
1517d5de7839SBastian Koppelmann }
1518d5de7839SBastian Koppelmann
1519d5de7839SBastian Koppelmann return ret;
1520d5de7839SBastian Koppelmann }
1521d5de7839SBastian Koppelmann
helper_eq_h(target_ulong r1,target_ulong r2)1522d5de7839SBastian Koppelmann uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1523d5de7839SBastian Koppelmann {
1524d5de7839SBastian Koppelmann int32_t ret = 0;
1525d5de7839SBastian Koppelmann
1526d5de7839SBastian Koppelmann if ((r1 & 0xffff) == (r2 & 0xffff)) {
1527d5de7839SBastian Koppelmann ret = 0xffff;
1528d5de7839SBastian Koppelmann }
1529d5de7839SBastian Koppelmann
1530d5de7839SBastian Koppelmann if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1531d5de7839SBastian Koppelmann ret |= 0xffff0000;
1532d5de7839SBastian Koppelmann }
1533d5de7839SBastian Koppelmann
1534d5de7839SBastian Koppelmann return ret;
1535d5de7839SBastian Koppelmann }
1536d5de7839SBastian Koppelmann
helper_eqany_b(target_ulong r1,target_ulong r2)1537d5de7839SBastian Koppelmann uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1538d5de7839SBastian Koppelmann {
1539d5de7839SBastian Koppelmann int32_t i;
1540d5de7839SBastian Koppelmann uint32_t ret = 0;
1541d5de7839SBastian Koppelmann
1542d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) {
1543d5de7839SBastian Koppelmann ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8));
1544d5de7839SBastian Koppelmann }
1545d5de7839SBastian Koppelmann
1546d5de7839SBastian Koppelmann return ret;
1547d5de7839SBastian Koppelmann }
1548d5de7839SBastian Koppelmann
helper_eqany_h(target_ulong r1,target_ulong r2)1549d5de7839SBastian Koppelmann uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1550d5de7839SBastian Koppelmann {
1551d5de7839SBastian Koppelmann uint32_t ret;
1552d5de7839SBastian Koppelmann
1553d5de7839SBastian Koppelmann ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16));
1554d5de7839SBastian Koppelmann ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16));
1555d5de7839SBastian Koppelmann
1556d5de7839SBastian Koppelmann return ret;
1557d5de7839SBastian Koppelmann }
1558d5de7839SBastian Koppelmann
helper_lt_b(target_ulong r1,target_ulong r2)1559d5de7839SBastian Koppelmann uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1560d5de7839SBastian Koppelmann {
1561d5de7839SBastian Koppelmann int32_t i;
1562d5de7839SBastian Koppelmann uint32_t ret = 0;
1563d5de7839SBastian Koppelmann
1564d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) {
1565d5de7839SBastian Koppelmann if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) {
1566d5de7839SBastian Koppelmann ret |= (0xff << (i * 8));
1567d5de7839SBastian Koppelmann }
1568d5de7839SBastian Koppelmann }
1569d5de7839SBastian Koppelmann
1570d5de7839SBastian Koppelmann return ret;
1571d5de7839SBastian Koppelmann }
1572d5de7839SBastian Koppelmann
helper_lt_bu(target_ulong r1,target_ulong r2)1573d5de7839SBastian Koppelmann uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1574d5de7839SBastian Koppelmann {
1575d5de7839SBastian Koppelmann int32_t i;
1576d5de7839SBastian Koppelmann uint32_t ret = 0;
1577d5de7839SBastian Koppelmann
1578d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) {
1579d5de7839SBastian Koppelmann if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) {
1580d5de7839SBastian Koppelmann ret |= (0xff << (i * 8));
1581d5de7839SBastian Koppelmann }
1582d5de7839SBastian Koppelmann }
1583d5de7839SBastian Koppelmann
1584d5de7839SBastian Koppelmann return ret;
1585d5de7839SBastian Koppelmann }
1586d5de7839SBastian Koppelmann
helper_lt_h(target_ulong r1,target_ulong r2)1587d5de7839SBastian Koppelmann uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1588d5de7839SBastian Koppelmann {
1589d5de7839SBastian Koppelmann uint32_t ret = 0;
1590d5de7839SBastian Koppelmann
1591d5de7839SBastian Koppelmann if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) {
1592d5de7839SBastian Koppelmann ret |= 0xffff;
1593d5de7839SBastian Koppelmann }
1594d5de7839SBastian Koppelmann
1595d5de7839SBastian Koppelmann if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) {
1596d5de7839SBastian Koppelmann ret |= 0xffff0000;
1597d5de7839SBastian Koppelmann }
1598d5de7839SBastian Koppelmann
1599d5de7839SBastian Koppelmann return ret;
1600d5de7839SBastian Koppelmann }
1601d5de7839SBastian Koppelmann
helper_lt_hu(target_ulong r1,target_ulong r2)1602d5de7839SBastian Koppelmann uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1603d5de7839SBastian Koppelmann {
1604d5de7839SBastian Koppelmann uint32_t ret = 0;
1605d5de7839SBastian Koppelmann
1606d5de7839SBastian Koppelmann if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) {
1607d5de7839SBastian Koppelmann ret |= 0xffff;
1608d5de7839SBastian Koppelmann }
1609d5de7839SBastian Koppelmann
1610d5de7839SBastian Koppelmann if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) {
1611d5de7839SBastian Koppelmann ret |= 0xffff0000;
1612d5de7839SBastian Koppelmann }
1613d5de7839SBastian Koppelmann
1614d5de7839SBastian Koppelmann return ret;
1615d5de7839SBastian Koppelmann }
1616d5de7839SBastian Koppelmann
1617d5de7839SBastian Koppelmann #define EXTREMA_H_B(name, op) \
1618d5de7839SBastian Koppelmann uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1619d5de7839SBastian Koppelmann { \
1620d5de7839SBastian Koppelmann int32_t i, extr_r1, extr_r2; \
1621d5de7839SBastian Koppelmann uint32_t ret = 0; \
1622d5de7839SBastian Koppelmann \
1623d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \
1624d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, i * 8, 8); \
1625d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, i * 8, 8); \
1626d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1627d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \
1628d5de7839SBastian Koppelmann } \
1629d5de7839SBastian Koppelmann return ret; \
1630d5de7839SBastian Koppelmann } \
1631d5de7839SBastian Koppelmann \
1632d5de7839SBastian Koppelmann uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1633d5de7839SBastian Koppelmann { \
1634d5de7839SBastian Koppelmann int32_t i; \
1635d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \
1636d5de7839SBastian Koppelmann uint32_t ret = 0; \
1637d5de7839SBastian Koppelmann \
1638d5de7839SBastian Koppelmann for (i = 0; i < 4; i++) { \
1639d5de7839SBastian Koppelmann extr_r1 = extract32(r1, i * 8, 8); \
1640d5de7839SBastian Koppelmann extr_r2 = extract32(r2, i * 8, 8); \
1641d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1642d5de7839SBastian Koppelmann ret |= (extr_r1 & 0xff) << (i * 8); \
1643d5de7839SBastian Koppelmann } \
1644d5de7839SBastian Koppelmann return ret; \
1645d5de7839SBastian Koppelmann } \
1646d5de7839SBastian Koppelmann \
1647d5de7839SBastian Koppelmann uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1648d5de7839SBastian Koppelmann { \
1649d5de7839SBastian Koppelmann int32_t extr_r1, extr_r2; \
1650d5de7839SBastian Koppelmann uint32_t ret = 0; \
1651d5de7839SBastian Koppelmann \
1652d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 0, 16); \
1653d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 0, 16); \
1654d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1655d5de7839SBastian Koppelmann ret = ret & 0xffff; \
1656d5de7839SBastian Koppelmann \
1657d5de7839SBastian Koppelmann extr_r1 = sextract32(r1, 16, 16); \
1658d5de7839SBastian Koppelmann extr_r2 = sextract32(r2, 16, 16); \
1659d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1660d5de7839SBastian Koppelmann ret |= extr_r1 << 16; \
1661d5de7839SBastian Koppelmann \
1662d5de7839SBastian Koppelmann return ret; \
1663d5de7839SBastian Koppelmann } \
1664d5de7839SBastian Koppelmann \
1665d5de7839SBastian Koppelmann uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1666d5de7839SBastian Koppelmann { \
1667d5de7839SBastian Koppelmann uint32_t extr_r1, extr_r2; \
1668d5de7839SBastian Koppelmann uint32_t ret = 0; \
1669d5de7839SBastian Koppelmann \
1670d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 0, 16); \
1671d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 0, 16); \
1672d5de7839SBastian Koppelmann ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1673d5de7839SBastian Koppelmann ret = ret & 0xffff; \
1674d5de7839SBastian Koppelmann \
1675d5de7839SBastian Koppelmann extr_r1 = extract32(r1, 16, 16); \
1676d5de7839SBastian Koppelmann extr_r2 = extract32(r2, 16, 16); \
1677d5de7839SBastian Koppelmann extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
1678d5de7839SBastian Koppelmann ret |= extr_r1 << (16); \
1679d5de7839SBastian Koppelmann \
1680d5de7839SBastian Koppelmann return ret; \
1681d5de7839SBastian Koppelmann } \
168209532255SBastian Koppelmann \
168309532255SBastian Koppelmann uint64_t helper_ix##name(uint64_t r1, uint32_t r2) \
168409532255SBastian Koppelmann { \
168509532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \
168609532255SBastian Koppelmann uint64_t ret = 0; \
168709532255SBastian Koppelmann \
168809532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \
168909532255SBastian Koppelmann r2l = sextract64(r2, 0, 16); \
169009532255SBastian Koppelmann r2h = sextract64(r2, 16, 16); \
169109532255SBastian Koppelmann r1hl = sextract64(r1, 32, 16); \
169209532255SBastian Koppelmann \
169309532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \
169409532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \
169509532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \
169609532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \
169709532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \
169809532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \
169909532255SBastian Koppelmann } else { \
170009532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \
170109532255SBastian Koppelmann } \
170209532255SBastian Koppelmann return ret; \
170309532255SBastian Koppelmann } \
170409532255SBastian Koppelmann \
170509532255SBastian Koppelmann uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2) \
170609532255SBastian Koppelmann { \
170709532255SBastian Koppelmann int64_t r2l, r2h, r1hl; \
170809532255SBastian Koppelmann uint64_t ret = 0; \
170909532255SBastian Koppelmann \
171009532255SBastian Koppelmann ret = ((r1 + 2) & 0xffff); \
171109532255SBastian Koppelmann r2l = extract64(r2, 0, 16); \
171209532255SBastian Koppelmann r2h = extract64(r2, 16, 16); \
171309532255SBastian Koppelmann r1hl = extract64(r1, 32, 16); \
171409532255SBastian Koppelmann \
171509532255SBastian Koppelmann if ((r2l op ## = r2h) && (r2l op r1hl)) { \
171609532255SBastian Koppelmann ret |= (r2l & 0xffff) << 32; \
171709532255SBastian Koppelmann ret |= extract64(r1, 0, 16) << 16; \
171809532255SBastian Koppelmann } else if ((r2h op r2l) && (r2h op r1hl)) { \
171909532255SBastian Koppelmann ret |= extract64(r2, 16, 16) << 32; \
172009532255SBastian Koppelmann ret |= extract64(r1 + 1, 0, 16) << 16; \
172109532255SBastian Koppelmann } else { \
172209532255SBastian Koppelmann ret |= r1 & 0xffffffff0000ull; \
172309532255SBastian Koppelmann } \
172409532255SBastian Koppelmann return ret; \
172509532255SBastian Koppelmann }
1726d5de7839SBastian Koppelmann
1727d5de7839SBastian Koppelmann EXTREMA_H_B(max, >)
1728d5de7839SBastian Koppelmann EXTREMA_H_B(min, <)
1729d5de7839SBastian Koppelmann
1730d5de7839SBastian Koppelmann #undef EXTREMA_H_B
1731d5de7839SBastian Koppelmann
helper_clo_h(target_ulong r1)17320b79a781SBastian Koppelmann uint32_t helper_clo_h(target_ulong r1)
17330b79a781SBastian Koppelmann {
17340b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16);
17350b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16);
17360b79a781SBastian Koppelmann
17370b79a781SBastian Koppelmann ret_hw0 = clo32(ret_hw0 << 16);
17380b79a781SBastian Koppelmann ret_hw1 = clo32(ret_hw1 << 16);
17390b79a781SBastian Koppelmann
17400b79a781SBastian Koppelmann if (ret_hw0 > 16) {
17410b79a781SBastian Koppelmann ret_hw0 = 16;
17420b79a781SBastian Koppelmann }
17430b79a781SBastian Koppelmann if (ret_hw1 > 16) {
17440b79a781SBastian Koppelmann ret_hw1 = 16;
17450b79a781SBastian Koppelmann }
17460b79a781SBastian Koppelmann
17470b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16);
17480b79a781SBastian Koppelmann }
17490b79a781SBastian Koppelmann
helper_clz_h(target_ulong r1)17500b79a781SBastian Koppelmann uint32_t helper_clz_h(target_ulong r1)
17510b79a781SBastian Koppelmann {
17520b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16);
17530b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16);
17540b79a781SBastian Koppelmann
17550b79a781SBastian Koppelmann ret_hw0 = clz32(ret_hw0 << 16);
17560b79a781SBastian Koppelmann ret_hw1 = clz32(ret_hw1 << 16);
17570b79a781SBastian Koppelmann
17580b79a781SBastian Koppelmann if (ret_hw0 > 16) {
17590b79a781SBastian Koppelmann ret_hw0 = 16;
17600b79a781SBastian Koppelmann }
17610b79a781SBastian Koppelmann if (ret_hw1 > 16) {
17620b79a781SBastian Koppelmann ret_hw1 = 16;
17630b79a781SBastian Koppelmann }
17640b79a781SBastian Koppelmann
17650b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16);
17660b79a781SBastian Koppelmann }
17670b79a781SBastian Koppelmann
helper_cls_h(target_ulong r1)17680b79a781SBastian Koppelmann uint32_t helper_cls_h(target_ulong r1)
17690b79a781SBastian Koppelmann {
17700b79a781SBastian Koppelmann uint32_t ret_hw0 = extract32(r1, 0, 16);
17710b79a781SBastian Koppelmann uint32_t ret_hw1 = extract32(r1, 16, 16);
17720b79a781SBastian Koppelmann
17730b79a781SBastian Koppelmann ret_hw0 = clrsb32(ret_hw0 << 16);
17740b79a781SBastian Koppelmann ret_hw1 = clrsb32(ret_hw1 << 16);
17750b79a781SBastian Koppelmann
17760b79a781SBastian Koppelmann if (ret_hw0 > 15) {
17770b79a781SBastian Koppelmann ret_hw0 = 15;
17780b79a781SBastian Koppelmann }
17790b79a781SBastian Koppelmann if (ret_hw1 > 15) {
17800b79a781SBastian Koppelmann ret_hw1 = 15;
17810b79a781SBastian Koppelmann }
17820b79a781SBastian Koppelmann
17830b79a781SBastian Koppelmann return ret_hw0 | (ret_hw1 << 16);
17840b79a781SBastian Koppelmann }
17850b79a781SBastian Koppelmann
helper_sh(target_ulong r1,target_ulong r2)17860b79a781SBastian Koppelmann uint32_t helper_sh(target_ulong r1, target_ulong r2)
17870b79a781SBastian Koppelmann {
17880b79a781SBastian Koppelmann int32_t shift_count = sextract32(r2, 0, 6);
17890b79a781SBastian Koppelmann
17900b79a781SBastian Koppelmann if (shift_count == -32) {
17910b79a781SBastian Koppelmann return 0;
17920b79a781SBastian Koppelmann } else if (shift_count < 0) {
17930b79a781SBastian Koppelmann return r1 >> -shift_count;
17940b79a781SBastian Koppelmann } else {
17950b79a781SBastian Koppelmann return r1 << shift_count;
17960b79a781SBastian Koppelmann }
17970b79a781SBastian Koppelmann }
17980b79a781SBastian Koppelmann
helper_sh_h(target_ulong r1,target_ulong r2)17990b79a781SBastian Koppelmann uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
18000b79a781SBastian Koppelmann {
18010b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1;
18020b79a781SBastian Koppelmann int32_t shift_count;
18030b79a781SBastian Koppelmann
18040b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5);
18050b79a781SBastian Koppelmann
18060b79a781SBastian Koppelmann if (shift_count == -16) {
18070b79a781SBastian Koppelmann return 0;
18080b79a781SBastian Koppelmann } else if (shift_count < 0) {
18090b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
18100b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
18110b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
18120b79a781SBastian Koppelmann } else {
18130b79a781SBastian Koppelmann ret_hw0 = extract32(r1, 0, 16) << shift_count;
18140b79a781SBastian Koppelmann ret_hw1 = extract32(r1, 16, 16) << shift_count;
18150b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
18160b79a781SBastian Koppelmann }
18170b79a781SBastian Koppelmann }
18180b79a781SBastian Koppelmann
helper_sha(CPUTriCoreState * env,target_ulong r1,target_ulong r2)18190b79a781SBastian Koppelmann uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
18200b79a781SBastian Koppelmann {
18210b79a781SBastian Koppelmann int32_t shift_count;
18220b79a781SBastian Koppelmann int64_t result, t1;
18230b79a781SBastian Koppelmann uint32_t ret;
18240b79a781SBastian Koppelmann
18250b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 6);
18260b79a781SBastian Koppelmann t1 = sextract32(r1, 0, 32);
18270b79a781SBastian Koppelmann
18280b79a781SBastian Koppelmann if (shift_count == 0) {
18290b79a781SBastian Koppelmann env->PSW_USB_C = env->PSW_USB_V = 0;
18300b79a781SBastian Koppelmann ret = r1;
18310b79a781SBastian Koppelmann } else if (shift_count == -32) {
18320b79a781SBastian Koppelmann env->PSW_USB_C = r1;
18330b79a781SBastian Koppelmann env->PSW_USB_V = 0;
18340b79a781SBastian Koppelmann ret = t1 >> 31;
18350b79a781SBastian Koppelmann } else if (shift_count > 0) {
18360b79a781SBastian Koppelmann result = t1 << shift_count;
18370b79a781SBastian Koppelmann /* calc carry */
1838452e3d49SPeter Maydell env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
18390b79a781SBastian Koppelmann /* calc v */
18400b79a781SBastian Koppelmann env->PSW_USB_V = (((result > 0x7fffffffLL) ||
18410b79a781SBastian Koppelmann (result < -0x80000000LL)) << 31);
18420b79a781SBastian Koppelmann /* calc sv */
18430b79a781SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
18440b79a781SBastian Koppelmann ret = (uint32_t)result;
18450b79a781SBastian Koppelmann } else {
18460b79a781SBastian Koppelmann env->PSW_USB_V = 0;
18470b79a781SBastian Koppelmann env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
18480b79a781SBastian Koppelmann ret = t1 >> -shift_count;
18490b79a781SBastian Koppelmann }
18500b79a781SBastian Koppelmann
18510b79a781SBastian Koppelmann env->PSW_USB_AV = ret ^ ret * 2u;
18520b79a781SBastian Koppelmann env->PSW_USB_SAV |= env->PSW_USB_AV;
18530b79a781SBastian Koppelmann
18540b79a781SBastian Koppelmann return ret;
18550b79a781SBastian Koppelmann }
18560b79a781SBastian Koppelmann
helper_sha_h(target_ulong r1,target_ulong r2)18570b79a781SBastian Koppelmann uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
18580b79a781SBastian Koppelmann {
18590b79a781SBastian Koppelmann int32_t shift_count;
18600b79a781SBastian Koppelmann int32_t ret_hw0, ret_hw1;
18610b79a781SBastian Koppelmann
18620b79a781SBastian Koppelmann shift_count = sextract32(r2, 0, 5);
18630b79a781SBastian Koppelmann
18640b79a781SBastian Koppelmann if (shift_count == 0) {
18650b79a781SBastian Koppelmann return r1;
18660b79a781SBastian Koppelmann } else if (shift_count < 0) {
18670b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
18680b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
18690b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
18700b79a781SBastian Koppelmann } else {
18710b79a781SBastian Koppelmann ret_hw0 = sextract32(r1, 0, 16) << shift_count;
18720b79a781SBastian Koppelmann ret_hw1 = sextract32(r1, 16, 16) << shift_count;
18730b79a781SBastian Koppelmann return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
18740b79a781SBastian Koppelmann }
18750b79a781SBastian Koppelmann }
18760b79a781SBastian Koppelmann
helper_bmerge(target_ulong r1,target_ulong r2)1877e2bed107SBastian Koppelmann uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1878e2bed107SBastian Koppelmann {
1879e2bed107SBastian Koppelmann uint32_t i, ret;
1880e2bed107SBastian Koppelmann
1881e2bed107SBastian Koppelmann ret = 0;
1882e2bed107SBastian Koppelmann for (i = 0; i < 16; i++) {
1883e2bed107SBastian Koppelmann ret |= (r1 & 1) << (2 * i + 1);
1884e2bed107SBastian Koppelmann ret |= (r2 & 1) << (2 * i);
1885e2bed107SBastian Koppelmann r1 = r1 >> 1;
1886e2bed107SBastian Koppelmann r2 = r2 >> 1;
1887e2bed107SBastian Koppelmann }
1888e2bed107SBastian Koppelmann return ret;
1889e2bed107SBastian Koppelmann }
1890e2bed107SBastian Koppelmann
helper_bsplit(uint32_t r1)1891e2bed107SBastian Koppelmann uint64_t helper_bsplit(uint32_t r1)
1892e2bed107SBastian Koppelmann {
1893e2bed107SBastian Koppelmann int32_t i;
1894e2bed107SBastian Koppelmann uint64_t ret;
1895e2bed107SBastian Koppelmann
1896e2bed107SBastian Koppelmann ret = 0;
1897e2bed107SBastian Koppelmann for (i = 0; i < 32; i = i + 2) {
1898e2bed107SBastian Koppelmann /* even */
1899e2bed107SBastian Koppelmann ret |= (r1 & 1) << (i/2);
1900e2bed107SBastian Koppelmann r1 = r1 >> 1;
1901e2bed107SBastian Koppelmann /* odd */
1902e2bed107SBastian Koppelmann ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1903e2bed107SBastian Koppelmann r1 = r1 >> 1;
1904e2bed107SBastian Koppelmann }
1905e2bed107SBastian Koppelmann return ret;
1906e2bed107SBastian Koppelmann }
1907e2bed107SBastian Koppelmann
helper_parity(target_ulong r1)1908e2bed107SBastian Koppelmann uint32_t helper_parity(target_ulong r1)
1909e2bed107SBastian Koppelmann {
1910e2bed107SBastian Koppelmann uint32_t ret;
1911e2bed107SBastian Koppelmann uint32_t nOnes, i;
1912e2bed107SBastian Koppelmann
1913e2bed107SBastian Koppelmann ret = 0;
1914e2bed107SBastian Koppelmann nOnes = 0;
1915e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) {
1916e2bed107SBastian Koppelmann ret ^= (r1 & 1);
1917e2bed107SBastian Koppelmann r1 = r1 >> 1;
1918e2bed107SBastian Koppelmann }
1919e2bed107SBastian Koppelmann /* second byte */
1920e2bed107SBastian Koppelmann nOnes = 0;
1921e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) {
1922e2bed107SBastian Koppelmann nOnes ^= (r1 & 1);
1923e2bed107SBastian Koppelmann r1 = r1 >> 1;
1924e2bed107SBastian Koppelmann }
1925e2bed107SBastian Koppelmann ret |= nOnes << 8;
1926e2bed107SBastian Koppelmann /* third byte */
1927e2bed107SBastian Koppelmann nOnes = 0;
1928e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) {
1929e2bed107SBastian Koppelmann nOnes ^= (r1 & 1);
1930e2bed107SBastian Koppelmann r1 = r1 >> 1;
1931e2bed107SBastian Koppelmann }
1932e2bed107SBastian Koppelmann ret |= nOnes << 16;
1933e2bed107SBastian Koppelmann /* fourth byte */
1934e2bed107SBastian Koppelmann nOnes = 0;
1935e2bed107SBastian Koppelmann for (i = 0; i < 8; i++) {
1936e2bed107SBastian Koppelmann nOnes ^= (r1 & 1);
1937e2bed107SBastian Koppelmann r1 = r1 >> 1;
1938e2bed107SBastian Koppelmann }
1939e2bed107SBastian Koppelmann ret |= nOnes << 24;
1940e2bed107SBastian Koppelmann
1941e2bed107SBastian Koppelmann return ret;
1942e2bed107SBastian Koppelmann }
1943e2bed107SBastian Koppelmann
helper_pack(uint32_t carry,uint32_t r1_low,uint32_t r1_high,target_ulong r2)194409532255SBastian Koppelmann uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
194509532255SBastian Koppelmann target_ulong r2)
194609532255SBastian Koppelmann {
194709532255SBastian Koppelmann uint32_t ret;
194809532255SBastian Koppelmann int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
194909532255SBastian Koppelmann int32_t int_exp = r1_high;
195009532255SBastian Koppelmann int32_t int_mant = r1_low;
195109532255SBastian Koppelmann uint32_t flag_rnd = (int_mant & (1 << 7)) && (
195209532255SBastian Koppelmann (int_mant & (1 << 8)) ||
195309532255SBastian Koppelmann (int_mant & 0x7f) ||
195409532255SBastian Koppelmann (carry != 0));
195509532255SBastian Koppelmann if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
195609532255SBastian Koppelmann fp_exp = 255;
195709532255SBastian Koppelmann fp_frac = extract32(int_mant, 8, 23);
195809532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
195909532255SBastian Koppelmann fp_exp = 255;
196009532255SBastian Koppelmann fp_frac = 0;
196109532255SBastian Koppelmann } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
196209532255SBastian Koppelmann fp_exp = 0;
196309532255SBastian Koppelmann fp_frac = 0;
196409532255SBastian Koppelmann } else if (int_mant == 0) {
196509532255SBastian Koppelmann fp_exp = 0;
196609532255SBastian Koppelmann fp_frac = 0;
196709532255SBastian Koppelmann } else {
196809532255SBastian Koppelmann if (((int_mant & (1 << 31)) == 0)) {
196909532255SBastian Koppelmann temp_exp = 0;
197009532255SBastian Koppelmann } else {
197109532255SBastian Koppelmann temp_exp = int_exp + 128;
197209532255SBastian Koppelmann }
197309532255SBastian Koppelmann fp_exp_frac = (((temp_exp & 0xff) << 23) |
197409532255SBastian Koppelmann extract32(int_mant, 8, 23))
197509532255SBastian Koppelmann + flag_rnd;
197609532255SBastian Koppelmann fp_exp = extract32(fp_exp_frac, 23, 8);
197709532255SBastian Koppelmann fp_frac = extract32(fp_exp_frac, 0, 23);
197809532255SBastian Koppelmann }
197909532255SBastian Koppelmann ret = r2 & (1 << 31);
198009532255SBastian Koppelmann ret = ret + (fp_exp << 23);
198109532255SBastian Koppelmann ret = ret + (fp_frac & 0x7fffff);
198209532255SBastian Koppelmann
198309532255SBastian Koppelmann return ret;
198409532255SBastian Koppelmann }
198509532255SBastian Koppelmann
helper_unpack(target_ulong arg1)1986e2bed107SBastian Koppelmann uint64_t helper_unpack(target_ulong arg1)
1987e2bed107SBastian Koppelmann {
1988e2bed107SBastian Koppelmann int32_t fp_exp = extract32(arg1, 23, 8);
1989e2bed107SBastian Koppelmann int32_t fp_frac = extract32(arg1, 0, 23);
1990e2bed107SBastian Koppelmann uint64_t ret;
1991e2bed107SBastian Koppelmann int32_t int_exp, int_mant;
1992e2bed107SBastian Koppelmann
1993e2bed107SBastian Koppelmann if (fp_exp == 255) {
1994e2bed107SBastian Koppelmann int_exp = 255;
1995e2bed107SBastian Koppelmann int_mant = (fp_frac << 7);
1996e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac == 0)) {
1997e2bed107SBastian Koppelmann int_exp = -127;
1998e2bed107SBastian Koppelmann int_mant = 0;
1999e2bed107SBastian Koppelmann } else if ((fp_exp == 0) && (fp_frac != 0)) {
2000e2bed107SBastian Koppelmann int_exp = -126;
2001e2bed107SBastian Koppelmann int_mant = (fp_frac << 7);
2002e2bed107SBastian Koppelmann } else {
2003e2bed107SBastian Koppelmann int_exp = fp_exp - 127;
2004e2bed107SBastian Koppelmann int_mant = (fp_frac << 7);
2005e2bed107SBastian Koppelmann int_mant |= (1 << 30);
2006e2bed107SBastian Koppelmann }
2007e2bed107SBastian Koppelmann ret = int_exp;
2008e2bed107SBastian Koppelmann ret = ret << 32;
2009e2bed107SBastian Koppelmann ret |= int_mant;
2010e2bed107SBastian Koppelmann
2011e2bed107SBastian Koppelmann return ret;
2012e2bed107SBastian Koppelmann }
2013e2bed107SBastian Koppelmann
helper_dvinit_b_13(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2014e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2015e2bed107SBastian Koppelmann {
2016e2bed107SBastian Koppelmann uint64_t ret;
2017f69c24e4SBastian Koppelmann int32_t abs_sig_dividend, abs_divisor;
2018e2bed107SBastian Koppelmann
2019e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32);
2020e2bed107SBastian Koppelmann ret = ret << 24;
2021e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2022e2bed107SBastian Koppelmann ret |= 0xffffff;
2023e2bed107SBastian Koppelmann }
2024e2bed107SBastian Koppelmann
2025f69c24e4SBastian Koppelmann abs_sig_dividend = abs((int32_t)r1) >> 8;
202630a0d72fSStefan Weil abs_divisor = abs((int32_t)r2);
2027f69c24e4SBastian Koppelmann /* calc overflow
2028f69c24e4SBastian Koppelmann ofv if (a/b >= 255) <=> (a/255 >= b) */
2029f69c24e4SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2030e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31;
2031e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
2032e2bed107SBastian Koppelmann env->PSW_USB_AV = 0;
2033e2bed107SBastian Koppelmann
2034e2bed107SBastian Koppelmann return ret;
2035e2bed107SBastian Koppelmann }
2036e2bed107SBastian Koppelmann
helper_dvinit_b_131(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2037e2bed107SBastian Koppelmann uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2038e2bed107SBastian Koppelmann {
2039e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32);
2040e2bed107SBastian Koppelmann
2041e2bed107SBastian Koppelmann ret = ret << 24;
2042e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2043e2bed107SBastian Koppelmann ret |= 0xffffff;
2044e2bed107SBastian Koppelmann }
2045e2bed107SBastian Koppelmann /* calc overflow */
2046e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
2047e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31;
2048e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
2049e2bed107SBastian Koppelmann env->PSW_USB_AV = 0;
2050e2bed107SBastian Koppelmann
2051e2bed107SBastian Koppelmann return ret;
2052e2bed107SBastian Koppelmann }
2053e2bed107SBastian Koppelmann
helper_dvinit_h_13(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2054e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2055e2bed107SBastian Koppelmann {
2056e2bed107SBastian Koppelmann uint64_t ret;
2057f69c24e4SBastian Koppelmann int32_t abs_sig_dividend, abs_divisor;
2058e2bed107SBastian Koppelmann
2059e2bed107SBastian Koppelmann ret = sextract32(r1, 0, 32);
2060e2bed107SBastian Koppelmann ret = ret << 16;
2061e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2062e2bed107SBastian Koppelmann ret |= 0xffff;
2063e2bed107SBastian Koppelmann }
2064e2bed107SBastian Koppelmann
2065f69c24e4SBastian Koppelmann abs_sig_dividend = abs((int32_t)r1) >> 16;
206630a0d72fSStefan Weil abs_divisor = abs((int32_t)r2);
2067f69c24e4SBastian Koppelmann /* calc overflow
2068f69c24e4SBastian Koppelmann ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */
2069f69c24e4SBastian Koppelmann env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2070e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31;
2071e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
2072e2bed107SBastian Koppelmann env->PSW_USB_AV = 0;
2073e2bed107SBastian Koppelmann
2074e2bed107SBastian Koppelmann return ret;
2075e2bed107SBastian Koppelmann }
2076e2bed107SBastian Koppelmann
helper_dvinit_h_131(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2077e2bed107SBastian Koppelmann uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2078e2bed107SBastian Koppelmann {
2079e2bed107SBastian Koppelmann uint64_t ret = sextract32(r1, 0, 32);
2080e2bed107SBastian Koppelmann
2081e2bed107SBastian Koppelmann ret = ret << 16;
2082e2bed107SBastian Koppelmann if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2083e2bed107SBastian Koppelmann ret |= 0xffff;
2084e2bed107SBastian Koppelmann }
2085e2bed107SBastian Koppelmann /* calc overflow */
2086e2bed107SBastian Koppelmann env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
2087e2bed107SBastian Koppelmann env->PSW_USB_V = env->PSW_USB_V << 31;
2088e2bed107SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
2089e2bed107SBastian Koppelmann env->PSW_USB_AV = 0;
2090e2bed107SBastian Koppelmann
2091e2bed107SBastian Koppelmann return ret;
2092e2bed107SBastian Koppelmann }
2093e2bed107SBastian Koppelmann
helper_dvadj(uint64_t r1,uint32_t r2)209409532255SBastian Koppelmann uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
209509532255SBastian Koppelmann {
209609532255SBastian Koppelmann int32_t x_sign = (r1 >> 63);
209709532255SBastian Koppelmann int32_t q_sign = x_sign ^ (r2 >> 31);
209809532255SBastian Koppelmann int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
209909532255SBastian Koppelmann int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
210009532255SBastian Koppelmann uint32_t quotient;
21019be38598SEduardo Habkost uint64_t remainder;
210209532255SBastian Koppelmann
210309532255SBastian Koppelmann if ((q_sign & ~eq_neg) | eq_pos) {
210409532255SBastian Koppelmann quotient = (r1 + 1) & 0xffffffff;
210509532255SBastian Koppelmann } else {
210609532255SBastian Koppelmann quotient = r1 & 0xffffffff;
210709532255SBastian Koppelmann }
210809532255SBastian Koppelmann
210909532255SBastian Koppelmann if (eq_pos | eq_neg) {
211009532255SBastian Koppelmann remainder = 0;
211109532255SBastian Koppelmann } else {
211209532255SBastian Koppelmann remainder = (r1 & 0xffffffff00000000ull);
211309532255SBastian Koppelmann }
21149be38598SEduardo Habkost return remainder | quotient;
211509532255SBastian Koppelmann }
211609532255SBastian Koppelmann
helper_dvstep(uint64_t r1,uint32_t r2)211709532255SBastian Koppelmann uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
211809532255SBastian Koppelmann {
211909532255SBastian Koppelmann int32_t dividend_sign = extract64(r1, 63, 1);
212009532255SBastian Koppelmann int32_t divisor_sign = extract32(r2, 31, 1);
212109532255SBastian Koppelmann int32_t quotient_sign = (dividend_sign != divisor_sign);
212209532255SBastian Koppelmann int32_t addend, dividend_quotient, remainder;
212309532255SBastian Koppelmann int32_t i, temp;
212409532255SBastian Koppelmann
212509532255SBastian Koppelmann if (quotient_sign) {
212609532255SBastian Koppelmann addend = r2;
212709532255SBastian Koppelmann } else {
212809532255SBastian Koppelmann addend = -r2;
212909532255SBastian Koppelmann }
213009532255SBastian Koppelmann dividend_quotient = (int32_t)r1;
213109532255SBastian Koppelmann remainder = (int32_t)(r1 >> 32);
213209532255SBastian Koppelmann
213309532255SBastian Koppelmann for (i = 0; i < 8; i++) {
213409532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
213509532255SBastian Koppelmann dividend_quotient <<= 1;
213609532255SBastian Koppelmann temp = remainder + addend;
213709532255SBastian Koppelmann if ((temp < 0) == dividend_sign) {
213809532255SBastian Koppelmann remainder = temp;
213909532255SBastian Koppelmann }
214009532255SBastian Koppelmann if (((temp < 0) == dividend_sign)) {
214109532255SBastian Koppelmann dividend_quotient = dividend_quotient | !quotient_sign;
214209532255SBastian Koppelmann } else {
214309532255SBastian Koppelmann dividend_quotient = dividend_quotient | quotient_sign;
214409532255SBastian Koppelmann }
214509532255SBastian Koppelmann }
214609532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
214709532255SBastian Koppelmann }
214809532255SBastian Koppelmann
helper_dvstep_u(uint64_t r1,uint32_t r2)214909532255SBastian Koppelmann uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
215009532255SBastian Koppelmann {
215109532255SBastian Koppelmann int32_t dividend_quotient = extract64(r1, 0, 32);
215209532255SBastian Koppelmann int64_t remainder = extract64(r1, 32, 32);
215309532255SBastian Koppelmann int32_t i;
215409532255SBastian Koppelmann int64_t temp;
215509532255SBastian Koppelmann for (i = 0; i < 8; i++) {
215609532255SBastian Koppelmann remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
215709532255SBastian Koppelmann dividend_quotient <<= 1;
215809532255SBastian Koppelmann temp = (remainder & 0xffffffff) - r2;
215909532255SBastian Koppelmann if (temp >= 0) {
216009532255SBastian Koppelmann remainder = temp;
216109532255SBastian Koppelmann }
216209532255SBastian Koppelmann dividend_quotient = dividend_quotient | !(temp < 0);
216309532255SBastian Koppelmann }
216409532255SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
216509532255SBastian Koppelmann }
216609532255SBastian Koppelmann
helper_divide(CPUTriCoreState * env,uint32_t r1,uint32_t r2)216793715571SBastian Koppelmann uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
216893715571SBastian Koppelmann {
216993715571SBastian Koppelmann int32_t quotient, remainder;
217093715571SBastian Koppelmann int32_t dividend = (int32_t)r1;
217193715571SBastian Koppelmann int32_t divisor = (int32_t)r2;
217293715571SBastian Koppelmann
217393715571SBastian Koppelmann if (divisor == 0) {
217493715571SBastian Koppelmann if (dividend >= 0) {
217593715571SBastian Koppelmann quotient = 0x7fffffff;
217693715571SBastian Koppelmann remainder = 0;
217793715571SBastian Koppelmann } else {
217893715571SBastian Koppelmann quotient = 0x80000000;
217993715571SBastian Koppelmann remainder = 0;
218093715571SBastian Koppelmann }
218193715571SBastian Koppelmann env->PSW_USB_V = (1 << 31);
218293715571SBastian Koppelmann } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
218393715571SBastian Koppelmann quotient = 0x7fffffff;
218493715571SBastian Koppelmann remainder = 0;
218593715571SBastian Koppelmann env->PSW_USB_V = (1 << 31);
218693715571SBastian Koppelmann } else {
218793715571SBastian Koppelmann remainder = dividend % divisor;
218893715571SBastian Koppelmann quotient = (dividend - remainder)/divisor;
218993715571SBastian Koppelmann env->PSW_USB_V = 0;
219093715571SBastian Koppelmann }
219193715571SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
219293715571SBastian Koppelmann env->PSW_USB_AV = 0;
219393715571SBastian Koppelmann return ((uint64_t)remainder << 32) | (uint32_t)quotient;
219493715571SBastian Koppelmann }
219593715571SBastian Koppelmann
helper_divide_u(CPUTriCoreState * env,uint32_t r1,uint32_t r2)219693715571SBastian Koppelmann uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
219793715571SBastian Koppelmann {
219893715571SBastian Koppelmann uint32_t quotient, remainder;
219993715571SBastian Koppelmann uint32_t dividend = r1;
220093715571SBastian Koppelmann uint32_t divisor = r2;
220193715571SBastian Koppelmann
220293715571SBastian Koppelmann if (divisor == 0) {
220393715571SBastian Koppelmann quotient = 0xffffffff;
220493715571SBastian Koppelmann remainder = 0;
220593715571SBastian Koppelmann env->PSW_USB_V = (1 << 31);
220693715571SBastian Koppelmann } else {
220793715571SBastian Koppelmann remainder = dividend % divisor;
220893715571SBastian Koppelmann quotient = (dividend - remainder)/divisor;
220993715571SBastian Koppelmann env->PSW_USB_V = 0;
221093715571SBastian Koppelmann }
221193715571SBastian Koppelmann env->PSW_USB_SV |= env->PSW_USB_V;
221293715571SBastian Koppelmann env->PSW_USB_AV = 0;
221393715571SBastian Koppelmann return ((uint64_t)remainder << 32) | quotient;
221493715571SBastian Koppelmann }
221593715571SBastian Koppelmann
helper_mul_h(uint32_t arg00,uint32_t arg01,uint32_t arg10,uint32_t arg11,uint32_t n)22169655b932SBastian Koppelmann uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
22179655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n)
22189655b932SBastian Koppelmann {
22199655b932SBastian Koppelmann uint32_t result0, result1;
22209655b932SBastian Koppelmann
22219655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
22229655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1);
22239655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
22249655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1);
22259655b932SBastian Koppelmann if (sc1) {
22269655b932SBastian Koppelmann result1 = 0x7fffffff;
22279655b932SBastian Koppelmann } else {
22289655b932SBastian Koppelmann result1 = (((uint32_t)(arg00 * arg10)) << n);
22299655b932SBastian Koppelmann }
22309655b932SBastian Koppelmann if (sc0) {
22319655b932SBastian Koppelmann result0 = 0x7fffffff;
22329655b932SBastian Koppelmann } else {
22339655b932SBastian Koppelmann result0 = (((uint32_t)(arg01 * arg11)) << n);
22349655b932SBastian Koppelmann }
22359be38598SEduardo Habkost return (((uint64_t)result1 << 32)) | result0;
22369655b932SBastian Koppelmann }
22379655b932SBastian Koppelmann
helper_mulm_h(uint32_t arg00,uint32_t arg01,uint32_t arg10,uint32_t arg11,uint32_t n)22389655b932SBastian Koppelmann uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
22399655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n)
22409655b932SBastian Koppelmann {
22419655b932SBastian Koppelmann uint64_t ret;
22429655b932SBastian Koppelmann int64_t result0, result1;
22439655b932SBastian Koppelmann
22449655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
22459655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1);
22469655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
22479655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1);
22489655b932SBastian Koppelmann
22499655b932SBastian Koppelmann if (sc1) {
22509655b932SBastian Koppelmann result1 = 0x7fffffff;
22519655b932SBastian Koppelmann } else {
22529655b932SBastian Koppelmann result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
22539655b932SBastian Koppelmann }
22549655b932SBastian Koppelmann if (sc0) {
22559655b932SBastian Koppelmann result0 = 0x7fffffff;
22569655b932SBastian Koppelmann } else {
22579655b932SBastian Koppelmann result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
22589655b932SBastian Koppelmann }
22599655b932SBastian Koppelmann ret = (result1 + result0);
22609655b932SBastian Koppelmann ret = ret << 16;
22619655b932SBastian Koppelmann return ret;
22629655b932SBastian Koppelmann }
helper_mulr_h(uint32_t arg00,uint32_t arg01,uint32_t arg10,uint32_t arg11,uint32_t n)22639655b932SBastian Koppelmann uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
22649655b932SBastian Koppelmann uint32_t arg10, uint32_t arg11, uint32_t n)
22659655b932SBastian Koppelmann {
22669655b932SBastian Koppelmann uint32_t result0, result1;
22679655b932SBastian Koppelmann
22689655b932SBastian Koppelmann int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
22699655b932SBastian Koppelmann ((arg10 & 0xffff) == 0x8000) && (n == 1);
22709655b932SBastian Koppelmann int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
22719655b932SBastian Koppelmann ((arg11 & 0xffff) == 0x8000) && (n == 1);
22729655b932SBastian Koppelmann
22739655b932SBastian Koppelmann if (sc1) {
22749655b932SBastian Koppelmann result1 = 0x7fffffff;
22759655b932SBastian Koppelmann } else {
22769655b932SBastian Koppelmann result1 = ((arg00 * arg10) << n) + 0x8000;
22779655b932SBastian Koppelmann }
22789655b932SBastian Koppelmann if (sc0) {
22799655b932SBastian Koppelmann result0 = 0x7fffffff;
22809655b932SBastian Koppelmann } else {
22819655b932SBastian Koppelmann result0 = ((arg01 * arg11) << n) + 0x8000;
22829655b932SBastian Koppelmann }
22839655b932SBastian Koppelmann return (result1 & 0xffff0000) | (result0 >> 16);
22849655b932SBastian Koppelmann }
22859655b932SBastian Koppelmann
helper_crc32b(uint32_t arg0,uint32_t arg1)22860eaafe33SBastian Koppelmann uint32_t helper_crc32b(uint32_t arg0, uint32_t arg1)
22870eaafe33SBastian Koppelmann {
22880eaafe33SBastian Koppelmann uint8_t buf[1] = { arg0 & 0xff };
22890eaafe33SBastian Koppelmann
22900eaafe33SBastian Koppelmann return crc32(arg1, buf, 1);
22910eaafe33SBastian Koppelmann }
22920eaafe33SBastian Koppelmann
22930eaafe33SBastian Koppelmann
helper_crc32_be(uint32_t arg0,uint32_t arg1)2294dc0b4368SBastian Koppelmann uint32_t helper_crc32_be(uint32_t arg0, uint32_t arg1)
2295e5c96c82SBastian Koppelmann {
2296e5c96c82SBastian Koppelmann uint8_t buf[4];
2297e5c96c82SBastian Koppelmann stl_be_p(buf, arg0);
2298e5c96c82SBastian Koppelmann
22999be38598SEduardo Habkost return crc32(arg1, buf, 4);
2300e5c96c82SBastian Koppelmann }
2301e5c96c82SBastian Koppelmann
helper_crc32_le(uint32_t arg0,uint32_t arg1)2302dc0b4368SBastian Koppelmann uint32_t helper_crc32_le(uint32_t arg0, uint32_t arg1)
2303dc0b4368SBastian Koppelmann {
2304dc0b4368SBastian Koppelmann uint8_t buf[4];
2305dc0b4368SBastian Koppelmann stl_le_p(buf, arg0);
2306dc0b4368SBastian Koppelmann
2307dc0b4368SBastian Koppelmann return crc32(arg1, buf, 4);
2308dc0b4368SBastian Koppelmann }
2309dc0b4368SBastian Koppelmann
crc_div(uint32_t crc_in,uint32_t data,uint32_t gen,uint32_t n,uint32_t m)23103e2a5107SBastian Koppelmann static uint32_t crc_div(uint32_t crc_in, uint32_t data, uint32_t gen,
23113e2a5107SBastian Koppelmann uint32_t n, uint32_t m)
23123e2a5107SBastian Koppelmann {
23133e2a5107SBastian Koppelmann uint32_t i;
23143e2a5107SBastian Koppelmann
23153e2a5107SBastian Koppelmann data = data << n;
23163e2a5107SBastian Koppelmann for (i = 0; i < m; i++) {
23173e2a5107SBastian Koppelmann if (crc_in & (1u << (n - 1))) {
23183e2a5107SBastian Koppelmann crc_in <<= 1;
23193e2a5107SBastian Koppelmann if (data & (1u << (m - 1))) {
23203e2a5107SBastian Koppelmann crc_in++;
23213e2a5107SBastian Koppelmann }
23223e2a5107SBastian Koppelmann crc_in ^= gen;
23233e2a5107SBastian Koppelmann } else {
23243e2a5107SBastian Koppelmann crc_in <<= 1;
23253e2a5107SBastian Koppelmann if (data & (1u << (m - 1))) {
23263e2a5107SBastian Koppelmann crc_in++;
23273e2a5107SBastian Koppelmann }
23283e2a5107SBastian Koppelmann }
23293e2a5107SBastian Koppelmann data <<= 1;
23303e2a5107SBastian Koppelmann }
23313e2a5107SBastian Koppelmann
23323e2a5107SBastian Koppelmann return crc_in;
23333e2a5107SBastian Koppelmann }
23343e2a5107SBastian Koppelmann
helper_crcn(uint32_t arg0,uint32_t arg1,uint32_t arg2)23353e2a5107SBastian Koppelmann uint32_t helper_crcn(uint32_t arg0, uint32_t arg1, uint32_t arg2)
23363e2a5107SBastian Koppelmann {
23373e2a5107SBastian Koppelmann uint32_t crc_out, crc_in;
23383e2a5107SBastian Koppelmann uint32_t n = extract32(arg0, 12, 4) + 1;
23393e2a5107SBastian Koppelmann uint32_t gen = extract32(arg0, 16, n);
23403e2a5107SBastian Koppelmann uint32_t inv = extract32(arg0, 9, 1);
23413e2a5107SBastian Koppelmann uint32_t le = extract32(arg0, 8, 1);
23423e2a5107SBastian Koppelmann uint32_t m = extract32(arg0, 0, 3) + 1;
23433e2a5107SBastian Koppelmann uint32_t data = extract32(arg1, 0, m);
23443e2a5107SBastian Koppelmann uint32_t seed = extract32(arg2, 0, n);
23453e2a5107SBastian Koppelmann
23463e2a5107SBastian Koppelmann if (le == 1) {
23473e2a5107SBastian Koppelmann if (m == 0) {
23483e2a5107SBastian Koppelmann data = 0;
23493e2a5107SBastian Koppelmann } else {
23503e2a5107SBastian Koppelmann data = revbit32(data) >> (32 - m);
23513e2a5107SBastian Koppelmann }
23523e2a5107SBastian Koppelmann }
23533e2a5107SBastian Koppelmann
23543e2a5107SBastian Koppelmann if (inv == 1) {
23553e2a5107SBastian Koppelmann seed = ~seed;
23563e2a5107SBastian Koppelmann }
23573e2a5107SBastian Koppelmann
23583e2a5107SBastian Koppelmann if (m > n) {
23593e2a5107SBastian Koppelmann crc_in = (data >> (m - n)) ^ seed;
23603e2a5107SBastian Koppelmann } else {
23613e2a5107SBastian Koppelmann crc_in = (data << (n - m)) ^ seed;
23623e2a5107SBastian Koppelmann }
23633e2a5107SBastian Koppelmann
23643e2a5107SBastian Koppelmann crc_out = crc_div(crc_in, data, gen, n, m);
23653e2a5107SBastian Koppelmann
23663e2a5107SBastian Koppelmann if (inv) {
23673e2a5107SBastian Koppelmann crc_out = ~crc_out;
23683e2a5107SBastian Koppelmann }
23693e2a5107SBastian Koppelmann
23703e2a5107SBastian Koppelmann return extract32(crc_out, 0, n);
23713e2a5107SBastian Koppelmann }
23723e2a5107SBastian Koppelmann
helper_shuffle(uint32_t arg0,uint32_t arg1)23734e3377bbSBastian Koppelmann uint32_t helper_shuffle(uint32_t arg0, uint32_t arg1)
23744e3377bbSBastian Koppelmann {
23754e3377bbSBastian Koppelmann uint32_t resb;
23764e3377bbSBastian Koppelmann uint32_t byte_select;
23774e3377bbSBastian Koppelmann uint32_t res = 0;
23784e3377bbSBastian Koppelmann
23794e3377bbSBastian Koppelmann byte_select = arg1 & 0x3;
23804e3377bbSBastian Koppelmann resb = extract32(arg0, byte_select * 8, 8);
23814e3377bbSBastian Koppelmann res |= resb << 0;
23824e3377bbSBastian Koppelmann
23834e3377bbSBastian Koppelmann byte_select = (arg1 >> 2) & 0x3;
23844e3377bbSBastian Koppelmann resb = extract32(arg0, byte_select * 8, 8);
23854e3377bbSBastian Koppelmann res |= resb << 8;
23864e3377bbSBastian Koppelmann
23874e3377bbSBastian Koppelmann byte_select = (arg1 >> 4) & 0x3;
23884e3377bbSBastian Koppelmann resb = extract32(arg0, byte_select * 8, 8);
23894e3377bbSBastian Koppelmann res |= resb << 16;
23904e3377bbSBastian Koppelmann
23914e3377bbSBastian Koppelmann byte_select = (arg1 >> 6) & 0x3;
23924e3377bbSBastian Koppelmann resb = extract32(arg0, byte_select * 8, 8);
23934e3377bbSBastian Koppelmann res |= resb << 24;
23944e3377bbSBastian Koppelmann
23954e3377bbSBastian Koppelmann if (arg1 & 0x100) {
23964e3377bbSBastian Koppelmann /* Assign the correct nibble position. */
23974e3377bbSBastian Koppelmann res = ((res & 0xf0f0f0f0) >> 4)
23984e3377bbSBastian Koppelmann | ((res & 0x0f0f0f0f) << 4);
23994e3377bbSBastian Koppelmann /* Assign the correct bit position. */
24004e3377bbSBastian Koppelmann res = ((res & 0x88888888) >> 3)
24014e3377bbSBastian Koppelmann | ((res & 0x44444444) >> 1)
24024e3377bbSBastian Koppelmann | ((res & 0x22222222) << 1)
24034e3377bbSBastian Koppelmann | ((res & 0x11111111) << 3);
24044e3377bbSBastian Koppelmann }
24054e3377bbSBastian Koppelmann
24064e3377bbSBastian Koppelmann return res;
24074e3377bbSBastian Koppelmann }
24084e3377bbSBastian Koppelmann
24099a31922bSBastian Koppelmann /* context save area (CSA) related helpers */
24109a31922bSBastian Koppelmann
cdc_increment(target_ulong * psw)24119a31922bSBastian Koppelmann static int cdc_increment(target_ulong *psw)
24129a31922bSBastian Koppelmann {
24139a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) {
24149a31922bSBastian Koppelmann return 0;
24159a31922bSBastian Koppelmann }
24169a31922bSBastian Koppelmann
24179a31922bSBastian Koppelmann (*psw)++;
24189a31922bSBastian Koppelmann /* check for overflow */
24199a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
24209a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1;
24219a31922bSBastian Koppelmann int count = *psw & mask;
24229a31922bSBastian Koppelmann if (count == 0) {
24239a31922bSBastian Koppelmann (*psw)--;
24249a31922bSBastian Koppelmann return 1;
24259a31922bSBastian Koppelmann }
24269a31922bSBastian Koppelmann return 0;
24279a31922bSBastian Koppelmann }
24289a31922bSBastian Koppelmann
cdc_decrement(target_ulong * psw)24299a31922bSBastian Koppelmann static int cdc_decrement(target_ulong *psw)
24309a31922bSBastian Koppelmann {
24319a31922bSBastian Koppelmann if ((*psw & MASK_PSW_CDC) == 0x7f) {
24329a31922bSBastian Koppelmann return 0;
24339a31922bSBastian Koppelmann }
24349a31922bSBastian Koppelmann /* check for underflow */
24359a31922bSBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
24369a31922bSBastian Koppelmann int mask = (1u << (7 - lo)) - 1;
24379a31922bSBastian Koppelmann int count = *psw & mask;
24389a31922bSBastian Koppelmann if (count == 0) {
24399a31922bSBastian Koppelmann return 1;
24409a31922bSBastian Koppelmann }
24419a31922bSBastian Koppelmann (*psw)--;
24429a31922bSBastian Koppelmann return 0;
24439a31922bSBastian Koppelmann }
24449a31922bSBastian Koppelmann
cdc_zero(target_ulong * psw)244544ea3430SBastian Koppelmann static bool cdc_zero(target_ulong *psw)
244644ea3430SBastian Koppelmann {
244744ea3430SBastian Koppelmann int cdc = *psw & MASK_PSW_CDC;
244844ea3430SBastian Koppelmann /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
244944ea3430SBastian Koppelmann 7'b1111111, otherwise returns FALSE. */
245044ea3430SBastian Koppelmann if (cdc == 0x7f) {
245144ea3430SBastian Koppelmann return true;
245244ea3430SBastian Koppelmann }
245344ea3430SBastian Koppelmann /* find CDC.COUNT */
245444ea3430SBastian Koppelmann int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
245544ea3430SBastian Koppelmann int mask = (1u << (7 - lo)) - 1;
245644ea3430SBastian Koppelmann int count = *psw & mask;
245744ea3430SBastian Koppelmann return count == 0;
245844ea3430SBastian Koppelmann }
245944ea3430SBastian Koppelmann
save_context_upper(CPUTriCoreState * env,target_ulong ea)2460ceada000SBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, target_ulong ea)
24619a31922bSBastian Koppelmann {
24629a31922bSBastian Koppelmann cpu_stl_data(env, ea, env->PCXI);
246372373357SBastian Koppelmann cpu_stl_data(env, ea+4, psw_read(env));
24649a31922bSBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[10]);
24659a31922bSBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[11]);
24669a31922bSBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[8]);
24679a31922bSBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[9]);
24689a31922bSBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[10]);
24699a31922bSBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[11]);
24709a31922bSBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[12]);
24719a31922bSBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[13]);
24729a31922bSBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[14]);
24739a31922bSBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[15]);
24749a31922bSBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[12]);
24759a31922bSBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[13]);
24769a31922bSBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[14]);
24779a31922bSBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[15]);
24789a31922bSBastian Koppelmann }
24799a31922bSBastian Koppelmann
save_context_lower(CPUTriCoreState * env,target_ulong ea)2480ceada000SBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, target_ulong ea)
24815de93515SBastian Koppelmann {
24825de93515SBastian Koppelmann cpu_stl_data(env, ea, env->PCXI);
2483030c58dfSBastian Koppelmann cpu_stl_data(env, ea+4, env->gpr_a[11]);
24845de93515SBastian Koppelmann cpu_stl_data(env, ea+8, env->gpr_a[2]);
24855de93515SBastian Koppelmann cpu_stl_data(env, ea+12, env->gpr_a[3]);
24865de93515SBastian Koppelmann cpu_stl_data(env, ea+16, env->gpr_d[0]);
24875de93515SBastian Koppelmann cpu_stl_data(env, ea+20, env->gpr_d[1]);
24885de93515SBastian Koppelmann cpu_stl_data(env, ea+24, env->gpr_d[2]);
24895de93515SBastian Koppelmann cpu_stl_data(env, ea+28, env->gpr_d[3]);
24905de93515SBastian Koppelmann cpu_stl_data(env, ea+32, env->gpr_a[4]);
24915de93515SBastian Koppelmann cpu_stl_data(env, ea+36, env->gpr_a[5]);
24925de93515SBastian Koppelmann cpu_stl_data(env, ea+40, env->gpr_a[6]);
24935de93515SBastian Koppelmann cpu_stl_data(env, ea+44, env->gpr_a[7]);
24945de93515SBastian Koppelmann cpu_stl_data(env, ea+48, env->gpr_d[4]);
24955de93515SBastian Koppelmann cpu_stl_data(env, ea+52, env->gpr_d[5]);
24965de93515SBastian Koppelmann cpu_stl_data(env, ea+56, env->gpr_d[6]);
24975de93515SBastian Koppelmann cpu_stl_data(env, ea+60, env->gpr_d[7]);
24985de93515SBastian Koppelmann }
24995de93515SBastian Koppelmann
restore_context_upper(CPUTriCoreState * env,target_ulong ea,target_ulong * new_PCXI,target_ulong * new_PSW)2500ceada000SBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, target_ulong ea,
25019a31922bSBastian Koppelmann target_ulong *new_PCXI, target_ulong *new_PSW)
25029a31922bSBastian Koppelmann {
25039a31922bSBastian Koppelmann *new_PCXI = cpu_ldl_data(env, ea);
25049a31922bSBastian Koppelmann *new_PSW = cpu_ldl_data(env, ea+4);
25059a31922bSBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, ea+8);
25069a31922bSBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, ea+12);
25079a31922bSBastian Koppelmann env->gpr_d[8] = cpu_ldl_data(env, ea+16);
25089a31922bSBastian Koppelmann env->gpr_d[9] = cpu_ldl_data(env, ea+20);
25099a31922bSBastian Koppelmann env->gpr_d[10] = cpu_ldl_data(env, ea+24);
25109a31922bSBastian Koppelmann env->gpr_d[11] = cpu_ldl_data(env, ea+28);
25119a31922bSBastian Koppelmann env->gpr_a[12] = cpu_ldl_data(env, ea+32);
25129a31922bSBastian Koppelmann env->gpr_a[13] = cpu_ldl_data(env, ea+36);
25139a31922bSBastian Koppelmann env->gpr_a[14] = cpu_ldl_data(env, ea+40);
25149a31922bSBastian Koppelmann env->gpr_a[15] = cpu_ldl_data(env, ea+44);
25159a31922bSBastian Koppelmann env->gpr_d[12] = cpu_ldl_data(env, ea+48);
25169a31922bSBastian Koppelmann env->gpr_d[13] = cpu_ldl_data(env, ea+52);
25179a31922bSBastian Koppelmann env->gpr_d[14] = cpu_ldl_data(env, ea+56);
25189a31922bSBastian Koppelmann env->gpr_d[15] = cpu_ldl_data(env, ea+60);
25199a31922bSBastian Koppelmann }
25209a31922bSBastian Koppelmann
restore_context_lower(CPUTriCoreState * env,target_ulong ea,target_ulong * ra,target_ulong * pcxi)2521ceada000SBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, target_ulong ea,
252259543d4eSBastian Koppelmann target_ulong *ra, target_ulong *pcxi)
252359543d4eSBastian Koppelmann {
252459543d4eSBastian Koppelmann *pcxi = cpu_ldl_data(env, ea);
252559543d4eSBastian Koppelmann *ra = cpu_ldl_data(env, ea+4);
252659543d4eSBastian Koppelmann env->gpr_a[2] = cpu_ldl_data(env, ea+8);
252759543d4eSBastian Koppelmann env->gpr_a[3] = cpu_ldl_data(env, ea+12);
252859543d4eSBastian Koppelmann env->gpr_d[0] = cpu_ldl_data(env, ea+16);
252959543d4eSBastian Koppelmann env->gpr_d[1] = cpu_ldl_data(env, ea+20);
253059543d4eSBastian Koppelmann env->gpr_d[2] = cpu_ldl_data(env, ea+24);
253159543d4eSBastian Koppelmann env->gpr_d[3] = cpu_ldl_data(env, ea+28);
253259543d4eSBastian Koppelmann env->gpr_a[4] = cpu_ldl_data(env, ea+32);
253359543d4eSBastian Koppelmann env->gpr_a[5] = cpu_ldl_data(env, ea+36);
253459543d4eSBastian Koppelmann env->gpr_a[6] = cpu_ldl_data(env, ea+40);
253559543d4eSBastian Koppelmann env->gpr_a[7] = cpu_ldl_data(env, ea+44);
253659543d4eSBastian Koppelmann env->gpr_d[4] = cpu_ldl_data(env, ea+48);
253759543d4eSBastian Koppelmann env->gpr_d[5] = cpu_ldl_data(env, ea+52);
253859543d4eSBastian Koppelmann env->gpr_d[6] = cpu_ldl_data(env, ea+56);
253959543d4eSBastian Koppelmann env->gpr_d[7] = cpu_ldl_data(env, ea+60);
254059543d4eSBastian Koppelmann }
254159543d4eSBastian Koppelmann
helper_call(CPUTriCoreState * env,uint32_t next_pc)25429a31922bSBastian Koppelmann void helper_call(CPUTriCoreState *env, uint32_t next_pc)
25439a31922bSBastian Koppelmann {
25449a31922bSBastian Koppelmann target_ulong tmp_FCX;
25459a31922bSBastian Koppelmann target_ulong ea;
25469a31922bSBastian Koppelmann target_ulong new_FCX;
25479a31922bSBastian Koppelmann target_ulong psw;
25489a31922bSBastian Koppelmann
25499a31922bSBastian Koppelmann psw = psw_read(env);
25509a31922bSBastian Koppelmann /* if (FCX == 0) trap(FCU); */
25519a31922bSBastian Koppelmann if (env->FCX == 0) {
25529a31922bSBastian Koppelmann /* FCU trap */
25533292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
25549a31922bSBastian Koppelmann }
25559a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
25569a31922bSBastian Koppelmann if (psw & MASK_PSW_CDE) {
25579a31922bSBastian Koppelmann if (cdc_increment(&psw)) {
25589a31922bSBastian Koppelmann /* CDO trap */
25593292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC());
25609a31922bSBastian Koppelmann }
25619a31922bSBastian Koppelmann }
25629a31922bSBastian Koppelmann /* PSW.CDE = 1;*/
25639a31922bSBastian Koppelmann psw |= MASK_PSW_CDE;
25645434557fSBastian Koppelmann /*
25655434557fSBastian Koppelmann * we need to save PSW.CDE and not PSW.CDC into the CSAs. psw already
25665434557fSBastian Koppelmann * contains the CDC from cdc_increment(), so we cannot call psw_write()
25675434557fSBastian Koppelmann * here.
25685434557fSBastian Koppelmann */
25695434557fSBastian Koppelmann env->PSW |= MASK_PSW_CDE;
257012b95dc4SBastian Koppelmann
25719a31922bSBastian Koppelmann /* tmp_FCX = FCX; */
25729a31922bSBastian Koppelmann tmp_FCX = env->FCX;
25739a31922bSBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
25749a31922bSBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
25759a31922bSBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6);
2576030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */
2577030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea);
2578030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
25799a31922bSBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14],
25809a31922bSBastian Koppelmann D[15]}; */
2581030c58dfSBastian Koppelmann save_context_upper(env, ea);
25829a31922bSBastian Koppelmann
25839a31922bSBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */
2584343cdf2cSBastian Koppelmann pcxi_set_pcpn(env, icr_get_ccpn(env));
25859a31922bSBastian Koppelmann /* PCXI.PIE = ICR.IE; */
2586343cdf2cSBastian Koppelmann pcxi_set_pie(env, icr_get_ie(env));
25879a31922bSBastian Koppelmann /* PCXI.UL = 1; */
2588343cdf2cSBastian Koppelmann pcxi_set_ul(env, 1);
25899a31922bSBastian Koppelmann
25909a31922bSBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */
25919a31922bSBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
25929a31922bSBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */
25939a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
25949a31922bSBastian Koppelmann /* A[11] = next_pc[31: 0]; */
25959a31922bSBastian Koppelmann env->gpr_a[11] = next_pc;
25969a31922bSBastian Koppelmann
25979a31922bSBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/
25989a31922bSBastian Koppelmann if (tmp_FCX == env->LCX) {
25999a31922bSBastian Koppelmann /* FCD trap */
26003292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
26019a31922bSBastian Koppelmann }
26029a31922bSBastian Koppelmann psw_write(env, psw);
26039a31922bSBastian Koppelmann }
26049a31922bSBastian Koppelmann
helper_ret(CPUTriCoreState * env)26059a31922bSBastian Koppelmann void helper_ret(CPUTriCoreState *env)
26069a31922bSBastian Koppelmann {
26079a31922bSBastian Koppelmann target_ulong ea;
26089a31922bSBastian Koppelmann target_ulong new_PCXI;
26099a31922bSBastian Koppelmann target_ulong new_PSW, psw;
26109a31922bSBastian Koppelmann
26119a31922bSBastian Koppelmann psw = psw_read(env);
26129a31922bSBastian Koppelmann /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
26133292b447SBastian Koppelmann if (psw & MASK_PSW_CDE) {
26143292b447SBastian Koppelmann if (cdc_decrement(&psw)) {
26159a31922bSBastian Koppelmann /* CDU trap */
26163292b447SBastian Koppelmann psw_write(env, psw);
26173292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC());
26189a31922bSBastian Koppelmann }
26199a31922bSBastian Koppelmann }
26209a31922bSBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */
26219a31922bSBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) {
26229a31922bSBastian Koppelmann /* CSU trap */
26233292b447SBastian Koppelmann psw_write(env, psw);
26243292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
26259a31922bSBastian Koppelmann }
26269a31922bSBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */
2627343cdf2cSBastian Koppelmann if (pcxi_get_ul(env) == 0) {
26289a31922bSBastian Koppelmann /* CTYP trap */
26293292b447SBastian Koppelmann cdc_increment(&psw); /* restore to the start of helper */
26303292b447SBastian Koppelmann psw_write(env, psw);
26313292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
26329a31922bSBastian Koppelmann }
26339a31922bSBastian Koppelmann /* PC = {A11 [31: 1], 1’b0}; */
26349a31922bSBastian Koppelmann env->PC = env->gpr_a[11] & 0xfffffffe;
26359a31922bSBastian Koppelmann
26369a31922bSBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2637343cdf2cSBastian Koppelmann ea = (pcxi_get_pcxs(env) << 28) |
2638343cdf2cSBastian Koppelmann (pcxi_get_pcxo(env) << 6);
26399a31922bSBastian Koppelmann /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2640030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
26419a31922bSBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2642030c58dfSBastian Koppelmann /* M(EA, word) = FCX; */
2643030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX);
26449a31922bSBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */
26459a31922bSBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
26469a31922bSBastian Koppelmann /* PCXI = new_PCXI; */
26479a31922bSBastian Koppelmann env->PCXI = new_PCXI;
26489a31922bSBastian Koppelmann
2649f8cfdd20SBastian Koppelmann if (tricore_has_feature(env, TRICORE_FEATURE_131)) {
26509a31922bSBastian Koppelmann /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
26519a31922bSBastian Koppelmann psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
265282736612SBastian Koppelmann } else { /* TRICORE_FEATURE_13 only */
265382736612SBastian Koppelmann /* PSW = new_PSW */
265482736612SBastian Koppelmann psw_write(env, new_PSW);
26559a31922bSBastian Koppelmann }
26569a31922bSBastian Koppelmann }
26579a31922bSBastian Koppelmann
helper_bisr(CPUTriCoreState * env,uint32_t const9)26585de93515SBastian Koppelmann void helper_bisr(CPUTriCoreState *env, uint32_t const9)
26595de93515SBastian Koppelmann {
26605de93515SBastian Koppelmann target_ulong tmp_FCX;
26615de93515SBastian Koppelmann target_ulong ea;
26625de93515SBastian Koppelmann target_ulong new_FCX;
26635de93515SBastian Koppelmann
26645de93515SBastian Koppelmann if (env->FCX == 0) {
26655de93515SBastian Koppelmann /* FCU trap */
26663292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
26675de93515SBastian Koppelmann }
26685de93515SBastian Koppelmann
26695de93515SBastian Koppelmann tmp_FCX = env->FCX;
26705de93515SBastian Koppelmann ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
26715de93515SBastian Koppelmann
2672030c58dfSBastian Koppelmann /* new_FCX = M(EA, word); */
2673030c58dfSBastian Koppelmann new_FCX = cpu_ldl_data(env, ea);
2674030c58dfSBastian Koppelmann /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2675030c58dfSBastian Koppelmann , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2676030c58dfSBastian Koppelmann save_context_lower(env, ea);
2677030c58dfSBastian Koppelmann
26785de93515SBastian Koppelmann
26795de93515SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN */
2680343cdf2cSBastian Koppelmann pcxi_set_pcpn(env, icr_get_ccpn(env));
26815de93515SBastian Koppelmann /* PCXI.PIE = ICR.IE */
2682343cdf2cSBastian Koppelmann pcxi_set_pie(env, icr_get_ie(env));
26835de93515SBastian Koppelmann /* PCXI.UL = 0 */
2684343cdf2cSBastian Koppelmann pcxi_set_ul(env, 0);
2685343cdf2cSBastian Koppelmann
26865de93515SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0] */
26875de93515SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
26885de93515SBastian Koppelmann /* FXC[19: 0] = new_FCX[19: 0] */
26895de93515SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
26905de93515SBastian Koppelmann
2691343cdf2cSBastian Koppelmann /* ICR.IE = 1 */
2692343cdf2cSBastian Koppelmann icr_set_ie(env, 1);
2693343cdf2cSBastian Koppelmann
2694343cdf2cSBastian Koppelmann icr_set_ccpn(env, const9);
26955de93515SBastian Koppelmann
26965de93515SBastian Koppelmann if (tmp_FCX == env->LCX) {
26975de93515SBastian Koppelmann /* FCD trap */
26983292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
26995de93515SBastian Koppelmann }
27005de93515SBastian Koppelmann }
27015de93515SBastian Koppelmann
helper_rfe(CPUTriCoreState * env)270244ea3430SBastian Koppelmann void helper_rfe(CPUTriCoreState *env)
270344ea3430SBastian Koppelmann {
270444ea3430SBastian Koppelmann target_ulong ea;
270544ea3430SBastian Koppelmann target_ulong new_PCXI;
270644ea3430SBastian Koppelmann target_ulong new_PSW;
270744ea3430SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */
270844ea3430SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) {
270944ea3430SBastian Koppelmann /* raise csu trap */
27103292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
271144ea3430SBastian Koppelmann }
271244ea3430SBastian Koppelmann /* if (PCXI.UL == 0) then trap(CTYP); */
2713343cdf2cSBastian Koppelmann if (pcxi_get_ul(env) == 0) {
271444ea3430SBastian Koppelmann /* raise CTYP trap */
27153292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
271644ea3430SBastian Koppelmann }
271744ea3430SBastian Koppelmann /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
271844ea3430SBastian Koppelmann if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
27193292b447SBastian Koppelmann /* raise NEST trap */
27203292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC());
272144ea3430SBastian Koppelmann }
27223446a111SBastian Koppelmann env->PC = env->gpr_a[11] & ~0x1;
272344ea3430SBastian Koppelmann /* ICR.IE = PCXI.PIE; */
2724343cdf2cSBastian Koppelmann icr_set_ie(env, pcxi_get_pie(env));
2725343cdf2cSBastian Koppelmann
272644ea3430SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */
2727343cdf2cSBastian Koppelmann icr_set_ccpn(env, pcxi_get_pcpn(env));
2728343cdf2cSBastian Koppelmann
272944ea3430SBastian Koppelmann /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
2730343cdf2cSBastian Koppelmann ea = (pcxi_get_pcxs(env) << 28) |
2731343cdf2cSBastian Koppelmann (pcxi_get_pcxo(env) << 6);
2732343cdf2cSBastian Koppelmann
273344ea3430SBastian Koppelmann /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2734030c58dfSBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
273544ea3430SBastian Koppelmann restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2736030c58dfSBastian Koppelmann /* M(EA, word) = FCX;*/
2737030c58dfSBastian Koppelmann cpu_stl_data(env, ea, env->FCX);
273844ea3430SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */
273944ea3430SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
274044ea3430SBastian Koppelmann /* PCXI = new_PCXI; */
274144ea3430SBastian Koppelmann env->PCXI = new_PCXI;
274244ea3430SBastian Koppelmann /* write psw */
274344ea3430SBastian Koppelmann psw_write(env, new_PSW);
274444ea3430SBastian Koppelmann }
274544ea3430SBastian Koppelmann
helper_rfm(CPUTriCoreState * env)2746b724b012SBastian Koppelmann void helper_rfm(CPUTriCoreState *env)
2747b724b012SBastian Koppelmann {
2748b724b012SBastian Koppelmann env->PC = (env->gpr_a[11] & ~0x1);
2749b724b012SBastian Koppelmann /* ICR.IE = PCXI.PIE; */
2750343cdf2cSBastian Koppelmann icr_set_ie(env, pcxi_get_pie(env));
2751b724b012SBastian Koppelmann /* ICR.CCPN = PCXI.PCPN; */
2752343cdf2cSBastian Koppelmann icr_set_ccpn(env, pcxi_get_pcpn(env));
2753343cdf2cSBastian Koppelmann
2754b724b012SBastian Koppelmann /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */
2755b724b012SBastian Koppelmann env->PCXI = cpu_ldl_data(env, env->DCX);
2756b724b012SBastian Koppelmann psw_write(env, cpu_ldl_data(env, env->DCX+4));
2757b724b012SBastian Koppelmann env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
2758b724b012SBastian Koppelmann env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
2759b724b012SBastian Koppelmann
2760f8cfdd20SBastian Koppelmann if (tricore_has_feature(env, TRICORE_FEATURE_131)) {
2761b724b012SBastian Koppelmann env->DBGTCR = 0;
2762b724b012SBastian Koppelmann }
2763b724b012SBastian Koppelmann }
2764b724b012SBastian Koppelmann
helper_ldlcx(CPUTriCoreState * env,target_ulong ea)2765ceada000SBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, target_ulong ea)
276659543d4eSBastian Koppelmann {
276759543d4eSBastian Koppelmann uint32_t dummy;
276859543d4eSBastian Koppelmann /* insn doesn't load PCXI and RA */
276959543d4eSBastian Koppelmann restore_context_lower(env, ea, &dummy, &dummy);
277059543d4eSBastian Koppelmann }
277159543d4eSBastian Koppelmann
helper_lducx(CPUTriCoreState * env,target_ulong ea)2772ceada000SBastian Koppelmann void helper_lducx(CPUTriCoreState *env, target_ulong ea)
277359543d4eSBastian Koppelmann {
277459543d4eSBastian Koppelmann uint32_t dummy;
277559543d4eSBastian Koppelmann /* insn doesn't load PCXI and PSW */
277659543d4eSBastian Koppelmann restore_context_upper(env, ea, &dummy, &dummy);
277759543d4eSBastian Koppelmann }
277859543d4eSBastian Koppelmann
helper_stlcx(CPUTriCoreState * env,target_ulong ea)2779ceada000SBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, target_ulong ea)
278059543d4eSBastian Koppelmann {
278159543d4eSBastian Koppelmann save_context_lower(env, ea);
278259543d4eSBastian Koppelmann }
278359543d4eSBastian Koppelmann
helper_stucx(CPUTriCoreState * env,target_ulong ea)2784ceada000SBastian Koppelmann void helper_stucx(CPUTriCoreState *env, target_ulong ea)
278559543d4eSBastian Koppelmann {
278659543d4eSBastian Koppelmann save_context_upper(env, ea);
278759543d4eSBastian Koppelmann }
278859543d4eSBastian Koppelmann
helper_svlcx(CPUTriCoreState * env)2789b724b012SBastian Koppelmann void helper_svlcx(CPUTriCoreState *env)
2790b724b012SBastian Koppelmann {
2791b724b012SBastian Koppelmann target_ulong tmp_FCX;
2792b724b012SBastian Koppelmann target_ulong ea;
2793b724b012SBastian Koppelmann target_ulong new_FCX;
2794b724b012SBastian Koppelmann
2795b724b012SBastian Koppelmann if (env->FCX == 0) {
2796b724b012SBastian Koppelmann /* FCU trap */
27973292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2798b724b012SBastian Koppelmann }
2799b724b012SBastian Koppelmann /* tmp_FCX = FCX; */
2800b724b012SBastian Koppelmann tmp_FCX = env->FCX;
2801b724b012SBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2802b724b012SBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2803b724b012SBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6);
2804b724b012SBastian Koppelmann /* new_FCX = M(EA, word); */
2805b724b012SBastian Koppelmann new_FCX = cpu_ldl_data(env, ea);
2806b724b012SBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2807b724b012SBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2808b724b012SBastian Koppelmann D[15]}; */
2809b724b012SBastian Koppelmann save_context_lower(env, ea);
2810b724b012SBastian Koppelmann
2811b724b012SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */
2812343cdf2cSBastian Koppelmann pcxi_set_pcpn(env, icr_get_ccpn(env));
2813343cdf2cSBastian Koppelmann
2814b724b012SBastian Koppelmann /* PCXI.PIE = ICR.IE; */
2815343cdf2cSBastian Koppelmann pcxi_set_pie(env, icr_get_ie(env));
2816343cdf2cSBastian Koppelmann
2817b724b012SBastian Koppelmann /* PCXI.UL = 0; */
2818343cdf2cSBastian Koppelmann pcxi_set_ul(env, 0);
2819b724b012SBastian Koppelmann
2820b724b012SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */
2821b724b012SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2822b724b012SBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */
2823b724b012SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2824b724b012SBastian Koppelmann
2825b724b012SBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/
2826b724b012SBastian Koppelmann if (tmp_FCX == env->LCX) {
2827b724b012SBastian Koppelmann /* FCD trap */
28283292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2829b724b012SBastian Koppelmann }
2830b724b012SBastian Koppelmann }
2831b724b012SBastian Koppelmann
helper_svucx(CPUTriCoreState * env)2832518d7fd2SBastian Koppelmann void helper_svucx(CPUTriCoreState *env)
2833518d7fd2SBastian Koppelmann {
2834518d7fd2SBastian Koppelmann target_ulong tmp_FCX;
2835518d7fd2SBastian Koppelmann target_ulong ea;
2836518d7fd2SBastian Koppelmann target_ulong new_FCX;
2837518d7fd2SBastian Koppelmann
2838518d7fd2SBastian Koppelmann if (env->FCX == 0) {
2839518d7fd2SBastian Koppelmann /* FCU trap */
28403292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2841518d7fd2SBastian Koppelmann }
2842518d7fd2SBastian Koppelmann /* tmp_FCX = FCX; */
2843518d7fd2SBastian Koppelmann tmp_FCX = env->FCX;
2844518d7fd2SBastian Koppelmann /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2845518d7fd2SBastian Koppelmann ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2846518d7fd2SBastian Koppelmann ((env->FCX & MASK_FCX_FCXO) << 6);
2847518d7fd2SBastian Koppelmann /* new_FCX = M(EA, word); */
2848518d7fd2SBastian Koppelmann new_FCX = cpu_ldl_data(env, ea);
2849518d7fd2SBastian Koppelmann /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2850518d7fd2SBastian Koppelmann A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2851518d7fd2SBastian Koppelmann D[15]}; */
2852518d7fd2SBastian Koppelmann save_context_upper(env, ea);
2853518d7fd2SBastian Koppelmann
2854518d7fd2SBastian Koppelmann /* PCXI.PCPN = ICR.CCPN; */
2855343cdf2cSBastian Koppelmann pcxi_set_pcpn(env, icr_get_ccpn(env));
2856343cdf2cSBastian Koppelmann
2857518d7fd2SBastian Koppelmann /* PCXI.PIE = ICR.IE; */
2858343cdf2cSBastian Koppelmann pcxi_set_pie(env, icr_get_ie(env));
2859343cdf2cSBastian Koppelmann
2860518d7fd2SBastian Koppelmann /* PCXI.UL = 1; */
2861343cdf2cSBastian Koppelmann pcxi_set_ul(env, 1);
2862518d7fd2SBastian Koppelmann
2863518d7fd2SBastian Koppelmann /* PCXI[19: 0] = FCX[19: 0]; */
2864518d7fd2SBastian Koppelmann env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2865518d7fd2SBastian Koppelmann /* FCX[19: 0] = new_FCX[19: 0]; */
2866518d7fd2SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2867518d7fd2SBastian Koppelmann
2868518d7fd2SBastian Koppelmann /* if (tmp_FCX == LCX) trap(FCD);*/
2869518d7fd2SBastian Koppelmann if (tmp_FCX == env->LCX) {
2870518d7fd2SBastian Koppelmann /* FCD trap */
28713292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2872518d7fd2SBastian Koppelmann }
2873518d7fd2SBastian Koppelmann }
2874518d7fd2SBastian Koppelmann
helper_rslcx(CPUTriCoreState * env)2875b724b012SBastian Koppelmann void helper_rslcx(CPUTriCoreState *env)
2876b724b012SBastian Koppelmann {
2877b724b012SBastian Koppelmann target_ulong ea;
2878b724b012SBastian Koppelmann target_ulong new_PCXI;
2879b724b012SBastian Koppelmann /* if (PCXI[19: 0] == 0) then trap(CSU); */
2880b724b012SBastian Koppelmann if ((env->PCXI & 0xfffff) == 0) {
2881b724b012SBastian Koppelmann /* CSU trap */
28823292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2883b724b012SBastian Koppelmann }
2884b724b012SBastian Koppelmann /* if (PCXI.UL == 1) then trap(CTYP); */
2885343cdf2cSBastian Koppelmann if (pcxi_get_ul(env) == 1) {
2886b724b012SBastian Koppelmann /* CTYP trap */
28873292b447SBastian Koppelmann raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2888b724b012SBastian Koppelmann }
2889b724b012SBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2890343cdf2cSBastian Koppelmann /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2891343cdf2cSBastian Koppelmann ea = (pcxi_get_pcxs(env) << 28) |
2892343cdf2cSBastian Koppelmann (pcxi_get_pcxo(env) << 6);
2893343cdf2cSBastian Koppelmann
2894b724b012SBastian Koppelmann /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2895b724b012SBastian Koppelmann A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2896bc72f8aaSBastian Koppelmann restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI);
2897b724b012SBastian Koppelmann /* M(EA, word) = FCX; */
2898b724b012SBastian Koppelmann cpu_stl_data(env, ea, env->FCX);
2899b724b012SBastian Koppelmann /* M(EA, word) = FCX; */
2900b724b012SBastian Koppelmann cpu_stl_data(env, ea, env->FCX);
2901b724b012SBastian Koppelmann /* FCX[19: 0] = PCXI[19: 0]; */
2902b724b012SBastian Koppelmann env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2903b724b012SBastian Koppelmann /* PCXI = new_PCXI; */
2904b724b012SBastian Koppelmann env->PCXI = new_PCXI;
2905b724b012SBastian Koppelmann }
2906b724b012SBastian Koppelmann
helper_psw_write(CPUTriCoreState * env,uint32_t arg)29072b2f7d97SBastian Koppelmann void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
29082b2f7d97SBastian Koppelmann {
29092b2f7d97SBastian Koppelmann psw_write(env, arg);
29102b2f7d97SBastian Koppelmann }
29112b2f7d97SBastian Koppelmann
helper_psw_read(CPUTriCoreState * env)29122b2f7d97SBastian Koppelmann uint32_t helper_psw_read(CPUTriCoreState *env)
29132b2f7d97SBastian Koppelmann {
29142b2f7d97SBastian Koppelmann return psw_read(env);
29152b2f7d97SBastian Koppelmann }
2916