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