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