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