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