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