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