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