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