xref: /openbmc/qemu/target/tricore/op_helper.c (revision da4f7b8561e69112171f52279d23b9014902a398)
1fcf5ef2aSThomas Huth /*
2fcf5ef2aSThomas Huth  *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
3fcf5ef2aSThomas Huth  *
4fcf5ef2aSThomas Huth  * This library is free software; you can redistribute it and/or
5fcf5ef2aSThomas Huth  * modify it under the terms of the GNU Lesser General Public
6fcf5ef2aSThomas Huth  * License as published by the Free Software Foundation; either
702754acdSThomas Huth  * version 2.1 of the License, or (at your option) any later version.
8fcf5ef2aSThomas Huth  *
9fcf5ef2aSThomas Huth  * This library is distributed in the hope that it will be useful,
10fcf5ef2aSThomas Huth  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11fcf5ef2aSThomas Huth  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12fcf5ef2aSThomas Huth  * Lesser General Public License for more details.
13fcf5ef2aSThomas Huth  *
14fcf5ef2aSThomas Huth  * You should have received a copy of the GNU Lesser General Public
15fcf5ef2aSThomas Huth  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16fcf5ef2aSThomas Huth  */
17fcf5ef2aSThomas Huth #include "qemu/osdep.h"
18fcf5ef2aSThomas Huth #include "cpu.h"
19fcf5ef2aSThomas Huth #include "qemu/host-utils.h"
20fcf5ef2aSThomas Huth #include "exec/helper-proto.h"
21fcf5ef2aSThomas Huth #include "exec/exec-all.h"
22fcf5ef2aSThomas Huth #include "exec/cpu_ldst.h"
23fcf5ef2aSThomas Huth #include <zlib.h> /* for crc32 */
24fcf5ef2aSThomas Huth 
25fcf5ef2aSThomas Huth 
26fcf5ef2aSThomas Huth /* Exception helpers */
27fcf5ef2aSThomas Huth 
288905770bSMarc-André Lureau static G_NORETURN
raise_exception_sync_internal(CPUTriCoreState * env,uint32_t class,int tin,uintptr_t pc,uint32_t fcd_pc)298905770bSMarc-André Lureau void raise_exception_sync_internal(CPUTriCoreState *env, uint32_t class, int tin,
30fcf5ef2aSThomas Huth                                    uintptr_t pc, uint32_t fcd_pc)
31fcf5ef2aSThomas Huth {
3206eb2e29SRichard Henderson     CPUState *cs = env_cpu(env);
33fcf5ef2aSThomas Huth     /* in case we come from a helper-call we need to restore the PC */
343d419a4dSRichard Henderson     cpu_restore_state(cs, pc);
35fcf5ef2aSThomas Huth 
36fcf5ef2aSThomas Huth     /* Tin is loaded into d[15] */
37fcf5ef2aSThomas Huth     env->gpr_d[15] = tin;
38fcf5ef2aSThomas Huth 
39fcf5ef2aSThomas Huth     if (class == TRAPC_CTX_MNG && tin == TIN3_FCU) {
40fcf5ef2aSThomas Huth         /* upper context cannot be saved, if the context list is empty */
41fcf5ef2aSThomas Huth     } else {
42fcf5ef2aSThomas Huth         helper_svucx(env);
43fcf5ef2aSThomas Huth     }
44fcf5ef2aSThomas Huth 
45fcf5ef2aSThomas Huth     /* The return address in a[11] is updated */
46fcf5ef2aSThomas Huth     if (class == TRAPC_CTX_MNG && tin == TIN3_FCD) {
47fcf5ef2aSThomas Huth         env->SYSCON |= MASK_SYSCON_FCD_SF;
48fcf5ef2aSThomas Huth         /* when we run out of CSAs after saving a context a FCD trap is taken
49fcf5ef2aSThomas Huth            and the return address is the start of the trap handler which used
50fcf5ef2aSThomas Huth            the last CSA */
51fcf5ef2aSThomas Huth         env->gpr_a[11] = fcd_pc;
52fcf5ef2aSThomas Huth     } else if (class == TRAPC_SYSCALL) {
53fcf5ef2aSThomas Huth         env->gpr_a[11] = env->PC + 4;
54fcf5ef2aSThomas Huth     } else {
55fcf5ef2aSThomas Huth         env->gpr_a[11] = env->PC;
56fcf5ef2aSThomas Huth     }
57fcf5ef2aSThomas Huth     /* The stack pointer in A[10] is set to the Interrupt Stack Pointer (ISP)
58fcf5ef2aSThomas Huth        when the processor was not previously using the interrupt stack
59fcf5ef2aSThomas Huth        (in case of PSW.IS = 0). The stack pointer bit is set for using the
60fcf5ef2aSThomas Huth        interrupt stack: PSW.IS = 1. */
61fcf5ef2aSThomas Huth     if ((env->PSW & MASK_PSW_IS) == 0) {
62fcf5ef2aSThomas Huth         env->gpr_a[10] = env->ISP;
63fcf5ef2aSThomas Huth     }
64fcf5ef2aSThomas Huth     env->PSW |= MASK_PSW_IS;
65fcf5ef2aSThomas Huth     /* The I/O mode is set to Supervisor mode, which means all permissions
66fcf5ef2aSThomas Huth        are enabled: PSW.IO = 10 B .*/
67fcf5ef2aSThomas Huth     env->PSW |= (2 << 10);
68fcf5ef2aSThomas Huth 
69fcf5ef2aSThomas Huth     /*The current Protection Register Set is set to 0: PSW.PRS = 00 B .*/
70fcf5ef2aSThomas Huth     env->PSW &= ~MASK_PSW_PRS;
71fcf5ef2aSThomas Huth 
72fcf5ef2aSThomas Huth     /* The Call Depth Counter (CDC) is cleared, and the call depth limit is
73fcf5ef2aSThomas Huth        set for 64: PSW.CDC = 0000000 B .*/
74fcf5ef2aSThomas Huth     env->PSW &= ~MASK_PSW_CDC;
75fcf5ef2aSThomas Huth 
76fcf5ef2aSThomas Huth     /* Call Depth Counter is enabled, PSW.CDE = 1. */
77fcf5ef2aSThomas Huth     env->PSW |= MASK_PSW_CDE;
78fcf5ef2aSThomas Huth 
79fcf5ef2aSThomas Huth     /* Write permission to global registers A[0], A[1], A[8], A[9] is
80fcf5ef2aSThomas Huth        disabled: PSW.GW = 0. */
81fcf5ef2aSThomas Huth     env->PSW &= ~MASK_PSW_GW;
82fcf5ef2aSThomas Huth 
83fcf5ef2aSThomas Huth     /*The interrupt system is globally disabled: ICR.IE = 0. The ‘old’
84fcf5ef2aSThomas Huth       ICR.IE and ICR.CCPN are saved */
85fcf5ef2aSThomas Huth 
86fcf5ef2aSThomas Huth     /* PCXI.PIE = ICR.IE */
87343cdf2cSBastian Koppelmann     pcxi_set_pie(env, icr_get_ie(env));
88343cdf2cSBastian Koppelmann 
89fcf5ef2aSThomas Huth     /* PCXI.PCPN = ICR.CCPN */
90343cdf2cSBastian Koppelmann     pcxi_set_pcpn(env, icr_get_ccpn(env));
91fcf5ef2aSThomas Huth     /* Update PC using the trap vector table */
92fcf5ef2aSThomas Huth     env->PC = env->BTV | (class << 5);
93fcf5ef2aSThomas Huth 
94fcf5ef2aSThomas Huth     cpu_loop_exit(cs);
95fcf5ef2aSThomas Huth }
96fcf5ef2aSThomas Huth 
helper_raise_exception_sync(CPUTriCoreState * env,uint32_t class,uint32_t tin)97fcf5ef2aSThomas Huth void helper_raise_exception_sync(CPUTriCoreState *env, uint32_t class,
98fcf5ef2aSThomas Huth                                  uint32_t tin)
99fcf5ef2aSThomas Huth {
100fcf5ef2aSThomas Huth     raise_exception_sync_internal(env, class, tin, 0, 0);
101fcf5ef2aSThomas Huth }
102fcf5ef2aSThomas Huth 
raise_exception_sync_helper(CPUTriCoreState * env,uint32_t class,uint32_t tin,uintptr_t pc)103fcf5ef2aSThomas Huth static void raise_exception_sync_helper(CPUTriCoreState *env, uint32_t class,
104fcf5ef2aSThomas Huth                                         uint32_t tin, uintptr_t pc)
105fcf5ef2aSThomas Huth {
106fcf5ef2aSThomas Huth     raise_exception_sync_internal(env, class, tin, pc, 0);
107fcf5ef2aSThomas Huth }
108fcf5ef2aSThomas Huth 
109fcf5ef2aSThomas Huth /* Addressing mode helper */
110fcf5ef2aSThomas Huth 
reverse16(uint16_t val)111fcf5ef2aSThomas Huth static uint16_t reverse16(uint16_t val)
112fcf5ef2aSThomas Huth {
113fcf5ef2aSThomas Huth     uint8_t high = (uint8_t)(val >> 8);
114fcf5ef2aSThomas Huth     uint8_t low  = (uint8_t)(val & 0xff);
115fcf5ef2aSThomas Huth 
116fcf5ef2aSThomas Huth     uint16_t rh, rl;
117fcf5ef2aSThomas Huth 
118fcf5ef2aSThomas Huth     rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
119fcf5ef2aSThomas Huth     rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
120fcf5ef2aSThomas Huth 
121fcf5ef2aSThomas Huth     return (rh << 8) | rl;
122fcf5ef2aSThomas Huth }
123fcf5ef2aSThomas Huth 
helper_br_update(uint32_t reg)124fcf5ef2aSThomas Huth uint32_t helper_br_update(uint32_t reg)
125fcf5ef2aSThomas Huth {
126fcf5ef2aSThomas Huth     uint32_t index = reg & 0xffff;
127fcf5ef2aSThomas Huth     uint32_t incr  = reg >> 16;
128fcf5ef2aSThomas Huth     uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
129fcf5ef2aSThomas Huth     return reg - index + new_index;
130fcf5ef2aSThomas Huth }
131fcf5ef2aSThomas Huth 
helper_circ_update(uint32_t reg,uint32_t off)132fcf5ef2aSThomas Huth uint32_t helper_circ_update(uint32_t reg, uint32_t off)
133fcf5ef2aSThomas Huth {
134fcf5ef2aSThomas Huth     uint32_t index = reg & 0xffff;
135fcf5ef2aSThomas Huth     uint32_t length = reg >> 16;
136fcf5ef2aSThomas Huth     int32_t new_index = index + off;
137fcf5ef2aSThomas Huth     if (new_index < 0) {
138fcf5ef2aSThomas Huth         new_index += length;
139fcf5ef2aSThomas Huth     } else {
140fcf5ef2aSThomas Huth         new_index %= length;
141fcf5ef2aSThomas Huth     }
142fcf5ef2aSThomas Huth     return reg - index + new_index;
143fcf5ef2aSThomas Huth }
144fcf5ef2aSThomas Huth 
ssov32(CPUTriCoreState * env,int64_t arg)145fcf5ef2aSThomas Huth static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
146fcf5ef2aSThomas Huth {
147fcf5ef2aSThomas Huth     uint32_t ret;
148fcf5ef2aSThomas Huth     int64_t max_pos = INT32_MAX;
149fcf5ef2aSThomas Huth     int64_t max_neg = INT32_MIN;
150fcf5ef2aSThomas Huth     if (arg > max_pos) {
151fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
152fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
153fcf5ef2aSThomas Huth         ret = (target_ulong)max_pos;
154fcf5ef2aSThomas Huth     } else {
155fcf5ef2aSThomas Huth         if (arg < max_neg) {
156fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
157fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
158fcf5ef2aSThomas Huth             ret = (target_ulong)max_neg;
159fcf5ef2aSThomas Huth         } else {
160fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
161fcf5ef2aSThomas Huth             ret = (target_ulong)arg;
162fcf5ef2aSThomas Huth         }
163fcf5ef2aSThomas Huth     }
164fcf5ef2aSThomas Huth     env->PSW_USB_AV = arg ^ arg * 2u;
165fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
166fcf5ef2aSThomas Huth     return ret;
167fcf5ef2aSThomas Huth }
168fcf5ef2aSThomas Huth 
suov32_pos(CPUTriCoreState * env,uint64_t arg)169fcf5ef2aSThomas Huth static uint32_t suov32_pos(CPUTriCoreState *env, uint64_t arg)
170fcf5ef2aSThomas Huth {
171fcf5ef2aSThomas Huth     uint32_t ret;
172fcf5ef2aSThomas Huth     uint64_t max_pos = UINT32_MAX;
173fcf5ef2aSThomas Huth     if (arg > max_pos) {
174fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
175fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
176fcf5ef2aSThomas Huth         ret = (target_ulong)max_pos;
177fcf5ef2aSThomas Huth     } else {
178fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
179fcf5ef2aSThomas Huth         ret = (target_ulong)arg;
180fcf5ef2aSThomas Huth      }
181fcf5ef2aSThomas Huth     env->PSW_USB_AV = arg ^ arg * 2u;
182fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
183fcf5ef2aSThomas Huth     return ret;
184fcf5ef2aSThomas Huth }
185fcf5ef2aSThomas Huth 
suov32_neg(CPUTriCoreState * env,int64_t arg)186fcf5ef2aSThomas Huth static uint32_t suov32_neg(CPUTriCoreState *env, int64_t arg)
187fcf5ef2aSThomas Huth {
188fcf5ef2aSThomas Huth     uint32_t ret;
189fcf5ef2aSThomas Huth 
190fcf5ef2aSThomas Huth     if (arg < 0) {
191fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
192fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
193fcf5ef2aSThomas Huth         ret = 0;
194fcf5ef2aSThomas Huth     } else {
195fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
196fcf5ef2aSThomas Huth         ret = (target_ulong)arg;
197fcf5ef2aSThomas Huth     }
198fcf5ef2aSThomas Huth     env->PSW_USB_AV = arg ^ arg * 2u;
199fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
200fcf5ef2aSThomas Huth     return ret;
201fcf5ef2aSThomas Huth }
202fcf5ef2aSThomas Huth 
ssov16(CPUTriCoreState * env,int32_t hw0,int32_t hw1)203fcf5ef2aSThomas Huth static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
204fcf5ef2aSThomas Huth {
205fcf5ef2aSThomas Huth     int32_t max_pos = INT16_MAX;
206fcf5ef2aSThomas Huth     int32_t max_neg = INT16_MIN;
207fcf5ef2aSThomas Huth     int32_t av0, av1;
208fcf5ef2aSThomas Huth 
209fcf5ef2aSThomas Huth     env->PSW_USB_V = 0;
210fcf5ef2aSThomas Huth     av0 = hw0 ^ hw0 * 2u;
211fcf5ef2aSThomas Huth     if (hw0 > max_pos) {
212fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
213fcf5ef2aSThomas Huth         hw0 = max_pos;
214fcf5ef2aSThomas Huth     } else if (hw0 < max_neg) {
215fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
216fcf5ef2aSThomas Huth         hw0 = max_neg;
217fcf5ef2aSThomas Huth     }
218fcf5ef2aSThomas Huth 
219fcf5ef2aSThomas Huth     av1 = hw1 ^ hw1 * 2u;
220fcf5ef2aSThomas Huth     if (hw1 > max_pos) {
221fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
222fcf5ef2aSThomas Huth         hw1 = max_pos;
223fcf5ef2aSThomas Huth     } else if (hw1 < max_neg) {
224fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
225fcf5ef2aSThomas Huth         hw1 = max_neg;
226fcf5ef2aSThomas Huth     }
227fcf5ef2aSThomas Huth 
228fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
229fcf5ef2aSThomas Huth     env->PSW_USB_AV = (av0 | av1) << 16;
230fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
231fcf5ef2aSThomas Huth     return (hw0 & 0xffff) | (hw1 << 16);
232fcf5ef2aSThomas Huth }
233fcf5ef2aSThomas Huth 
suov16(CPUTriCoreState * env,int32_t hw0,int32_t hw1)234fcf5ef2aSThomas Huth static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
235fcf5ef2aSThomas Huth {
236fcf5ef2aSThomas Huth     int32_t max_pos = UINT16_MAX;
237fcf5ef2aSThomas Huth     int32_t av0, av1;
238fcf5ef2aSThomas Huth 
239fcf5ef2aSThomas Huth     env->PSW_USB_V = 0;
240fcf5ef2aSThomas Huth     av0 = hw0 ^ hw0 * 2u;
241fcf5ef2aSThomas Huth     if (hw0 > max_pos) {
242fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
243fcf5ef2aSThomas Huth         hw0 = max_pos;
244fcf5ef2aSThomas Huth     } else if (hw0 < 0) {
245fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
246fcf5ef2aSThomas Huth         hw0 = 0;
247fcf5ef2aSThomas Huth     }
248fcf5ef2aSThomas Huth 
249fcf5ef2aSThomas Huth     av1 = hw1 ^ hw1 * 2u;
250fcf5ef2aSThomas Huth     if (hw1 > max_pos) {
251fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
252fcf5ef2aSThomas Huth         hw1 = max_pos;
253fcf5ef2aSThomas Huth     } else if (hw1 < 0) {
254fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
255fcf5ef2aSThomas Huth         hw1 = 0;
256fcf5ef2aSThomas Huth     }
257fcf5ef2aSThomas Huth 
258fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
259fcf5ef2aSThomas Huth     env->PSW_USB_AV = (av0 | av1) << 16;
260fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
261fcf5ef2aSThomas Huth     return (hw0 & 0xffff) | (hw1 << 16);
262fcf5ef2aSThomas Huth }
263fcf5ef2aSThomas Huth 
helper_add_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)264fcf5ef2aSThomas Huth target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
265fcf5ef2aSThomas Huth                              target_ulong r2)
266fcf5ef2aSThomas Huth {
267fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
268fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
269fcf5ef2aSThomas Huth     int64_t result = t1 + t2;
270fcf5ef2aSThomas Huth     return ssov32(env, result);
271fcf5ef2aSThomas Huth }
272fcf5ef2aSThomas Huth 
helper_add64_ssov(CPUTriCoreState * env,uint64_t r1,uint64_t r2)273fcf5ef2aSThomas Huth uint64_t helper_add64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
274fcf5ef2aSThomas Huth {
275fcf5ef2aSThomas Huth     uint64_t result;
276fcf5ef2aSThomas Huth     int64_t ovf;
277fcf5ef2aSThomas Huth 
278fcf5ef2aSThomas Huth     result = r1 + r2;
279fcf5ef2aSThomas Huth     ovf = (result ^ r1) & ~(r1 ^ r2);
280fcf5ef2aSThomas Huth     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
281fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
282fcf5ef2aSThomas Huth     if (ovf < 0) {
283fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
284fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
285fcf5ef2aSThomas Huth         /* ext_ret > MAX_INT */
286fcf5ef2aSThomas Huth         if ((int64_t)r1 >= 0) {
287fcf5ef2aSThomas Huth             result = INT64_MAX;
288fcf5ef2aSThomas Huth         /* ext_ret < MIN_INT */
289fcf5ef2aSThomas Huth         } else {
290fcf5ef2aSThomas Huth             result = INT64_MIN;
291fcf5ef2aSThomas Huth         }
292fcf5ef2aSThomas Huth     } else {
293fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
294fcf5ef2aSThomas Huth     }
295fcf5ef2aSThomas Huth     return result;
296fcf5ef2aSThomas Huth }
297fcf5ef2aSThomas Huth 
helper_add_h_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)298fcf5ef2aSThomas Huth target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
299fcf5ef2aSThomas Huth                                target_ulong r2)
300fcf5ef2aSThomas Huth {
301fcf5ef2aSThomas Huth     int32_t ret_hw0, ret_hw1;
302fcf5ef2aSThomas Huth 
303fcf5ef2aSThomas Huth     ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
304fcf5ef2aSThomas Huth     ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
305fcf5ef2aSThomas Huth     return ssov16(env, ret_hw0, ret_hw1);
306fcf5ef2aSThomas Huth }
307fcf5ef2aSThomas Huth 
helper_addr_h_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)308fcf5ef2aSThomas Huth uint32_t helper_addr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
309fcf5ef2aSThomas Huth                             uint32_t r2_h)
310fcf5ef2aSThomas Huth {
311fcf5ef2aSThomas Huth     int64_t mul_res0 = sextract64(r1, 0, 32);
312fcf5ef2aSThomas Huth     int64_t mul_res1 = sextract64(r1, 32, 32);
313fcf5ef2aSThomas Huth     int64_t r2_low = sextract64(r2_l, 0, 32);
314fcf5ef2aSThomas Huth     int64_t r2_high = sextract64(r2_h, 0, 32);
315fcf5ef2aSThomas Huth     int64_t result0, result1;
316fcf5ef2aSThomas Huth     uint32_t ovf0, ovf1;
317fcf5ef2aSThomas Huth     uint32_t avf0, avf1;
318fcf5ef2aSThomas Huth 
319fcf5ef2aSThomas Huth     ovf0 = ovf1 = 0;
320fcf5ef2aSThomas Huth 
321fcf5ef2aSThomas Huth     result0 = r2_low + mul_res0 + 0x8000;
322fcf5ef2aSThomas Huth     result1 = r2_high + mul_res1 + 0x8000;
323fcf5ef2aSThomas Huth 
324fcf5ef2aSThomas Huth     avf0 = result0 * 2u;
325fcf5ef2aSThomas Huth     avf0 = result0 ^ avf0;
326fcf5ef2aSThomas Huth     avf1 = result1 * 2u;
327fcf5ef2aSThomas Huth     avf1 = result1 ^ avf1;
328fcf5ef2aSThomas Huth 
329fcf5ef2aSThomas Huth     if (result0 > INT32_MAX) {
330fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
331fcf5ef2aSThomas Huth         result0 = INT32_MAX;
332fcf5ef2aSThomas Huth     } else if (result0 < INT32_MIN) {
333fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
334fcf5ef2aSThomas Huth         result0 = INT32_MIN;
335fcf5ef2aSThomas Huth     }
336fcf5ef2aSThomas Huth 
337fcf5ef2aSThomas Huth     if (result1 > INT32_MAX) {
338fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
339fcf5ef2aSThomas Huth         result1 = INT32_MAX;
340fcf5ef2aSThomas Huth     } else if (result1 < INT32_MIN) {
341fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
342fcf5ef2aSThomas Huth         result1 = INT32_MIN;
343fcf5ef2aSThomas Huth     }
344fcf5ef2aSThomas Huth 
345fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf0 | ovf1;
346fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
347fcf5ef2aSThomas Huth 
348fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf0 | avf1;
349fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
350fcf5ef2aSThomas Huth 
351fcf5ef2aSThomas Huth     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
352fcf5ef2aSThomas Huth }
353fcf5ef2aSThomas Huth 
helper_addsur_h_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)354fcf5ef2aSThomas Huth uint32_t helper_addsur_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
355fcf5ef2aSThomas Huth                               uint32_t r2_h)
356fcf5ef2aSThomas Huth {
357fcf5ef2aSThomas Huth     int64_t mul_res0 = sextract64(r1, 0, 32);
358fcf5ef2aSThomas Huth     int64_t mul_res1 = sextract64(r1, 32, 32);
359fcf5ef2aSThomas Huth     int64_t r2_low = sextract64(r2_l, 0, 32);
360fcf5ef2aSThomas Huth     int64_t r2_high = sextract64(r2_h, 0, 32);
361fcf5ef2aSThomas Huth     int64_t result0, result1;
362fcf5ef2aSThomas Huth     uint32_t ovf0, ovf1;
363fcf5ef2aSThomas Huth     uint32_t avf0, avf1;
364fcf5ef2aSThomas Huth 
365fcf5ef2aSThomas Huth     ovf0 = ovf1 = 0;
366fcf5ef2aSThomas Huth 
367fcf5ef2aSThomas Huth     result0 = r2_low - mul_res0 + 0x8000;
368fcf5ef2aSThomas Huth     result1 = r2_high + mul_res1 + 0x8000;
369fcf5ef2aSThomas Huth 
370fcf5ef2aSThomas Huth     avf0 = result0 * 2u;
371fcf5ef2aSThomas Huth     avf0 = result0 ^ avf0;
372fcf5ef2aSThomas Huth     avf1 = result1 * 2u;
373fcf5ef2aSThomas Huth     avf1 = result1 ^ avf1;
374fcf5ef2aSThomas Huth 
375fcf5ef2aSThomas Huth     if (result0 > INT32_MAX) {
376fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
377fcf5ef2aSThomas Huth         result0 = INT32_MAX;
378fcf5ef2aSThomas Huth     } else if (result0 < INT32_MIN) {
379fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
380fcf5ef2aSThomas Huth         result0 = INT32_MIN;
381fcf5ef2aSThomas Huth     }
382fcf5ef2aSThomas Huth 
383fcf5ef2aSThomas Huth     if (result1 > INT32_MAX) {
384fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
385fcf5ef2aSThomas Huth         result1 = INT32_MAX;
386fcf5ef2aSThomas Huth     } else if (result1 < INT32_MIN) {
387fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
388fcf5ef2aSThomas Huth         result1 = INT32_MIN;
389fcf5ef2aSThomas Huth     }
390fcf5ef2aSThomas Huth 
391fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf0 | ovf1;
392fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
393fcf5ef2aSThomas Huth 
394fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf0 | avf1;
395fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
396fcf5ef2aSThomas Huth 
397fcf5ef2aSThomas Huth     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
398fcf5ef2aSThomas Huth }
399fcf5ef2aSThomas Huth 
400fcf5ef2aSThomas Huth 
helper_add_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)401fcf5ef2aSThomas Huth target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
402fcf5ef2aSThomas Huth                              target_ulong r2)
403fcf5ef2aSThomas Huth {
404fcf5ef2aSThomas Huth     int64_t t1 = extract64(r1, 0, 32);
405fcf5ef2aSThomas Huth     int64_t t2 = extract64(r2, 0, 32);
406fcf5ef2aSThomas Huth     int64_t result = t1 + t2;
407fcf5ef2aSThomas Huth     return suov32_pos(env, result);
408fcf5ef2aSThomas Huth }
409fcf5ef2aSThomas Huth 
helper_add_h_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)410fcf5ef2aSThomas Huth target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
411fcf5ef2aSThomas Huth                                target_ulong r2)
412fcf5ef2aSThomas Huth {
413fcf5ef2aSThomas Huth     int32_t ret_hw0, ret_hw1;
414fcf5ef2aSThomas Huth 
415fcf5ef2aSThomas Huth     ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
416fcf5ef2aSThomas Huth     ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
417fcf5ef2aSThomas Huth     return suov16(env, ret_hw0, ret_hw1);
418fcf5ef2aSThomas Huth }
419fcf5ef2aSThomas Huth 
helper_sub_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)420fcf5ef2aSThomas Huth target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
421fcf5ef2aSThomas Huth                              target_ulong r2)
422fcf5ef2aSThomas Huth {
423fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
424fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
425fcf5ef2aSThomas Huth     int64_t result = t1 - t2;
426fcf5ef2aSThomas Huth     return ssov32(env, result);
427fcf5ef2aSThomas Huth }
428fcf5ef2aSThomas Huth 
helper_sub64_ssov(CPUTriCoreState * env,uint64_t r1,uint64_t r2)429fcf5ef2aSThomas Huth uint64_t helper_sub64_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
430fcf5ef2aSThomas Huth {
431fcf5ef2aSThomas Huth     uint64_t result;
432fcf5ef2aSThomas Huth     int64_t ovf;
433fcf5ef2aSThomas Huth 
434fcf5ef2aSThomas Huth     result = r1 - r2;
435fcf5ef2aSThomas Huth     ovf = (result ^ r1) & (r1 ^ r2);
436fcf5ef2aSThomas Huth     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
437fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
438fcf5ef2aSThomas Huth     if (ovf < 0) {
439fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
440fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
441fcf5ef2aSThomas Huth         /* ext_ret > MAX_INT */
442fcf5ef2aSThomas Huth         if ((int64_t)r1 >= 0) {
443fcf5ef2aSThomas Huth             result = INT64_MAX;
444fcf5ef2aSThomas Huth         /* ext_ret < MIN_INT */
445fcf5ef2aSThomas Huth         } else {
446fcf5ef2aSThomas Huth             result = INT64_MIN;
447fcf5ef2aSThomas Huth         }
448fcf5ef2aSThomas Huth     } else {
449fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
450fcf5ef2aSThomas Huth     }
451fcf5ef2aSThomas Huth     return result;
452fcf5ef2aSThomas Huth }
453fcf5ef2aSThomas Huth 
helper_sub_h_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)454fcf5ef2aSThomas Huth target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
455fcf5ef2aSThomas Huth                              target_ulong r2)
456fcf5ef2aSThomas Huth {
457fcf5ef2aSThomas Huth     int32_t ret_hw0, ret_hw1;
458fcf5ef2aSThomas Huth 
459fcf5ef2aSThomas Huth     ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
460fcf5ef2aSThomas Huth     ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
461fcf5ef2aSThomas Huth     return ssov16(env, ret_hw0, ret_hw1);
462fcf5ef2aSThomas Huth }
463fcf5ef2aSThomas Huth 
helper_subr_h_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)464fcf5ef2aSThomas Huth uint32_t helper_subr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
465fcf5ef2aSThomas Huth                             uint32_t r2_h)
466fcf5ef2aSThomas Huth {
467fcf5ef2aSThomas Huth     int64_t mul_res0 = sextract64(r1, 0, 32);
468fcf5ef2aSThomas Huth     int64_t mul_res1 = sextract64(r1, 32, 32);
469fcf5ef2aSThomas Huth     int64_t r2_low = sextract64(r2_l, 0, 32);
470fcf5ef2aSThomas Huth     int64_t r2_high = sextract64(r2_h, 0, 32);
471fcf5ef2aSThomas Huth     int64_t result0, result1;
472fcf5ef2aSThomas Huth     uint32_t ovf0, ovf1;
473fcf5ef2aSThomas Huth     uint32_t avf0, avf1;
474fcf5ef2aSThomas Huth 
475fcf5ef2aSThomas Huth     ovf0 = ovf1 = 0;
476fcf5ef2aSThomas Huth 
477fcf5ef2aSThomas Huth     result0 = r2_low - mul_res0 + 0x8000;
478fcf5ef2aSThomas Huth     result1 = r2_high - mul_res1 + 0x8000;
479fcf5ef2aSThomas Huth 
480fcf5ef2aSThomas Huth     avf0 = result0 * 2u;
481fcf5ef2aSThomas Huth     avf0 = result0 ^ avf0;
482fcf5ef2aSThomas Huth     avf1 = result1 * 2u;
483fcf5ef2aSThomas Huth     avf1 = result1 ^ avf1;
484fcf5ef2aSThomas Huth 
485fcf5ef2aSThomas Huth     if (result0 > INT32_MAX) {
486fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
487fcf5ef2aSThomas Huth         result0 = INT32_MAX;
488fcf5ef2aSThomas Huth     } else if (result0 < INT32_MIN) {
489fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
490fcf5ef2aSThomas Huth         result0 = INT32_MIN;
491fcf5ef2aSThomas Huth     }
492fcf5ef2aSThomas Huth 
493fcf5ef2aSThomas Huth     if (result1 > INT32_MAX) {
494fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
495fcf5ef2aSThomas Huth         result1 = INT32_MAX;
496fcf5ef2aSThomas Huth     } else if (result1 < INT32_MIN) {
497fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
498fcf5ef2aSThomas Huth         result1 = INT32_MIN;
499fcf5ef2aSThomas Huth     }
500fcf5ef2aSThomas Huth 
501fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf0 | ovf1;
502fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
503fcf5ef2aSThomas Huth 
504fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf0 | avf1;
505fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
506fcf5ef2aSThomas Huth 
507fcf5ef2aSThomas Huth     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
508fcf5ef2aSThomas Huth }
509fcf5ef2aSThomas Huth 
helper_subadr_h_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)510fcf5ef2aSThomas Huth uint32_t helper_subadr_h_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
511fcf5ef2aSThomas Huth                               uint32_t r2_h)
512fcf5ef2aSThomas Huth {
513fcf5ef2aSThomas Huth     int64_t mul_res0 = sextract64(r1, 0, 32);
514fcf5ef2aSThomas Huth     int64_t mul_res1 = sextract64(r1, 32, 32);
515fcf5ef2aSThomas Huth     int64_t r2_low = sextract64(r2_l, 0, 32);
516fcf5ef2aSThomas Huth     int64_t r2_high = sextract64(r2_h, 0, 32);
517fcf5ef2aSThomas Huth     int64_t result0, result1;
518fcf5ef2aSThomas Huth     uint32_t ovf0, ovf1;
519fcf5ef2aSThomas Huth     uint32_t avf0, avf1;
520fcf5ef2aSThomas Huth 
521fcf5ef2aSThomas Huth     ovf0 = ovf1 = 0;
522fcf5ef2aSThomas Huth 
523fcf5ef2aSThomas Huth     result0 = r2_low + mul_res0 + 0x8000;
524fcf5ef2aSThomas Huth     result1 = r2_high - mul_res1 + 0x8000;
525fcf5ef2aSThomas Huth 
526fcf5ef2aSThomas Huth     avf0 = result0 * 2u;
527fcf5ef2aSThomas Huth     avf0 = result0 ^ avf0;
528fcf5ef2aSThomas Huth     avf1 = result1 * 2u;
529fcf5ef2aSThomas Huth     avf1 = result1 ^ avf1;
530fcf5ef2aSThomas Huth 
531fcf5ef2aSThomas Huth     if (result0 > INT32_MAX) {
532fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
533fcf5ef2aSThomas Huth         result0 = INT32_MAX;
534fcf5ef2aSThomas Huth     } else if (result0 < INT32_MIN) {
535fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
536fcf5ef2aSThomas Huth         result0 = INT32_MIN;
537fcf5ef2aSThomas Huth     }
538fcf5ef2aSThomas Huth 
539fcf5ef2aSThomas Huth     if (result1 > INT32_MAX) {
540fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
541fcf5ef2aSThomas Huth         result1 = INT32_MAX;
542fcf5ef2aSThomas Huth     } else if (result1 < INT32_MIN) {
543fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
544fcf5ef2aSThomas Huth         result1 = INT32_MIN;
545fcf5ef2aSThomas Huth     }
546fcf5ef2aSThomas Huth 
547fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf0 | ovf1;
548fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
549fcf5ef2aSThomas Huth 
550fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf0 | avf1;
551fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
552fcf5ef2aSThomas Huth 
553fcf5ef2aSThomas Huth     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
554fcf5ef2aSThomas Huth }
555fcf5ef2aSThomas Huth 
helper_sub_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)556fcf5ef2aSThomas Huth target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
557fcf5ef2aSThomas Huth                              target_ulong r2)
558fcf5ef2aSThomas Huth {
559fcf5ef2aSThomas Huth     int64_t t1 = extract64(r1, 0, 32);
560fcf5ef2aSThomas Huth     int64_t t2 = extract64(r2, 0, 32);
561fcf5ef2aSThomas Huth     int64_t result = t1 - t2;
562fcf5ef2aSThomas Huth     return suov32_neg(env, result);
563fcf5ef2aSThomas Huth }
564fcf5ef2aSThomas Huth 
helper_sub_h_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)565fcf5ef2aSThomas Huth target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
566fcf5ef2aSThomas Huth                                target_ulong r2)
567fcf5ef2aSThomas Huth {
568fcf5ef2aSThomas Huth     int32_t ret_hw0, ret_hw1;
569fcf5ef2aSThomas Huth 
570fcf5ef2aSThomas Huth     ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
571fcf5ef2aSThomas Huth     ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
572fcf5ef2aSThomas Huth     return suov16(env, ret_hw0, ret_hw1);
573fcf5ef2aSThomas Huth }
574fcf5ef2aSThomas Huth 
helper_mul_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)575fcf5ef2aSThomas Huth target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
576fcf5ef2aSThomas Huth                              target_ulong r2)
577fcf5ef2aSThomas Huth {
578fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
579fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
580fcf5ef2aSThomas Huth     int64_t result = t1 * t2;
581fcf5ef2aSThomas Huth     return ssov32(env, result);
582fcf5ef2aSThomas Huth }
583fcf5ef2aSThomas Huth 
helper_mul_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)584fcf5ef2aSThomas Huth target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
585fcf5ef2aSThomas Huth                              target_ulong r2)
586fcf5ef2aSThomas Huth {
587fcf5ef2aSThomas Huth     int64_t t1 = extract64(r1, 0, 32);
588fcf5ef2aSThomas Huth     int64_t t2 = extract64(r2, 0, 32);
589fcf5ef2aSThomas Huth     int64_t result = t1 * t2;
590fcf5ef2aSThomas Huth 
591fcf5ef2aSThomas Huth     return suov32_pos(env, result);
592fcf5ef2aSThomas Huth }
593fcf5ef2aSThomas Huth 
helper_sha_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)594fcf5ef2aSThomas Huth target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
595fcf5ef2aSThomas Huth                              target_ulong r2)
596fcf5ef2aSThomas Huth {
597fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
598fcf5ef2aSThomas Huth     int32_t t2 = sextract64(r2, 0, 6);
599fcf5ef2aSThomas Huth     int64_t result;
600fcf5ef2aSThomas Huth     if (t2 == 0) {
601fcf5ef2aSThomas Huth         result = t1;
602fcf5ef2aSThomas Huth     } else if (t2 > 0) {
603fcf5ef2aSThomas Huth         result = t1 << t2;
604fcf5ef2aSThomas Huth     } else {
605fcf5ef2aSThomas Huth         result = t1 >> -t2;
606fcf5ef2aSThomas Huth     }
607fcf5ef2aSThomas Huth     return ssov32(env, result);
608fcf5ef2aSThomas Huth }
609fcf5ef2aSThomas Huth 
helper_abs_ssov(CPUTriCoreState * env,target_ulong r1)610fcf5ef2aSThomas Huth uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
611fcf5ef2aSThomas Huth {
612fcf5ef2aSThomas Huth     target_ulong result;
613fcf5ef2aSThomas Huth     result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
614fcf5ef2aSThomas Huth     return ssov32(env, result);
615fcf5ef2aSThomas Huth }
616fcf5ef2aSThomas Huth 
helper_abs_h_ssov(CPUTriCoreState * env,target_ulong r1)617fcf5ef2aSThomas Huth uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
618fcf5ef2aSThomas Huth {
619fcf5ef2aSThomas Huth     int32_t ret_h0, ret_h1;
620fcf5ef2aSThomas Huth 
621fcf5ef2aSThomas Huth     ret_h0 = sextract32(r1, 0, 16);
622fcf5ef2aSThomas Huth     ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
623fcf5ef2aSThomas Huth 
624fcf5ef2aSThomas Huth     ret_h1 = sextract32(r1, 16, 16);
625fcf5ef2aSThomas Huth     ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
626fcf5ef2aSThomas Huth 
627fcf5ef2aSThomas Huth     return ssov16(env, ret_h0, ret_h1);
628fcf5ef2aSThomas Huth }
629fcf5ef2aSThomas Huth 
helper_absdif_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)630fcf5ef2aSThomas Huth target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
631fcf5ef2aSThomas Huth                                 target_ulong r2)
632fcf5ef2aSThomas Huth {
633fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
634fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
635fcf5ef2aSThomas Huth     int64_t result;
636fcf5ef2aSThomas Huth 
637fcf5ef2aSThomas Huth     if (t1 > t2) {
638fcf5ef2aSThomas Huth         result = t1 - t2;
639fcf5ef2aSThomas Huth     } else {
640fcf5ef2aSThomas Huth         result = t2 - t1;
641fcf5ef2aSThomas Huth     }
642fcf5ef2aSThomas Huth     return ssov32(env, result);
643fcf5ef2aSThomas Huth }
644fcf5ef2aSThomas Huth 
helper_absdif_h_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2)645fcf5ef2aSThomas Huth uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
646fcf5ef2aSThomas Huth                               target_ulong r2)
647fcf5ef2aSThomas Huth {
648fcf5ef2aSThomas Huth     int32_t t1, t2;
649fcf5ef2aSThomas Huth     int32_t ret_h0, ret_h1;
650fcf5ef2aSThomas Huth 
651fcf5ef2aSThomas Huth     t1 = sextract32(r1, 0, 16);
652fcf5ef2aSThomas Huth     t2 = sextract32(r2, 0, 16);
653fcf5ef2aSThomas Huth     if (t1 > t2) {
654fcf5ef2aSThomas Huth         ret_h0 = t1 - t2;
655fcf5ef2aSThomas Huth     } else {
656fcf5ef2aSThomas Huth         ret_h0 = t2 - t1;
657fcf5ef2aSThomas Huth     }
658fcf5ef2aSThomas Huth 
659fcf5ef2aSThomas Huth     t1 = sextract32(r1, 16, 16);
660fcf5ef2aSThomas Huth     t2 = sextract32(r2, 16, 16);
661fcf5ef2aSThomas Huth     if (t1 > t2) {
662fcf5ef2aSThomas Huth         ret_h1 = t1 - t2;
663fcf5ef2aSThomas Huth     } else {
664fcf5ef2aSThomas Huth         ret_h1 = t2 - t1;
665fcf5ef2aSThomas Huth     }
666fcf5ef2aSThomas Huth 
667fcf5ef2aSThomas Huth     return ssov16(env, ret_h0, ret_h1);
668fcf5ef2aSThomas Huth }
669fcf5ef2aSThomas Huth 
helper_madd32_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2,target_ulong r3)670fcf5ef2aSThomas Huth target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
671fcf5ef2aSThomas Huth                                 target_ulong r2, target_ulong r3)
672fcf5ef2aSThomas Huth {
673fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
674fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
675fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
676fcf5ef2aSThomas Huth     int64_t result;
677fcf5ef2aSThomas Huth 
678fcf5ef2aSThomas Huth     result = t2 + (t1 * t3);
679fcf5ef2aSThomas Huth     return ssov32(env, result);
680fcf5ef2aSThomas Huth }
681fcf5ef2aSThomas Huth 
helper_madd32_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2,target_ulong r3)682fcf5ef2aSThomas Huth target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
683fcf5ef2aSThomas Huth                                 target_ulong r2, target_ulong r3)
684fcf5ef2aSThomas Huth {
685fcf5ef2aSThomas Huth     uint64_t t1 = extract64(r1, 0, 32);
686fcf5ef2aSThomas Huth     uint64_t t2 = extract64(r2, 0, 32);
687fcf5ef2aSThomas Huth     uint64_t t3 = extract64(r3, 0, 32);
688fcf5ef2aSThomas Huth     int64_t result;
689fcf5ef2aSThomas Huth 
690fcf5ef2aSThomas Huth     result = t2 + (t1 * t3);
691fcf5ef2aSThomas Huth     return suov32_pos(env, result);
692fcf5ef2aSThomas Huth }
693fcf5ef2aSThomas Huth 
helper_madd64_ssov(CPUTriCoreState * env,target_ulong r1,uint64_t r2,target_ulong r3)694fcf5ef2aSThomas Huth uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
695fcf5ef2aSThomas Huth                             uint64_t r2, target_ulong r3)
696fcf5ef2aSThomas Huth {
697fcf5ef2aSThomas Huth     uint64_t ret, ovf;
698fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
699fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
700fcf5ef2aSThomas Huth     int64_t mul;
701fcf5ef2aSThomas Huth 
702fcf5ef2aSThomas Huth     mul = t1 * t3;
703fcf5ef2aSThomas Huth     ret = mul + r2;
704fcf5ef2aSThomas Huth     ovf = (ret ^ mul) & ~(mul ^ r2);
705fcf5ef2aSThomas Huth 
706fcf5ef2aSThomas Huth     t1 = ret >> 32;
707fcf5ef2aSThomas Huth     env->PSW_USB_AV = t1 ^ t1 * 2u;
708fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
709fcf5ef2aSThomas Huth 
710fcf5ef2aSThomas Huth     if ((int64_t)ovf < 0) {
711fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
712fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
713fcf5ef2aSThomas Huth         /* ext_ret > MAX_INT */
714fcf5ef2aSThomas Huth         if (mul >= 0) {
715fcf5ef2aSThomas Huth             ret = INT64_MAX;
716fcf5ef2aSThomas Huth         /* ext_ret < MIN_INT */
717fcf5ef2aSThomas Huth         } else {
718fcf5ef2aSThomas Huth             ret = INT64_MIN;
719fcf5ef2aSThomas Huth         }
720fcf5ef2aSThomas Huth     } else {
721fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
722fcf5ef2aSThomas Huth     }
723fcf5ef2aSThomas Huth 
724fcf5ef2aSThomas Huth     return ret;
725fcf5ef2aSThomas Huth }
726fcf5ef2aSThomas Huth 
727fcf5ef2aSThomas Huth uint32_t
helper_madd32_q_add_ssov(CPUTriCoreState * env,uint64_t r1,uint64_t r2)728fcf5ef2aSThomas Huth helper_madd32_q_add_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
729fcf5ef2aSThomas Huth {
730fcf5ef2aSThomas Huth     int64_t result;
731fcf5ef2aSThomas Huth 
732fcf5ef2aSThomas Huth     result = (r1 + r2);
733fcf5ef2aSThomas Huth 
734fcf5ef2aSThomas Huth     env->PSW_USB_AV = (result ^ result * 2u);
735fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
736fcf5ef2aSThomas Huth 
737fcf5ef2aSThomas Huth     /* we do the saturation by hand, since we produce an overflow on the host
738fcf5ef2aSThomas Huth        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
739fcf5ef2aSThomas Huth        case, we flip the saturated value. */
740fcf5ef2aSThomas Huth     if (r2 == 0x8000000000000000LL) {
741fcf5ef2aSThomas Huth         if (result > 0x7fffffffLL) {
742fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
743fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
744fcf5ef2aSThomas Huth             result = INT32_MIN;
745fcf5ef2aSThomas Huth         } else if (result < -0x80000000LL) {
746fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
747fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
748fcf5ef2aSThomas Huth             result = INT32_MAX;
749fcf5ef2aSThomas Huth         } else {
750fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
751fcf5ef2aSThomas Huth         }
752fcf5ef2aSThomas Huth     } else {
753fcf5ef2aSThomas Huth         if (result > 0x7fffffffLL) {
754fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
755fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
756fcf5ef2aSThomas Huth             result = INT32_MAX;
757fcf5ef2aSThomas Huth         } else if (result < -0x80000000LL) {
758fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
759fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
760fcf5ef2aSThomas Huth             result = INT32_MIN;
761fcf5ef2aSThomas Huth         } else {
762fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
763fcf5ef2aSThomas Huth         }
764fcf5ef2aSThomas Huth     }
765fcf5ef2aSThomas Huth     return (uint32_t)result;
766fcf5ef2aSThomas Huth }
767fcf5ef2aSThomas Huth 
helper_madd64_q_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2,uint32_t r3,uint32_t n)768fcf5ef2aSThomas Huth uint64_t helper_madd64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
769fcf5ef2aSThomas Huth                               uint32_t r3, uint32_t n)
770fcf5ef2aSThomas Huth {
771fcf5ef2aSThomas Huth     int64_t t1 = (int64_t)r1;
772fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
773fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
774fcf5ef2aSThomas Huth     int64_t result, mul;
775fcf5ef2aSThomas Huth     int64_t ovf;
776fcf5ef2aSThomas Huth 
777fcf5ef2aSThomas Huth     mul = (t2 * t3) << n;
778fcf5ef2aSThomas Huth     result = mul + t1;
779fcf5ef2aSThomas Huth 
780fcf5ef2aSThomas Huth     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
781fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
782fcf5ef2aSThomas Huth 
783fcf5ef2aSThomas Huth     ovf = (result ^ mul) & ~(mul ^ t1);
784fcf5ef2aSThomas Huth     /* we do the saturation by hand, since we produce an overflow on the host
785fcf5ef2aSThomas Huth        if the mul was (0x80000000 * 0x80000000) << 1). If this is the
786fcf5ef2aSThomas Huth        case, we flip the saturated value. */
787fcf5ef2aSThomas Huth     if ((r2 == 0x80000000) && (r3 == 0x80000000) && (n == 1)) {
788fcf5ef2aSThomas Huth         if (ovf >= 0) {
789fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
790fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
791fcf5ef2aSThomas Huth             /* ext_ret > MAX_INT */
792fcf5ef2aSThomas Huth             if (mul < 0) {
793fcf5ef2aSThomas Huth                 result = INT64_MAX;
794fcf5ef2aSThomas Huth             /* ext_ret < MIN_INT */
795fcf5ef2aSThomas Huth             } else {
796fcf5ef2aSThomas Huth                result = INT64_MIN;
797fcf5ef2aSThomas Huth             }
798fcf5ef2aSThomas Huth         } else {
799fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
800fcf5ef2aSThomas Huth         }
801fcf5ef2aSThomas Huth     } else {
802fcf5ef2aSThomas Huth         if (ovf < 0) {
803fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
804fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
805fcf5ef2aSThomas Huth             /* ext_ret > MAX_INT */
806fcf5ef2aSThomas Huth             if (mul >= 0) {
807fcf5ef2aSThomas Huth                 result = INT64_MAX;
808fcf5ef2aSThomas Huth             /* ext_ret < MIN_INT */
809fcf5ef2aSThomas Huth             } else {
810fcf5ef2aSThomas Huth                result = INT64_MIN;
811fcf5ef2aSThomas Huth             }
812fcf5ef2aSThomas Huth         } else {
813fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
814fcf5ef2aSThomas Huth         }
815fcf5ef2aSThomas Huth     }
816fcf5ef2aSThomas Huth     return (uint64_t)result;
817fcf5ef2aSThomas Huth }
818fcf5ef2aSThomas Huth 
helper_maddr_q_ssov(CPUTriCoreState * env,uint32_t r1,uint32_t r2,uint32_t r3,uint32_t n)819fcf5ef2aSThomas Huth uint32_t helper_maddr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
820fcf5ef2aSThomas Huth                              uint32_t r3, uint32_t n)
821fcf5ef2aSThomas Huth {
822fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
823fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
824fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
825fcf5ef2aSThomas Huth     int64_t mul, ret;
826fcf5ef2aSThomas Huth 
827fcf5ef2aSThomas Huth     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
828fcf5ef2aSThomas Huth         mul = 0x7fffffff;
829fcf5ef2aSThomas Huth     } else {
830fcf5ef2aSThomas Huth         mul = (t2 * t3) << n;
831fcf5ef2aSThomas Huth     }
832fcf5ef2aSThomas Huth 
833fcf5ef2aSThomas Huth     ret = t1 + mul + 0x8000;
834fcf5ef2aSThomas Huth 
835fcf5ef2aSThomas Huth     env->PSW_USB_AV = ret ^ ret * 2u;
836fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
837fcf5ef2aSThomas Huth 
838fcf5ef2aSThomas Huth     if (ret > 0x7fffffffll) {
839fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
840fcf5ef2aSThomas Huth         env->PSW_USB_SV |= env->PSW_USB_V;
841fcf5ef2aSThomas Huth         ret = INT32_MAX;
842fcf5ef2aSThomas Huth     } else if (ret < -0x80000000ll) {
843fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
844fcf5ef2aSThomas Huth         env->PSW_USB_SV |= env->PSW_USB_V;
845fcf5ef2aSThomas Huth         ret = INT32_MIN;
846fcf5ef2aSThomas Huth     } else {
847fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
848fcf5ef2aSThomas Huth     }
849fcf5ef2aSThomas Huth     return ret & 0xffff0000ll;
850fcf5ef2aSThomas Huth }
851fcf5ef2aSThomas Huth 
helper_madd64_suov(CPUTriCoreState * env,target_ulong r1,uint64_t r2,target_ulong r3)852fcf5ef2aSThomas Huth uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
853fcf5ef2aSThomas Huth                             uint64_t r2, target_ulong r3)
854fcf5ef2aSThomas Huth {
855fcf5ef2aSThomas Huth     uint64_t ret, mul;
856fcf5ef2aSThomas Huth     uint64_t t1 = extract64(r1, 0, 32);
857fcf5ef2aSThomas Huth     uint64_t t3 = extract64(r3, 0, 32);
858fcf5ef2aSThomas Huth 
859fcf5ef2aSThomas Huth     mul = t1 * t3;
860fcf5ef2aSThomas Huth     ret = mul + r2;
861fcf5ef2aSThomas Huth 
862fcf5ef2aSThomas Huth     t1 = ret >> 32;
863fcf5ef2aSThomas Huth     env->PSW_USB_AV = t1 ^ t1 * 2u;
864fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
865fcf5ef2aSThomas Huth 
866fcf5ef2aSThomas Huth     if (ret < r2) {
867fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
868fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
869fcf5ef2aSThomas Huth         /* saturate */
870fcf5ef2aSThomas Huth         ret = UINT64_MAX;
871fcf5ef2aSThomas Huth     } else {
872fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
873fcf5ef2aSThomas Huth     }
874fcf5ef2aSThomas Huth     return ret;
875fcf5ef2aSThomas Huth }
876fcf5ef2aSThomas Huth 
helper_msub32_ssov(CPUTriCoreState * env,target_ulong r1,target_ulong r2,target_ulong r3)877fcf5ef2aSThomas Huth target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
878fcf5ef2aSThomas Huth                                 target_ulong r2, target_ulong r3)
879fcf5ef2aSThomas Huth {
880fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
881fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
882fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
883fcf5ef2aSThomas Huth     int64_t result;
884fcf5ef2aSThomas Huth 
885fcf5ef2aSThomas Huth     result = t2 - (t1 * t3);
886fcf5ef2aSThomas Huth     return ssov32(env, result);
887fcf5ef2aSThomas Huth }
888fcf5ef2aSThomas Huth 
helper_msub32_suov(CPUTriCoreState * env,target_ulong r1,target_ulong r2,target_ulong r3)889fcf5ef2aSThomas Huth target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
890fcf5ef2aSThomas Huth                                 target_ulong r2, target_ulong r3)
891fcf5ef2aSThomas Huth {
892fcf5ef2aSThomas Huth     uint64_t t1 = extract64(r1, 0, 32);
893fcf5ef2aSThomas Huth     uint64_t t2 = extract64(r2, 0, 32);
894fcf5ef2aSThomas Huth     uint64_t t3 = extract64(r3, 0, 32);
895fcf5ef2aSThomas Huth     uint64_t result;
896fcf5ef2aSThomas Huth     uint64_t mul;
897fcf5ef2aSThomas Huth 
898fcf5ef2aSThomas Huth     mul = (t1 * t3);
899fcf5ef2aSThomas Huth     result = t2 - mul;
900fcf5ef2aSThomas Huth 
901fcf5ef2aSThomas Huth     env->PSW_USB_AV = result ^ result * 2u;
902fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
903fcf5ef2aSThomas Huth     /* we calculate ovf by hand here, because the multiplication can overflow on
904fcf5ef2aSThomas Huth        the host, which would give false results if we compare to less than
905fcf5ef2aSThomas Huth        zero */
906fcf5ef2aSThomas Huth     if (mul > t2) {
907fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
908fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
909fcf5ef2aSThomas Huth         result = 0;
910fcf5ef2aSThomas Huth     } else {
911fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
912fcf5ef2aSThomas Huth     }
913fcf5ef2aSThomas Huth     return result;
914fcf5ef2aSThomas Huth }
915fcf5ef2aSThomas Huth 
helper_msub64_ssov(CPUTriCoreState * env,target_ulong r1,uint64_t r2,target_ulong r3)916fcf5ef2aSThomas Huth uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
917fcf5ef2aSThomas Huth                             uint64_t r2, target_ulong r3)
918fcf5ef2aSThomas Huth {
919fcf5ef2aSThomas Huth     uint64_t ret, ovf;
920fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
921fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
922fcf5ef2aSThomas Huth     int64_t mul;
923fcf5ef2aSThomas Huth 
924fcf5ef2aSThomas Huth     mul = t1 * t3;
925fcf5ef2aSThomas Huth     ret = r2 - mul;
926fcf5ef2aSThomas Huth     ovf = (ret ^ r2) & (mul ^ r2);
927fcf5ef2aSThomas Huth 
928fcf5ef2aSThomas Huth     t1 = ret >> 32;
929fcf5ef2aSThomas Huth     env->PSW_USB_AV = t1 ^ t1 * 2u;
930fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
931fcf5ef2aSThomas Huth 
932fcf5ef2aSThomas Huth     if ((int64_t)ovf < 0) {
933fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
934fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
935fcf5ef2aSThomas Huth         /* ext_ret > MAX_INT */
936fcf5ef2aSThomas Huth         if (mul < 0) {
937fcf5ef2aSThomas Huth             ret = INT64_MAX;
938fcf5ef2aSThomas Huth         /* ext_ret < MIN_INT */
939fcf5ef2aSThomas Huth         } else {
940fcf5ef2aSThomas Huth             ret = INT64_MIN;
941fcf5ef2aSThomas Huth         }
942fcf5ef2aSThomas Huth     } else {
943fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
944fcf5ef2aSThomas Huth     }
945fcf5ef2aSThomas Huth     return ret;
946fcf5ef2aSThomas Huth }
947fcf5ef2aSThomas Huth 
helper_msub64_suov(CPUTriCoreState * env,target_ulong r1,uint64_t r2,target_ulong r3)948fcf5ef2aSThomas Huth uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
949fcf5ef2aSThomas Huth                             uint64_t r2, target_ulong r3)
950fcf5ef2aSThomas Huth {
951fcf5ef2aSThomas Huth     uint64_t ret, mul;
952fcf5ef2aSThomas Huth     uint64_t t1 = extract64(r1, 0, 32);
953fcf5ef2aSThomas Huth     uint64_t t3 = extract64(r3, 0, 32);
954fcf5ef2aSThomas Huth 
955fcf5ef2aSThomas Huth     mul = t1 * t3;
956fcf5ef2aSThomas Huth     ret = r2 - mul;
957fcf5ef2aSThomas Huth 
958fcf5ef2aSThomas Huth     t1 = ret >> 32;
959fcf5ef2aSThomas Huth     env->PSW_USB_AV = t1 ^ t1 * 2u;
960fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
961fcf5ef2aSThomas Huth 
962fcf5ef2aSThomas Huth     if (ret > r2) {
963fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
964fcf5ef2aSThomas Huth         env->PSW_USB_SV = (1 << 31);
965fcf5ef2aSThomas Huth         /* saturate */
966fcf5ef2aSThomas Huth         ret = 0;
967fcf5ef2aSThomas Huth     } else {
968fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
969fcf5ef2aSThomas Huth     }
970fcf5ef2aSThomas Huth     return ret;
971fcf5ef2aSThomas Huth }
972fcf5ef2aSThomas Huth 
973fcf5ef2aSThomas Huth uint32_t
helper_msub32_q_sub_ssov(CPUTriCoreState * env,uint64_t r1,uint64_t r2)974fcf5ef2aSThomas Huth helper_msub32_q_sub_ssov(CPUTriCoreState *env, uint64_t r1, uint64_t r2)
975fcf5ef2aSThomas Huth {
976fcf5ef2aSThomas Huth     int64_t result;
977fcf5ef2aSThomas Huth     int64_t t1 = (int64_t)r1;
978fcf5ef2aSThomas Huth     int64_t t2 = (int64_t)r2;
979fcf5ef2aSThomas Huth 
980fcf5ef2aSThomas Huth     result = t1 - t2;
981fcf5ef2aSThomas Huth 
982fcf5ef2aSThomas Huth     env->PSW_USB_AV = (result ^ result * 2u);
983fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
984fcf5ef2aSThomas Huth 
985fcf5ef2aSThomas Huth     /* we do the saturation by hand, since we produce an overflow on the host
986fcf5ef2aSThomas Huth        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
987fcf5ef2aSThomas Huth        case, we flip the saturated value. */
988fcf5ef2aSThomas Huth     if (r2 == 0x8000000000000000LL) {
989fcf5ef2aSThomas Huth         if (result > 0x7fffffffLL) {
990fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
991fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
992fcf5ef2aSThomas Huth             result = INT32_MIN;
993fcf5ef2aSThomas Huth         } else if (result < -0x80000000LL) {
994fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
995fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
996fcf5ef2aSThomas Huth             result = INT32_MAX;
997fcf5ef2aSThomas Huth         } else {
998fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
999fcf5ef2aSThomas Huth         }
1000fcf5ef2aSThomas Huth     } else {
1001fcf5ef2aSThomas Huth         if (result > 0x7fffffffLL) {
1002fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
1003fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
1004fcf5ef2aSThomas Huth             result = INT32_MAX;
1005fcf5ef2aSThomas Huth         } else if (result < -0x80000000LL) {
1006fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
1007fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
1008fcf5ef2aSThomas Huth             result = INT32_MIN;
1009fcf5ef2aSThomas Huth         } else {
1010fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
1011fcf5ef2aSThomas Huth         }
1012fcf5ef2aSThomas Huth     }
1013fcf5ef2aSThomas Huth     return (uint32_t)result;
1014fcf5ef2aSThomas Huth }
1015fcf5ef2aSThomas Huth 
helper_msub64_q_ssov(CPUTriCoreState * env,uint64_t r1,uint32_t r2,uint32_t r3,uint32_t n)1016fcf5ef2aSThomas Huth uint64_t helper_msub64_q_ssov(CPUTriCoreState *env, uint64_t r1, uint32_t r2,
1017fcf5ef2aSThomas Huth                               uint32_t r3, uint32_t n)
1018fcf5ef2aSThomas Huth {
1019fcf5ef2aSThomas Huth     int64_t t1 = (int64_t)r1;
1020fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
1021fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
1022fcf5ef2aSThomas Huth     int64_t result, mul;
1023fcf5ef2aSThomas Huth     int64_t ovf;
1024fcf5ef2aSThomas Huth 
1025fcf5ef2aSThomas Huth     mul = (t2 * t3) << n;
1026fcf5ef2aSThomas Huth     result = t1 - mul;
1027fcf5ef2aSThomas Huth 
1028fcf5ef2aSThomas Huth     env->PSW_USB_AV = (result ^ result * 2u) >> 32;
1029fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1030fcf5ef2aSThomas Huth 
1031fcf5ef2aSThomas Huth     ovf = (result ^ t1) & (t1 ^ mul);
1032fcf5ef2aSThomas Huth     /* we do the saturation by hand, since we produce an overflow on the host
1033fcf5ef2aSThomas Huth        if the mul before was (0x80000000 * 0x80000000) << 1). If this is the
1034fcf5ef2aSThomas Huth        case, we flip the saturated value. */
1035fcf5ef2aSThomas Huth     if (mul == 0x8000000000000000LL) {
1036fcf5ef2aSThomas Huth         if (ovf >= 0) {
1037fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
1038fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
1039fcf5ef2aSThomas Huth             /* ext_ret > MAX_INT */
1040fcf5ef2aSThomas Huth             if (mul >= 0) {
1041fcf5ef2aSThomas Huth                 result = INT64_MAX;
1042fcf5ef2aSThomas Huth             /* ext_ret < MIN_INT */
1043fcf5ef2aSThomas Huth             } else {
1044fcf5ef2aSThomas Huth                result = INT64_MIN;
1045fcf5ef2aSThomas Huth             }
1046fcf5ef2aSThomas Huth         } else {
1047fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
1048fcf5ef2aSThomas Huth         }
1049fcf5ef2aSThomas Huth     } else {
1050fcf5ef2aSThomas Huth         if (ovf < 0) {
1051fcf5ef2aSThomas Huth             env->PSW_USB_V = (1 << 31);
1052fcf5ef2aSThomas Huth             env->PSW_USB_SV = (1 << 31);
1053fcf5ef2aSThomas Huth             /* ext_ret > MAX_INT */
1054fcf5ef2aSThomas Huth             if (mul < 0) {
1055fcf5ef2aSThomas Huth                 result = INT64_MAX;
1056fcf5ef2aSThomas Huth             /* ext_ret < MIN_INT */
1057fcf5ef2aSThomas Huth             } else {
1058fcf5ef2aSThomas Huth                result = INT64_MIN;
1059fcf5ef2aSThomas Huth             }
1060fcf5ef2aSThomas Huth         } else {
1061fcf5ef2aSThomas Huth             env->PSW_USB_V = 0;
1062fcf5ef2aSThomas Huth         }
1063fcf5ef2aSThomas Huth     }
1064fcf5ef2aSThomas Huth 
1065fcf5ef2aSThomas Huth     return (uint64_t)result;
1066fcf5ef2aSThomas Huth }
1067fcf5ef2aSThomas Huth 
helper_msubr_q_ssov(CPUTriCoreState * env,uint32_t r1,uint32_t r2,uint32_t r3,uint32_t n)1068fcf5ef2aSThomas Huth uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1069fcf5ef2aSThomas Huth                              uint32_t r3, uint32_t n)
1070fcf5ef2aSThomas Huth {
1071fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
1072fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
1073fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
1074fcf5ef2aSThomas Huth     int64_t mul, ret;
1075fcf5ef2aSThomas Huth 
1076fcf5ef2aSThomas Huth     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1077fcf5ef2aSThomas Huth         mul = 0x7fffffff;
1078fcf5ef2aSThomas Huth     } else {
1079fcf5ef2aSThomas Huth         mul = (t2 * t3) << n;
1080fcf5ef2aSThomas Huth     }
1081fcf5ef2aSThomas Huth 
1082fcf5ef2aSThomas Huth     ret = t1 - mul + 0x8000;
1083fcf5ef2aSThomas Huth 
1084fcf5ef2aSThomas Huth     env->PSW_USB_AV = ret ^ ret * 2u;
1085fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1086fcf5ef2aSThomas Huth 
1087fcf5ef2aSThomas Huth     if (ret > 0x7fffffffll) {
1088fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
1089fcf5ef2aSThomas Huth         env->PSW_USB_SV |= env->PSW_USB_V;
1090fcf5ef2aSThomas Huth         ret = INT32_MAX;
1091fcf5ef2aSThomas Huth     } else if (ret < -0x80000000ll) {
1092fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
1093fcf5ef2aSThomas Huth         env->PSW_USB_SV |= env->PSW_USB_V;
1094fcf5ef2aSThomas Huth         ret = INT32_MIN;
1095fcf5ef2aSThomas Huth     } else {
1096fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
1097fcf5ef2aSThomas Huth     }
1098fcf5ef2aSThomas Huth     return ret & 0xffff0000ll;
1099fcf5ef2aSThomas Huth }
1100fcf5ef2aSThomas Huth 
helper_abs_b(CPUTriCoreState * env,target_ulong arg)1101fcf5ef2aSThomas Huth uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
1102fcf5ef2aSThomas Huth {
1103fcf5ef2aSThomas Huth     int32_t b, i;
1104fcf5ef2aSThomas Huth     int32_t ovf = 0;
1105fcf5ef2aSThomas Huth     int32_t avf = 0;
1106fcf5ef2aSThomas Huth     int32_t ret = 0;
1107fcf5ef2aSThomas Huth 
1108fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {
1109fcf5ef2aSThomas Huth         b = sextract32(arg, i * 8, 8);
1110fcf5ef2aSThomas Huth         b = (b >= 0) ? b : (0 - b);
1111fcf5ef2aSThomas Huth         ovf |= (b > 0x7F) || (b < -0x80);
1112fcf5ef2aSThomas Huth         avf |= b ^ b * 2u;
1113fcf5ef2aSThomas Huth         ret |= (b & 0xff) << (i * 8);
1114fcf5ef2aSThomas Huth     }
1115fcf5ef2aSThomas Huth 
1116fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf << 31;
1117fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1118fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf << 24;
1119fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1120fcf5ef2aSThomas Huth 
1121fcf5ef2aSThomas Huth     return ret;
1122fcf5ef2aSThomas Huth }
1123fcf5ef2aSThomas Huth 
helper_abs_h(CPUTriCoreState * env,target_ulong arg)1124fcf5ef2aSThomas Huth uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
1125fcf5ef2aSThomas Huth {
1126fcf5ef2aSThomas Huth     int32_t h, i;
1127fcf5ef2aSThomas Huth     int32_t ovf = 0;
1128fcf5ef2aSThomas Huth     int32_t avf = 0;
1129fcf5ef2aSThomas Huth     int32_t ret = 0;
1130fcf5ef2aSThomas Huth 
1131fcf5ef2aSThomas Huth     for (i = 0; i < 2; i++) {
1132fcf5ef2aSThomas Huth         h = sextract32(arg, i * 16, 16);
1133fcf5ef2aSThomas Huth         h = (h >= 0) ? h : (0 - h);
1134fcf5ef2aSThomas Huth         ovf |= (h > 0x7FFF) || (h < -0x8000);
1135fcf5ef2aSThomas Huth         avf |= h ^ h * 2u;
1136fcf5ef2aSThomas Huth         ret |= (h & 0xffff) << (i * 16);
1137fcf5ef2aSThomas Huth     }
1138fcf5ef2aSThomas Huth 
1139fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf << 31;
1140fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1141fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf << 16;
1142fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1143fcf5ef2aSThomas Huth 
1144fcf5ef2aSThomas Huth     return ret;
1145fcf5ef2aSThomas Huth }
1146fcf5ef2aSThomas Huth 
helper_absdif_b(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1147fcf5ef2aSThomas Huth uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1148fcf5ef2aSThomas Huth {
1149fcf5ef2aSThomas Huth     int32_t b, i;
1150fcf5ef2aSThomas Huth     int32_t extr_r2;
1151fcf5ef2aSThomas Huth     int32_t ovf = 0;
1152fcf5ef2aSThomas Huth     int32_t avf = 0;
1153fcf5ef2aSThomas Huth     int32_t ret = 0;
1154fcf5ef2aSThomas Huth 
1155fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {
1156fcf5ef2aSThomas Huth         extr_r2 = sextract32(r2, i * 8, 8);
1157fcf5ef2aSThomas Huth         b = sextract32(r1, i * 8, 8);
1158fcf5ef2aSThomas Huth         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
1159fcf5ef2aSThomas Huth         ovf |= (b > 0x7F) || (b < -0x80);
1160fcf5ef2aSThomas Huth         avf |= b ^ b * 2u;
1161fcf5ef2aSThomas Huth         ret |= (b & 0xff) << (i * 8);
1162fcf5ef2aSThomas Huth     }
1163fcf5ef2aSThomas Huth 
1164fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf << 31;
1165fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1166fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf << 24;
1167fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1168fcf5ef2aSThomas Huth     return ret;
1169fcf5ef2aSThomas Huth }
1170fcf5ef2aSThomas Huth 
helper_absdif_h(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1171fcf5ef2aSThomas Huth uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1172fcf5ef2aSThomas Huth {
1173fcf5ef2aSThomas Huth     int32_t h, i;
1174fcf5ef2aSThomas Huth     int32_t extr_r2;
1175fcf5ef2aSThomas Huth     int32_t ovf = 0;
1176fcf5ef2aSThomas Huth     int32_t avf = 0;
1177fcf5ef2aSThomas Huth     int32_t ret = 0;
1178fcf5ef2aSThomas Huth 
1179fcf5ef2aSThomas Huth     for (i = 0; i < 2; i++) {
1180fcf5ef2aSThomas Huth         extr_r2 = sextract32(r2, i * 16, 16);
1181fcf5ef2aSThomas Huth         h = sextract32(r1, i * 16, 16);
1182fcf5ef2aSThomas Huth         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
1183fcf5ef2aSThomas Huth         ovf |= (h > 0x7FFF) || (h < -0x8000);
1184fcf5ef2aSThomas Huth         avf |= h ^ h * 2u;
1185fcf5ef2aSThomas Huth         ret |= (h & 0xffff) << (i * 16);
1186fcf5ef2aSThomas Huth     }
1187fcf5ef2aSThomas Huth 
1188fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf << 31;
1189fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1190fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf << 16;
1191fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1192fcf5ef2aSThomas Huth 
1193fcf5ef2aSThomas Huth     return ret;
1194fcf5ef2aSThomas Huth }
1195fcf5ef2aSThomas Huth 
helper_addr_h(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)1196fcf5ef2aSThomas Huth uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1197fcf5ef2aSThomas Huth                        uint32_t r2_h)
1198fcf5ef2aSThomas Huth {
1199fcf5ef2aSThomas Huth     int64_t mul_res0 = sextract64(r1, 0, 32);
1200fcf5ef2aSThomas Huth     int64_t mul_res1 = sextract64(r1, 32, 32);
1201fcf5ef2aSThomas Huth     int64_t r2_low = sextract64(r2_l, 0, 32);
1202fcf5ef2aSThomas Huth     int64_t r2_high = sextract64(r2_h, 0, 32);
1203fcf5ef2aSThomas Huth     int64_t result0, result1;
1204fcf5ef2aSThomas Huth     uint32_t ovf0, ovf1;
1205fcf5ef2aSThomas Huth     uint32_t avf0, avf1;
1206fcf5ef2aSThomas Huth 
1207fcf5ef2aSThomas Huth     ovf0 = ovf1 = 0;
1208fcf5ef2aSThomas Huth 
1209fcf5ef2aSThomas Huth     result0 = r2_low + mul_res0 + 0x8000;
1210fcf5ef2aSThomas Huth     result1 = r2_high + mul_res1 + 0x8000;
1211fcf5ef2aSThomas Huth 
1212fcf5ef2aSThomas Huth     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1213fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
1214fcf5ef2aSThomas Huth     }
1215fcf5ef2aSThomas Huth 
1216fcf5ef2aSThomas Huth     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1217fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
1218fcf5ef2aSThomas Huth     }
1219fcf5ef2aSThomas Huth 
1220fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf0 | ovf1;
1221fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1222fcf5ef2aSThomas Huth 
1223fcf5ef2aSThomas Huth     avf0 = result0 * 2u;
1224fcf5ef2aSThomas Huth     avf0 = result0 ^ avf0;
1225fcf5ef2aSThomas Huth     avf1 = result1 * 2u;
1226fcf5ef2aSThomas Huth     avf1 = result1 ^ avf1;
1227fcf5ef2aSThomas Huth 
1228fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf0 | avf1;
1229fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1230fcf5ef2aSThomas Huth 
1231fcf5ef2aSThomas Huth     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1232fcf5ef2aSThomas Huth }
1233fcf5ef2aSThomas Huth 
helper_addsur_h(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)1234fcf5ef2aSThomas Huth uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1235fcf5ef2aSThomas Huth                          uint32_t r2_h)
1236fcf5ef2aSThomas Huth {
1237fcf5ef2aSThomas Huth     int64_t mul_res0 = sextract64(r1, 0, 32);
1238fcf5ef2aSThomas Huth     int64_t mul_res1 = sextract64(r1, 32, 32);
1239fcf5ef2aSThomas Huth     int64_t r2_low = sextract64(r2_l, 0, 32);
1240fcf5ef2aSThomas Huth     int64_t r2_high = sextract64(r2_h, 0, 32);
1241fcf5ef2aSThomas Huth     int64_t result0, result1;
1242fcf5ef2aSThomas Huth     uint32_t ovf0, ovf1;
1243fcf5ef2aSThomas Huth     uint32_t avf0, avf1;
1244fcf5ef2aSThomas Huth 
1245fcf5ef2aSThomas Huth     ovf0 = ovf1 = 0;
1246fcf5ef2aSThomas Huth 
1247fcf5ef2aSThomas Huth     result0 = r2_low - mul_res0 + 0x8000;
1248fcf5ef2aSThomas Huth     result1 = r2_high + mul_res1 + 0x8000;
1249fcf5ef2aSThomas Huth 
1250fcf5ef2aSThomas Huth     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1251fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
1252fcf5ef2aSThomas Huth     }
1253fcf5ef2aSThomas Huth 
1254fcf5ef2aSThomas Huth     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1255fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
1256fcf5ef2aSThomas Huth     }
1257fcf5ef2aSThomas Huth 
1258fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf0 | ovf1;
1259fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1260fcf5ef2aSThomas Huth 
1261fcf5ef2aSThomas Huth     avf0 = result0 * 2u;
1262fcf5ef2aSThomas Huth     avf0 = result0 ^ avf0;
1263fcf5ef2aSThomas Huth     avf1 = result1 * 2u;
1264fcf5ef2aSThomas Huth     avf1 = result1 ^ avf1;
1265fcf5ef2aSThomas Huth 
1266fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf0 | avf1;
1267fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1268fcf5ef2aSThomas Huth 
1269fcf5ef2aSThomas Huth     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1270fcf5ef2aSThomas Huth }
1271fcf5ef2aSThomas Huth 
helper_maddr_q(CPUTriCoreState * env,uint32_t r1,uint32_t r2,uint32_t r3,uint32_t n)1272fcf5ef2aSThomas Huth uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1273fcf5ef2aSThomas Huth                         uint32_t r3, uint32_t n)
1274fcf5ef2aSThomas Huth {
1275fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
1276fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
1277fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
1278fcf5ef2aSThomas Huth     int64_t mul, ret;
1279fcf5ef2aSThomas Huth 
1280fcf5ef2aSThomas Huth     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1281fcf5ef2aSThomas Huth         mul = 0x7fffffff;
1282fcf5ef2aSThomas Huth     } else {
1283fcf5ef2aSThomas Huth         mul = (t2 * t3) << n;
1284fcf5ef2aSThomas Huth     }
1285fcf5ef2aSThomas Huth 
1286fcf5ef2aSThomas Huth     ret = t1 + mul + 0x8000;
1287fcf5ef2aSThomas Huth 
1288fcf5ef2aSThomas Huth     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1289fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
1290fcf5ef2aSThomas Huth         env->PSW_USB_SV |= env->PSW_USB_V;
1291fcf5ef2aSThomas Huth     } else {
1292fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
1293fcf5ef2aSThomas Huth     }
1294fcf5ef2aSThomas Huth     env->PSW_USB_AV = ret ^ ret * 2u;
1295fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1296fcf5ef2aSThomas Huth 
1297fcf5ef2aSThomas Huth     return ret & 0xffff0000ll;
1298fcf5ef2aSThomas Huth }
1299fcf5ef2aSThomas Huth 
helper_add_b(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1300fcf5ef2aSThomas Huth uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1301fcf5ef2aSThomas Huth {
1302fcf5ef2aSThomas Huth     int32_t b, i;
1303fcf5ef2aSThomas Huth     int32_t extr_r1, extr_r2;
1304fcf5ef2aSThomas Huth     int32_t ovf = 0;
1305fcf5ef2aSThomas Huth     int32_t avf = 0;
1306fcf5ef2aSThomas Huth     uint32_t ret = 0;
1307fcf5ef2aSThomas Huth 
1308fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {
1309fcf5ef2aSThomas Huth         extr_r1 = sextract32(r1, i * 8, 8);
1310fcf5ef2aSThomas Huth         extr_r2 = sextract32(r2, i * 8, 8);
1311fcf5ef2aSThomas Huth 
1312fcf5ef2aSThomas Huth         b = extr_r1 + extr_r2;
1313fcf5ef2aSThomas Huth         ovf |= ((b > 0x7f) || (b < -0x80));
1314fcf5ef2aSThomas Huth         avf |= b ^ b * 2u;
1315fcf5ef2aSThomas Huth         ret |= ((b & 0xff) << (i*8));
1316fcf5ef2aSThomas Huth     }
1317fcf5ef2aSThomas Huth 
1318fcf5ef2aSThomas Huth     env->PSW_USB_V = (ovf << 31);
1319fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1320fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf << 24;
1321fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1322fcf5ef2aSThomas Huth 
1323fcf5ef2aSThomas Huth     return ret;
1324fcf5ef2aSThomas Huth }
1325fcf5ef2aSThomas Huth 
helper_add_h(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1326fcf5ef2aSThomas Huth uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1327fcf5ef2aSThomas Huth {
1328fcf5ef2aSThomas Huth     int32_t h, i;
1329fcf5ef2aSThomas Huth     int32_t extr_r1, extr_r2;
1330fcf5ef2aSThomas Huth     int32_t ovf = 0;
1331fcf5ef2aSThomas Huth     int32_t avf = 0;
1332fcf5ef2aSThomas Huth     int32_t ret = 0;
1333fcf5ef2aSThomas Huth 
1334fcf5ef2aSThomas Huth     for (i = 0; i < 2; i++) {
1335fcf5ef2aSThomas Huth         extr_r1 = sextract32(r1, i * 16, 16);
1336fcf5ef2aSThomas Huth         extr_r2 = sextract32(r2, i * 16, 16);
1337fcf5ef2aSThomas Huth         h = extr_r1 + extr_r2;
1338fcf5ef2aSThomas Huth         ovf |= ((h > 0x7fff) || (h < -0x8000));
1339fcf5ef2aSThomas Huth         avf |= h ^ h * 2u;
1340fcf5ef2aSThomas Huth         ret |= (h & 0xffff) << (i * 16);
1341fcf5ef2aSThomas Huth     }
1342fcf5ef2aSThomas Huth 
1343fcf5ef2aSThomas Huth     env->PSW_USB_V = (ovf << 31);
1344fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1345fcf5ef2aSThomas Huth     env->PSW_USB_AV = (avf << 16);
1346fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1347fcf5ef2aSThomas Huth 
1348fcf5ef2aSThomas Huth     return ret;
1349fcf5ef2aSThomas Huth }
1350fcf5ef2aSThomas Huth 
helper_subr_h(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)1351fcf5ef2aSThomas Huth uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1352fcf5ef2aSThomas Huth                        uint32_t r2_h)
1353fcf5ef2aSThomas Huth {
1354fcf5ef2aSThomas Huth     int64_t mul_res0 = sextract64(r1, 0, 32);
1355fcf5ef2aSThomas Huth     int64_t mul_res1 = sextract64(r1, 32, 32);
1356fcf5ef2aSThomas Huth     int64_t r2_low = sextract64(r2_l, 0, 32);
1357fcf5ef2aSThomas Huth     int64_t r2_high = sextract64(r2_h, 0, 32);
1358fcf5ef2aSThomas Huth     int64_t result0, result1;
1359fcf5ef2aSThomas Huth     uint32_t ovf0, ovf1;
1360fcf5ef2aSThomas Huth     uint32_t avf0, avf1;
1361fcf5ef2aSThomas Huth 
1362fcf5ef2aSThomas Huth     ovf0 = ovf1 = 0;
1363fcf5ef2aSThomas Huth 
1364fcf5ef2aSThomas Huth     result0 = r2_low - mul_res0 + 0x8000;
1365fcf5ef2aSThomas Huth     result1 = r2_high - mul_res1 + 0x8000;
1366fcf5ef2aSThomas Huth 
1367fcf5ef2aSThomas Huth     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1368fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
1369fcf5ef2aSThomas Huth     }
1370fcf5ef2aSThomas Huth 
1371fcf5ef2aSThomas Huth     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1372fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
1373fcf5ef2aSThomas Huth     }
1374fcf5ef2aSThomas Huth 
1375fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf0 | ovf1;
1376fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1377fcf5ef2aSThomas Huth 
1378fcf5ef2aSThomas Huth     avf0 = result0 * 2u;
1379fcf5ef2aSThomas Huth     avf0 = result0 ^ avf0;
1380fcf5ef2aSThomas Huth     avf1 = result1 * 2u;
1381fcf5ef2aSThomas Huth     avf1 = result1 ^ avf1;
1382fcf5ef2aSThomas Huth 
1383fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf0 | avf1;
1384fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1385fcf5ef2aSThomas Huth 
1386fcf5ef2aSThomas Huth     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1387fcf5ef2aSThomas Huth }
1388fcf5ef2aSThomas Huth 
helper_subadr_h(CPUTriCoreState * env,uint64_t r1,uint32_t r2_l,uint32_t r2_h)1389fcf5ef2aSThomas Huth uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1390fcf5ef2aSThomas Huth                          uint32_t r2_h)
1391fcf5ef2aSThomas Huth {
1392fcf5ef2aSThomas Huth     int64_t mul_res0 = sextract64(r1, 0, 32);
1393fcf5ef2aSThomas Huth     int64_t mul_res1 = sextract64(r1, 32, 32);
1394fcf5ef2aSThomas Huth     int64_t r2_low = sextract64(r2_l, 0, 32);
1395fcf5ef2aSThomas Huth     int64_t r2_high = sextract64(r2_h, 0, 32);
1396fcf5ef2aSThomas Huth     int64_t result0, result1;
1397fcf5ef2aSThomas Huth     uint32_t ovf0, ovf1;
1398fcf5ef2aSThomas Huth     uint32_t avf0, avf1;
1399fcf5ef2aSThomas Huth 
1400fcf5ef2aSThomas Huth     ovf0 = ovf1 = 0;
1401fcf5ef2aSThomas Huth 
1402fcf5ef2aSThomas Huth     result0 = r2_low + mul_res0 + 0x8000;
1403fcf5ef2aSThomas Huth     result1 = r2_high - mul_res1 + 0x8000;
1404fcf5ef2aSThomas Huth 
1405fcf5ef2aSThomas Huth     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1406fcf5ef2aSThomas Huth         ovf0 = (1 << 31);
1407fcf5ef2aSThomas Huth     }
1408fcf5ef2aSThomas Huth 
1409fcf5ef2aSThomas Huth     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1410fcf5ef2aSThomas Huth         ovf1 = (1 << 31);
1411fcf5ef2aSThomas Huth     }
1412fcf5ef2aSThomas Huth 
1413fcf5ef2aSThomas Huth     env->PSW_USB_V = ovf0 | ovf1;
1414fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1415fcf5ef2aSThomas Huth 
1416fcf5ef2aSThomas Huth     avf0 = result0 * 2u;
1417fcf5ef2aSThomas Huth     avf0 = result0 ^ avf0;
1418fcf5ef2aSThomas Huth     avf1 = result1 * 2u;
1419fcf5ef2aSThomas Huth     avf1 = result1 ^ avf1;
1420fcf5ef2aSThomas Huth 
1421fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf0 | avf1;
1422fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1423fcf5ef2aSThomas Huth 
1424fcf5ef2aSThomas Huth     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1425fcf5ef2aSThomas Huth }
1426fcf5ef2aSThomas Huth 
helper_msubr_q(CPUTriCoreState * env,uint32_t r1,uint32_t r2,uint32_t r3,uint32_t n)1427fcf5ef2aSThomas Huth uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1428fcf5ef2aSThomas Huth                         uint32_t r3, uint32_t n)
1429fcf5ef2aSThomas Huth {
1430fcf5ef2aSThomas Huth     int64_t t1 = sextract64(r1, 0, 32);
1431fcf5ef2aSThomas Huth     int64_t t2 = sextract64(r2, 0, 32);
1432fcf5ef2aSThomas Huth     int64_t t3 = sextract64(r3, 0, 32);
1433fcf5ef2aSThomas Huth     int64_t mul, ret;
1434fcf5ef2aSThomas Huth 
1435fcf5ef2aSThomas Huth     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1436fcf5ef2aSThomas Huth         mul = 0x7fffffff;
1437fcf5ef2aSThomas Huth     } else {
1438fcf5ef2aSThomas Huth         mul = (t2 * t3) << n;
1439fcf5ef2aSThomas Huth     }
1440fcf5ef2aSThomas Huth 
1441fcf5ef2aSThomas Huth     ret = t1 - mul + 0x8000;
1442fcf5ef2aSThomas Huth 
1443fcf5ef2aSThomas Huth     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1444fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
1445fcf5ef2aSThomas Huth         env->PSW_USB_SV |= env->PSW_USB_V;
1446fcf5ef2aSThomas Huth     } else {
1447fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
1448fcf5ef2aSThomas Huth     }
1449fcf5ef2aSThomas Huth     env->PSW_USB_AV = ret ^ ret * 2u;
1450fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1451fcf5ef2aSThomas Huth 
1452fcf5ef2aSThomas Huth     return ret & 0xffff0000ll;
1453fcf5ef2aSThomas Huth }
1454fcf5ef2aSThomas Huth 
helper_sub_b(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1455fcf5ef2aSThomas Huth uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1456fcf5ef2aSThomas Huth {
1457fcf5ef2aSThomas Huth     int32_t b, i;
1458fcf5ef2aSThomas Huth     int32_t extr_r1, extr_r2;
1459fcf5ef2aSThomas Huth     int32_t ovf = 0;
1460fcf5ef2aSThomas Huth     int32_t avf = 0;
1461fcf5ef2aSThomas Huth     uint32_t ret = 0;
1462fcf5ef2aSThomas Huth 
1463fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {
1464fcf5ef2aSThomas Huth         extr_r1 = sextract32(r1, i * 8, 8);
1465fcf5ef2aSThomas Huth         extr_r2 = sextract32(r2, i * 8, 8);
1466fcf5ef2aSThomas Huth 
1467fcf5ef2aSThomas Huth         b = extr_r1 - extr_r2;
1468fcf5ef2aSThomas Huth         ovf |= ((b > 0x7f) || (b < -0x80));
1469fcf5ef2aSThomas Huth         avf |= b ^ b * 2u;
1470fcf5ef2aSThomas Huth         ret |= ((b & 0xff) << (i*8));
1471fcf5ef2aSThomas Huth     }
1472fcf5ef2aSThomas Huth 
1473fcf5ef2aSThomas Huth     env->PSW_USB_V = (ovf << 31);
1474fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1475fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf << 24;
1476fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1477fcf5ef2aSThomas Huth 
1478fcf5ef2aSThomas Huth     return ret;
1479fcf5ef2aSThomas Huth }
1480fcf5ef2aSThomas Huth 
helper_sub_h(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1481fcf5ef2aSThomas Huth uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1482fcf5ef2aSThomas Huth {
1483fcf5ef2aSThomas Huth     int32_t h, i;
1484fcf5ef2aSThomas Huth     int32_t extr_r1, extr_r2;
1485fcf5ef2aSThomas Huth     int32_t ovf = 0;
1486fcf5ef2aSThomas Huth     int32_t avf = 0;
1487fcf5ef2aSThomas Huth     int32_t ret = 0;
1488fcf5ef2aSThomas Huth 
1489fcf5ef2aSThomas Huth     for (i = 0; i < 2; i++) {
1490fcf5ef2aSThomas Huth         extr_r1 = sextract32(r1, i * 16, 16);
1491fcf5ef2aSThomas Huth         extr_r2 = sextract32(r2, i * 16, 16);
1492fcf5ef2aSThomas Huth         h = extr_r1 - extr_r2;
1493fcf5ef2aSThomas Huth         ovf |= ((h > 0x7fff) || (h < -0x8000));
1494fcf5ef2aSThomas Huth         avf |= h ^ h * 2u;
1495fcf5ef2aSThomas Huth         ret |= (h & 0xffff) << (i * 16);
1496fcf5ef2aSThomas Huth     }
1497fcf5ef2aSThomas Huth 
1498fcf5ef2aSThomas Huth     env->PSW_USB_V = (ovf << 31);
1499fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
1500fcf5ef2aSThomas Huth     env->PSW_USB_AV = avf << 16;
1501fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1502fcf5ef2aSThomas Huth 
1503fcf5ef2aSThomas Huth     return ret;
1504fcf5ef2aSThomas Huth }
1505fcf5ef2aSThomas Huth 
helper_eq_b(target_ulong r1,target_ulong r2)1506fcf5ef2aSThomas Huth uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
1507fcf5ef2aSThomas Huth {
1508*b69c95e7SPeter Maydell     uint32_t ret, msk;
1509*b69c95e7SPeter Maydell     int32_t i;
1510fcf5ef2aSThomas Huth 
1511fcf5ef2aSThomas Huth     ret = 0;
1512fcf5ef2aSThomas Huth     msk = 0xff;
1513fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {
1514fcf5ef2aSThomas Huth         if ((r1 & msk) == (r2 & msk)) {
1515fcf5ef2aSThomas Huth             ret |= msk;
1516fcf5ef2aSThomas Huth         }
1517fcf5ef2aSThomas Huth         msk = msk << 8;
1518fcf5ef2aSThomas Huth     }
1519fcf5ef2aSThomas Huth 
1520fcf5ef2aSThomas Huth     return ret;
1521fcf5ef2aSThomas Huth }
1522fcf5ef2aSThomas Huth 
helper_eq_h(target_ulong r1,target_ulong r2)1523fcf5ef2aSThomas Huth uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1524fcf5ef2aSThomas Huth {
1525fcf5ef2aSThomas Huth     int32_t ret = 0;
1526fcf5ef2aSThomas Huth 
1527fcf5ef2aSThomas Huth     if ((r1 & 0xffff) == (r2 & 0xffff)) {
1528fcf5ef2aSThomas Huth         ret = 0xffff;
1529fcf5ef2aSThomas Huth     }
1530fcf5ef2aSThomas Huth 
1531fcf5ef2aSThomas Huth     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1532fcf5ef2aSThomas Huth         ret |= 0xffff0000;
1533fcf5ef2aSThomas Huth     }
1534fcf5ef2aSThomas Huth 
1535fcf5ef2aSThomas Huth     return ret;
1536fcf5ef2aSThomas Huth }
1537fcf5ef2aSThomas Huth 
helper_eqany_b(target_ulong r1,target_ulong r2)1538fcf5ef2aSThomas Huth uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1539fcf5ef2aSThomas Huth {
1540fcf5ef2aSThomas Huth     int32_t i;
1541fcf5ef2aSThomas Huth     uint32_t ret = 0;
1542fcf5ef2aSThomas Huth 
1543fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {
1544fcf5ef2aSThomas Huth         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
1545fcf5ef2aSThomas Huth     }
1546fcf5ef2aSThomas Huth 
1547fcf5ef2aSThomas Huth     return ret;
1548fcf5ef2aSThomas Huth }
1549fcf5ef2aSThomas Huth 
helper_eqany_h(target_ulong r1,target_ulong r2)1550fcf5ef2aSThomas Huth uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1551fcf5ef2aSThomas Huth {
1552fcf5ef2aSThomas Huth     uint32_t ret;
1553fcf5ef2aSThomas Huth 
1554fcf5ef2aSThomas Huth     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
1555fcf5ef2aSThomas Huth     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
1556fcf5ef2aSThomas Huth 
1557fcf5ef2aSThomas Huth     return ret;
1558fcf5ef2aSThomas Huth }
1559fcf5ef2aSThomas Huth 
helper_lt_b(target_ulong r1,target_ulong r2)1560fcf5ef2aSThomas Huth uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1561fcf5ef2aSThomas Huth {
1562fcf5ef2aSThomas Huth     int32_t i;
1563fcf5ef2aSThomas Huth     uint32_t ret = 0;
1564fcf5ef2aSThomas Huth 
1565fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {
1566fcf5ef2aSThomas Huth         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
1567fcf5ef2aSThomas Huth             ret |= (0xff << (i * 8));
1568fcf5ef2aSThomas Huth         }
1569fcf5ef2aSThomas Huth     }
1570fcf5ef2aSThomas Huth 
1571fcf5ef2aSThomas Huth     return ret;
1572fcf5ef2aSThomas Huth }
1573fcf5ef2aSThomas Huth 
helper_lt_bu(target_ulong r1,target_ulong r2)1574fcf5ef2aSThomas Huth uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1575fcf5ef2aSThomas Huth {
1576fcf5ef2aSThomas Huth     int32_t i;
1577fcf5ef2aSThomas Huth     uint32_t ret = 0;
1578fcf5ef2aSThomas Huth 
1579fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {
1580fcf5ef2aSThomas Huth         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
1581fcf5ef2aSThomas Huth             ret |= (0xff << (i * 8));
1582fcf5ef2aSThomas Huth         }
1583fcf5ef2aSThomas Huth     }
1584fcf5ef2aSThomas Huth 
1585fcf5ef2aSThomas Huth     return ret;
1586fcf5ef2aSThomas Huth }
1587fcf5ef2aSThomas Huth 
helper_lt_h(target_ulong r1,target_ulong r2)1588fcf5ef2aSThomas Huth uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1589fcf5ef2aSThomas Huth {
1590fcf5ef2aSThomas Huth     uint32_t ret = 0;
1591fcf5ef2aSThomas Huth 
1592fcf5ef2aSThomas Huth     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
1593fcf5ef2aSThomas Huth         ret |= 0xffff;
1594fcf5ef2aSThomas Huth     }
1595fcf5ef2aSThomas Huth 
1596fcf5ef2aSThomas Huth     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
1597fcf5ef2aSThomas Huth         ret |= 0xffff0000;
1598fcf5ef2aSThomas Huth     }
1599fcf5ef2aSThomas Huth 
1600fcf5ef2aSThomas Huth     return ret;
1601fcf5ef2aSThomas Huth }
1602fcf5ef2aSThomas Huth 
helper_lt_hu(target_ulong r1,target_ulong r2)1603fcf5ef2aSThomas Huth uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1604fcf5ef2aSThomas Huth {
1605fcf5ef2aSThomas Huth     uint32_t ret = 0;
1606fcf5ef2aSThomas Huth 
1607fcf5ef2aSThomas Huth     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
1608fcf5ef2aSThomas Huth         ret |= 0xffff;
1609fcf5ef2aSThomas Huth     }
1610fcf5ef2aSThomas Huth 
1611fcf5ef2aSThomas Huth     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
1612fcf5ef2aSThomas Huth         ret |= 0xffff0000;
1613fcf5ef2aSThomas Huth     }
1614fcf5ef2aSThomas Huth 
1615fcf5ef2aSThomas Huth     return ret;
1616fcf5ef2aSThomas Huth }
1617fcf5ef2aSThomas Huth 
1618fcf5ef2aSThomas Huth #define EXTREMA_H_B(name, op)                                 \
1619fcf5ef2aSThomas Huth uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1620fcf5ef2aSThomas Huth {                                                             \
1621fcf5ef2aSThomas Huth     int32_t i, extr_r1, extr_r2;                              \
1622fcf5ef2aSThomas Huth     uint32_t ret = 0;                                         \
1623fcf5ef2aSThomas Huth                                                               \
1624fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {                                 \
1625fcf5ef2aSThomas Huth         extr_r1 = sextract32(r1, i * 8, 8);                   \
1626fcf5ef2aSThomas Huth         extr_r2 = sextract32(r2, i * 8, 8);                   \
1627fcf5ef2aSThomas Huth         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1628fcf5ef2aSThomas Huth         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1629fcf5ef2aSThomas Huth     }                                                         \
1630fcf5ef2aSThomas Huth     return ret;                                               \
1631fcf5ef2aSThomas Huth }                                                             \
1632fcf5ef2aSThomas Huth                                                               \
1633fcf5ef2aSThomas Huth uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1634fcf5ef2aSThomas Huth {                                                             \
1635fcf5ef2aSThomas Huth     int32_t i;                                                \
1636fcf5ef2aSThomas Huth     uint32_t extr_r1, extr_r2;                                \
1637fcf5ef2aSThomas Huth     uint32_t ret = 0;                                         \
1638fcf5ef2aSThomas Huth                                                               \
1639fcf5ef2aSThomas Huth     for (i = 0; i < 4; i++) {                                 \
1640fcf5ef2aSThomas Huth         extr_r1 = extract32(r1, i * 8, 8);                    \
1641fcf5ef2aSThomas Huth         extr_r2 = extract32(r2, i * 8, 8);                    \
1642fcf5ef2aSThomas Huth         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1643fcf5ef2aSThomas Huth         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1644fcf5ef2aSThomas Huth     }                                                         \
1645fcf5ef2aSThomas Huth     return ret;                                               \
1646fcf5ef2aSThomas Huth }                                                             \
1647fcf5ef2aSThomas Huth                                                               \
1648fcf5ef2aSThomas Huth uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1649fcf5ef2aSThomas Huth {                                                             \
1650fcf5ef2aSThomas Huth     int32_t extr_r1, extr_r2;                                 \
1651fcf5ef2aSThomas Huth     uint32_t ret = 0;                                         \
1652fcf5ef2aSThomas Huth                                                               \
1653fcf5ef2aSThomas Huth     extr_r1 = sextract32(r1, 0, 16);                          \
1654fcf5ef2aSThomas Huth     extr_r2 = sextract32(r2, 0, 16);                          \
1655fcf5ef2aSThomas Huth     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1656fcf5ef2aSThomas Huth     ret = ret & 0xffff;                                       \
1657fcf5ef2aSThomas Huth                                                               \
1658fcf5ef2aSThomas Huth     extr_r1 = sextract32(r1, 16, 16);                         \
1659fcf5ef2aSThomas Huth     extr_r2 = sextract32(r2, 16, 16);                         \
1660fcf5ef2aSThomas Huth     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1661fcf5ef2aSThomas Huth     ret |= extr_r1 << 16;                                     \
1662fcf5ef2aSThomas Huth                                                               \
1663fcf5ef2aSThomas Huth     return ret;                                               \
1664fcf5ef2aSThomas Huth }                                                             \
1665fcf5ef2aSThomas Huth                                                               \
1666fcf5ef2aSThomas Huth uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1667fcf5ef2aSThomas Huth {                                                             \
1668fcf5ef2aSThomas Huth     uint32_t extr_r1, extr_r2;                                \
1669fcf5ef2aSThomas Huth     uint32_t ret = 0;                                         \
1670fcf5ef2aSThomas Huth                                                               \
1671fcf5ef2aSThomas Huth     extr_r1 = extract32(r1, 0, 16);                           \
1672fcf5ef2aSThomas Huth     extr_r2 = extract32(r2, 0, 16);                           \
1673fcf5ef2aSThomas Huth     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1674fcf5ef2aSThomas Huth     ret = ret & 0xffff;                                       \
1675fcf5ef2aSThomas Huth                                                               \
1676fcf5ef2aSThomas Huth     extr_r1 = extract32(r1, 16, 16);                          \
1677fcf5ef2aSThomas Huth     extr_r2 = extract32(r2, 16, 16);                          \
1678fcf5ef2aSThomas Huth     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1679fcf5ef2aSThomas Huth     ret |= extr_r1 << (16);                                   \
1680fcf5ef2aSThomas Huth                                                               \
1681fcf5ef2aSThomas Huth     return ret;                                               \
1682fcf5ef2aSThomas Huth }                                                             \
1683fcf5ef2aSThomas Huth                                                               \
1684fcf5ef2aSThomas Huth uint64_t helper_ix##name(uint64_t r1, uint32_t r2)            \
1685fcf5ef2aSThomas Huth {                                                             \
1686fcf5ef2aSThomas Huth     int64_t r2l, r2h, r1hl;                                   \
1687fcf5ef2aSThomas Huth     uint64_t ret = 0;                                         \
1688fcf5ef2aSThomas Huth                                                               \
1689fcf5ef2aSThomas Huth     ret = ((r1 + 2) & 0xffff);                                \
1690fcf5ef2aSThomas Huth     r2l = sextract64(r2, 0, 16);                              \
1691fcf5ef2aSThomas Huth     r2h = sextract64(r2, 16, 16);                             \
1692fcf5ef2aSThomas Huth     r1hl = sextract64(r1, 32, 16);                            \
1693fcf5ef2aSThomas Huth                                                               \
1694fcf5ef2aSThomas Huth     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
1695fcf5ef2aSThomas Huth         ret |= (r2l & 0xffff) << 32;                          \
1696fcf5ef2aSThomas Huth         ret |= extract64(r1, 0, 16) << 16;                    \
1697fcf5ef2aSThomas Huth     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
1698fcf5ef2aSThomas Huth         ret |= extract64(r2, 16, 16) << 32;                   \
1699fcf5ef2aSThomas Huth         ret |= extract64(r1 + 1, 0, 16) << 16;                \
1700fcf5ef2aSThomas Huth     } else {                                                  \
1701fcf5ef2aSThomas Huth         ret |= r1 & 0xffffffff0000ull;                        \
1702fcf5ef2aSThomas Huth     }                                                         \
1703fcf5ef2aSThomas Huth     return ret;                                               \
1704fcf5ef2aSThomas Huth }                                                             \
1705fcf5ef2aSThomas Huth                                                               \
1706fcf5ef2aSThomas Huth uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)       \
1707fcf5ef2aSThomas Huth {                                                             \
1708fcf5ef2aSThomas Huth     int64_t r2l, r2h, r1hl;                                   \
1709fcf5ef2aSThomas Huth     uint64_t ret = 0;                                         \
1710fcf5ef2aSThomas Huth                                                               \
1711fcf5ef2aSThomas Huth     ret = ((r1 + 2) & 0xffff);                                \
1712fcf5ef2aSThomas Huth     r2l = extract64(r2, 0, 16);                               \
1713fcf5ef2aSThomas Huth     r2h = extract64(r2, 16, 16);                              \
1714fcf5ef2aSThomas Huth     r1hl = extract64(r1, 32, 16);                             \
1715fcf5ef2aSThomas Huth                                                               \
1716fcf5ef2aSThomas Huth     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
1717fcf5ef2aSThomas Huth         ret |= (r2l & 0xffff) << 32;                          \
1718fcf5ef2aSThomas Huth         ret |= extract64(r1, 0, 16) << 16;                    \
1719fcf5ef2aSThomas Huth     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
1720fcf5ef2aSThomas Huth         ret |= extract64(r2, 16, 16) << 32;                   \
1721fcf5ef2aSThomas Huth         ret |= extract64(r1 + 1, 0, 16) << 16;                \
1722fcf5ef2aSThomas Huth     } else {                                                  \
1723fcf5ef2aSThomas Huth         ret |= r1 & 0xffffffff0000ull;                        \
1724fcf5ef2aSThomas Huth     }                                                         \
1725fcf5ef2aSThomas Huth     return ret;                                               \
1726fcf5ef2aSThomas Huth }
1727fcf5ef2aSThomas Huth 
1728fcf5ef2aSThomas Huth EXTREMA_H_B(max, >)
1729fcf5ef2aSThomas Huth EXTREMA_H_B(min, <)
1730fcf5ef2aSThomas Huth 
1731fcf5ef2aSThomas Huth #undef EXTREMA_H_B
1732fcf5ef2aSThomas Huth 
helper_clo_h(target_ulong r1)1733fcf5ef2aSThomas Huth uint32_t helper_clo_h(target_ulong r1)
1734fcf5ef2aSThomas Huth {
1735fcf5ef2aSThomas Huth     uint32_t ret_hw0 = extract32(r1, 0, 16);
1736fcf5ef2aSThomas Huth     uint32_t ret_hw1 = extract32(r1, 16, 16);
1737fcf5ef2aSThomas Huth 
1738fcf5ef2aSThomas Huth     ret_hw0 = clo32(ret_hw0 << 16);
1739fcf5ef2aSThomas Huth     ret_hw1 = clo32(ret_hw1 << 16);
1740fcf5ef2aSThomas Huth 
1741fcf5ef2aSThomas Huth     if (ret_hw0 > 16) {
1742fcf5ef2aSThomas Huth         ret_hw0 = 16;
1743fcf5ef2aSThomas Huth     }
1744fcf5ef2aSThomas Huth     if (ret_hw1 > 16) {
1745fcf5ef2aSThomas Huth         ret_hw1 = 16;
1746fcf5ef2aSThomas Huth     }
1747fcf5ef2aSThomas Huth 
1748fcf5ef2aSThomas Huth     return ret_hw0 | (ret_hw1 << 16);
1749fcf5ef2aSThomas Huth }
1750fcf5ef2aSThomas Huth 
helper_clz_h(target_ulong r1)1751fcf5ef2aSThomas Huth uint32_t helper_clz_h(target_ulong r1)
1752fcf5ef2aSThomas Huth {
1753fcf5ef2aSThomas Huth     uint32_t ret_hw0 = extract32(r1, 0, 16);
1754fcf5ef2aSThomas Huth     uint32_t ret_hw1 = extract32(r1, 16, 16);
1755fcf5ef2aSThomas Huth 
1756fcf5ef2aSThomas Huth     ret_hw0 = clz32(ret_hw0 << 16);
1757fcf5ef2aSThomas Huth     ret_hw1 = clz32(ret_hw1 << 16);
1758fcf5ef2aSThomas Huth 
1759fcf5ef2aSThomas Huth     if (ret_hw0 > 16) {
1760fcf5ef2aSThomas Huth         ret_hw0 = 16;
1761fcf5ef2aSThomas Huth     }
1762fcf5ef2aSThomas Huth     if (ret_hw1 > 16) {
1763fcf5ef2aSThomas Huth         ret_hw1 = 16;
1764fcf5ef2aSThomas Huth     }
1765fcf5ef2aSThomas Huth 
1766fcf5ef2aSThomas Huth     return ret_hw0 | (ret_hw1 << 16);
1767fcf5ef2aSThomas Huth }
1768fcf5ef2aSThomas Huth 
helper_cls_h(target_ulong r1)1769fcf5ef2aSThomas Huth uint32_t helper_cls_h(target_ulong r1)
1770fcf5ef2aSThomas Huth {
1771fcf5ef2aSThomas Huth     uint32_t ret_hw0 = extract32(r1, 0, 16);
1772fcf5ef2aSThomas Huth     uint32_t ret_hw1 = extract32(r1, 16, 16);
1773fcf5ef2aSThomas Huth 
1774fcf5ef2aSThomas Huth     ret_hw0 = clrsb32(ret_hw0 << 16);
1775fcf5ef2aSThomas Huth     ret_hw1 = clrsb32(ret_hw1 << 16);
1776fcf5ef2aSThomas Huth 
1777fcf5ef2aSThomas Huth     if (ret_hw0 > 15) {
1778fcf5ef2aSThomas Huth         ret_hw0 = 15;
1779fcf5ef2aSThomas Huth     }
1780fcf5ef2aSThomas Huth     if (ret_hw1 > 15) {
1781fcf5ef2aSThomas Huth         ret_hw1 = 15;
1782fcf5ef2aSThomas Huth     }
1783fcf5ef2aSThomas Huth 
1784fcf5ef2aSThomas Huth     return ret_hw0 | (ret_hw1 << 16);
1785fcf5ef2aSThomas Huth }
1786fcf5ef2aSThomas Huth 
helper_sh(target_ulong r1,target_ulong r2)1787fcf5ef2aSThomas Huth uint32_t helper_sh(target_ulong r1, target_ulong r2)
1788fcf5ef2aSThomas Huth {
1789fcf5ef2aSThomas Huth     int32_t shift_count = sextract32(r2, 0, 6);
1790fcf5ef2aSThomas Huth 
1791fcf5ef2aSThomas Huth     if (shift_count == -32) {
1792fcf5ef2aSThomas Huth         return 0;
1793fcf5ef2aSThomas Huth     } else if (shift_count < 0) {
1794fcf5ef2aSThomas Huth         return r1 >> -shift_count;
1795fcf5ef2aSThomas Huth     } else {
1796fcf5ef2aSThomas Huth         return r1 << shift_count;
1797fcf5ef2aSThomas Huth     }
1798fcf5ef2aSThomas Huth }
1799fcf5ef2aSThomas Huth 
helper_sh_h(target_ulong r1,target_ulong r2)1800fcf5ef2aSThomas Huth uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
1801fcf5ef2aSThomas Huth {
1802fcf5ef2aSThomas Huth     int32_t ret_hw0, ret_hw1;
1803fcf5ef2aSThomas Huth     int32_t shift_count;
1804fcf5ef2aSThomas Huth 
1805fcf5ef2aSThomas Huth     shift_count = sextract32(r2, 0, 5);
1806fcf5ef2aSThomas Huth 
1807fcf5ef2aSThomas Huth     if (shift_count == -16) {
1808fcf5ef2aSThomas Huth         return 0;
1809fcf5ef2aSThomas Huth     } else if (shift_count < 0) {
1810fcf5ef2aSThomas Huth         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
1811fcf5ef2aSThomas Huth         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
1812fcf5ef2aSThomas Huth         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1813fcf5ef2aSThomas Huth     } else {
1814fcf5ef2aSThomas Huth         ret_hw0 = extract32(r1, 0, 16) << shift_count;
1815fcf5ef2aSThomas Huth         ret_hw1 = extract32(r1, 16, 16) << shift_count;
1816fcf5ef2aSThomas Huth         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1817fcf5ef2aSThomas Huth     }
1818fcf5ef2aSThomas Huth }
1819fcf5ef2aSThomas Huth 
helper_sha(CPUTriCoreState * env,target_ulong r1,target_ulong r2)1820fcf5ef2aSThomas Huth uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1821fcf5ef2aSThomas Huth {
1822fcf5ef2aSThomas Huth     int32_t shift_count;
1823fcf5ef2aSThomas Huth     int64_t result, t1;
1824fcf5ef2aSThomas Huth     uint32_t ret;
1825fcf5ef2aSThomas Huth 
1826fcf5ef2aSThomas Huth     shift_count = sextract32(r2, 0, 6);
1827fcf5ef2aSThomas Huth     t1 = sextract32(r1, 0, 32);
1828fcf5ef2aSThomas Huth 
1829fcf5ef2aSThomas Huth     if (shift_count == 0) {
1830fcf5ef2aSThomas Huth         env->PSW_USB_C = env->PSW_USB_V = 0;
1831fcf5ef2aSThomas Huth         ret = r1;
1832fcf5ef2aSThomas Huth     } else if (shift_count == -32) {
1833fcf5ef2aSThomas Huth         env->PSW_USB_C = r1;
1834fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
1835fcf5ef2aSThomas Huth         ret = t1 >> 31;
1836fcf5ef2aSThomas Huth     } else if (shift_count > 0) {
1837fcf5ef2aSThomas Huth         result = t1 << shift_count;
1838fcf5ef2aSThomas Huth         /* calc carry */
1839fcf5ef2aSThomas Huth         env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
1840fcf5ef2aSThomas Huth         /* calc v */
1841fcf5ef2aSThomas Huth         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
1842fcf5ef2aSThomas Huth                            (result < -0x80000000LL)) << 31);
1843fcf5ef2aSThomas Huth         /* calc sv */
1844fcf5ef2aSThomas Huth         env->PSW_USB_SV |= env->PSW_USB_V;
1845fcf5ef2aSThomas Huth         ret = (uint32_t)result;
1846fcf5ef2aSThomas Huth     } else {
1847fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
1848fcf5ef2aSThomas Huth         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
1849fcf5ef2aSThomas Huth         ret = t1 >> -shift_count;
1850fcf5ef2aSThomas Huth     }
1851fcf5ef2aSThomas Huth 
1852fcf5ef2aSThomas Huth     env->PSW_USB_AV = ret ^ ret * 2u;
1853fcf5ef2aSThomas Huth     env->PSW_USB_SAV |= env->PSW_USB_AV;
1854fcf5ef2aSThomas Huth 
1855fcf5ef2aSThomas Huth     return ret;
1856fcf5ef2aSThomas Huth }
1857fcf5ef2aSThomas Huth 
helper_sha_h(target_ulong r1,target_ulong r2)1858fcf5ef2aSThomas Huth uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
1859fcf5ef2aSThomas Huth {
1860fcf5ef2aSThomas Huth     int32_t shift_count;
1861fcf5ef2aSThomas Huth     int32_t ret_hw0, ret_hw1;
1862fcf5ef2aSThomas Huth 
1863fcf5ef2aSThomas Huth     shift_count = sextract32(r2, 0, 5);
1864fcf5ef2aSThomas Huth 
1865fcf5ef2aSThomas Huth     if (shift_count == 0) {
1866fcf5ef2aSThomas Huth         return r1;
1867fcf5ef2aSThomas Huth     } else if (shift_count < 0) {
1868fcf5ef2aSThomas Huth         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
1869fcf5ef2aSThomas Huth         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
1870fcf5ef2aSThomas Huth         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1871fcf5ef2aSThomas Huth     } else {
1872fcf5ef2aSThomas Huth         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
1873fcf5ef2aSThomas Huth         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
1874fcf5ef2aSThomas Huth         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1875fcf5ef2aSThomas Huth     }
1876fcf5ef2aSThomas Huth }
1877fcf5ef2aSThomas Huth 
helper_bmerge(target_ulong r1,target_ulong r2)1878fcf5ef2aSThomas Huth uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1879fcf5ef2aSThomas Huth {
1880fcf5ef2aSThomas Huth     uint32_t i, ret;
1881fcf5ef2aSThomas Huth 
1882fcf5ef2aSThomas Huth     ret = 0;
1883fcf5ef2aSThomas Huth     for (i = 0; i < 16; i++) {
1884fcf5ef2aSThomas Huth         ret |= (r1 & 1) << (2 * i + 1);
1885fcf5ef2aSThomas Huth         ret |= (r2 & 1) << (2 * i);
1886fcf5ef2aSThomas Huth         r1 = r1 >> 1;
1887fcf5ef2aSThomas Huth         r2 = r2 >> 1;
1888fcf5ef2aSThomas Huth     }
1889fcf5ef2aSThomas Huth     return ret;
1890fcf5ef2aSThomas Huth }
1891fcf5ef2aSThomas Huth 
helper_bsplit(uint32_t r1)1892fcf5ef2aSThomas Huth uint64_t helper_bsplit(uint32_t r1)
1893fcf5ef2aSThomas Huth {
1894fcf5ef2aSThomas Huth     int32_t i;
1895fcf5ef2aSThomas Huth     uint64_t ret;
1896fcf5ef2aSThomas Huth 
1897fcf5ef2aSThomas Huth     ret = 0;
1898fcf5ef2aSThomas Huth     for (i = 0; i < 32; i = i + 2) {
1899fcf5ef2aSThomas Huth         /* even */
1900fcf5ef2aSThomas Huth         ret |= (r1 & 1) << (i/2);
1901fcf5ef2aSThomas Huth         r1 = r1 >> 1;
1902fcf5ef2aSThomas Huth         /* odd */
1903fcf5ef2aSThomas Huth         ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1904fcf5ef2aSThomas Huth         r1 = r1 >> 1;
1905fcf5ef2aSThomas Huth     }
1906fcf5ef2aSThomas Huth     return ret;
1907fcf5ef2aSThomas Huth }
1908fcf5ef2aSThomas Huth 
helper_parity(target_ulong r1)1909fcf5ef2aSThomas Huth uint32_t helper_parity(target_ulong r1)
1910fcf5ef2aSThomas Huth {
1911fcf5ef2aSThomas Huth     uint32_t ret;
1912fcf5ef2aSThomas Huth     uint32_t nOnes, i;
1913fcf5ef2aSThomas Huth 
1914fcf5ef2aSThomas Huth     ret = 0;
1915fcf5ef2aSThomas Huth     nOnes = 0;
1916fcf5ef2aSThomas Huth     for (i = 0; i < 8; i++) {
1917fcf5ef2aSThomas Huth         ret ^= (r1 & 1);
1918fcf5ef2aSThomas Huth         r1 = r1 >> 1;
1919fcf5ef2aSThomas Huth     }
1920fcf5ef2aSThomas Huth     /* second byte */
1921fcf5ef2aSThomas Huth     nOnes = 0;
1922fcf5ef2aSThomas Huth     for (i = 0; i < 8; i++) {
1923fcf5ef2aSThomas Huth         nOnes ^= (r1 & 1);
1924fcf5ef2aSThomas Huth         r1 = r1 >> 1;
1925fcf5ef2aSThomas Huth     }
1926fcf5ef2aSThomas Huth     ret |= nOnes << 8;
1927fcf5ef2aSThomas Huth     /* third byte */
1928fcf5ef2aSThomas Huth     nOnes = 0;
1929fcf5ef2aSThomas Huth     for (i = 0; i < 8; i++) {
1930fcf5ef2aSThomas Huth         nOnes ^= (r1 & 1);
1931fcf5ef2aSThomas Huth         r1 = r1 >> 1;
1932fcf5ef2aSThomas Huth     }
1933fcf5ef2aSThomas Huth     ret |= nOnes << 16;
1934fcf5ef2aSThomas Huth     /* fourth byte */
1935fcf5ef2aSThomas Huth     nOnes = 0;
1936fcf5ef2aSThomas Huth     for (i = 0; i < 8; i++) {
1937fcf5ef2aSThomas Huth         nOnes ^= (r1 & 1);
1938fcf5ef2aSThomas Huth         r1 = r1 >> 1;
1939fcf5ef2aSThomas Huth     }
1940fcf5ef2aSThomas Huth     ret |= nOnes << 24;
1941fcf5ef2aSThomas Huth 
1942fcf5ef2aSThomas Huth     return ret;
1943fcf5ef2aSThomas Huth }
1944fcf5ef2aSThomas Huth 
helper_pack(uint32_t carry,uint32_t r1_low,uint32_t r1_high,target_ulong r2)1945fcf5ef2aSThomas Huth uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
1946fcf5ef2aSThomas Huth                      target_ulong r2)
1947fcf5ef2aSThomas Huth {
1948fcf5ef2aSThomas Huth     uint32_t ret;
1949fcf5ef2aSThomas Huth     int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
1950fcf5ef2aSThomas Huth     int32_t int_exp  = r1_high;
1951fcf5ef2aSThomas Huth     int32_t int_mant = r1_low;
1952fcf5ef2aSThomas Huth     uint32_t flag_rnd = (int_mant & (1 << 7)) && (
1953fcf5ef2aSThomas Huth                         (int_mant & (1 << 8)) ||
1954fcf5ef2aSThomas Huth                         (int_mant & 0x7f)     ||
1955fcf5ef2aSThomas Huth                         (carry != 0));
1956fcf5ef2aSThomas Huth     if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
1957fcf5ef2aSThomas Huth         fp_exp = 255;
1958fcf5ef2aSThomas Huth         fp_frac = extract32(int_mant, 8, 23);
1959fcf5ef2aSThomas Huth     } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
1960fcf5ef2aSThomas Huth         fp_exp  = 255;
1961fcf5ef2aSThomas Huth         fp_frac = 0;
1962fcf5ef2aSThomas Huth     } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
1963fcf5ef2aSThomas Huth         fp_exp  = 0;
1964fcf5ef2aSThomas Huth         fp_frac = 0;
1965fcf5ef2aSThomas Huth     } else if (int_mant == 0) {
1966fcf5ef2aSThomas Huth         fp_exp  = 0;
1967fcf5ef2aSThomas Huth         fp_frac = 0;
1968fcf5ef2aSThomas Huth     } else {
1969fcf5ef2aSThomas Huth         if (((int_mant & (1 << 31)) == 0)) {
1970fcf5ef2aSThomas Huth             temp_exp = 0;
1971fcf5ef2aSThomas Huth         } else {
1972fcf5ef2aSThomas Huth             temp_exp = int_exp + 128;
1973fcf5ef2aSThomas Huth         }
1974fcf5ef2aSThomas Huth         fp_exp_frac = (((temp_exp & 0xff) << 23) |
1975fcf5ef2aSThomas Huth                       extract32(int_mant, 8, 23))
1976fcf5ef2aSThomas Huth                       + flag_rnd;
1977fcf5ef2aSThomas Huth         fp_exp  = extract32(fp_exp_frac, 23, 8);
1978fcf5ef2aSThomas Huth         fp_frac = extract32(fp_exp_frac, 0, 23);
1979fcf5ef2aSThomas Huth     }
1980fcf5ef2aSThomas Huth     ret = r2 & (1 << 31);
1981fcf5ef2aSThomas Huth     ret = ret + (fp_exp << 23);
1982fcf5ef2aSThomas Huth     ret = ret + (fp_frac & 0x7fffff);
1983fcf5ef2aSThomas Huth 
1984fcf5ef2aSThomas Huth     return ret;
1985fcf5ef2aSThomas Huth }
1986fcf5ef2aSThomas Huth 
helper_unpack(target_ulong arg1)1987fcf5ef2aSThomas Huth uint64_t helper_unpack(target_ulong arg1)
1988fcf5ef2aSThomas Huth {
1989fcf5ef2aSThomas Huth     int32_t fp_exp  = extract32(arg1, 23, 8);
1990fcf5ef2aSThomas Huth     int32_t fp_frac = extract32(arg1, 0, 23);
1991fcf5ef2aSThomas Huth     uint64_t ret;
1992fcf5ef2aSThomas Huth     int32_t int_exp, int_mant;
1993fcf5ef2aSThomas Huth 
1994fcf5ef2aSThomas Huth     if (fp_exp == 255) {
1995fcf5ef2aSThomas Huth         int_exp = 255;
1996fcf5ef2aSThomas Huth         int_mant = (fp_frac << 7);
1997fcf5ef2aSThomas Huth     } else if ((fp_exp == 0) && (fp_frac == 0)) {
1998fcf5ef2aSThomas Huth         int_exp  = -127;
1999fcf5ef2aSThomas Huth         int_mant = 0;
2000fcf5ef2aSThomas Huth     } else if ((fp_exp == 0) && (fp_frac != 0)) {
2001fcf5ef2aSThomas Huth         int_exp  = -126;
2002fcf5ef2aSThomas Huth         int_mant = (fp_frac << 7);
2003fcf5ef2aSThomas Huth     } else {
2004fcf5ef2aSThomas Huth         int_exp  = fp_exp - 127;
2005fcf5ef2aSThomas Huth         int_mant = (fp_frac << 7);
2006fcf5ef2aSThomas Huth         int_mant |= (1 << 30);
2007fcf5ef2aSThomas Huth     }
2008fcf5ef2aSThomas Huth     ret = int_exp;
2009fcf5ef2aSThomas Huth     ret = ret << 32;
2010fcf5ef2aSThomas Huth     ret |= int_mant;
2011fcf5ef2aSThomas Huth 
2012fcf5ef2aSThomas Huth     return ret;
2013fcf5ef2aSThomas Huth }
2014fcf5ef2aSThomas Huth 
helper_dvinit_b_13(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2015fcf5ef2aSThomas Huth uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2016fcf5ef2aSThomas Huth {
2017fcf5ef2aSThomas Huth     uint64_t ret;
2018fcf5ef2aSThomas Huth     int32_t abs_sig_dividend, abs_divisor;
2019fcf5ef2aSThomas Huth 
2020fcf5ef2aSThomas Huth     ret = sextract32(r1, 0, 32);
2021fcf5ef2aSThomas Huth     ret = ret << 24;
2022fcf5ef2aSThomas Huth     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2023fcf5ef2aSThomas Huth         ret |= 0xffffff;
2024fcf5ef2aSThomas Huth     }
2025fcf5ef2aSThomas Huth 
2026fcf5ef2aSThomas Huth     abs_sig_dividend = abs((int32_t)r1) >> 8;
2027fcf5ef2aSThomas Huth     abs_divisor = abs((int32_t)r2);
2028fcf5ef2aSThomas Huth     /* calc overflow
2029fcf5ef2aSThomas Huth        ofv if (a/b >= 255) <=> (a/255 >= b) */
2030fcf5ef2aSThomas Huth     env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2031fcf5ef2aSThomas Huth     env->PSW_USB_V = env->PSW_USB_V << 31;
2032fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
2033fcf5ef2aSThomas Huth     env->PSW_USB_AV = 0;
2034fcf5ef2aSThomas Huth 
2035fcf5ef2aSThomas Huth     return ret;
2036fcf5ef2aSThomas Huth }
2037fcf5ef2aSThomas Huth 
helper_dvinit_b_131(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2038fcf5ef2aSThomas Huth uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2039fcf5ef2aSThomas Huth {
2040fcf5ef2aSThomas Huth     uint64_t ret = sextract32(r1, 0, 32);
2041fcf5ef2aSThomas Huth 
2042fcf5ef2aSThomas Huth     ret = ret << 24;
2043fcf5ef2aSThomas Huth     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2044fcf5ef2aSThomas Huth         ret |= 0xffffff;
2045fcf5ef2aSThomas Huth     }
2046fcf5ef2aSThomas Huth     /* calc overflow */
2047fcf5ef2aSThomas Huth     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
2048fcf5ef2aSThomas Huth     env->PSW_USB_V = env->PSW_USB_V << 31;
2049fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
2050fcf5ef2aSThomas Huth     env->PSW_USB_AV = 0;
2051fcf5ef2aSThomas Huth 
2052fcf5ef2aSThomas Huth     return ret;
2053fcf5ef2aSThomas Huth }
2054fcf5ef2aSThomas Huth 
helper_dvinit_h_13(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2055fcf5ef2aSThomas Huth uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2056fcf5ef2aSThomas Huth {
2057fcf5ef2aSThomas Huth     uint64_t ret;
2058fcf5ef2aSThomas Huth     int32_t abs_sig_dividend, abs_divisor;
2059fcf5ef2aSThomas Huth 
2060fcf5ef2aSThomas Huth     ret = sextract32(r1, 0, 32);
2061fcf5ef2aSThomas Huth     ret = ret << 16;
2062fcf5ef2aSThomas Huth     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2063fcf5ef2aSThomas Huth         ret |= 0xffff;
2064fcf5ef2aSThomas Huth     }
2065fcf5ef2aSThomas Huth 
2066fcf5ef2aSThomas Huth     abs_sig_dividend = abs((int32_t)r1) >> 16;
2067fcf5ef2aSThomas Huth     abs_divisor = abs((int32_t)r2);
2068fcf5ef2aSThomas Huth     /* calc overflow
2069fcf5ef2aSThomas Huth        ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */
2070fcf5ef2aSThomas Huth     env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2071fcf5ef2aSThomas Huth     env->PSW_USB_V = env->PSW_USB_V << 31;
2072fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
2073fcf5ef2aSThomas Huth     env->PSW_USB_AV = 0;
2074fcf5ef2aSThomas Huth 
2075fcf5ef2aSThomas Huth     return ret;
2076fcf5ef2aSThomas Huth }
2077fcf5ef2aSThomas Huth 
helper_dvinit_h_131(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2078fcf5ef2aSThomas Huth uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2079fcf5ef2aSThomas Huth {
2080fcf5ef2aSThomas Huth     uint64_t ret = sextract32(r1, 0, 32);
2081fcf5ef2aSThomas Huth 
2082fcf5ef2aSThomas Huth     ret = ret << 16;
2083fcf5ef2aSThomas Huth     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2084fcf5ef2aSThomas Huth         ret |= 0xffff;
2085fcf5ef2aSThomas Huth     }
2086fcf5ef2aSThomas Huth     /* calc overflow */
2087fcf5ef2aSThomas Huth     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
2088fcf5ef2aSThomas Huth     env->PSW_USB_V = env->PSW_USB_V << 31;
2089fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
2090fcf5ef2aSThomas Huth     env->PSW_USB_AV = 0;
2091fcf5ef2aSThomas Huth 
2092fcf5ef2aSThomas Huth     return ret;
2093fcf5ef2aSThomas Huth }
2094fcf5ef2aSThomas Huth 
helper_dvadj(uint64_t r1,uint32_t r2)2095fcf5ef2aSThomas Huth uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
2096fcf5ef2aSThomas Huth {
2097fcf5ef2aSThomas Huth     int32_t x_sign = (r1 >> 63);
2098fcf5ef2aSThomas Huth     int32_t q_sign = x_sign ^ (r2 >> 31);
2099fcf5ef2aSThomas Huth     int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
2100fcf5ef2aSThomas Huth     int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
2101fcf5ef2aSThomas Huth     uint32_t quotient;
2102fcf5ef2aSThomas Huth     uint64_t remainder;
2103fcf5ef2aSThomas Huth 
2104fcf5ef2aSThomas Huth     if ((q_sign & ~eq_neg) | eq_pos) {
2105fcf5ef2aSThomas Huth         quotient = (r1 + 1) & 0xffffffff;
2106fcf5ef2aSThomas Huth     } else {
2107fcf5ef2aSThomas Huth         quotient = r1 & 0xffffffff;
2108fcf5ef2aSThomas Huth     }
2109fcf5ef2aSThomas Huth 
2110fcf5ef2aSThomas Huth     if (eq_pos | eq_neg) {
2111fcf5ef2aSThomas Huth         remainder = 0;
2112fcf5ef2aSThomas Huth     } else {
2113fcf5ef2aSThomas Huth         remainder = (r1 & 0xffffffff00000000ull);
2114fcf5ef2aSThomas Huth     }
2115fcf5ef2aSThomas Huth     return remainder | quotient;
2116fcf5ef2aSThomas Huth }
2117fcf5ef2aSThomas Huth 
helper_dvstep(uint64_t r1,uint32_t r2)2118fcf5ef2aSThomas Huth uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
2119fcf5ef2aSThomas Huth {
2120fcf5ef2aSThomas Huth     int32_t dividend_sign = extract64(r1, 63, 1);
2121fcf5ef2aSThomas Huth     int32_t divisor_sign = extract32(r2, 31, 1);
2122fcf5ef2aSThomas Huth     int32_t quotient_sign = (dividend_sign != divisor_sign);
2123fcf5ef2aSThomas Huth     int32_t addend, dividend_quotient, remainder;
2124fcf5ef2aSThomas Huth     int32_t i, temp;
2125fcf5ef2aSThomas Huth 
2126fcf5ef2aSThomas Huth     if (quotient_sign) {
2127fcf5ef2aSThomas Huth         addend = r2;
2128fcf5ef2aSThomas Huth     } else {
2129fcf5ef2aSThomas Huth         addend = -r2;
2130fcf5ef2aSThomas Huth     }
2131fcf5ef2aSThomas Huth     dividend_quotient = (int32_t)r1;
2132fcf5ef2aSThomas Huth     remainder = (int32_t)(r1 >> 32);
2133fcf5ef2aSThomas Huth 
2134fcf5ef2aSThomas Huth     for (i = 0; i < 8; i++) {
2135fcf5ef2aSThomas Huth         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2136fcf5ef2aSThomas Huth         dividend_quotient <<= 1;
2137fcf5ef2aSThomas Huth         temp = remainder + addend;
2138fcf5ef2aSThomas Huth         if ((temp < 0) == dividend_sign) {
2139fcf5ef2aSThomas Huth             remainder = temp;
2140fcf5ef2aSThomas Huth         }
2141fcf5ef2aSThomas Huth         if (((temp < 0) == dividend_sign)) {
2142fcf5ef2aSThomas Huth             dividend_quotient = dividend_quotient | !quotient_sign;
2143fcf5ef2aSThomas Huth         } else {
2144fcf5ef2aSThomas Huth             dividend_quotient = dividend_quotient | quotient_sign;
2145fcf5ef2aSThomas Huth         }
2146fcf5ef2aSThomas Huth     }
2147fcf5ef2aSThomas Huth     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2148fcf5ef2aSThomas Huth }
2149fcf5ef2aSThomas Huth 
helper_dvstep_u(uint64_t r1,uint32_t r2)2150fcf5ef2aSThomas Huth uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
2151fcf5ef2aSThomas Huth {
2152fcf5ef2aSThomas Huth     int32_t dividend_quotient = extract64(r1, 0, 32);
2153fcf5ef2aSThomas Huth     int64_t remainder = extract64(r1, 32, 32);
2154fcf5ef2aSThomas Huth     int32_t i;
2155fcf5ef2aSThomas Huth     int64_t temp;
2156fcf5ef2aSThomas Huth     for (i = 0; i < 8; i++) {
2157fcf5ef2aSThomas Huth         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2158fcf5ef2aSThomas Huth         dividend_quotient <<= 1;
2159fcf5ef2aSThomas Huth         temp = (remainder & 0xffffffff) - r2;
2160fcf5ef2aSThomas Huth         if (temp >= 0) {
2161fcf5ef2aSThomas Huth             remainder = temp;
2162fcf5ef2aSThomas Huth         }
2163fcf5ef2aSThomas Huth         dividend_quotient = dividend_quotient | !(temp < 0);
2164fcf5ef2aSThomas Huth     }
2165fcf5ef2aSThomas Huth     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2166fcf5ef2aSThomas Huth }
2167fcf5ef2aSThomas Huth 
helper_divide(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2168fcf5ef2aSThomas Huth uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2169fcf5ef2aSThomas Huth {
2170fcf5ef2aSThomas Huth     int32_t quotient, remainder;
2171fcf5ef2aSThomas Huth     int32_t dividend = (int32_t)r1;
2172fcf5ef2aSThomas Huth     int32_t divisor = (int32_t)r2;
2173fcf5ef2aSThomas Huth 
2174fcf5ef2aSThomas Huth     if (divisor == 0) {
2175fcf5ef2aSThomas Huth         if (dividend >= 0) {
2176fcf5ef2aSThomas Huth             quotient = 0x7fffffff;
2177fcf5ef2aSThomas Huth             remainder = 0;
2178fcf5ef2aSThomas Huth         } else {
2179fcf5ef2aSThomas Huth             quotient = 0x80000000;
2180fcf5ef2aSThomas Huth             remainder = 0;
2181fcf5ef2aSThomas Huth         }
2182fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
2183fcf5ef2aSThomas Huth     } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
2184fcf5ef2aSThomas Huth         quotient = 0x7fffffff;
2185fcf5ef2aSThomas Huth         remainder = 0;
2186fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
2187fcf5ef2aSThomas Huth     } else {
2188fcf5ef2aSThomas Huth         remainder = dividend % divisor;
2189fcf5ef2aSThomas Huth         quotient = (dividend - remainder)/divisor;
2190fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
2191fcf5ef2aSThomas Huth     }
2192fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
2193fcf5ef2aSThomas Huth     env->PSW_USB_AV = 0;
2194fcf5ef2aSThomas Huth     return ((uint64_t)remainder << 32) | (uint32_t)quotient;
2195fcf5ef2aSThomas Huth }
2196fcf5ef2aSThomas Huth 
helper_divide_u(CPUTriCoreState * env,uint32_t r1,uint32_t r2)2197fcf5ef2aSThomas Huth uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2198fcf5ef2aSThomas Huth {
2199fcf5ef2aSThomas Huth     uint32_t quotient, remainder;
2200fcf5ef2aSThomas Huth     uint32_t dividend = r1;
2201fcf5ef2aSThomas Huth     uint32_t divisor = r2;
2202fcf5ef2aSThomas Huth 
2203fcf5ef2aSThomas Huth     if (divisor == 0) {
2204fcf5ef2aSThomas Huth         quotient = 0xffffffff;
2205fcf5ef2aSThomas Huth         remainder = 0;
2206fcf5ef2aSThomas Huth         env->PSW_USB_V = (1 << 31);
2207fcf5ef2aSThomas Huth     } else {
2208fcf5ef2aSThomas Huth         remainder = dividend % divisor;
2209fcf5ef2aSThomas Huth         quotient = (dividend - remainder)/divisor;
2210fcf5ef2aSThomas Huth         env->PSW_USB_V = 0;
2211fcf5ef2aSThomas Huth     }
2212fcf5ef2aSThomas Huth     env->PSW_USB_SV |= env->PSW_USB_V;
2213fcf5ef2aSThomas Huth     env->PSW_USB_AV = 0;
2214fcf5ef2aSThomas Huth     return ((uint64_t)remainder << 32) | quotient;
2215fcf5ef2aSThomas Huth }
2216fcf5ef2aSThomas Huth 
helper_mul_h(uint32_t arg00,uint32_t arg01,uint32_t arg10,uint32_t arg11,uint32_t n)2217fcf5ef2aSThomas Huth uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
2218fcf5ef2aSThomas Huth                       uint32_t arg10, uint32_t arg11, uint32_t n)
2219fcf5ef2aSThomas Huth {
2220fcf5ef2aSThomas Huth     uint32_t result0, result1;
2221fcf5ef2aSThomas Huth 
2222fcf5ef2aSThomas Huth     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2223fcf5ef2aSThomas Huth                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
2224fcf5ef2aSThomas Huth     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2225fcf5ef2aSThomas Huth                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
2226fcf5ef2aSThomas Huth     if (sc1) {
2227fcf5ef2aSThomas Huth         result1 = 0x7fffffff;
2228fcf5ef2aSThomas Huth     } else {
2229fcf5ef2aSThomas Huth         result1 = (((uint32_t)(arg00 * arg10)) << n);
2230fcf5ef2aSThomas Huth     }
2231fcf5ef2aSThomas Huth     if (sc0) {
2232fcf5ef2aSThomas Huth         result0 = 0x7fffffff;
2233fcf5ef2aSThomas Huth     } else {
2234fcf5ef2aSThomas Huth         result0 = (((uint32_t)(arg01 * arg11)) << n);
2235fcf5ef2aSThomas Huth     }
2236fcf5ef2aSThomas Huth     return (((uint64_t)result1 << 32)) | result0;
2237fcf5ef2aSThomas Huth }
2238fcf5ef2aSThomas Huth 
helper_mulm_h(uint32_t arg00,uint32_t arg01,uint32_t arg10,uint32_t arg11,uint32_t n)2239fcf5ef2aSThomas Huth uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
2240fcf5ef2aSThomas Huth                        uint32_t arg10, uint32_t arg11, uint32_t n)
2241fcf5ef2aSThomas Huth {
2242fcf5ef2aSThomas Huth     uint64_t ret;
2243fcf5ef2aSThomas Huth     int64_t result0, result1;
2244fcf5ef2aSThomas Huth 
2245fcf5ef2aSThomas Huth     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2246fcf5ef2aSThomas Huth                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
2247fcf5ef2aSThomas Huth     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2248fcf5ef2aSThomas Huth                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
2249fcf5ef2aSThomas Huth 
2250fcf5ef2aSThomas Huth     if (sc1) {
2251fcf5ef2aSThomas Huth         result1 = 0x7fffffff;
2252fcf5ef2aSThomas Huth     } else {
2253fcf5ef2aSThomas Huth         result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
2254fcf5ef2aSThomas Huth     }
2255fcf5ef2aSThomas Huth     if (sc0) {
2256fcf5ef2aSThomas Huth         result0 = 0x7fffffff;
2257fcf5ef2aSThomas Huth     } else {
2258fcf5ef2aSThomas Huth         result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
2259fcf5ef2aSThomas Huth     }
2260fcf5ef2aSThomas Huth     ret = (result1 + result0);
2261fcf5ef2aSThomas Huth     ret = ret << 16;
2262fcf5ef2aSThomas Huth     return ret;
2263fcf5ef2aSThomas Huth }
helper_mulr_h(uint32_t arg00,uint32_t arg01,uint32_t arg10,uint32_t arg11,uint32_t n)2264fcf5ef2aSThomas Huth uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
2265fcf5ef2aSThomas Huth                        uint32_t arg10, uint32_t arg11, uint32_t n)
2266fcf5ef2aSThomas Huth {
2267fcf5ef2aSThomas Huth     uint32_t result0, result1;
2268fcf5ef2aSThomas Huth 
2269fcf5ef2aSThomas Huth     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2270fcf5ef2aSThomas Huth                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
2271fcf5ef2aSThomas Huth     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2272fcf5ef2aSThomas Huth                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
2273fcf5ef2aSThomas Huth 
2274fcf5ef2aSThomas Huth     if (sc1) {
2275fcf5ef2aSThomas Huth         result1 = 0x7fffffff;
2276fcf5ef2aSThomas Huth     } else {
2277fcf5ef2aSThomas Huth         result1 = ((arg00 * arg10) << n) + 0x8000;
2278fcf5ef2aSThomas Huth     }
2279fcf5ef2aSThomas Huth     if (sc0) {
2280fcf5ef2aSThomas Huth         result0 = 0x7fffffff;
2281fcf5ef2aSThomas Huth     } else {
2282fcf5ef2aSThomas Huth         result0 = ((arg01 * arg11) << n) + 0x8000;
2283fcf5ef2aSThomas Huth     }
2284fcf5ef2aSThomas Huth     return (result1 & 0xffff0000) | (result0 >> 16);
2285fcf5ef2aSThomas Huth }
2286fcf5ef2aSThomas Huth 
helper_crc32b(uint32_t arg0,uint32_t arg1)22870eaafe33SBastian Koppelmann uint32_t helper_crc32b(uint32_t arg0, uint32_t arg1)
22880eaafe33SBastian Koppelmann {
22890eaafe33SBastian Koppelmann     uint8_t buf[1] = { arg0 & 0xff };
22900eaafe33SBastian Koppelmann 
22910eaafe33SBastian Koppelmann     return crc32(arg1, buf, 1);
22920eaafe33SBastian Koppelmann }
22930eaafe33SBastian Koppelmann 
22940eaafe33SBastian Koppelmann 
helper_crc32_be(uint32_t arg0,uint32_t arg1)2295dc0b4368SBastian Koppelmann uint32_t helper_crc32_be(uint32_t arg0, uint32_t arg1)
2296fcf5ef2aSThomas Huth {
2297fcf5ef2aSThomas Huth     uint8_t buf[4];
2298fcf5ef2aSThomas Huth     stl_be_p(buf, arg0);
2299fcf5ef2aSThomas Huth 
2300fcf5ef2aSThomas Huth     return crc32(arg1, buf, 4);
2301fcf5ef2aSThomas Huth }
2302fcf5ef2aSThomas Huth 
helper_crc32_le(uint32_t arg0,uint32_t arg1)2303dc0b4368SBastian Koppelmann uint32_t helper_crc32_le(uint32_t arg0, uint32_t arg1)
2304dc0b4368SBastian Koppelmann {
2305dc0b4368SBastian Koppelmann     uint8_t buf[4];
2306dc0b4368SBastian Koppelmann     stl_le_p(buf, arg0);
2307dc0b4368SBastian Koppelmann 
2308dc0b4368SBastian Koppelmann     return crc32(arg1, buf, 4);
2309dc0b4368SBastian Koppelmann }
2310dc0b4368SBastian Koppelmann 
crc_div(uint32_t crc_in,uint32_t data,uint32_t gen,uint32_t n,uint32_t m)23113e2a5107SBastian Koppelmann static uint32_t crc_div(uint32_t crc_in, uint32_t data, uint32_t gen,
23123e2a5107SBastian Koppelmann                         uint32_t n, uint32_t m)
23133e2a5107SBastian Koppelmann {
23143e2a5107SBastian Koppelmann     uint32_t i;
23153e2a5107SBastian Koppelmann 
23163e2a5107SBastian Koppelmann     data = data << n;
23173e2a5107SBastian Koppelmann     for (i = 0; i < m; i++) {
23183e2a5107SBastian Koppelmann         if (crc_in & (1u << (n - 1))) {
23193e2a5107SBastian Koppelmann             crc_in <<= 1;
23203e2a5107SBastian Koppelmann             if (data & (1u << (m - 1))) {
23213e2a5107SBastian Koppelmann                 crc_in++;
23223e2a5107SBastian Koppelmann             }
23233e2a5107SBastian Koppelmann             crc_in ^= gen;
23243e2a5107SBastian Koppelmann         } else {
23253e2a5107SBastian Koppelmann             crc_in <<= 1;
23263e2a5107SBastian Koppelmann             if (data & (1u << (m - 1))) {
23273e2a5107SBastian Koppelmann                 crc_in++;
23283e2a5107SBastian Koppelmann             }
23293e2a5107SBastian Koppelmann         }
23303e2a5107SBastian Koppelmann         data <<= 1;
23313e2a5107SBastian Koppelmann     }
23323e2a5107SBastian Koppelmann 
23333e2a5107SBastian Koppelmann     return crc_in;
23343e2a5107SBastian Koppelmann }
23353e2a5107SBastian Koppelmann 
helper_crcn(uint32_t arg0,uint32_t arg1,uint32_t arg2)23363e2a5107SBastian Koppelmann uint32_t helper_crcn(uint32_t arg0, uint32_t arg1, uint32_t arg2)
23373e2a5107SBastian Koppelmann {
23383e2a5107SBastian Koppelmann     uint32_t crc_out, crc_in;
23393e2a5107SBastian Koppelmann     uint32_t n = extract32(arg0, 12, 4) + 1;
23403e2a5107SBastian Koppelmann     uint32_t gen = extract32(arg0, 16, n);
23413e2a5107SBastian Koppelmann     uint32_t inv = extract32(arg0, 9, 1);
23423e2a5107SBastian Koppelmann     uint32_t le = extract32(arg0, 8, 1);
23433e2a5107SBastian Koppelmann     uint32_t m = extract32(arg0, 0, 3) + 1;
23443e2a5107SBastian Koppelmann     uint32_t data = extract32(arg1, 0, m);
23453e2a5107SBastian Koppelmann     uint32_t seed = extract32(arg2, 0, n);
23463e2a5107SBastian Koppelmann 
23473e2a5107SBastian Koppelmann     if (le == 1) {
23483e2a5107SBastian Koppelmann         if (m == 0) {
23493e2a5107SBastian Koppelmann             data = 0;
23503e2a5107SBastian Koppelmann         } else {
23513e2a5107SBastian Koppelmann             data = revbit32(data) >> (32 - m);
23523e2a5107SBastian Koppelmann         }
23533e2a5107SBastian Koppelmann     }
23543e2a5107SBastian Koppelmann 
23553e2a5107SBastian Koppelmann     if (inv == 1) {
23563e2a5107SBastian Koppelmann         seed = ~seed;
23573e2a5107SBastian Koppelmann     }
23583e2a5107SBastian Koppelmann 
23593e2a5107SBastian Koppelmann     if (m > n) {
23603e2a5107SBastian Koppelmann         crc_in = (data >> (m - n)) ^ seed;
23613e2a5107SBastian Koppelmann     } else {
23623e2a5107SBastian Koppelmann         crc_in = (data << (n - m)) ^ seed;
23633e2a5107SBastian Koppelmann     }
23643e2a5107SBastian Koppelmann 
23653e2a5107SBastian Koppelmann     crc_out = crc_div(crc_in, data, gen, n, m);
23663e2a5107SBastian Koppelmann 
23673e2a5107SBastian Koppelmann     if (inv) {
23683e2a5107SBastian Koppelmann         crc_out = ~crc_out;
23693e2a5107SBastian Koppelmann     }
23703e2a5107SBastian Koppelmann 
23713e2a5107SBastian Koppelmann     return extract32(crc_out, 0, n);
23723e2a5107SBastian Koppelmann }
23733e2a5107SBastian Koppelmann 
helper_shuffle(uint32_t arg0,uint32_t arg1)23744e3377bbSBastian Koppelmann uint32_t helper_shuffle(uint32_t arg0, uint32_t arg1)
23754e3377bbSBastian Koppelmann {
23764e3377bbSBastian Koppelmann     uint32_t resb;
23774e3377bbSBastian Koppelmann     uint32_t byte_select;
23784e3377bbSBastian Koppelmann     uint32_t res = 0;
23794e3377bbSBastian Koppelmann 
23804e3377bbSBastian Koppelmann     byte_select = arg1 & 0x3;
23814e3377bbSBastian Koppelmann     resb = extract32(arg0, byte_select * 8, 8);
23824e3377bbSBastian Koppelmann     res |= resb << 0;
23834e3377bbSBastian Koppelmann 
23844e3377bbSBastian Koppelmann     byte_select = (arg1 >> 2) & 0x3;
23854e3377bbSBastian Koppelmann     resb = extract32(arg0, byte_select * 8, 8);
23864e3377bbSBastian Koppelmann     res |= resb << 8;
23874e3377bbSBastian Koppelmann 
23884e3377bbSBastian Koppelmann     byte_select = (arg1 >> 4) & 0x3;
23894e3377bbSBastian Koppelmann     resb = extract32(arg0, byte_select * 8, 8);
23904e3377bbSBastian Koppelmann     res |= resb << 16;
23914e3377bbSBastian Koppelmann 
23924e3377bbSBastian Koppelmann     byte_select = (arg1 >> 6) & 0x3;
23934e3377bbSBastian Koppelmann     resb = extract32(arg0, byte_select * 8, 8);
23944e3377bbSBastian Koppelmann     res |= resb << 24;
23954e3377bbSBastian Koppelmann 
23964e3377bbSBastian Koppelmann     if (arg1 & 0x100) {
23974e3377bbSBastian Koppelmann         /* Assign the correct nibble position.  */
23984e3377bbSBastian Koppelmann         res = ((res & 0xf0f0f0f0) >> 4)
23994e3377bbSBastian Koppelmann           | ((res & 0x0f0f0f0f) << 4);
24004e3377bbSBastian Koppelmann         /* Assign the correct bit position.  */
24014e3377bbSBastian Koppelmann         res = ((res & 0x88888888) >> 3)
24024e3377bbSBastian Koppelmann           | ((res & 0x44444444) >> 1)
24034e3377bbSBastian Koppelmann           | ((res & 0x22222222) << 1)
24044e3377bbSBastian Koppelmann           | ((res & 0x11111111) << 3);
24054e3377bbSBastian Koppelmann     }
24064e3377bbSBastian Koppelmann 
24074e3377bbSBastian Koppelmann     return res;
24084e3377bbSBastian Koppelmann }
24094e3377bbSBastian Koppelmann 
2410fcf5ef2aSThomas Huth /* context save area (CSA) related helpers */
2411fcf5ef2aSThomas Huth 
cdc_increment(target_ulong * psw)2412fcf5ef2aSThomas Huth static int cdc_increment(target_ulong *psw)
2413fcf5ef2aSThomas Huth {
2414fcf5ef2aSThomas Huth     if ((*psw & MASK_PSW_CDC) == 0x7f) {
2415fcf5ef2aSThomas Huth         return 0;
2416fcf5ef2aSThomas Huth     }
2417fcf5ef2aSThomas Huth 
2418fcf5ef2aSThomas Huth     (*psw)++;
2419fcf5ef2aSThomas Huth     /* check for overflow */
2420fcf5ef2aSThomas Huth     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2421fcf5ef2aSThomas Huth     int mask = (1u << (7 - lo)) - 1;
2422fcf5ef2aSThomas Huth     int count = *psw & mask;
2423fcf5ef2aSThomas Huth     if (count == 0) {
2424fcf5ef2aSThomas Huth         (*psw)--;
2425fcf5ef2aSThomas Huth         return 1;
2426fcf5ef2aSThomas Huth     }
2427fcf5ef2aSThomas Huth     return 0;
2428fcf5ef2aSThomas Huth }
2429fcf5ef2aSThomas Huth 
cdc_decrement(target_ulong * psw)2430fcf5ef2aSThomas Huth static int cdc_decrement(target_ulong *psw)
2431fcf5ef2aSThomas Huth {
2432fcf5ef2aSThomas Huth     if ((*psw & MASK_PSW_CDC) == 0x7f) {
2433fcf5ef2aSThomas Huth         return 0;
2434fcf5ef2aSThomas Huth     }
2435fcf5ef2aSThomas Huth     /* check for underflow */
2436fcf5ef2aSThomas Huth     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2437fcf5ef2aSThomas Huth     int mask = (1u << (7 - lo)) - 1;
2438fcf5ef2aSThomas Huth     int count = *psw & mask;
2439fcf5ef2aSThomas Huth     if (count == 0) {
2440fcf5ef2aSThomas Huth         return 1;
2441fcf5ef2aSThomas Huth     }
2442fcf5ef2aSThomas Huth     (*psw)--;
2443fcf5ef2aSThomas Huth     return 0;
2444fcf5ef2aSThomas Huth }
2445fcf5ef2aSThomas Huth 
cdc_zero(target_ulong * psw)2446fcf5ef2aSThomas Huth static bool cdc_zero(target_ulong *psw)
2447fcf5ef2aSThomas Huth {
2448fcf5ef2aSThomas Huth     int cdc = *psw & MASK_PSW_CDC;
2449fcf5ef2aSThomas Huth     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
2450fcf5ef2aSThomas Huth        7'b1111111, otherwise returns FALSE. */
2451fcf5ef2aSThomas Huth     if (cdc == 0x7f) {
2452fcf5ef2aSThomas Huth         return true;
2453fcf5ef2aSThomas Huth     }
2454fcf5ef2aSThomas Huth     /* find CDC.COUNT */
2455fcf5ef2aSThomas Huth     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2456fcf5ef2aSThomas Huth     int mask = (1u << (7 - lo)) - 1;
2457fcf5ef2aSThomas Huth     int count = *psw & mask;
2458fcf5ef2aSThomas Huth     return count == 0;
2459fcf5ef2aSThomas Huth }
2460fcf5ef2aSThomas Huth 
save_context_upper(CPUTriCoreState * env,target_ulong ea)2461ceada000SBastian Koppelmann static void save_context_upper(CPUTriCoreState *env, target_ulong ea)
2462fcf5ef2aSThomas Huth {
2463fcf5ef2aSThomas Huth     cpu_stl_data(env, ea, env->PCXI);
2464fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+4, psw_read(env));
2465fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+8, env->gpr_a[10]);
2466fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+12, env->gpr_a[11]);
2467fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+16, env->gpr_d[8]);
2468fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+20, env->gpr_d[9]);
2469fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+24, env->gpr_d[10]);
2470fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+28, env->gpr_d[11]);
2471fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+32, env->gpr_a[12]);
2472fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+36, env->gpr_a[13]);
2473fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+40, env->gpr_a[14]);
2474fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+44, env->gpr_a[15]);
2475fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+48, env->gpr_d[12]);
2476fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+52, env->gpr_d[13]);
2477fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+56, env->gpr_d[14]);
2478fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+60, env->gpr_d[15]);
2479fcf5ef2aSThomas Huth }
2480fcf5ef2aSThomas Huth 
save_context_lower(CPUTriCoreState * env,target_ulong ea)2481ceada000SBastian Koppelmann static void save_context_lower(CPUTriCoreState *env, target_ulong ea)
2482fcf5ef2aSThomas Huth {
2483fcf5ef2aSThomas Huth     cpu_stl_data(env, ea, env->PCXI);
2484fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+4, env->gpr_a[11]);
2485fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+8, env->gpr_a[2]);
2486fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+12, env->gpr_a[3]);
2487fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+16, env->gpr_d[0]);
2488fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+20, env->gpr_d[1]);
2489fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+24, env->gpr_d[2]);
2490fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+28, env->gpr_d[3]);
2491fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+32, env->gpr_a[4]);
2492fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+36, env->gpr_a[5]);
2493fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+40, env->gpr_a[6]);
2494fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+44, env->gpr_a[7]);
2495fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+48, env->gpr_d[4]);
2496fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+52, env->gpr_d[5]);
2497fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+56, env->gpr_d[6]);
2498fcf5ef2aSThomas Huth     cpu_stl_data(env, ea+60, env->gpr_d[7]);
2499fcf5ef2aSThomas Huth }
2500fcf5ef2aSThomas Huth 
restore_context_upper(CPUTriCoreState * env,target_ulong ea,target_ulong * new_PCXI,target_ulong * new_PSW)2501ceada000SBastian Koppelmann static void restore_context_upper(CPUTriCoreState *env, target_ulong ea,
2502fcf5ef2aSThomas Huth                                   target_ulong *new_PCXI, target_ulong *new_PSW)
2503fcf5ef2aSThomas Huth {
2504fcf5ef2aSThomas Huth     *new_PCXI = cpu_ldl_data(env, ea);
2505fcf5ef2aSThomas Huth     *new_PSW = cpu_ldl_data(env, ea+4);
2506fcf5ef2aSThomas Huth     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
2507fcf5ef2aSThomas Huth     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
2508fcf5ef2aSThomas Huth     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
2509fcf5ef2aSThomas Huth     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
2510fcf5ef2aSThomas Huth     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
2511fcf5ef2aSThomas Huth     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
2512fcf5ef2aSThomas Huth     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
2513fcf5ef2aSThomas Huth     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
2514fcf5ef2aSThomas Huth     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
2515fcf5ef2aSThomas Huth     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
2516fcf5ef2aSThomas Huth     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
2517fcf5ef2aSThomas Huth     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
2518fcf5ef2aSThomas Huth     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
2519fcf5ef2aSThomas Huth     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
2520fcf5ef2aSThomas Huth }
2521fcf5ef2aSThomas Huth 
restore_context_lower(CPUTriCoreState * env,target_ulong ea,target_ulong * ra,target_ulong * pcxi)2522ceada000SBastian Koppelmann static void restore_context_lower(CPUTriCoreState *env, target_ulong ea,
2523fcf5ef2aSThomas Huth                                   target_ulong *ra, target_ulong *pcxi)
2524fcf5ef2aSThomas Huth {
2525fcf5ef2aSThomas Huth     *pcxi = cpu_ldl_data(env, ea);
2526fcf5ef2aSThomas Huth     *ra = cpu_ldl_data(env, ea+4);
2527fcf5ef2aSThomas Huth     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
2528fcf5ef2aSThomas Huth     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
2529fcf5ef2aSThomas Huth     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
2530fcf5ef2aSThomas Huth     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
2531fcf5ef2aSThomas Huth     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
2532fcf5ef2aSThomas Huth     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
2533fcf5ef2aSThomas Huth     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
2534fcf5ef2aSThomas Huth     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
2535fcf5ef2aSThomas Huth     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
2536fcf5ef2aSThomas Huth     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
2537fcf5ef2aSThomas Huth     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
2538fcf5ef2aSThomas Huth     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
2539fcf5ef2aSThomas Huth     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
2540fcf5ef2aSThomas Huth     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
2541fcf5ef2aSThomas Huth }
2542fcf5ef2aSThomas Huth 
helper_call(CPUTriCoreState * env,uint32_t next_pc)2543fcf5ef2aSThomas Huth void helper_call(CPUTriCoreState *env, uint32_t next_pc)
2544fcf5ef2aSThomas Huth {
2545fcf5ef2aSThomas Huth     target_ulong tmp_FCX;
2546fcf5ef2aSThomas Huth     target_ulong ea;
2547fcf5ef2aSThomas Huth     target_ulong new_FCX;
2548fcf5ef2aSThomas Huth     target_ulong psw;
2549fcf5ef2aSThomas Huth 
2550fcf5ef2aSThomas Huth     psw = psw_read(env);
2551fcf5ef2aSThomas Huth     /* if (FCX == 0) trap(FCU); */
2552fcf5ef2aSThomas Huth     if (env->FCX == 0) {
2553fcf5ef2aSThomas Huth         /* FCU trap */
2554fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2555fcf5ef2aSThomas Huth     }
2556fcf5ef2aSThomas Huth     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
2557fcf5ef2aSThomas Huth     if (psw & MASK_PSW_CDE) {
2558fcf5ef2aSThomas Huth         if (cdc_increment(&psw)) {
2559fcf5ef2aSThomas Huth             /* CDO trap */
2560fcf5ef2aSThomas Huth             raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC());
2561fcf5ef2aSThomas Huth         }
2562fcf5ef2aSThomas Huth     }
2563fcf5ef2aSThomas Huth     /* PSW.CDE = 1;*/
2564fcf5ef2aSThomas Huth     psw |= MASK_PSW_CDE;
25655434557fSBastian Koppelmann     /*
25665434557fSBastian Koppelmann      * we need to save PSW.CDE and not PSW.CDC into the CSAs. psw already
25675434557fSBastian Koppelmann      * contains the CDC from cdc_increment(), so we cannot call psw_write()
25685434557fSBastian Koppelmann      * here.
25695434557fSBastian Koppelmann      */
25705434557fSBastian Koppelmann     env->PSW |= MASK_PSW_CDE;
257112b95dc4SBastian Koppelmann 
2572fcf5ef2aSThomas Huth     /* tmp_FCX = FCX; */
2573fcf5ef2aSThomas Huth     tmp_FCX = env->FCX;
2574fcf5ef2aSThomas Huth     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2575fcf5ef2aSThomas Huth     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2576fcf5ef2aSThomas Huth          ((env->FCX & MASK_FCX_FCXO) << 6);
2577fcf5ef2aSThomas Huth     /* new_FCX = M(EA, word); */
2578fcf5ef2aSThomas Huth     new_FCX = cpu_ldl_data(env, ea);
2579fcf5ef2aSThomas Huth     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2580fcf5ef2aSThomas Huth                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2581fcf5ef2aSThomas Huth                            D[15]}; */
2582fcf5ef2aSThomas Huth     save_context_upper(env, ea);
2583fcf5ef2aSThomas Huth 
2584fcf5ef2aSThomas Huth     /* PCXI.PCPN = ICR.CCPN; */
2585343cdf2cSBastian Koppelmann     pcxi_set_pcpn(env, icr_get_ccpn(env));
2586fcf5ef2aSThomas Huth     /* PCXI.PIE = ICR.IE; */
2587343cdf2cSBastian Koppelmann     pcxi_set_pie(env, icr_get_ie(env));
2588fcf5ef2aSThomas Huth     /* PCXI.UL = 1; */
2589343cdf2cSBastian Koppelmann     pcxi_set_ul(env, 1);
2590fcf5ef2aSThomas Huth 
2591fcf5ef2aSThomas Huth     /* PCXI[19: 0] = FCX[19: 0]; */
2592fcf5ef2aSThomas Huth     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2593fcf5ef2aSThomas Huth     /* FCX[19: 0] = new_FCX[19: 0]; */
2594fcf5ef2aSThomas Huth     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2595fcf5ef2aSThomas Huth     /* A[11] = next_pc[31: 0]; */
2596fcf5ef2aSThomas Huth     env->gpr_a[11] = next_pc;
2597fcf5ef2aSThomas Huth 
2598fcf5ef2aSThomas Huth     /* if (tmp_FCX == LCX) trap(FCD);*/
2599fcf5ef2aSThomas Huth     if (tmp_FCX == env->LCX) {
2600fcf5ef2aSThomas Huth         /* FCD trap */
2601fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2602fcf5ef2aSThomas Huth     }
2603fcf5ef2aSThomas Huth     psw_write(env, psw);
2604fcf5ef2aSThomas Huth }
2605fcf5ef2aSThomas Huth 
helper_ret(CPUTriCoreState * env)2606fcf5ef2aSThomas Huth void helper_ret(CPUTriCoreState *env)
2607fcf5ef2aSThomas Huth {
2608fcf5ef2aSThomas Huth     target_ulong ea;
2609fcf5ef2aSThomas Huth     target_ulong new_PCXI;
2610fcf5ef2aSThomas Huth     target_ulong new_PSW, psw;
2611fcf5ef2aSThomas Huth 
2612fcf5ef2aSThomas Huth     psw = psw_read(env);
2613fcf5ef2aSThomas Huth      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
2614fcf5ef2aSThomas Huth     if (psw & MASK_PSW_CDE) {
2615fcf5ef2aSThomas Huth         if (cdc_decrement(&psw)) {
2616fcf5ef2aSThomas Huth             /* CDU trap */
2617fcf5ef2aSThomas Huth             psw_write(env, psw);
2618fcf5ef2aSThomas Huth             raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC());
2619fcf5ef2aSThomas Huth         }
2620fcf5ef2aSThomas Huth     }
2621fcf5ef2aSThomas Huth     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2622fcf5ef2aSThomas Huth     if ((env->PCXI & 0xfffff) == 0) {
2623fcf5ef2aSThomas Huth         /* CSU trap */
2624fcf5ef2aSThomas Huth         psw_write(env, psw);
2625fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2626fcf5ef2aSThomas Huth     }
2627fcf5ef2aSThomas Huth     /* if (PCXI.UL == 0) then trap(CTYP); */
2628343cdf2cSBastian Koppelmann     if (pcxi_get_ul(env) == 0) {
2629fcf5ef2aSThomas Huth         /* CTYP trap */
2630fcf5ef2aSThomas Huth         cdc_increment(&psw); /* restore to the start of helper */
2631fcf5ef2aSThomas Huth         psw_write(env, psw);
2632fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2633fcf5ef2aSThomas Huth     }
2634fcf5ef2aSThomas Huth     /* PC = {A11 [31: 1], 1’b0}; */
2635fcf5ef2aSThomas Huth     env->PC = env->gpr_a[11] & 0xfffffffe;
2636fcf5ef2aSThomas Huth 
2637fcf5ef2aSThomas Huth     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2638343cdf2cSBastian Koppelmann     ea = (pcxi_get_pcxs(env) << 28) |
2639343cdf2cSBastian Koppelmann          (pcxi_get_pcxo(env) << 6);
2640fcf5ef2aSThomas Huth     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2641fcf5ef2aSThomas Huth         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2642fcf5ef2aSThomas Huth     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2643fcf5ef2aSThomas Huth     /* M(EA, word) = FCX; */
2644fcf5ef2aSThomas Huth     cpu_stl_data(env, ea, env->FCX);
2645fcf5ef2aSThomas Huth     /* FCX[19: 0] = PCXI[19: 0]; */
2646fcf5ef2aSThomas Huth     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2647fcf5ef2aSThomas Huth     /* PCXI = new_PCXI; */
2648fcf5ef2aSThomas Huth     env->PCXI = new_PCXI;
2649fcf5ef2aSThomas Huth 
2650f8cfdd20SBastian Koppelmann     if (tricore_has_feature(env, TRICORE_FEATURE_131)) {
2651fcf5ef2aSThomas Huth         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
2652fcf5ef2aSThomas Huth         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
265382736612SBastian Koppelmann     } else { /* TRICORE_FEATURE_13 only */
265482736612SBastian Koppelmann         /* PSW = new_PSW */
265582736612SBastian Koppelmann         psw_write(env, new_PSW);
2656fcf5ef2aSThomas Huth     }
2657fcf5ef2aSThomas Huth }
2658fcf5ef2aSThomas Huth 
helper_bisr(CPUTriCoreState * env,uint32_t const9)2659fcf5ef2aSThomas Huth void helper_bisr(CPUTriCoreState *env, uint32_t const9)
2660fcf5ef2aSThomas Huth {
2661fcf5ef2aSThomas Huth     target_ulong tmp_FCX;
2662fcf5ef2aSThomas Huth     target_ulong ea;
2663fcf5ef2aSThomas Huth     target_ulong new_FCX;
2664fcf5ef2aSThomas Huth 
2665fcf5ef2aSThomas Huth     if (env->FCX == 0) {
2666fcf5ef2aSThomas Huth         /* FCU trap */
2667fcf5ef2aSThomas Huth        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2668fcf5ef2aSThomas Huth     }
2669fcf5ef2aSThomas Huth 
2670fcf5ef2aSThomas Huth     tmp_FCX = env->FCX;
2671fcf5ef2aSThomas Huth     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
2672fcf5ef2aSThomas Huth 
2673fcf5ef2aSThomas Huth     /* new_FCX = M(EA, word); */
2674fcf5ef2aSThomas Huth     new_FCX = cpu_ldl_data(env, ea);
2675fcf5ef2aSThomas Huth     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2676fcf5ef2aSThomas Huth                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2677fcf5ef2aSThomas Huth     save_context_lower(env, ea);
2678fcf5ef2aSThomas Huth 
2679fcf5ef2aSThomas Huth 
2680fcf5ef2aSThomas Huth     /* PCXI.PCPN = ICR.CCPN */
2681343cdf2cSBastian Koppelmann     pcxi_set_pcpn(env, icr_get_ccpn(env));
2682fcf5ef2aSThomas Huth     /* PCXI.PIE  = ICR.IE */
2683343cdf2cSBastian Koppelmann     pcxi_set_pie(env, icr_get_ie(env));
2684fcf5ef2aSThomas Huth     /* PCXI.UL = 0 */
2685343cdf2cSBastian Koppelmann     pcxi_set_ul(env, 0);
2686343cdf2cSBastian Koppelmann 
2687fcf5ef2aSThomas Huth     /* PCXI[19: 0] = FCX[19: 0] */
2688fcf5ef2aSThomas Huth     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2689fcf5ef2aSThomas Huth     /* FXC[19: 0] = new_FCX[19: 0] */
2690fcf5ef2aSThomas Huth     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2691fcf5ef2aSThomas Huth 
2692343cdf2cSBastian Koppelmann     /* ICR.IE = 1 */
2693343cdf2cSBastian Koppelmann     icr_set_ie(env, 1);
2694343cdf2cSBastian Koppelmann 
2695343cdf2cSBastian Koppelmann     icr_set_ccpn(env, const9);
2696fcf5ef2aSThomas Huth 
2697fcf5ef2aSThomas Huth     if (tmp_FCX == env->LCX) {
2698fcf5ef2aSThomas Huth         /* FCD trap */
2699fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2700fcf5ef2aSThomas Huth     }
2701fcf5ef2aSThomas Huth }
2702fcf5ef2aSThomas Huth 
helper_rfe(CPUTriCoreState * env)2703fcf5ef2aSThomas Huth void helper_rfe(CPUTriCoreState *env)
2704fcf5ef2aSThomas Huth {
2705fcf5ef2aSThomas Huth     target_ulong ea;
2706fcf5ef2aSThomas Huth     target_ulong new_PCXI;
2707fcf5ef2aSThomas Huth     target_ulong new_PSW;
2708fcf5ef2aSThomas Huth     /* if (PCXI[19: 0] == 0) then trap(CSU); */
2709fcf5ef2aSThomas Huth     if ((env->PCXI & 0xfffff) == 0) {
2710fcf5ef2aSThomas Huth         /* raise csu trap */
2711fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2712fcf5ef2aSThomas Huth     }
2713fcf5ef2aSThomas Huth     /* if (PCXI.UL == 0) then trap(CTYP); */
2714343cdf2cSBastian Koppelmann     if (pcxi_get_ul(env) == 0) {
2715fcf5ef2aSThomas Huth         /* raise CTYP trap */
2716fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2717fcf5ef2aSThomas Huth     }
2718fcf5ef2aSThomas Huth     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
2719fcf5ef2aSThomas Huth     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
2720fcf5ef2aSThomas Huth         /* raise NEST trap */
2721fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC());
2722fcf5ef2aSThomas Huth     }
2723fcf5ef2aSThomas Huth     env->PC = env->gpr_a[11] & ~0x1;
2724fcf5ef2aSThomas Huth     /* ICR.IE = PCXI.PIE; */
2725343cdf2cSBastian Koppelmann     icr_set_ie(env, pcxi_get_pie(env));
2726343cdf2cSBastian Koppelmann 
2727fcf5ef2aSThomas Huth     /* ICR.CCPN = PCXI.PCPN; */
2728343cdf2cSBastian Koppelmann     icr_set_ccpn(env, pcxi_get_pcpn(env));
2729343cdf2cSBastian Koppelmann 
2730fcf5ef2aSThomas Huth     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
2731343cdf2cSBastian Koppelmann     ea = (pcxi_get_pcxs(env) << 28) |
2732343cdf2cSBastian Koppelmann          (pcxi_get_pcxo(env) << 6);
2733343cdf2cSBastian Koppelmann 
2734fcf5ef2aSThomas Huth     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2735fcf5ef2aSThomas Huth       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2736fcf5ef2aSThomas Huth     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2737fcf5ef2aSThomas Huth     /* M(EA, word) = FCX;*/
2738fcf5ef2aSThomas Huth     cpu_stl_data(env, ea, env->FCX);
2739fcf5ef2aSThomas Huth     /* FCX[19: 0] = PCXI[19: 0]; */
2740fcf5ef2aSThomas Huth     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2741fcf5ef2aSThomas Huth     /* PCXI = new_PCXI; */
2742fcf5ef2aSThomas Huth     env->PCXI = new_PCXI;
2743fcf5ef2aSThomas Huth     /* write psw */
2744fcf5ef2aSThomas Huth     psw_write(env, new_PSW);
2745fcf5ef2aSThomas Huth }
2746fcf5ef2aSThomas Huth 
helper_rfm(CPUTriCoreState * env)2747fcf5ef2aSThomas Huth void helper_rfm(CPUTriCoreState *env)
2748fcf5ef2aSThomas Huth {
2749fcf5ef2aSThomas Huth     env->PC = (env->gpr_a[11] & ~0x1);
2750fcf5ef2aSThomas Huth     /* ICR.IE = PCXI.PIE; */
2751343cdf2cSBastian Koppelmann     icr_set_ie(env, pcxi_get_pie(env));
2752fcf5ef2aSThomas Huth     /* ICR.CCPN = PCXI.PCPN; */
2753343cdf2cSBastian Koppelmann     icr_set_ccpn(env, pcxi_get_pcpn(env));
2754343cdf2cSBastian Koppelmann 
2755fcf5ef2aSThomas Huth     /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */
2756fcf5ef2aSThomas Huth     env->PCXI = cpu_ldl_data(env, env->DCX);
2757fcf5ef2aSThomas Huth     psw_write(env, cpu_ldl_data(env, env->DCX+4));
2758fcf5ef2aSThomas Huth     env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
2759fcf5ef2aSThomas Huth     env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
2760fcf5ef2aSThomas Huth 
2761f8cfdd20SBastian Koppelmann     if (tricore_has_feature(env, TRICORE_FEATURE_131)) {
2762fcf5ef2aSThomas Huth         env->DBGTCR = 0;
2763fcf5ef2aSThomas Huth     }
2764fcf5ef2aSThomas Huth }
2765fcf5ef2aSThomas Huth 
helper_ldlcx(CPUTriCoreState * env,target_ulong ea)2766ceada000SBastian Koppelmann void helper_ldlcx(CPUTriCoreState *env, target_ulong ea)
2767fcf5ef2aSThomas Huth {
2768fcf5ef2aSThomas Huth     uint32_t dummy;
2769fcf5ef2aSThomas Huth     /* insn doesn't load PCXI and RA */
2770fcf5ef2aSThomas Huth     restore_context_lower(env, ea, &dummy, &dummy);
2771fcf5ef2aSThomas Huth }
2772fcf5ef2aSThomas Huth 
helper_lducx(CPUTriCoreState * env,target_ulong ea)2773ceada000SBastian Koppelmann void helper_lducx(CPUTriCoreState *env, target_ulong ea)
2774fcf5ef2aSThomas Huth {
2775fcf5ef2aSThomas Huth     uint32_t dummy;
2776fcf5ef2aSThomas Huth     /* insn doesn't load PCXI and PSW */
2777fcf5ef2aSThomas Huth     restore_context_upper(env, ea, &dummy, &dummy);
2778fcf5ef2aSThomas Huth }
2779fcf5ef2aSThomas Huth 
helper_stlcx(CPUTriCoreState * env,target_ulong ea)2780ceada000SBastian Koppelmann void helper_stlcx(CPUTriCoreState *env, target_ulong ea)
2781fcf5ef2aSThomas Huth {
2782fcf5ef2aSThomas Huth     save_context_lower(env, ea);
2783fcf5ef2aSThomas Huth }
2784fcf5ef2aSThomas Huth 
helper_stucx(CPUTriCoreState * env,target_ulong ea)2785ceada000SBastian Koppelmann void helper_stucx(CPUTriCoreState *env, target_ulong ea)
2786fcf5ef2aSThomas Huth {
2787fcf5ef2aSThomas Huth     save_context_upper(env, ea);
2788fcf5ef2aSThomas Huth }
2789fcf5ef2aSThomas Huth 
helper_svlcx(CPUTriCoreState * env)2790fcf5ef2aSThomas Huth void helper_svlcx(CPUTriCoreState *env)
2791fcf5ef2aSThomas Huth {
2792fcf5ef2aSThomas Huth     target_ulong tmp_FCX;
2793fcf5ef2aSThomas Huth     target_ulong ea;
2794fcf5ef2aSThomas Huth     target_ulong new_FCX;
2795fcf5ef2aSThomas Huth 
2796fcf5ef2aSThomas Huth     if (env->FCX == 0) {
2797fcf5ef2aSThomas Huth         /* FCU trap */
2798fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2799fcf5ef2aSThomas Huth     }
2800fcf5ef2aSThomas Huth     /* tmp_FCX = FCX; */
2801fcf5ef2aSThomas Huth     tmp_FCX = env->FCX;
2802fcf5ef2aSThomas Huth     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2803fcf5ef2aSThomas Huth     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2804fcf5ef2aSThomas Huth          ((env->FCX & MASK_FCX_FCXO) << 6);
2805fcf5ef2aSThomas Huth     /* new_FCX = M(EA, word); */
2806fcf5ef2aSThomas Huth     new_FCX = cpu_ldl_data(env, ea);
2807fcf5ef2aSThomas Huth     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2808fcf5ef2aSThomas Huth                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2809fcf5ef2aSThomas Huth                            D[15]}; */
2810fcf5ef2aSThomas Huth     save_context_lower(env, ea);
2811fcf5ef2aSThomas Huth 
2812fcf5ef2aSThomas Huth     /* PCXI.PCPN = ICR.CCPN; */
2813343cdf2cSBastian Koppelmann     pcxi_set_pcpn(env, icr_get_ccpn(env));
2814343cdf2cSBastian Koppelmann 
2815fcf5ef2aSThomas Huth     /* PCXI.PIE = ICR.IE; */
2816343cdf2cSBastian Koppelmann     pcxi_set_pie(env, icr_get_ie(env));
2817343cdf2cSBastian Koppelmann 
2818fcf5ef2aSThomas Huth     /* PCXI.UL = 0; */
2819343cdf2cSBastian Koppelmann     pcxi_set_ul(env, 0);
2820fcf5ef2aSThomas Huth 
2821fcf5ef2aSThomas Huth     /* PCXI[19: 0] = FCX[19: 0]; */
2822fcf5ef2aSThomas Huth     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2823fcf5ef2aSThomas Huth     /* FCX[19: 0] = new_FCX[19: 0]; */
2824fcf5ef2aSThomas Huth     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2825fcf5ef2aSThomas Huth 
2826fcf5ef2aSThomas Huth     /* if (tmp_FCX == LCX) trap(FCD);*/
2827fcf5ef2aSThomas Huth     if (tmp_FCX == env->LCX) {
2828fcf5ef2aSThomas Huth         /* FCD trap */
2829fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2830fcf5ef2aSThomas Huth     }
2831fcf5ef2aSThomas Huth }
2832fcf5ef2aSThomas Huth 
helper_svucx(CPUTriCoreState * env)2833fcf5ef2aSThomas Huth void helper_svucx(CPUTriCoreState *env)
2834fcf5ef2aSThomas Huth {
2835fcf5ef2aSThomas Huth     target_ulong tmp_FCX;
2836fcf5ef2aSThomas Huth     target_ulong ea;
2837fcf5ef2aSThomas Huth     target_ulong new_FCX;
2838fcf5ef2aSThomas Huth 
2839fcf5ef2aSThomas Huth     if (env->FCX == 0) {
2840fcf5ef2aSThomas Huth         /* FCU trap */
2841fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2842fcf5ef2aSThomas Huth     }
2843fcf5ef2aSThomas Huth     /* tmp_FCX = FCX; */
2844fcf5ef2aSThomas Huth     tmp_FCX = env->FCX;
2845fcf5ef2aSThomas Huth     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2846fcf5ef2aSThomas Huth     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2847fcf5ef2aSThomas Huth          ((env->FCX & MASK_FCX_FCXO) << 6);
2848fcf5ef2aSThomas Huth     /* new_FCX = M(EA, word); */
2849fcf5ef2aSThomas Huth     new_FCX = cpu_ldl_data(env, ea);
2850fcf5ef2aSThomas Huth     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2851fcf5ef2aSThomas Huth                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2852fcf5ef2aSThomas Huth                            D[15]}; */
2853fcf5ef2aSThomas Huth     save_context_upper(env, ea);
2854fcf5ef2aSThomas Huth 
2855fcf5ef2aSThomas Huth     /* PCXI.PCPN = ICR.CCPN; */
2856343cdf2cSBastian Koppelmann     pcxi_set_pcpn(env, icr_get_ccpn(env));
2857343cdf2cSBastian Koppelmann 
2858fcf5ef2aSThomas Huth     /* PCXI.PIE = ICR.IE; */
2859343cdf2cSBastian Koppelmann     pcxi_set_pie(env, icr_get_ie(env));
2860343cdf2cSBastian Koppelmann 
2861fcf5ef2aSThomas Huth     /* PCXI.UL = 1; */
2862343cdf2cSBastian Koppelmann     pcxi_set_ul(env, 1);
2863fcf5ef2aSThomas Huth 
2864fcf5ef2aSThomas Huth     /* PCXI[19: 0] = FCX[19: 0]; */
2865fcf5ef2aSThomas Huth     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2866fcf5ef2aSThomas Huth     /* FCX[19: 0] = new_FCX[19: 0]; */
2867fcf5ef2aSThomas Huth     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2868fcf5ef2aSThomas Huth 
2869fcf5ef2aSThomas Huth     /* if (tmp_FCX == LCX) trap(FCD);*/
2870fcf5ef2aSThomas Huth     if (tmp_FCX == env->LCX) {
2871fcf5ef2aSThomas Huth         /* FCD trap */
2872fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2873fcf5ef2aSThomas Huth     }
2874fcf5ef2aSThomas Huth }
2875fcf5ef2aSThomas Huth 
helper_rslcx(CPUTriCoreState * env)2876fcf5ef2aSThomas Huth void helper_rslcx(CPUTriCoreState *env)
2877fcf5ef2aSThomas Huth {
2878fcf5ef2aSThomas Huth     target_ulong ea;
2879fcf5ef2aSThomas Huth     target_ulong new_PCXI;
2880fcf5ef2aSThomas Huth     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2881fcf5ef2aSThomas Huth     if ((env->PCXI & 0xfffff) == 0) {
2882fcf5ef2aSThomas Huth         /* CSU trap */
2883fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2884fcf5ef2aSThomas Huth     }
2885fcf5ef2aSThomas Huth     /* if (PCXI.UL == 1) then trap(CTYP); */
2886343cdf2cSBastian Koppelmann     if (pcxi_get_ul(env) == 1) {
2887fcf5ef2aSThomas Huth         /* CTYP trap */
2888fcf5ef2aSThomas Huth         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2889fcf5ef2aSThomas Huth     }
2890fcf5ef2aSThomas Huth     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2891343cdf2cSBastian Koppelmann     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2892343cdf2cSBastian Koppelmann     ea = (pcxi_get_pcxs(env) << 28) |
2893343cdf2cSBastian Koppelmann          (pcxi_get_pcxo(env) << 6);
2894343cdf2cSBastian Koppelmann 
2895fcf5ef2aSThomas Huth     /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2896fcf5ef2aSThomas Huth         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2897fcf5ef2aSThomas Huth     restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI);
2898fcf5ef2aSThomas Huth     /* M(EA, word) = FCX; */
2899fcf5ef2aSThomas Huth     cpu_stl_data(env, ea, env->FCX);
2900fcf5ef2aSThomas Huth     /* M(EA, word) = FCX; */
2901fcf5ef2aSThomas Huth     cpu_stl_data(env, ea, env->FCX);
2902fcf5ef2aSThomas Huth     /* FCX[19: 0] = PCXI[19: 0]; */
2903fcf5ef2aSThomas Huth     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2904fcf5ef2aSThomas Huth     /* PCXI = new_PCXI; */
2905fcf5ef2aSThomas Huth     env->PCXI = new_PCXI;
2906fcf5ef2aSThomas Huth }
2907fcf5ef2aSThomas Huth 
helper_psw_write(CPUTriCoreState * env,uint32_t arg)2908fcf5ef2aSThomas Huth void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
2909fcf5ef2aSThomas Huth {
2910fcf5ef2aSThomas Huth     psw_write(env, arg);
2911fcf5ef2aSThomas Huth }
2912fcf5ef2aSThomas Huth 
helper_psw_read(CPUTriCoreState * env)2913fcf5ef2aSThomas Huth uint32_t helper_psw_read(CPUTriCoreState *env)
2914fcf5ef2aSThomas Huth {
2915fcf5ef2aSThomas Huth     return psw_read(env);
2916fcf5ef2aSThomas Huth }
2917