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