target-tricore: add illegal opcode trap generation
[qemu.git] / 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         }
1049     } else {
1050         if (ovf < 0) {
1051             env->PSW_USB_V = (1 << 31);
1052             env->PSW_USB_SV = (1 << 31);
1053             /* ext_ret > MAX_INT */
1054             if (mul < 0) {
1055                 result = INT64_MAX;
1056             /* ext_ret < MIN_INT */
1057             } else {
1058                result = INT64_MIN;
1059             }
1060         } else {
1061             env->PSW_USB_V = 0;
1062         }
1063     }
1064
1065     return (uint64_t)result;
1066 }
1067
1068 uint32_t helper_msubr_q_ssov(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1069                              uint32_t r3, uint32_t n)
1070 {
1071     int64_t t1 = sextract64(r1, 0, 32);
1072     int64_t t2 = sextract64(r2, 0, 32);
1073     int64_t t3 = sextract64(r3, 0, 32);
1074     int64_t mul, ret;
1075
1076     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1077         mul = 0x7fffffff;
1078     } else {
1079         mul = (t2 * t3) << n;
1080     }
1081
1082     ret = t1 - mul + 0x8000;
1083
1084     env->PSW_USB_AV = ret ^ ret * 2u;
1085     env->PSW_USB_SAV |= env->PSW_USB_AV;
1086
1087     if (ret > 0x7fffffffll) {
1088         env->PSW_USB_V = (1 << 31);
1089         env->PSW_USB_SV |= env->PSW_USB_V;
1090         ret = INT32_MAX;
1091     } else if (ret < -0x80000000ll) {
1092         env->PSW_USB_V = (1 << 31);
1093         env->PSW_USB_SV |= env->PSW_USB_V;
1094         ret = INT32_MIN;
1095     } else {
1096         env->PSW_USB_V = 0;
1097     }
1098     return ret & 0xffff0000ll;
1099 }
1100
1101 uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
1102 {
1103     int32_t b, i;
1104     int32_t ovf = 0;
1105     int32_t avf = 0;
1106     int32_t ret = 0;
1107
1108     for (i = 0; i < 4; i++) {
1109         b = sextract32(arg, i * 8, 8);
1110         b = (b >= 0) ? b : (0 - b);
1111         ovf |= (b > 0x7F) || (b < -0x80);
1112         avf |= b ^ b * 2u;
1113         ret |= (b & 0xff) << (i * 8);
1114     }
1115
1116     env->PSW_USB_V = ovf << 31;
1117     env->PSW_USB_SV |= env->PSW_USB_V;
1118     env->PSW_USB_AV = avf << 24;
1119     env->PSW_USB_SAV |= env->PSW_USB_AV;
1120
1121     return ret;
1122 }
1123
1124 uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
1125 {
1126     int32_t h, i;
1127     int32_t ovf = 0;
1128     int32_t avf = 0;
1129     int32_t ret = 0;
1130
1131     for (i = 0; i < 2; i++) {
1132         h = sextract32(arg, i * 16, 16);
1133         h = (h >= 0) ? h : (0 - h);
1134         ovf |= (h > 0x7FFF) || (h < -0x8000);
1135         avf |= h ^ h * 2u;
1136         ret |= (h & 0xffff) << (i * 16);
1137     }
1138
1139     env->PSW_USB_V = ovf << 31;
1140     env->PSW_USB_SV |= env->PSW_USB_V;
1141     env->PSW_USB_AV = avf << 16;
1142     env->PSW_USB_SAV |= env->PSW_USB_AV;
1143
1144     return ret;
1145 }
1146
1147 uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1148 {
1149     int32_t b, i;
1150     int32_t extr_r2;
1151     int32_t ovf = 0;
1152     int32_t avf = 0;
1153     int32_t ret = 0;
1154
1155     for (i = 0; i < 4; i++) {
1156         extr_r2 = sextract32(r2, i * 8, 8);
1157         b = sextract32(r1, i * 8, 8);
1158         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
1159         ovf |= (b > 0x7F) || (b < -0x80);
1160         avf |= b ^ b * 2u;
1161         ret |= (b & 0xff) << (i * 8);
1162     }
1163
1164     env->PSW_USB_V = ovf << 31;
1165     env->PSW_USB_SV |= env->PSW_USB_V;
1166     env->PSW_USB_AV = avf << 24;
1167     env->PSW_USB_SAV |= env->PSW_USB_AV;
1168     return ret;
1169 }
1170
1171 uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1172 {
1173     int32_t h, i;
1174     int32_t extr_r2;
1175     int32_t ovf = 0;
1176     int32_t avf = 0;
1177     int32_t ret = 0;
1178
1179     for (i = 0; i < 2; i++) {
1180         extr_r2 = sextract32(r2, i * 16, 16);
1181         h = sextract32(r1, i * 16, 16);
1182         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
1183         ovf |= (h > 0x7FFF) || (h < -0x8000);
1184         avf |= h ^ h * 2u;
1185         ret |= (h & 0xffff) << (i * 16);
1186     }
1187
1188     env->PSW_USB_V = ovf << 31;
1189     env->PSW_USB_SV |= env->PSW_USB_V;
1190     env->PSW_USB_AV = avf << 16;
1191     env->PSW_USB_SAV |= env->PSW_USB_AV;
1192
1193     return ret;
1194 }
1195
1196 uint32_t helper_addr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1197                        uint32_t r2_h)
1198 {
1199     int64_t mul_res0 = sextract64(r1, 0, 32);
1200     int64_t mul_res1 = sextract64(r1, 32, 32);
1201     int64_t r2_low = sextract64(r2_l, 0, 32);
1202     int64_t r2_high = sextract64(r2_h, 0, 32);
1203     int64_t result0, result1;
1204     uint32_t ovf0, ovf1;
1205     uint32_t avf0, avf1;
1206
1207     ovf0 = ovf1 = 0;
1208
1209     result0 = r2_low + mul_res0 + 0x8000;
1210     result1 = r2_high + mul_res1 + 0x8000;
1211
1212     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1213         ovf0 = (1 << 31);
1214     }
1215
1216     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1217         ovf1 = (1 << 31);
1218     }
1219
1220     env->PSW_USB_V = ovf0 | ovf1;
1221     env->PSW_USB_SV |= env->PSW_USB_V;
1222
1223     avf0 = result0 * 2u;
1224     avf0 = result0 ^ avf0;
1225     avf1 = result1 * 2u;
1226     avf1 = result1 ^ avf1;
1227
1228     env->PSW_USB_AV = avf0 | avf1;
1229     env->PSW_USB_SAV |= env->PSW_USB_AV;
1230
1231     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1232 }
1233
1234 uint32_t helper_addsur_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1235                          uint32_t r2_h)
1236 {
1237     int64_t mul_res0 = sextract64(r1, 0, 32);
1238     int64_t mul_res1 = sextract64(r1, 32, 32);
1239     int64_t r2_low = sextract64(r2_l, 0, 32);
1240     int64_t r2_high = sextract64(r2_h, 0, 32);
1241     int64_t result0, result1;
1242     uint32_t ovf0, ovf1;
1243     uint32_t avf0, avf1;
1244
1245     ovf0 = ovf1 = 0;
1246
1247     result0 = r2_low - mul_res0 + 0x8000;
1248     result1 = r2_high + mul_res1 + 0x8000;
1249
1250     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1251         ovf0 = (1 << 31);
1252     }
1253
1254     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1255         ovf1 = (1 << 31);
1256     }
1257
1258     env->PSW_USB_V = ovf0 | ovf1;
1259     env->PSW_USB_SV |= env->PSW_USB_V;
1260
1261     avf0 = result0 * 2u;
1262     avf0 = result0 ^ avf0;
1263     avf1 = result1 * 2u;
1264     avf1 = result1 ^ avf1;
1265
1266     env->PSW_USB_AV = avf0 | avf1;
1267     env->PSW_USB_SAV |= env->PSW_USB_AV;
1268
1269     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1270 }
1271
1272 uint32_t helper_maddr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1273                         uint32_t r3, uint32_t n)
1274 {
1275     int64_t t1 = sextract64(r1, 0, 32);
1276     int64_t t2 = sextract64(r2, 0, 32);
1277     int64_t t3 = sextract64(r3, 0, 32);
1278     int64_t mul, ret;
1279
1280     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1281         mul = 0x7fffffff;
1282     } else {
1283         mul = (t2 * t3) << n;
1284     }
1285
1286     ret = t1 + mul + 0x8000;
1287
1288     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1289         env->PSW_USB_V = (1 << 31);
1290         env->PSW_USB_SV |= env->PSW_USB_V;
1291     } else {
1292         env->PSW_USB_V = 0;
1293     }
1294     env->PSW_USB_AV = ret ^ ret * 2u;
1295     env->PSW_USB_SAV |= env->PSW_USB_AV;
1296
1297     return ret & 0xffff0000ll;
1298 }
1299
1300 uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1301 {
1302     int32_t b, i;
1303     int32_t extr_r1, extr_r2;
1304     int32_t ovf = 0;
1305     int32_t avf = 0;
1306     uint32_t ret = 0;
1307
1308     for (i = 0; i < 4; i++) {
1309         extr_r1 = sextract32(r1, i * 8, 8);
1310         extr_r2 = sextract32(r2, i * 8, 8);
1311
1312         b = extr_r1 + extr_r2;
1313         ovf |= ((b > 0x7f) || (b < -0x80));
1314         avf |= b ^ b * 2u;
1315         ret |= ((b & 0xff) << (i*8));
1316     }
1317
1318     env->PSW_USB_V = (ovf << 31);
1319     env->PSW_USB_SV |= env->PSW_USB_V;
1320     env->PSW_USB_AV = avf << 24;
1321     env->PSW_USB_SAV |= env->PSW_USB_AV;
1322
1323     return ret;
1324 }
1325
1326 uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1327 {
1328     int32_t h, i;
1329     int32_t extr_r1, extr_r2;
1330     int32_t ovf = 0;
1331     int32_t avf = 0;
1332     int32_t ret = 0;
1333
1334     for (i = 0; i < 2; i++) {
1335         extr_r1 = sextract32(r1, i * 16, 16);
1336         extr_r2 = sextract32(r2, i * 16, 16);
1337         h = extr_r1 + extr_r2;
1338         ovf |= ((h > 0x7fff) || (h < -0x8000));
1339         avf |= h ^ h * 2u;
1340         ret |= (h & 0xffff) << (i * 16);
1341     }
1342
1343     env->PSW_USB_V = (ovf << 31);
1344     env->PSW_USB_SV |= env->PSW_USB_V;
1345     env->PSW_USB_AV = (avf << 16);
1346     env->PSW_USB_SAV |= env->PSW_USB_AV;
1347
1348     return ret;
1349 }
1350
1351 uint32_t helper_subr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1352                        uint32_t r2_h)
1353 {
1354     int64_t mul_res0 = sextract64(r1, 0, 32);
1355     int64_t mul_res1 = sextract64(r1, 32, 32);
1356     int64_t r2_low = sextract64(r2_l, 0, 32);
1357     int64_t r2_high = sextract64(r2_h, 0, 32);
1358     int64_t result0, result1;
1359     uint32_t ovf0, ovf1;
1360     uint32_t avf0, avf1;
1361
1362     ovf0 = ovf1 = 0;
1363
1364     result0 = r2_low - mul_res0 + 0x8000;
1365     result1 = r2_high - mul_res1 + 0x8000;
1366
1367     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1368         ovf0 = (1 << 31);
1369     }
1370
1371     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1372         ovf1 = (1 << 31);
1373     }
1374
1375     env->PSW_USB_V = ovf0 | ovf1;
1376     env->PSW_USB_SV |= env->PSW_USB_V;
1377
1378     avf0 = result0 * 2u;
1379     avf0 = result0 ^ avf0;
1380     avf1 = result1 * 2u;
1381     avf1 = result1 ^ avf1;
1382
1383     env->PSW_USB_AV = avf0 | avf1;
1384     env->PSW_USB_SAV |= env->PSW_USB_AV;
1385
1386     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1387 }
1388
1389 uint32_t helper_subadr_h(CPUTriCoreState *env, uint64_t r1, uint32_t r2_l,
1390                          uint32_t r2_h)
1391 {
1392     int64_t mul_res0 = sextract64(r1, 0, 32);
1393     int64_t mul_res1 = sextract64(r1, 32, 32);
1394     int64_t r2_low = sextract64(r2_l, 0, 32);
1395     int64_t r2_high = sextract64(r2_h, 0, 32);
1396     int64_t result0, result1;
1397     uint32_t ovf0, ovf1;
1398     uint32_t avf0, avf1;
1399
1400     ovf0 = ovf1 = 0;
1401
1402     result0 = r2_low + mul_res0 + 0x8000;
1403     result1 = r2_high - mul_res1 + 0x8000;
1404
1405     if ((result0 > INT32_MAX) || (result0 < INT32_MIN)) {
1406         ovf0 = (1 << 31);
1407     }
1408
1409     if ((result1 > INT32_MAX) || (result1 < INT32_MIN)) {
1410         ovf1 = (1 << 31);
1411     }
1412
1413     env->PSW_USB_V = ovf0 | ovf1;
1414     env->PSW_USB_SV |= env->PSW_USB_V;
1415
1416     avf0 = result0 * 2u;
1417     avf0 = result0 ^ avf0;
1418     avf1 = result1 * 2u;
1419     avf1 = result1 ^ avf1;
1420
1421     env->PSW_USB_AV = avf0 | avf1;
1422     env->PSW_USB_SAV |= env->PSW_USB_AV;
1423
1424     return (result1 & 0xffff0000ULL) | ((result0 >> 16) & 0xffffULL);
1425 }
1426
1427 uint32_t helper_msubr_q(CPUTriCoreState *env, uint32_t r1, uint32_t r2,
1428                         uint32_t r3, uint32_t n)
1429 {
1430     int64_t t1 = sextract64(r1, 0, 32);
1431     int64_t t2 = sextract64(r2, 0, 32);
1432     int64_t t3 = sextract64(r3, 0, 32);
1433     int64_t mul, ret;
1434
1435     if ((t2 == -0x8000ll) && (t3 == -0x8000ll) && (n == 1)) {
1436         mul = 0x7fffffff;
1437     } else {
1438         mul = (t2 * t3) << n;
1439     }
1440
1441     ret = t1 - mul + 0x8000;
1442
1443     if ((ret > 0x7fffffffll) || (ret < -0x80000000ll)) {
1444         env->PSW_USB_V = (1 << 31);
1445         env->PSW_USB_SV |= env->PSW_USB_V;
1446     } else {
1447         env->PSW_USB_V = 0;
1448     }
1449     env->PSW_USB_AV = ret ^ ret * 2u;
1450     env->PSW_USB_SAV |= env->PSW_USB_AV;
1451
1452     return ret & 0xffff0000ll;
1453 }
1454
1455 uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1456 {
1457     int32_t b, i;
1458     int32_t extr_r1, extr_r2;
1459     int32_t ovf = 0;
1460     int32_t avf = 0;
1461     uint32_t ret = 0;
1462
1463     for (i = 0; i < 4; i++) {
1464         extr_r1 = sextract32(r1, i * 8, 8);
1465         extr_r2 = sextract32(r2, i * 8, 8);
1466
1467         b = extr_r1 - extr_r2;
1468         ovf |= ((b > 0x7f) || (b < -0x80));
1469         avf |= b ^ b * 2u;
1470         ret |= ((b & 0xff) << (i*8));
1471     }
1472
1473     env->PSW_USB_V = (ovf << 31);
1474     env->PSW_USB_SV |= env->PSW_USB_V;
1475     env->PSW_USB_AV = avf << 24;
1476     env->PSW_USB_SAV |= env->PSW_USB_AV;
1477
1478     return ret;
1479 }
1480
1481 uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1482 {
1483     int32_t h, i;
1484     int32_t extr_r1, extr_r2;
1485     int32_t ovf = 0;
1486     int32_t avf = 0;
1487     int32_t ret = 0;
1488
1489     for (i = 0; i < 2; i++) {
1490         extr_r1 = sextract32(r1, i * 16, 16);
1491         extr_r2 = sextract32(r2, i * 16, 16);
1492         h = extr_r1 - extr_r2;
1493         ovf |= ((h > 0x7fff) || (h < -0x8000));
1494         avf |= h ^ h * 2u;
1495         ret |= (h & 0xffff) << (i * 16);
1496     }
1497
1498     env->PSW_USB_V = (ovf << 31);
1499     env->PSW_USB_SV |= env->PSW_USB_V;
1500     env->PSW_USB_AV = avf << 16;
1501     env->PSW_USB_SAV |= env->PSW_USB_AV;
1502
1503     return ret;
1504 }
1505
1506 uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
1507 {
1508     int32_t ret;
1509     int32_t i, msk;
1510
1511     ret = 0;
1512     msk = 0xff;
1513     for (i = 0; i < 4; i++) {
1514         if ((r1 & msk) == (r2 & msk)) {
1515             ret |= msk;
1516         }
1517         msk = msk << 8;
1518     }
1519
1520     return ret;
1521 }
1522
1523 uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
1524 {
1525     int32_t ret = 0;
1526
1527     if ((r1 & 0xffff) == (r2 & 0xffff)) {
1528         ret = 0xffff;
1529     }
1530
1531     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
1532         ret |= 0xffff0000;
1533     }
1534
1535     return ret;
1536 }
1537
1538 uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
1539 {
1540     int32_t i;
1541     uint32_t ret = 0;
1542
1543     for (i = 0; i < 4; i++) {
1544         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
1545     }
1546
1547     return ret;
1548 }
1549
1550 uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
1551 {
1552     uint32_t ret;
1553
1554     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
1555     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
1556
1557     return ret;
1558 }
1559
1560 uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
1561 {
1562     int32_t i;
1563     uint32_t ret = 0;
1564
1565     for (i = 0; i < 4; i++) {
1566         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
1567             ret |= (0xff << (i * 8));
1568         }
1569     }
1570
1571     return ret;
1572 }
1573
1574 uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
1575 {
1576     int32_t i;
1577     uint32_t ret = 0;
1578
1579     for (i = 0; i < 4; i++) {
1580         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
1581             ret |= (0xff << (i * 8));
1582         }
1583     }
1584
1585     return ret;
1586 }
1587
1588 uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
1589 {
1590     uint32_t ret = 0;
1591
1592     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
1593         ret |= 0xffff;
1594     }
1595
1596     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
1597         ret |= 0xffff0000;
1598     }
1599
1600     return ret;
1601 }
1602
1603 uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
1604 {
1605     uint32_t ret = 0;
1606
1607     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
1608         ret |= 0xffff;
1609     }
1610
1611     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
1612         ret |= 0xffff0000;
1613     }
1614
1615     return ret;
1616 }
1617
1618 #define EXTREMA_H_B(name, op)                                 \
1619 uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
1620 {                                                             \
1621     int32_t i, extr_r1, extr_r2;                              \
1622     uint32_t ret = 0;                                         \
1623                                                               \
1624     for (i = 0; i < 4; i++) {                                 \
1625         extr_r1 = sextract32(r1, i * 8, 8);                   \
1626         extr_r2 = sextract32(r2, i * 8, 8);                   \
1627         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1628         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1629     }                                                         \
1630     return ret;                                               \
1631 }                                                             \
1632                                                               \
1633 uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
1634 {                                                             \
1635     int32_t i;                                                \
1636     uint32_t extr_r1, extr_r2;                                \
1637     uint32_t ret = 0;                                         \
1638                                                               \
1639     for (i = 0; i < 4; i++) {                                 \
1640         extr_r1 = extract32(r1, i * 8, 8);                    \
1641         extr_r2 = extract32(r2, i * 8, 8);                    \
1642         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
1643         ret |= (extr_r1 & 0xff) << (i * 8);                   \
1644     }                                                         \
1645     return ret;                                               \
1646 }                                                             \
1647                                                               \
1648 uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
1649 {                                                             \
1650     int32_t extr_r1, extr_r2;                                 \
1651     uint32_t ret = 0;                                         \
1652                                                               \
1653     extr_r1 = sextract32(r1, 0, 16);                          \
1654     extr_r2 = sextract32(r2, 0, 16);                          \
1655     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1656     ret = ret & 0xffff;                                       \
1657                                                               \
1658     extr_r1 = sextract32(r1, 16, 16);                         \
1659     extr_r2 = sextract32(r2, 16, 16);                         \
1660     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1661     ret |= extr_r1 << 16;                                     \
1662                                                               \
1663     return ret;                                               \
1664 }                                                             \
1665                                                               \
1666 uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
1667 {                                                             \
1668     uint32_t extr_r1, extr_r2;                                \
1669     uint32_t ret = 0;                                         \
1670                                                               \
1671     extr_r1 = extract32(r1, 0, 16);                           \
1672     extr_r2 = extract32(r2, 0, 16);                           \
1673     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
1674     ret = ret & 0xffff;                                       \
1675                                                               \
1676     extr_r1 = extract32(r1, 16, 16);                          \
1677     extr_r2 = extract32(r2, 16, 16);                          \
1678     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
1679     ret |= extr_r1 << (16);                                   \
1680                                                               \
1681     return ret;                                               \
1682 }                                                             \
1683                                                               \
1684 uint64_t helper_ix##name(uint64_t r1, uint32_t r2)            \
1685 {                                                             \
1686     int64_t r2l, r2h, r1hl;                                   \
1687     uint64_t ret = 0;                                         \
1688                                                               \
1689     ret = ((r1 + 2) & 0xffff);                                \
1690     r2l = sextract64(r2, 0, 16);                              \
1691     r2h = sextract64(r2, 16, 16);                             \
1692     r1hl = sextract64(r1, 32, 16);                            \
1693                                                               \
1694     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
1695         ret |= (r2l & 0xffff) << 32;                          \
1696         ret |= extract64(r1, 0, 16) << 16;                    \
1697     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
1698         ret |= extract64(r2, 16, 16) << 32;                   \
1699         ret |= extract64(r1 + 1, 0, 16) << 16;                \
1700     } else {                                                  \
1701         ret |= r1 & 0xffffffff0000ull;                        \
1702     }                                                         \
1703     return ret;                                               \
1704 }                                                             \
1705                                                               \
1706 uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)       \
1707 {                                                             \
1708     int64_t r2l, r2h, r1hl;                                   \
1709     uint64_t ret = 0;                                         \
1710                                                               \
1711     ret = ((r1 + 2) & 0xffff);                                \
1712     r2l = extract64(r2, 0, 16);                               \
1713     r2h = extract64(r2, 16, 16);                              \
1714     r1hl = extract64(r1, 32, 16);                             \
1715                                                               \
1716     if ((r2l op ## = r2h) && (r2l op r1hl)) {                 \
1717         ret |= (r2l & 0xffff) << 32;                          \
1718         ret |= extract64(r1, 0, 16) << 16;                    \
1719     } else if ((r2h op r2l) && (r2h op r1hl)) {               \
1720         ret |= extract64(r2, 16, 16) << 32;                   \
1721         ret |= extract64(r1 + 1, 0, 16) << 16;                \
1722     } else {                                                  \
1723         ret |= r1 & 0xffffffff0000ull;                        \
1724     }                                                         \
1725     return ret;                                               \
1726 }
1727
1728 EXTREMA_H_B(max, >)
1729 EXTREMA_H_B(min, <)
1730
1731 #undef EXTREMA_H_B
1732
1733 uint32_t helper_clo(target_ulong r1)
1734 {
1735     return clo32(r1);
1736 }
1737
1738 uint32_t helper_clo_h(target_ulong r1)
1739 {
1740     uint32_t ret_hw0 = extract32(r1, 0, 16);
1741     uint32_t ret_hw1 = extract32(r1, 16, 16);
1742
1743     ret_hw0 = clo32(ret_hw0 << 16);
1744     ret_hw1 = clo32(ret_hw1 << 16);
1745
1746     if (ret_hw0 > 16) {
1747         ret_hw0 = 16;
1748     }
1749     if (ret_hw1 > 16) {
1750         ret_hw1 = 16;
1751     }
1752
1753     return ret_hw0 | (ret_hw1 << 16);
1754 }
1755
1756 uint32_t helper_clz(target_ulong r1)
1757 {
1758     return clz32(r1);
1759 }
1760
1761 uint32_t helper_clz_h(target_ulong r1)
1762 {
1763     uint32_t ret_hw0 = extract32(r1, 0, 16);
1764     uint32_t ret_hw1 = extract32(r1, 16, 16);
1765
1766     ret_hw0 = clz32(ret_hw0 << 16);
1767     ret_hw1 = clz32(ret_hw1 << 16);
1768
1769     if (ret_hw0 > 16) {
1770         ret_hw0 = 16;
1771     }
1772     if (ret_hw1 > 16) {
1773         ret_hw1 = 16;
1774     }
1775
1776     return ret_hw0 | (ret_hw1 << 16);
1777 }
1778
1779 uint32_t helper_cls(target_ulong r1)
1780 {
1781     return clrsb32(r1);
1782 }
1783
1784 uint32_t helper_cls_h(target_ulong r1)
1785 {
1786     uint32_t ret_hw0 = extract32(r1, 0, 16);
1787     uint32_t ret_hw1 = extract32(r1, 16, 16);
1788
1789     ret_hw0 = clrsb32(ret_hw0 << 16);
1790     ret_hw1 = clrsb32(ret_hw1 << 16);
1791
1792     if (ret_hw0 > 15) {
1793         ret_hw0 = 15;
1794     }
1795     if (ret_hw1 > 15) {
1796         ret_hw1 = 15;
1797     }
1798
1799     return ret_hw0 | (ret_hw1 << 16);
1800 }
1801
1802 uint32_t helper_sh(target_ulong r1, target_ulong r2)
1803 {
1804     int32_t shift_count = sextract32(r2, 0, 6);
1805
1806     if (shift_count == -32) {
1807         return 0;
1808     } else if (shift_count < 0) {
1809         return r1 >> -shift_count;
1810     } else {
1811         return r1 << shift_count;
1812     }
1813 }
1814
1815 uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
1816 {
1817     int32_t ret_hw0, ret_hw1;
1818     int32_t shift_count;
1819
1820     shift_count = sextract32(r2, 0, 5);
1821
1822     if (shift_count == -16) {
1823         return 0;
1824     } else if (shift_count < 0) {
1825         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
1826         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
1827         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1828     } else {
1829         ret_hw0 = extract32(r1, 0, 16) << shift_count;
1830         ret_hw1 = extract32(r1, 16, 16) << shift_count;
1831         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1832     }
1833 }
1834
1835 uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
1836 {
1837     int32_t shift_count;
1838     int64_t result, t1;
1839     uint32_t ret;
1840
1841     shift_count = sextract32(r2, 0, 6);
1842     t1 = sextract32(r1, 0, 32);
1843
1844     if (shift_count == 0) {
1845         env->PSW_USB_C = env->PSW_USB_V = 0;
1846         ret = r1;
1847     } else if (shift_count == -32) {
1848         env->PSW_USB_C = r1;
1849         env->PSW_USB_V = 0;
1850         ret = t1 >> 31;
1851     } else if (shift_count > 0) {
1852         result = t1 << shift_count;
1853         /* calc carry */
1854         env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
1855         /* calc v */
1856         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
1857                            (result < -0x80000000LL)) << 31);
1858         /* calc sv */
1859         env->PSW_USB_SV |= env->PSW_USB_V;
1860         ret = (uint32_t)result;
1861     } else {
1862         env->PSW_USB_V = 0;
1863         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
1864         ret = t1 >> -shift_count;
1865     }
1866
1867     env->PSW_USB_AV = ret ^ ret * 2u;
1868     env->PSW_USB_SAV |= env->PSW_USB_AV;
1869
1870     return ret;
1871 }
1872
1873 uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
1874 {
1875     int32_t shift_count;
1876     int32_t ret_hw0, ret_hw1;
1877
1878     shift_count = sextract32(r2, 0, 5);
1879
1880     if (shift_count == 0) {
1881         return r1;
1882     } else if (shift_count < 0) {
1883         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
1884         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
1885         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1886     } else {
1887         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
1888         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
1889         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1890     }
1891 }
1892
1893 uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1894 {
1895     uint32_t i, ret;
1896
1897     ret = 0;
1898     for (i = 0; i < 16; i++) {
1899         ret |= (r1 & 1) << (2 * i + 1);
1900         ret |= (r2 & 1) << (2 * i);
1901         r1 = r1 >> 1;
1902         r2 = r2 >> 1;
1903     }
1904     return ret;
1905 }
1906
1907 uint64_t helper_bsplit(uint32_t r1)
1908 {
1909     int32_t i;
1910     uint64_t ret;
1911
1912     ret = 0;
1913     for (i = 0; i < 32; i = i + 2) {
1914         /* even */
1915         ret |= (r1 & 1) << (i/2);
1916         r1 = r1 >> 1;
1917         /* odd */
1918         ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1919         r1 = r1 >> 1;
1920     }
1921     return ret;
1922 }
1923
1924 uint32_t helper_parity(target_ulong r1)
1925 {
1926     uint32_t ret;
1927     uint32_t nOnes, i;
1928
1929     ret = 0;
1930     nOnes = 0;
1931     for (i = 0; i < 8; i++) {
1932         ret ^= (r1 & 1);
1933         r1 = r1 >> 1;
1934     }
1935     /* second byte */
1936     nOnes = 0;
1937     for (i = 0; i < 8; i++) {
1938         nOnes ^= (r1 & 1);
1939         r1 = r1 >> 1;
1940     }
1941     ret |= nOnes << 8;
1942     /* third byte */
1943     nOnes = 0;
1944     for (i = 0; i < 8; i++) {
1945         nOnes ^= (r1 & 1);
1946         r1 = r1 >> 1;
1947     }
1948     ret |= nOnes << 16;
1949     /* fourth byte */
1950     nOnes = 0;
1951     for (i = 0; i < 8; i++) {
1952         nOnes ^= (r1 & 1);
1953         r1 = r1 >> 1;
1954     }
1955     ret |= nOnes << 24;
1956
1957     return ret;
1958 }
1959
1960 uint32_t helper_pack(uint32_t carry, uint32_t r1_low, uint32_t r1_high,
1961                      target_ulong r2)
1962 {
1963     uint32_t ret;
1964     int32_t fp_exp, fp_frac, temp_exp, fp_exp_frac;
1965     int32_t int_exp  = r1_high;
1966     int32_t int_mant = r1_low;
1967     uint32_t flag_rnd = (int_mant & (1 << 7)) && (
1968                         (int_mant & (1 << 8)) ||
1969                         (int_mant & 0x7f)     ||
1970                         (carry != 0));
1971     if (((int_mant & (1<<31)) == 0) && (int_exp == 255)) {
1972         fp_exp = 255;
1973         fp_frac = extract32(int_mant, 8, 23);
1974     } else if ((int_mant & (1<<31)) && (int_exp >= 127)) {
1975         fp_exp  = 255;
1976         fp_frac = 0;
1977     } else if ((int_mant & (1<<31)) && (int_exp <= -128)) {
1978         fp_exp  = 0;
1979         fp_frac = 0;
1980     } else if (int_mant == 0) {
1981         fp_exp  = 0;
1982         fp_frac = 0;
1983     } else {
1984         if (((int_mant & (1 << 31)) == 0)) {
1985             temp_exp = 0;
1986         } else {
1987             temp_exp = int_exp + 128;
1988         }
1989         fp_exp_frac = (((temp_exp & 0xff) << 23) |
1990                       extract32(int_mant, 8, 23))
1991                       + flag_rnd;
1992         fp_exp  = extract32(fp_exp_frac, 23, 8);
1993         fp_frac = extract32(fp_exp_frac, 0, 23);
1994     }
1995     ret = r2 & (1 << 31);
1996     ret = ret + (fp_exp << 23);
1997     ret = ret + (fp_frac & 0x7fffff);
1998
1999     return ret;
2000 }
2001
2002 uint64_t helper_unpack(target_ulong arg1)
2003 {
2004     int32_t fp_exp  = extract32(arg1, 23, 8);
2005     int32_t fp_frac = extract32(arg1, 0, 23);
2006     uint64_t ret;
2007     int32_t int_exp, int_mant;
2008
2009     if (fp_exp == 255) {
2010         int_exp = 255;
2011         int_mant = (fp_frac << 7);
2012     } else if ((fp_exp == 0) && (fp_frac == 0)) {
2013         int_exp  = -127;
2014         int_mant = 0;
2015     } else if ((fp_exp == 0) && (fp_frac != 0)) {
2016         int_exp  = -126;
2017         int_mant = (fp_frac << 7);
2018     } else {
2019         int_exp  = fp_exp - 127;
2020         int_mant = (fp_frac << 7);
2021         int_mant |= (1 << 30);
2022     }
2023     ret = int_exp;
2024     ret = ret << 32;
2025     ret |= int_mant;
2026
2027     return ret;
2028 }
2029
2030 uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2031 {
2032     uint64_t ret;
2033     int32_t abs_sig_dividend, abs_divisor;
2034
2035     ret = sextract32(r1, 0, 32);
2036     ret = ret << 24;
2037     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2038         ret |= 0xffffff;
2039     }
2040
2041     abs_sig_dividend = abs((int32_t)r1) >> 8;
2042     abs_divisor = abs((int32_t)r2);
2043     /* calc overflow
2044        ofv if (a/b >= 255) <=> (a/255 >= b) */
2045     env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2046     env->PSW_USB_V = env->PSW_USB_V << 31;
2047     env->PSW_USB_SV |= env->PSW_USB_V;
2048     env->PSW_USB_AV = 0;
2049
2050     return ret;
2051 }
2052
2053 uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2054 {
2055     uint64_t ret = sextract32(r1, 0, 32);
2056
2057     ret = ret << 24;
2058     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2059         ret |= 0xffffff;
2060     }
2061     /* calc overflow */
2062     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
2063     env->PSW_USB_V = env->PSW_USB_V << 31;
2064     env->PSW_USB_SV |= env->PSW_USB_V;
2065     env->PSW_USB_AV = 0;
2066
2067     return ret;
2068 }
2069
2070 uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2071 {
2072     uint64_t ret;
2073     int32_t abs_sig_dividend, abs_divisor;
2074
2075     ret = sextract32(r1, 0, 32);
2076     ret = ret << 16;
2077     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2078         ret |= 0xffff;
2079     }
2080
2081     abs_sig_dividend = abs((int32_t)r1) >> 16;
2082     abs_divisor = abs((int32_t)r2);
2083     /* calc overflow
2084        ofv if (a/b >= 0xffff) <=> (a/0xffff >= b) */
2085     env->PSW_USB_V = (abs_sig_dividend >= abs_divisor) << 31;
2086     env->PSW_USB_V = env->PSW_USB_V << 31;
2087     env->PSW_USB_SV |= env->PSW_USB_V;
2088     env->PSW_USB_AV = 0;
2089
2090     return ret;
2091 }
2092
2093 uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2094 {
2095     uint64_t ret = sextract32(r1, 0, 32);
2096
2097     ret = ret << 16;
2098     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
2099         ret |= 0xffff;
2100     }
2101     /* calc overflow */
2102     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
2103     env->PSW_USB_V = env->PSW_USB_V << 31;
2104     env->PSW_USB_SV |= env->PSW_USB_V;
2105     env->PSW_USB_AV = 0;
2106
2107     return ret;
2108 }
2109
2110 uint64_t helper_dvadj(uint64_t r1, uint32_t r2)
2111 {
2112     int32_t x_sign = (r1 >> 63);
2113     int32_t q_sign = x_sign ^ (r2 >> 31);
2114     int32_t eq_pos = x_sign & ((r1 >> 32) == r2);
2115     int32_t eq_neg = x_sign & ((r1 >> 32) == -r2);
2116     uint32_t quotient;
2117     uint64_t ret, remainder;
2118
2119     if ((q_sign & ~eq_neg) | eq_pos) {
2120         quotient = (r1 + 1) & 0xffffffff;
2121     } else {
2122         quotient = r1 & 0xffffffff;
2123     }
2124
2125     if (eq_pos | eq_neg) {
2126         remainder = 0;
2127     } else {
2128         remainder = (r1 & 0xffffffff00000000ull);
2129     }
2130     ret = remainder|quotient;
2131     return ret;
2132 }
2133
2134 uint64_t helper_dvstep(uint64_t r1, uint32_t r2)
2135 {
2136     int32_t dividend_sign = extract64(r1, 63, 1);
2137     int32_t divisor_sign = extract32(r2, 31, 1);
2138     int32_t quotient_sign = (dividend_sign != divisor_sign);
2139     int32_t addend, dividend_quotient, remainder;
2140     int32_t i, temp;
2141
2142     if (quotient_sign) {
2143         addend = r2;
2144     } else {
2145         addend = -r2;
2146     }
2147     dividend_quotient = (int32_t)r1;
2148     remainder = (int32_t)(r1 >> 32);
2149
2150     for (i = 0; i < 8; i++) {
2151         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2152         dividend_quotient <<= 1;
2153         temp = remainder + addend;
2154         if ((temp < 0) == dividend_sign) {
2155             remainder = temp;
2156         }
2157         if (((temp < 0) == dividend_sign)) {
2158             dividend_quotient = dividend_quotient | !quotient_sign;
2159         } else {
2160             dividend_quotient = dividend_quotient | quotient_sign;
2161         }
2162     }
2163     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2164 }
2165
2166 uint64_t helper_dvstep_u(uint64_t r1, uint32_t r2)
2167 {
2168     int32_t dividend_quotient = extract64(r1, 0, 32);
2169     int64_t remainder = extract64(r1, 32, 32);
2170     int32_t i;
2171     int64_t temp;
2172     for (i = 0; i < 8; i++) {
2173         remainder = (remainder << 1) | extract32(dividend_quotient, 31, 1);
2174         dividend_quotient <<= 1;
2175         temp = (remainder & 0xffffffff) - r2;
2176         if (temp >= 0) {
2177             remainder = temp;
2178         }
2179         dividend_quotient = dividend_quotient | !(temp < 0);
2180     }
2181     return ((uint64_t)remainder << 32) | (uint32_t)dividend_quotient;
2182 }
2183
2184 uint64_t helper_divide(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2185 {
2186     int32_t quotient, remainder;
2187     int32_t dividend = (int32_t)r1;
2188     int32_t divisor = (int32_t)r2;
2189
2190     if (divisor == 0) {
2191         if (dividend >= 0) {
2192             quotient = 0x7fffffff;
2193             remainder = 0;
2194         } else {
2195             quotient = 0x80000000;
2196             remainder = 0;
2197         }
2198         env->PSW_USB_V = (1 << 31);
2199     } else if ((divisor == 0xffffffff) && (dividend == 0x80000000)) {
2200         quotient = 0x7fffffff;
2201         remainder = 0;
2202         env->PSW_USB_V = (1 << 31);
2203     } else {
2204         remainder = dividend % divisor;
2205         quotient = (dividend - remainder)/divisor;
2206         env->PSW_USB_V = 0;
2207     }
2208     env->PSW_USB_SV |= env->PSW_USB_V;
2209     env->PSW_USB_AV = 0;
2210     return ((uint64_t)remainder << 32) | (uint32_t)quotient;
2211 }
2212
2213 uint64_t helper_divide_u(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
2214 {
2215     uint32_t quotient, remainder;
2216     uint32_t dividend = r1;
2217     uint32_t divisor = r2;
2218
2219     if (divisor == 0) {
2220         quotient = 0xffffffff;
2221         remainder = 0;
2222         env->PSW_USB_V = (1 << 31);
2223     } else {
2224         remainder = dividend % divisor;
2225         quotient = (dividend - remainder)/divisor;
2226         env->PSW_USB_V = 0;
2227     }
2228     env->PSW_USB_SV |= env->PSW_USB_V;
2229     env->PSW_USB_AV = 0;
2230     return ((uint64_t)remainder << 32) | quotient;
2231 }
2232
2233 uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
2234                       uint32_t arg10, uint32_t arg11, uint32_t n)
2235 {
2236     uint64_t ret;
2237     uint32_t result0, result1;
2238
2239     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2240                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
2241     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2242                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
2243     if (sc1) {
2244         result1 = 0x7fffffff;
2245     } else {
2246         result1 = (((uint32_t)(arg00 * arg10)) << n);
2247     }
2248     if (sc0) {
2249         result0 = 0x7fffffff;
2250     } else {
2251         result0 = (((uint32_t)(arg01 * arg11)) << n);
2252     }
2253     ret = (((uint64_t)result1 << 32)) | result0;
2254     return ret;
2255 }
2256
2257 uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
2258                        uint32_t arg10, uint32_t arg11, uint32_t n)
2259 {
2260     uint64_t ret;
2261     int64_t result0, result1;
2262
2263     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2264                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
2265     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2266                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
2267
2268     if (sc1) {
2269         result1 = 0x7fffffff;
2270     } else {
2271         result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
2272     }
2273     if (sc0) {
2274         result0 = 0x7fffffff;
2275     } else {
2276         result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
2277     }
2278     ret = (result1 + result0);
2279     ret = ret << 16;
2280     return ret;
2281 }
2282 uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
2283                        uint32_t arg10, uint32_t arg11, uint32_t n)
2284 {
2285     uint32_t result0, result1;
2286
2287     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
2288                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
2289     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
2290                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
2291
2292     if (sc1) {
2293         result1 = 0x7fffffff;
2294     } else {
2295         result1 = ((arg00 * arg10) << n) + 0x8000;
2296     }
2297     if (sc0) {
2298         result0 = 0x7fffffff;
2299     } else {
2300         result0 = ((arg01 * arg11) << n) + 0x8000;
2301     }
2302     return (result1 & 0xffff0000) | (result0 >> 16);
2303 }
2304
2305 uint32_t helper_crc32(uint32_t arg0, uint32_t arg1)
2306 {
2307     uint8_t buf[4];
2308     uint32_t ret;
2309     stl_be_p(buf, arg0);
2310
2311     ret = crc32(arg1, buf, 4);
2312     return ret;
2313 }
2314
2315 /* context save area (CSA) related helpers */
2316
2317 static int cdc_increment(target_ulong *psw)
2318 {
2319     if ((*psw & MASK_PSW_CDC) == 0x7f) {
2320         return 0;
2321     }
2322
2323     (*psw)++;
2324     /* check for overflow */
2325     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2326     int mask = (1u << (7 - lo)) - 1;
2327     int count = *psw & mask;
2328     if (count == 0) {
2329         (*psw)--;
2330         return 1;
2331     }
2332     return 0;
2333 }
2334
2335 static int cdc_decrement(target_ulong *psw)
2336 {
2337     if ((*psw & MASK_PSW_CDC) == 0x7f) {
2338         return 0;
2339     }
2340     /* check for underflow */
2341     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2342     int mask = (1u << (7 - lo)) - 1;
2343     int count = *psw & mask;
2344     if (count == 0) {
2345         return 1;
2346     }
2347     (*psw)--;
2348     return 0;
2349 }
2350
2351 static bool cdc_zero(target_ulong *psw)
2352 {
2353     int cdc = *psw & MASK_PSW_CDC;
2354     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
2355        7'b1111111, otherwise returns FALSE. */
2356     if (cdc == 0x7f) {
2357         return true;
2358     }
2359     /* find CDC.COUNT */
2360     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
2361     int mask = (1u << (7 - lo)) - 1;
2362     int count = *psw & mask;
2363     return count == 0;
2364 }
2365
2366 static void save_context_upper(CPUTriCoreState *env, int ea)
2367 {
2368     cpu_stl_data(env, ea, env->PCXI);
2369     cpu_stl_data(env, ea+4, psw_read(env));
2370     cpu_stl_data(env, ea+8, env->gpr_a[10]);
2371     cpu_stl_data(env, ea+12, env->gpr_a[11]);
2372     cpu_stl_data(env, ea+16, env->gpr_d[8]);
2373     cpu_stl_data(env, ea+20, env->gpr_d[9]);
2374     cpu_stl_data(env, ea+24, env->gpr_d[10]);
2375     cpu_stl_data(env, ea+28, env->gpr_d[11]);
2376     cpu_stl_data(env, ea+32, env->gpr_a[12]);
2377     cpu_stl_data(env, ea+36, env->gpr_a[13]);
2378     cpu_stl_data(env, ea+40, env->gpr_a[14]);
2379     cpu_stl_data(env, ea+44, env->gpr_a[15]);
2380     cpu_stl_data(env, ea+48, env->gpr_d[12]);
2381     cpu_stl_data(env, ea+52, env->gpr_d[13]);
2382     cpu_stl_data(env, ea+56, env->gpr_d[14]);
2383     cpu_stl_data(env, ea+60, env->gpr_d[15]);
2384 }
2385
2386 static void save_context_lower(CPUTriCoreState *env, int ea)
2387 {
2388     cpu_stl_data(env, ea, env->PCXI);
2389     cpu_stl_data(env, ea+4, env->gpr_a[11]);
2390     cpu_stl_data(env, ea+8, env->gpr_a[2]);
2391     cpu_stl_data(env, ea+12, env->gpr_a[3]);
2392     cpu_stl_data(env, ea+16, env->gpr_d[0]);
2393     cpu_stl_data(env, ea+20, env->gpr_d[1]);
2394     cpu_stl_data(env, ea+24, env->gpr_d[2]);
2395     cpu_stl_data(env, ea+28, env->gpr_d[3]);
2396     cpu_stl_data(env, ea+32, env->gpr_a[4]);
2397     cpu_stl_data(env, ea+36, env->gpr_a[5]);
2398     cpu_stl_data(env, ea+40, env->gpr_a[6]);
2399     cpu_stl_data(env, ea+44, env->gpr_a[7]);
2400     cpu_stl_data(env, ea+48, env->gpr_d[4]);
2401     cpu_stl_data(env, ea+52, env->gpr_d[5]);
2402     cpu_stl_data(env, ea+56, env->gpr_d[6]);
2403     cpu_stl_data(env, ea+60, env->gpr_d[7]);
2404 }
2405
2406 static void restore_context_upper(CPUTriCoreState *env, int ea,
2407                                   target_ulong *new_PCXI, target_ulong *new_PSW)
2408 {
2409     *new_PCXI = cpu_ldl_data(env, ea);
2410     *new_PSW = cpu_ldl_data(env, ea+4);
2411     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
2412     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
2413     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
2414     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
2415     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
2416     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
2417     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
2418     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
2419     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
2420     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
2421     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
2422     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
2423     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
2424     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
2425 }
2426
2427 static void restore_context_lower(CPUTriCoreState *env, int ea,
2428                                   target_ulong *ra, target_ulong *pcxi)
2429 {
2430     *pcxi = cpu_ldl_data(env, ea);
2431     *ra = cpu_ldl_data(env, ea+4);
2432     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
2433     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
2434     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
2435     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
2436     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
2437     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
2438     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
2439     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
2440     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
2441     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
2442     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
2443     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
2444     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
2445     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
2446 }
2447
2448 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
2449 {
2450     target_ulong tmp_FCX;
2451     target_ulong ea;
2452     target_ulong new_FCX;
2453     target_ulong psw;
2454
2455     psw = psw_read(env);
2456     /* if (FCX == 0) trap(FCU); */
2457     if (env->FCX == 0) {
2458         /* FCU trap */
2459         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2460     }
2461     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
2462     if (psw & MASK_PSW_CDE) {
2463         if (cdc_increment(&psw)) {
2464             /* CDO trap */
2465             raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDO, GETPC());
2466         }
2467     }
2468     /* PSW.CDE = 1;*/
2469     psw |= MASK_PSW_CDE;
2470     /* tmp_FCX = FCX; */
2471     tmp_FCX = env->FCX;
2472     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2473     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2474          ((env->FCX & MASK_FCX_FCXO) << 6);
2475     /* new_FCX = M(EA, word); */
2476     new_FCX = cpu_ldl_data(env, ea);
2477     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2478                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2479                            D[15]}; */
2480     save_context_upper(env, ea);
2481
2482     /* PCXI.PCPN = ICR.CCPN; */
2483     env->PCXI = (env->PCXI & 0xffffff) +
2484                 ((env->ICR & MASK_ICR_CCPN) << 24);
2485     /* PCXI.PIE = ICR.IE; */
2486     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2487                 ((env->ICR & MASK_ICR_IE) << 15));
2488     /* PCXI.UL = 1; */
2489     env->PCXI |= MASK_PCXI_UL;
2490
2491     /* PCXI[19: 0] = FCX[19: 0]; */
2492     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2493     /* FCX[19: 0] = new_FCX[19: 0]; */
2494     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2495     /* A[11] = next_pc[31: 0]; */
2496     env->gpr_a[11] = next_pc;
2497
2498     /* if (tmp_FCX == LCX) trap(FCD);*/
2499     if (tmp_FCX == env->LCX) {
2500         /* FCD trap */
2501         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2502     }
2503     psw_write(env, psw);
2504 }
2505
2506 void helper_ret(CPUTriCoreState *env)
2507 {
2508     target_ulong ea;
2509     target_ulong new_PCXI;
2510     target_ulong new_PSW, psw;
2511
2512     psw = psw_read(env);
2513      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
2514     if (psw & MASK_PSW_CDE) {
2515         if (cdc_decrement(&psw)) {
2516             /* CDU trap */
2517             psw_write(env, psw);
2518             raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CDU, GETPC());
2519         }
2520     }
2521     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2522     if ((env->PCXI & 0xfffff) == 0) {
2523         /* CSU trap */
2524         psw_write(env, psw);
2525         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2526     }
2527     /* if (PCXI.UL == 0) then trap(CTYP); */
2528     if ((env->PCXI & MASK_PCXI_UL) == 0) {
2529         /* CTYP trap */
2530         cdc_increment(&psw); /* restore to the start of helper */
2531         psw_write(env, psw);
2532         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2533     }
2534     /* PC = {A11 [31: 1], 1’b0}; */
2535     env->PC = env->gpr_a[11] & 0xfffffffe;
2536
2537     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2538     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2539          ((env->PCXI & MASK_PCXI_PCXO) << 6);
2540     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2541         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2542     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2543     /* M(EA, word) = FCX; */
2544     cpu_stl_data(env, ea, env->FCX);
2545     /* FCX[19: 0] = PCXI[19: 0]; */
2546     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2547     /* PCXI = new_PCXI; */
2548     env->PCXI = new_PCXI;
2549
2550     if (tricore_feature(env, TRICORE_FEATURE_13)) {
2551         /* PSW = new_PSW */
2552         psw_write(env, new_PSW);
2553     } else {
2554         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
2555         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
2556     }
2557 }
2558
2559 void helper_bisr(CPUTriCoreState *env, uint32_t const9)
2560 {
2561     target_ulong tmp_FCX;
2562     target_ulong ea;
2563     target_ulong new_FCX;
2564
2565     if (env->FCX == 0) {
2566         /* FCU trap */
2567        raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2568     }
2569
2570     tmp_FCX = env->FCX;
2571     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
2572
2573     /* new_FCX = M(EA, word); */
2574     new_FCX = cpu_ldl_data(env, ea);
2575     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
2576                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
2577     save_context_lower(env, ea);
2578
2579
2580     /* PCXI.PCPN = ICR.CCPN */
2581     env->PCXI = (env->PCXI & 0xffffff) +
2582                  ((env->ICR & MASK_ICR_CCPN) << 24);
2583     /* PCXI.PIE  = ICR.IE */
2584     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2585                  ((env->ICR & MASK_ICR_IE) << 15));
2586     /* PCXI.UL = 0 */
2587     env->PCXI &= ~(MASK_PCXI_UL);
2588     /* PCXI[19: 0] = FCX[19: 0] */
2589     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2590     /* FXC[19: 0] = new_FCX[19: 0] */
2591     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2592     /* ICR.IE = 1 */
2593     env->ICR |= MASK_ICR_IE;
2594
2595     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
2596
2597     if (tmp_FCX == env->LCX) {
2598         /* FCD trap */
2599         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2600     }
2601 }
2602
2603 void helper_rfe(CPUTriCoreState *env)
2604 {
2605     target_ulong ea;
2606     target_ulong new_PCXI;
2607     target_ulong new_PSW;
2608     /* if (PCXI[19: 0] == 0) then trap(CSU); */
2609     if ((env->PCXI & 0xfffff) == 0) {
2610         /* raise csu trap */
2611         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2612     }
2613     /* if (PCXI.UL == 0) then trap(CTYP); */
2614     if ((env->PCXI & MASK_PCXI_UL) == 0) {
2615         /* raise CTYP trap */
2616         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2617     }
2618     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
2619     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
2620         /* raise NEST trap */
2621         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_NEST, GETPC());
2622     }
2623     env->PC = env->gpr_a[11] & ~0x1;
2624     /* ICR.IE = PCXI.PIE; */
2625     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
2626     /* ICR.CCPN = PCXI.PCPN; */
2627     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
2628                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
2629     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
2630     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2631          ((env->PCXI & MASK_PCXI_PCXO) << 6);
2632     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2633       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2634     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
2635     /* M(EA, word) = FCX;*/
2636     cpu_stl_data(env, ea, env->FCX);
2637     /* FCX[19: 0] = PCXI[19: 0]; */
2638     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2639     /* PCXI = new_PCXI; */
2640     env->PCXI = new_PCXI;
2641     /* write psw */
2642     psw_write(env, new_PSW);
2643 }
2644
2645 void helper_rfm(CPUTriCoreState *env)
2646 {
2647     env->PC = (env->gpr_a[11] & ~0x1);
2648     /* ICR.IE = PCXI.PIE; */
2649     env->ICR = (env->ICR & ~MASK_ICR_IE) |
2650                ((env->PCXI & MASK_PCXI_PIE) >> 15);
2651     /* ICR.CCPN = PCXI.PCPN; */
2652     env->ICR = (env->ICR & ~MASK_ICR_CCPN) |
2653                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
2654     /* {PCXI, PSW, A[10], A[11]} = M(DCX, 4 * word); */
2655     env->PCXI = cpu_ldl_data(env, env->DCX);
2656     psw_write(env, cpu_ldl_data(env, env->DCX+4));
2657     env->gpr_a[10] = cpu_ldl_data(env, env->DCX+8);
2658     env->gpr_a[11] = cpu_ldl_data(env, env->DCX+12);
2659
2660     if (tricore_feature(env, TRICORE_FEATURE_131)) {
2661         env->DBGTCR = 0;
2662     }
2663 }
2664
2665 void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
2666 {
2667     uint32_t dummy;
2668     /* insn doesn't load PCXI and RA */
2669     restore_context_lower(env, ea, &dummy, &dummy);
2670 }
2671
2672 void helper_lducx(CPUTriCoreState *env, uint32_t ea)
2673 {
2674     uint32_t dummy;
2675     /* insn doesn't load PCXI and PSW */
2676     restore_context_upper(env, ea, &dummy, &dummy);
2677 }
2678
2679 void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
2680 {
2681     save_context_lower(env, ea);
2682 }
2683
2684 void helper_stucx(CPUTriCoreState *env, uint32_t ea)
2685 {
2686     save_context_upper(env, ea);
2687 }
2688
2689 void helper_svlcx(CPUTriCoreState *env)
2690 {
2691     target_ulong tmp_FCX;
2692     target_ulong ea;
2693     target_ulong new_FCX;
2694
2695     if (env->FCX == 0) {
2696         /* FCU trap */
2697         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2698     }
2699     /* tmp_FCX = FCX; */
2700     tmp_FCX = env->FCX;
2701     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2702     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2703          ((env->FCX & MASK_FCX_FCXO) << 6);
2704     /* new_FCX = M(EA, word); */
2705     new_FCX = cpu_ldl_data(env, ea);
2706     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2707                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2708                            D[15]}; */
2709     save_context_lower(env, ea);
2710
2711     /* PCXI.PCPN = ICR.CCPN; */
2712     env->PCXI = (env->PCXI & 0xffffff) +
2713                 ((env->ICR & MASK_ICR_CCPN) << 24);
2714     /* PCXI.PIE = ICR.IE; */
2715     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2716                 ((env->ICR & MASK_ICR_IE) << 15));
2717     /* PCXI.UL = 0; */
2718     env->PCXI &= ~MASK_PCXI_UL;
2719
2720     /* PCXI[19: 0] = FCX[19: 0]; */
2721     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2722     /* FCX[19: 0] = new_FCX[19: 0]; */
2723     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2724
2725     /* if (tmp_FCX == LCX) trap(FCD);*/
2726     if (tmp_FCX == env->LCX) {
2727         /* FCD trap */
2728         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2729     }
2730 }
2731
2732 void helper_svucx(CPUTriCoreState *env)
2733 {
2734     target_ulong tmp_FCX;
2735     target_ulong ea;
2736     target_ulong new_FCX;
2737
2738     if (env->FCX == 0) {
2739         /* FCU trap */
2740         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCU, GETPC());
2741     }
2742     /* tmp_FCX = FCX; */
2743     tmp_FCX = env->FCX;
2744     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
2745     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
2746          ((env->FCX & MASK_FCX_FCXO) << 6);
2747     /* new_FCX = M(EA, word); */
2748     new_FCX = cpu_ldl_data(env, ea);
2749     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
2750                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
2751                            D[15]}; */
2752     save_context_upper(env, ea);
2753
2754     /* PCXI.PCPN = ICR.CCPN; */
2755     env->PCXI = (env->PCXI & 0xffffff) +
2756                 ((env->ICR & MASK_ICR_CCPN) << 24);
2757     /* PCXI.PIE = ICR.IE; */
2758     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
2759                 ((env->ICR & MASK_ICR_IE) << 15));
2760     /* PCXI.UL = 1; */
2761     env->PCXI |= MASK_PCXI_UL;
2762
2763     /* PCXI[19: 0] = FCX[19: 0]; */
2764     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
2765     /* FCX[19: 0] = new_FCX[19: 0]; */
2766     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
2767
2768     /* if (tmp_FCX == LCX) trap(FCD);*/
2769     if (tmp_FCX == env->LCX) {
2770         /* FCD trap */
2771         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_FCD, GETPC());
2772     }
2773 }
2774
2775 void helper_rslcx(CPUTriCoreState *env)
2776 {
2777     target_ulong ea;
2778     target_ulong new_PCXI;
2779     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
2780     if ((env->PCXI & 0xfffff) == 0) {
2781         /* CSU trap */
2782         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CSU, GETPC());
2783     }
2784     /* if (PCXI.UL == 1) then trap(CTYP); */
2785     if ((env->PCXI & MASK_PCXI_UL) != 0) {
2786         /* CTYP trap */
2787         raise_exception_sync_helper(env, TRAPC_CTX_MNG, TIN3_CTYP, GETPC());
2788     }
2789     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
2790     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
2791          ((env->PCXI & MASK_PCXI_PCXO) << 6);
2792     /* {new_PCXI, A[11], A[10], A[11], D[8], D[9], D[10], D[11], A[12],
2793         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
2794     restore_context_lower(env, ea, &env->gpr_a[11], &new_PCXI);
2795     /* M(EA, word) = FCX; */
2796     cpu_stl_data(env, ea, env->FCX);
2797     /* M(EA, word) = FCX; */
2798     cpu_stl_data(env, ea, env->FCX);
2799     /* FCX[19: 0] = PCXI[19: 0]; */
2800     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
2801     /* PCXI = new_PCXI; */
2802     env->PCXI = new_PCXI;
2803 }
2804
2805 void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
2806 {
2807     psw_write(env, arg);
2808 }
2809
2810 uint32_t helper_psw_read(CPUTriCoreState *env)
2811 {
2812     return psw_read(env);
2813 }
2814
2815
2816 static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
2817                                                         uint32_t exception,
2818                                                         int error_code,
2819                                                         uintptr_t pc)
2820 {
2821     CPUState *cs = CPU(tricore_env_get_cpu(env));
2822     cs->exception_index = exception;
2823     env->error_code = error_code;
2824
2825     if (pc) {
2826         /* now we have a real cpu fault */
2827         cpu_restore_state(cs, pc);
2828     }
2829
2830     cpu_loop_exit(cs);
2831 }
2832
2833 void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
2834               uintptr_t retaddr)
2835 {
2836     int ret;
2837     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
2838     if (ret) {
2839         TriCoreCPU *cpu = TRICORE_CPU(cs);
2840         CPUTriCoreState *env = &cpu->env;
2841         do_raise_exception_err(env, cs->exception_index,
2842                                env->error_code, retaddr);
2843     }
2844 }
This page took 0.186764 seconds and 4 git commands to generate.