]> Git Repo - qemu.git/blob - target-tricore/op_helper.c
target-tricore: Fix new typos
[qemu.git] / target-tricore / op_helper.c
1 /*
2  *  Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16  */
17 #include <stdlib.h>
18 #include "cpu.h"
19 #include "qemu/host-utils.h"
20 #include "exec/helper-proto.h"
21 #include "exec/cpu_ldst.h"
22
23 /* Addressing mode helper */
24
25 static uint16_t reverse16(uint16_t val)
26 {
27     uint8_t high = (uint8_t)(val >> 8);
28     uint8_t low  = (uint8_t)(val & 0xff);
29
30     uint16_t rh, rl;
31
32     rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
33     rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
34
35     return (rh << 8) | rl;
36 }
37
38 uint32_t helper_br_update(uint32_t reg)
39 {
40     uint32_t index = reg & 0xffff;
41     uint32_t incr  = reg >> 16;
42     uint32_t new_index = reverse16(reverse16(index) + reverse16(incr));
43     return reg - index + new_index;
44 }
45
46 uint32_t helper_circ_update(uint32_t reg, uint32_t off)
47 {
48     uint32_t index = reg & 0xffff;
49     uint32_t length = reg >> 16;
50     int32_t new_index = index + off;
51     if (new_index < 0) {
52         new_index += length;
53     } else {
54         new_index %= length;
55     }
56     return reg - index + new_index;
57 }
58
59 static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
60 {
61     uint32_t ret;
62     int64_t max_pos = INT32_MAX;
63     int64_t max_neg = INT32_MIN;
64     if (arg > max_pos) {
65         env->PSW_USB_V = (1 << 31);
66         env->PSW_USB_SV = (1 << 31);
67         ret = (target_ulong)max_pos;
68     } else {
69         if (arg < max_neg) {
70             env->PSW_USB_V = (1 << 31);
71             env->PSW_USB_SV = (1 << 31);
72             ret = (target_ulong)max_neg;
73         } else {
74             env->PSW_USB_V = 0;
75             ret = (target_ulong)arg;
76         }
77     }
78     env->PSW_USB_AV = arg ^ arg * 2u;
79     env->PSW_USB_SAV |= env->PSW_USB_AV;
80     return ret;
81 }
82
83 static uint32_t suov32(CPUTriCoreState *env, int64_t arg)
84 {
85     uint32_t ret;
86     int64_t max_pos = UINT32_MAX;
87     if (arg > max_pos) {
88         env->PSW_USB_V = (1 << 31);
89         env->PSW_USB_SV = (1 << 31);
90         ret = (target_ulong)max_pos;
91     } else {
92         if (arg < 0) {
93             env->PSW_USB_V = (1 << 31);
94             env->PSW_USB_SV = (1 << 31);
95             ret = 0;
96         } else {
97             env->PSW_USB_V = 0;
98             ret = (target_ulong)arg;
99         }
100      }
101     env->PSW_USB_AV = arg ^ arg * 2u;
102     env->PSW_USB_SAV |= env->PSW_USB_AV;
103     return ret;
104 }
105
106 static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
107 {
108     int32_t max_pos = INT16_MAX;
109     int32_t max_neg = INT16_MIN;
110     int32_t av0, av1;
111
112     env->PSW_USB_V = 0;
113     av0 = hw0 ^ hw0 * 2u;
114     if (hw0 > max_pos) {
115         env->PSW_USB_V = (1 << 31);
116         hw0 = max_pos;
117     } else if (hw0 < max_neg) {
118         env->PSW_USB_V = (1 << 31);
119         hw0 = max_neg;
120     }
121
122     av1 = hw1 ^ hw1 * 2u;
123     if (hw1 > max_pos) {
124         env->PSW_USB_V = (1 << 31);
125         hw1 = max_pos;
126     } else if (hw1 < max_neg) {
127         env->PSW_USB_V = (1 << 31);
128         hw1 = max_neg;
129     }
130
131     env->PSW_USB_SV |= env->PSW_USB_V;
132     env->PSW_USB_AV = (av0 | av1) << 16;
133     env->PSW_USB_SAV |= env->PSW_USB_AV;
134     return (hw0 & 0xffff) | (hw1 << 16);
135 }
136
137 static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
138 {
139     int32_t max_pos = UINT16_MAX;
140     int32_t av0, av1;
141
142     env->PSW_USB_V = 0;
143     av0 = hw0 ^ hw0 * 2u;
144     if (hw0 > max_pos) {
145         env->PSW_USB_V = (1 << 31);
146         hw0 = max_pos;
147     } else if (hw0 < 0) {
148         env->PSW_USB_V = (1 << 31);
149         hw0 = 0;
150     }
151
152     av1 = hw1 ^ hw1 * 2u;
153     if (hw1 > max_pos) {
154         env->PSW_USB_V = (1 << 31);
155         hw1 = max_pos;
156     } else if (hw1 < 0) {
157         env->PSW_USB_V = (1 << 31);
158         hw1 = 0;
159     }
160
161     env->PSW_USB_SV |= env->PSW_USB_V;
162     env->PSW_USB_AV = (av0 | av1) << 16;
163     env->PSW_USB_SAV |= env->PSW_USB_AV;
164     return (hw0 & 0xffff) | (hw1 << 16);
165 }
166
167 target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
168                              target_ulong r2)
169 {
170     int64_t t1 = sextract64(r1, 0, 32);
171     int64_t t2 = sextract64(r2, 0, 32);
172     int64_t result = t1 + t2;
173     return ssov32(env, result);
174 }
175
176 target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
177                                target_ulong r2)
178 {
179     int32_t ret_hw0, ret_hw1;
180
181     ret_hw0 = sextract32(r1, 0, 16) + sextract32(r2, 0, 16);
182     ret_hw1 = sextract32(r1, 16, 16) + sextract32(r2, 16, 16);
183     return ssov16(env, ret_hw0, ret_hw1);
184 }
185
186 target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
187                              target_ulong r2)
188 {
189     int64_t t1 = extract64(r1, 0, 32);
190     int64_t t2 = extract64(r2, 0, 32);
191     int64_t result = t1 + t2;
192     return suov32(env, result);
193 }
194
195 target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
196                                target_ulong r2)
197 {
198     int32_t ret_hw0, ret_hw1;
199
200     ret_hw0 = extract32(r1, 0, 16) + extract32(r2, 0, 16);
201     ret_hw1 = extract32(r1, 16, 16) + extract32(r2, 16, 16);
202     return suov16(env, ret_hw0, ret_hw1);
203 }
204
205 target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
206                              target_ulong r2)
207 {
208     int64_t t1 = sextract64(r1, 0, 32);
209     int64_t t2 = sextract64(r2, 0, 32);
210     int64_t result = t1 - t2;
211     return ssov32(env, result);
212 }
213
214 target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
215                              target_ulong r2)
216 {
217     int32_t ret_hw0, ret_hw1;
218
219     ret_hw0 = sextract32(r1, 0, 16) - sextract32(r2, 0, 16);
220     ret_hw1 = sextract32(r1, 16, 16) - sextract32(r2, 16, 16);
221     return ssov16(env, ret_hw0, ret_hw1);
222 }
223
224 target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
225                              target_ulong r2)
226 {
227     int64_t t1 = extract64(r1, 0, 32);
228     int64_t t2 = extract64(r2, 0, 32);
229     int64_t result = t1 - t2;
230     return suov32(env, result);
231 }
232
233 target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
234                                target_ulong r2)
235 {
236     int32_t ret_hw0, ret_hw1;
237
238     ret_hw0 = extract32(r1, 0, 16) - extract32(r2, 0, 16);
239     ret_hw1 = extract32(r1, 16, 16) - extract32(r2, 16, 16);
240     return suov16(env, ret_hw0, ret_hw1);
241 }
242
243 target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
244                              target_ulong r2)
245 {
246     int64_t t1 = sextract64(r1, 0, 32);
247     int64_t t2 = sextract64(r2, 0, 32);
248     int64_t result = t1 * t2;
249     return ssov32(env, result);
250 }
251
252 target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
253                              target_ulong r2)
254 {
255     int64_t t1 = extract64(r1, 0, 32);
256     int64_t t2 = extract64(r2, 0, 32);
257     int64_t result = t1 * t2;
258     return suov32(env, result);
259 }
260
261 target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
262                              target_ulong r2)
263 {
264     int64_t t1 = sextract64(r1, 0, 32);
265     int32_t t2 = sextract64(r2, 0, 6);
266     int64_t result;
267     if (t2 == 0) {
268         result = t1;
269     } else if (t2 > 0) {
270         result = t1 << t2;
271     } else {
272         result = t1 >> -t2;
273     }
274     return ssov32(env, result);
275 }
276
277 uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
278 {
279     target_ulong result;
280     result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
281     return ssov32(env, result);
282 }
283
284 uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
285 {
286     int32_t ret_h0, ret_h1;
287
288     ret_h0 = sextract32(r1, 0, 16);
289     ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
290
291     ret_h1 = sextract32(r1, 16, 16);
292     ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
293
294     return ssov16(env, ret_h0, ret_h1);
295 }
296
297 target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
298                                 target_ulong r2)
299 {
300     int64_t t1 = sextract64(r1, 0, 32);
301     int64_t t2 = sextract64(r2, 0, 32);
302     int64_t result;
303
304     if (t1 > t2) {
305         result = t1 - t2;
306     } else {
307         result = t2 - t1;
308     }
309     return ssov32(env, result);
310 }
311
312 uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
313                               target_ulong r2)
314 {
315     int32_t t1, t2;
316     int32_t ret_h0, ret_h1;
317
318     t1 = sextract32(r1, 0, 16);
319     t2 = sextract32(r2, 0, 16);
320     if (t1 > t2) {
321         ret_h0 = t1 - t2;
322     } else {
323         ret_h0 = t2 - t1;
324     }
325
326     t1 = sextract32(r1, 16, 16);
327     t2 = sextract32(r2, 16, 16);
328     if (t1 > t2) {
329         ret_h1 = t1 - t2;
330     } else {
331         ret_h1 = t2 - t1;
332     }
333
334     return ssov16(env, ret_h0, ret_h1);
335 }
336
337 target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
338                                 target_ulong r2, target_ulong r3)
339 {
340     int64_t t1 = sextract64(r1, 0, 32);
341     int64_t t2 = sextract64(r2, 0, 32);
342     int64_t t3 = sextract64(r3, 0, 32);
343     int64_t result;
344
345     result = t2 + (t1 * t3);
346     return ssov32(env, result);
347 }
348
349 target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
350                                 target_ulong r2, target_ulong r3)
351 {
352     uint64_t t1 = extract64(r1, 0, 32);
353     uint64_t t2 = extract64(r2, 0, 32);
354     uint64_t t3 = extract64(r3, 0, 32);
355     int64_t result;
356
357     result = t2 + (t1 * t3);
358     return suov32(env, result);
359 }
360
361 uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
362                             uint64_t r2, target_ulong r3)
363 {
364     uint64_t ret, ovf;
365     int64_t t1 = sextract64(r1, 0, 32);
366     int64_t t3 = sextract64(r3, 0, 32);
367     int64_t mul;
368
369     mul = t1 * t3;
370     ret = mul + r2;
371     ovf = (ret ^ mul) & ~(mul ^ r2);
372
373     if ((int64_t)ovf < 0) {
374         env->PSW_USB_V = (1 << 31);
375         env->PSW_USB_SV = (1 << 31);
376         /* ext_ret > MAX_INT */
377         if (mul >= 0) {
378             ret = INT64_MAX;
379         /* ext_ret < MIN_INT */
380         } else {
381             ret = INT64_MIN;
382         }
383     } else {
384         env->PSW_USB_V = 0;
385     }
386     t1 = ret >> 32;
387     env->PSW_USB_AV = t1 ^ t1 * 2u;
388     env->PSW_USB_SAV |= env->PSW_USB_AV;
389
390     return ret;
391 }
392
393 uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
394                             uint64_t r2, target_ulong r3)
395 {
396     uint64_t ret, mul;
397     uint64_t t1 = extract64(r1, 0, 32);
398     uint64_t t3 = extract64(r3, 0, 32);
399
400     mul = t1 * t3;
401     ret = mul + r2;
402
403     if (ret < r2) {
404         env->PSW_USB_V = (1 << 31);
405         env->PSW_USB_SV = (1 << 31);
406         /* saturate */
407         ret = UINT64_MAX;
408     } else {
409         env->PSW_USB_V = 0;
410     }
411     t1 = ret >> 32;
412     env->PSW_USB_AV = t1 ^ t1 * 2u;
413     env->PSW_USB_SAV |= env->PSW_USB_AV;
414     return ret;
415 }
416
417 target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
418                                 target_ulong r2, target_ulong r3)
419 {
420     int64_t t1 = sextract64(r1, 0, 32);
421     int64_t t2 = sextract64(r2, 0, 32);
422     int64_t t3 = sextract64(r3, 0, 32);
423     int64_t result;
424
425     result = t2 - (t1 * t3);
426     return ssov32(env, result);
427 }
428
429 target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
430                                 target_ulong r2, target_ulong r3)
431 {
432     int64_t t1 = extract64(r1, 0, 32);
433     int64_t t2 = extract64(r2, 0, 32);
434     int64_t t3 = extract64(r3, 0, 32);
435     int64_t result;
436
437     result = t2 - (t1 * t3);
438     return suov32(env, result);
439 }
440
441 uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
442                             uint64_t r2, target_ulong r3)
443 {
444     uint64_t ret, ovf;
445     int64_t t1 = sextract64(r1, 0, 32);
446     int64_t t3 = sextract64(r3, 0, 32);
447     int64_t mul;
448
449     mul = t1 * t3;
450     ret = r2 - mul;
451     ovf = (ret ^ r2) & (mul ^ r2);
452
453     if ((int64_t)ovf < 0) {
454         env->PSW_USB_V = (1 << 31);
455         env->PSW_USB_SV = (1 << 31);
456         /* ext_ret > MAX_INT */
457         if (mul < 0) {
458             ret = INT64_MAX;
459         /* ext_ret < MIN_INT */
460         } else {
461             ret = INT64_MIN;
462         }
463     } else {
464         env->PSW_USB_V = 0;
465     }
466     t1 = ret >> 32;
467     env->PSW_USB_AV = t1 ^ t1 * 2u;
468     env->PSW_USB_SAV |= env->PSW_USB_AV;
469     return ret;
470 }
471
472 uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
473                             uint64_t r2, target_ulong r3)
474 {
475     uint64_t ret, mul;
476     uint64_t t1 = extract64(r1, 0, 32);
477     uint64_t t3 = extract64(r3, 0, 32);
478
479     mul = t1 * t3;
480     ret = r2 - mul;
481
482     if (ret > r2) {
483         env->PSW_USB_V = (1 << 31);
484         env->PSW_USB_SV = (1 << 31);
485         /* saturate */
486         ret = 0;
487     } else {
488         env->PSW_USB_V = 0;
489     }
490     t1 = ret >> 32;
491     env->PSW_USB_AV = t1 ^ t1 * 2u;
492     env->PSW_USB_SAV |= env->PSW_USB_AV;
493     return ret;
494 }
495
496 uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
497 {
498     int32_t b, i;
499     int32_t ovf = 0;
500     int32_t avf = 0;
501     int32_t ret = 0;
502
503     for (i = 0; i < 4; i++) {
504         b = sextract32(arg, i * 8, 8);
505         b = (b >= 0) ? b : (0 - b);
506         ovf |= (b > 0x7F) || (b < -0x80);
507         avf |= b ^ b * 2u;
508         ret |= (b & 0xff) << (i * 8);
509     }
510
511     env->PSW_USB_V = ovf << 31;
512     env->PSW_USB_SV |= env->PSW_USB_V;
513     env->PSW_USB_AV = avf << 24;
514     env->PSW_USB_SAV |= env->PSW_USB_AV;
515
516     return ret;
517 }
518
519 uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
520 {
521     int32_t h, i;
522     int32_t ovf = 0;
523     int32_t avf = 0;
524     int32_t ret = 0;
525
526     for (i = 0; i < 2; i++) {
527         h = sextract32(arg, i * 16, 16);
528         h = (h >= 0) ? h : (0 - h);
529         ovf |= (h > 0x7FFF) || (h < -0x8000);
530         avf |= h ^ h * 2u;
531         ret |= (h & 0xffff) << (i * 16);
532     }
533
534     env->PSW_USB_V = ovf << 31;
535     env->PSW_USB_SV |= env->PSW_USB_V;
536     env->PSW_USB_AV = avf << 16;
537     env->PSW_USB_SAV |= env->PSW_USB_AV;
538
539     return ret;
540 }
541
542 uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
543 {
544     int32_t b, i;
545     int32_t extr_r2;
546     int32_t ovf = 0;
547     int32_t avf = 0;
548     int32_t ret = 0;
549
550     for (i = 0; i < 4; i++) {
551         extr_r2 = sextract32(r2, i * 8, 8);
552         b = sextract32(r1, i * 8, 8);
553         b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
554         ovf |= (b > 0x7F) || (b < -0x80);
555         avf |= b ^ b * 2u;
556         ret |= (b & 0xff) << (i * 8);
557     }
558
559     env->PSW_USB_V = ovf << 31;
560     env->PSW_USB_SV |= env->PSW_USB_V;
561     env->PSW_USB_AV = avf << 24;
562     env->PSW_USB_SAV |= env->PSW_USB_AV;
563     return ret;
564 }
565
566 uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
567 {
568     int32_t h, i;
569     int32_t extr_r2;
570     int32_t ovf = 0;
571     int32_t avf = 0;
572     int32_t ret = 0;
573
574     for (i = 0; i < 2; i++) {
575         extr_r2 = sextract32(r2, i * 16, 16);
576         h = sextract32(r1, i * 16, 16);
577         h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
578         ovf |= (h > 0x7FFF) || (h < -0x8000);
579         avf |= h ^ h * 2u;
580         ret |= (h & 0xffff) << (i * 16);
581     }
582
583     env->PSW_USB_V = ovf << 31;
584     env->PSW_USB_SV |= env->PSW_USB_V;
585     env->PSW_USB_AV = avf << 16;
586     env->PSW_USB_SAV |= env->PSW_USB_AV;
587
588     return ret;
589 }
590
591 uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
592 {
593     int32_t b, i;
594     int32_t extr_r1, extr_r2;
595     int32_t ovf = 0;
596     int32_t avf = 0;
597     uint32_t ret = 0;
598
599     for (i = 0; i < 4; i++) {
600         extr_r1 = sextract32(r1, i * 8, 8);
601         extr_r2 = sextract32(r2, i * 8, 8);
602
603         b = extr_r1 + extr_r2;
604         ovf |= ((b > 0x7f) || (b < -0x80));
605         avf |= b ^ b * 2u;
606         ret |= ((b & 0xff) << (i*8));
607     }
608
609     env->PSW_USB_V = (ovf << 31);
610     env->PSW_USB_SV |= env->PSW_USB_V;
611     env->PSW_USB_AV = avf << 24;
612     env->PSW_USB_SAV |= env->PSW_USB_AV;
613
614     return ret;
615 }
616
617 uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
618 {
619     int32_t h, i;
620     int32_t extr_r1, extr_r2;
621     int32_t ovf = 0;
622     int32_t avf = 0;
623     int32_t ret = 0;
624
625     for (i = 0; i < 2; i++) {
626         extr_r1 = sextract32(r1, i * 16, 16);
627         extr_r2 = sextract32(r2, i * 16, 16);
628         h = extr_r1 + extr_r2;
629         ovf |= ((h > 0x7fff) || (h < -0x8000));
630         avf |= h ^ h * 2u;
631         ret |= (h & 0xffff) << (i * 16);
632     }
633
634     env->PSW_USB_V = (ovf << 31);
635     env->PSW_USB_SV |= env->PSW_USB_V;
636     env->PSW_USB_AV = (avf << 16);
637     env->PSW_USB_SAV |= env->PSW_USB_AV;
638
639     return ret;
640 }
641
642 uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
643 {
644     int32_t b, i;
645     int32_t extr_r1, extr_r2;
646     int32_t ovf = 0;
647     int32_t avf = 0;
648     uint32_t ret = 0;
649
650     for (i = 0; i < 4; i++) {
651         extr_r1 = sextract32(r1, i * 8, 8);
652         extr_r2 = sextract32(r2, i * 8, 8);
653
654         b = extr_r1 - extr_r2;
655         ovf |= ((b > 0x7f) || (b < -0x80));
656         avf |= b ^ b * 2u;
657         ret |= ((b & 0xff) << (i*8));
658     }
659
660     env->PSW_USB_V = (ovf << 31);
661     env->PSW_USB_SV |= env->PSW_USB_V;
662     env->PSW_USB_AV = avf << 24;
663     env->PSW_USB_SAV |= env->PSW_USB_AV;
664
665     return ret;
666 }
667
668 uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
669 {
670     int32_t h, i;
671     int32_t extr_r1, extr_r2;
672     int32_t ovf = 0;
673     int32_t avf = 0;
674     int32_t ret = 0;
675
676     for (i = 0; i < 2; i++) {
677         extr_r1 = sextract32(r1, i * 16, 16);
678         extr_r2 = sextract32(r2, i * 16, 16);
679         h = extr_r1 - extr_r2;
680         ovf |= ((h > 0x7fff) || (h < -0x8000));
681         avf |= h ^ h * 2u;
682         ret |= (h & 0xffff) << (i * 16);
683     }
684
685     env->PSW_USB_V = (ovf << 31);
686     env->PSW_USB_SV |= env->PSW_USB_V;
687     env->PSW_USB_AV = avf << 16;
688     env->PSW_USB_SAV |= env->PSW_USB_AV;
689
690     return ret;
691 }
692
693 uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
694 {
695     int32_t ret;
696     int32_t i, msk;
697
698     ret = 0;
699     msk = 0xff;
700     for (i = 0; i < 4; i++) {
701         if ((r1 & msk) == (r2 & msk)) {
702             ret |= msk;
703         }
704         msk = msk << 8;
705     }
706
707     return ret;
708 }
709
710 uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
711 {
712     int32_t ret = 0;
713
714     if ((r1 & 0xffff) == (r2 & 0xffff)) {
715         ret = 0xffff;
716     }
717
718     if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
719         ret |= 0xffff0000;
720     }
721
722     return ret;
723 }
724
725 uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
726 {
727     int32_t i;
728     uint32_t ret = 0;
729
730     for (i = 0; i < 4; i++) {
731         ret |= (sextract32(r1,  i * 8, 8) == sextract32(r2,  i * 8, 8));
732     }
733
734     return ret;
735 }
736
737 uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
738 {
739     uint32_t ret;
740
741     ret = (sextract32(r1, 0, 16) == sextract32(r2,  0, 16));
742     ret |= (sextract32(r1, 16, 16) == sextract32(r2,  16, 16));
743
744     return ret;
745 }
746
747 uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
748 {
749     int32_t i;
750     uint32_t ret = 0;
751
752     for (i = 0; i < 4; i++) {
753         if (sextract32(r1,  i * 8, 8) < sextract32(r2,  i * 8, 8)) {
754             ret |= (0xff << (i * 8));
755         }
756     }
757
758     return ret;
759 }
760
761 uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
762 {
763     int32_t i;
764     uint32_t ret = 0;
765
766     for (i = 0; i < 4; i++) {
767         if (extract32(r1,  i * 8, 8) < extract32(r2,  i * 8, 8)) {
768             ret |= (0xff << (i * 8));
769         }
770     }
771
772     return ret;
773 }
774
775 uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
776 {
777     uint32_t ret = 0;
778
779     if (sextract32(r1,  0, 16) < sextract32(r2,  0, 16)) {
780         ret |= 0xffff;
781     }
782
783     if (sextract32(r1,  16, 16) < sextract32(r2,  16, 16)) {
784         ret |= 0xffff0000;
785     }
786
787     return ret;
788 }
789
790 uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
791 {
792     uint32_t ret = 0;
793
794     if (extract32(r1,  0, 16) < extract32(r2,  0, 16)) {
795         ret |= 0xffff;
796     }
797
798     if (extract32(r1,  16, 16) < extract32(r2,  16, 16)) {
799         ret |= 0xffff0000;
800     }
801
802     return ret;
803 }
804
805 #define EXTREMA_H_B(name, op)                                 \
806 uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
807 {                                                             \
808     int32_t i, extr_r1, extr_r2;                              \
809     uint32_t ret = 0;                                         \
810                                                               \
811     for (i = 0; i < 4; i++) {                                 \
812         extr_r1 = sextract32(r1, i * 8, 8);                   \
813         extr_r2 = sextract32(r2, i * 8, 8);                   \
814         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
815         ret |= (extr_r1 & 0xff) << (i * 8);                   \
816     }                                                         \
817     return ret;                                               \
818 }                                                             \
819                                                               \
820 uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
821 {                                                             \
822     int32_t i;                                                \
823     uint32_t extr_r1, extr_r2;                                \
824     uint32_t ret = 0;                                         \
825                                                               \
826     for (i = 0; i < 4; i++) {                                 \
827         extr_r1 = extract32(r1, i * 8, 8);                    \
828         extr_r2 = extract32(r2, i * 8, 8);                    \
829         extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;   \
830         ret |= (extr_r1 & 0xff) << (i * 8);                   \
831     }                                                         \
832     return ret;                                               \
833 }                                                             \
834                                                               \
835 uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
836 {                                                             \
837     int32_t extr_r1, extr_r2;                                 \
838     uint32_t ret = 0;                                         \
839                                                               \
840     extr_r1 = sextract32(r1, 0, 16);                          \
841     extr_r2 = sextract32(r2, 0, 16);                          \
842     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
843     ret = ret & 0xffff;                                       \
844                                                               \
845     extr_r1 = sextract32(r1, 16, 16);                         \
846     extr_r2 = sextract32(r2, 16, 16);                         \
847     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
848     ret |= extr_r1 << 16;                                     \
849                                                               \
850     return ret;                                               \
851 }                                                             \
852                                                               \
853 uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
854 {                                                             \
855     uint32_t extr_r1, extr_r2;                                \
856     uint32_t ret = 0;                                         \
857                                                               \
858     extr_r1 = extract32(r1, 0, 16);                           \
859     extr_r2 = extract32(r2, 0, 16);                           \
860     ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;           \
861     ret = ret & 0xffff;                                       \
862                                                               \
863     extr_r1 = extract32(r1, 16, 16);                          \
864     extr_r2 = extract32(r2, 16, 16);                          \
865     extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2;       \
866     ret |= extr_r1 << (16);                                   \
867                                                               \
868     return ret;                                               \
869 }                                                             \
870
871 EXTREMA_H_B(max, >)
872 EXTREMA_H_B(min, <)
873
874 #undef EXTREMA_H_B
875
876 uint32_t helper_clo(target_ulong r1)
877 {
878     return clo32(r1);
879 }
880
881 uint32_t helper_clo_h(target_ulong r1)
882 {
883     uint32_t ret_hw0 = extract32(r1, 0, 16);
884     uint32_t ret_hw1 = extract32(r1, 16, 16);
885
886     ret_hw0 = clo32(ret_hw0 << 16);
887     ret_hw1 = clo32(ret_hw1 << 16);
888
889     if (ret_hw0 > 16) {
890         ret_hw0 = 16;
891     }
892     if (ret_hw1 > 16) {
893         ret_hw1 = 16;
894     }
895
896     return ret_hw0 | (ret_hw1 << 16);
897 }
898
899 uint32_t helper_clz(target_ulong r1)
900 {
901     return clz32(r1);
902 }
903
904 uint32_t helper_clz_h(target_ulong r1)
905 {
906     uint32_t ret_hw0 = extract32(r1, 0, 16);
907     uint32_t ret_hw1 = extract32(r1, 16, 16);
908
909     ret_hw0 = clz32(ret_hw0 << 16);
910     ret_hw1 = clz32(ret_hw1 << 16);
911
912     if (ret_hw0 > 16) {
913         ret_hw0 = 16;
914     }
915     if (ret_hw1 > 16) {
916         ret_hw1 = 16;
917     }
918
919     return ret_hw0 | (ret_hw1 << 16);
920 }
921
922 uint32_t helper_cls(target_ulong r1)
923 {
924     return clrsb32(r1);
925 }
926
927 uint32_t helper_cls_h(target_ulong r1)
928 {
929     uint32_t ret_hw0 = extract32(r1, 0, 16);
930     uint32_t ret_hw1 = extract32(r1, 16, 16);
931
932     ret_hw0 = clrsb32(ret_hw0 << 16);
933     ret_hw1 = clrsb32(ret_hw1 << 16);
934
935     if (ret_hw0 > 15) {
936         ret_hw0 = 15;
937     }
938     if (ret_hw1 > 15) {
939         ret_hw1 = 15;
940     }
941
942     return ret_hw0 | (ret_hw1 << 16);
943 }
944
945 uint32_t helper_sh(target_ulong r1, target_ulong r2)
946 {
947     int32_t shift_count = sextract32(r2, 0, 6);
948
949     if (shift_count == -32) {
950         return 0;
951     } else if (shift_count < 0) {
952         return r1 >> -shift_count;
953     } else {
954         return r1 << shift_count;
955     }
956 }
957
958 uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
959 {
960     int32_t ret_hw0, ret_hw1;
961     int32_t shift_count;
962
963     shift_count = sextract32(r2, 0, 5);
964
965     if (shift_count == -16) {
966         return 0;
967     } else if (shift_count < 0) {
968         ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
969         ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
970         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
971     } else {
972         ret_hw0 = extract32(r1, 0, 16) << shift_count;
973         ret_hw1 = extract32(r1, 16, 16) << shift_count;
974         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
975     }
976 }
977
978 uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
979 {
980     int32_t shift_count;
981     int64_t result, t1;
982     uint32_t ret;
983
984     shift_count = sextract32(r2, 0, 6);
985     t1 = sextract32(r1, 0, 32);
986
987     if (shift_count == 0) {
988         env->PSW_USB_C = env->PSW_USB_V = 0;
989         ret = r1;
990     } else if (shift_count == -32) {
991         env->PSW_USB_C = r1;
992         env->PSW_USB_V = 0;
993         ret = t1 >> 31;
994     } else if (shift_count > 0) {
995         result = t1 << shift_count;
996         /* calc carry */
997         env->PSW_USB_C = ((result & 0xffffffff00000000) != 0);
998         /* calc v */
999         env->PSW_USB_V = (((result > 0x7fffffffLL) ||
1000                            (result < -0x80000000LL)) << 31);
1001         /* calc sv */
1002         env->PSW_USB_SV |= env->PSW_USB_V;
1003         ret = (uint32_t)result;
1004     } else {
1005         env->PSW_USB_V = 0;
1006         env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
1007         ret = t1 >> -shift_count;
1008     }
1009
1010     env->PSW_USB_AV = ret ^ ret * 2u;
1011     env->PSW_USB_SAV |= env->PSW_USB_AV;
1012
1013     return ret;
1014 }
1015
1016 uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
1017 {
1018     int32_t shift_count;
1019     int32_t ret_hw0, ret_hw1;
1020
1021     shift_count = sextract32(r2, 0, 5);
1022
1023     if (shift_count == 0) {
1024         return r1;
1025     } else if (shift_count < 0) {
1026         ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
1027         ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
1028         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1029     } else {
1030         ret_hw0 = sextract32(r1, 0, 16) << shift_count;
1031         ret_hw1 = sextract32(r1, 16, 16) << shift_count;
1032         return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1033     }
1034 }
1035
1036 uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1037 {
1038     uint32_t i, ret;
1039
1040     ret = 0;
1041     for (i = 0; i < 16; i++) {
1042         ret |= (r1 & 1) << (2 * i + 1);
1043         ret |= (r2 & 1) << (2 * i);
1044         r1 = r1 >> 1;
1045         r2 = r2 >> 1;
1046     }
1047     return ret;
1048 }
1049
1050 uint64_t helper_bsplit(uint32_t r1)
1051 {
1052     int32_t i;
1053     uint64_t ret;
1054
1055     ret = 0;
1056     for (i = 0; i < 32; i = i + 2) {
1057         /* even */
1058         ret |= (r1 & 1) << (i/2);
1059         r1 = r1 >> 1;
1060         /* odd */
1061         ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1062         r1 = r1 >> 1;
1063     }
1064     return ret;
1065 }
1066
1067 uint32_t helper_parity(target_ulong r1)
1068 {
1069     uint32_t ret;
1070     uint32_t nOnes, i;
1071
1072     ret = 0;
1073     nOnes = 0;
1074     for (i = 0; i < 8; i++) {
1075         ret ^= (r1 & 1);
1076         r1 = r1 >> 1;
1077     }
1078     /* second byte */
1079     nOnes = 0;
1080     for (i = 0; i < 8; i++) {
1081         nOnes ^= (r1 & 1);
1082         r1 = r1 >> 1;
1083     }
1084     ret |= nOnes << 8;
1085     /* third byte */
1086     nOnes = 0;
1087     for (i = 0; i < 8; i++) {
1088         nOnes ^= (r1 & 1);
1089         r1 = r1 >> 1;
1090     }
1091     ret |= nOnes << 16;
1092     /* fourth byte */
1093     nOnes = 0;
1094     for (i = 0; i < 8; i++) {
1095         nOnes ^= (r1 & 1);
1096         r1 = r1 >> 1;
1097     }
1098     ret |= nOnes << 24;
1099
1100     return ret;
1101 }
1102
1103 uint64_t helper_unpack(target_ulong arg1)
1104 {
1105     int32_t fp_exp  = extract32(arg1, 23, 8);
1106     int32_t fp_frac = extract32(arg1, 0, 23);
1107     uint64_t ret;
1108     int32_t int_exp, int_mant;
1109
1110     if (fp_exp == 255) {
1111         int_exp = 255;
1112         int_mant = (fp_frac << 7);
1113     } else if ((fp_exp == 0) && (fp_frac == 0)) {
1114         int_exp  = -127;
1115         int_mant = 0;
1116     } else if ((fp_exp == 0) && (fp_frac != 0)) {
1117         int_exp  = -126;
1118         int_mant = (fp_frac << 7);
1119     } else {
1120         int_exp  = fp_exp - 127;
1121         int_mant = (fp_frac << 7);
1122         int_mant |= (1 << 30);
1123     }
1124     ret = int_exp;
1125     ret = ret << 32;
1126     ret |= int_mant;
1127
1128     return ret;
1129 }
1130
1131 uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1132 {
1133     uint64_t ret;
1134     int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1135     int32_t quotient_sign;
1136
1137     ret = sextract32(r1, 0, 32);
1138     ret = ret << 24;
1139     quotient_sign = 0;
1140     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1141         ret |= 0xffffff;
1142         quotient_sign = 1;
1143     }
1144
1145     abs_sig_dividend = abs(r1) >> 7;
1146     abs_base_dividend = abs(r1) & 0x7f;
1147     abs_divisor = abs(r1);
1148     /* calc overflow */
1149     env->PSW_USB_V = 0;
1150     if ((quotient_sign) && (abs_divisor)) {
1151         env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1152                          (abs_base_dividend >= abs_divisor)) ||
1153                          (abs_sig_dividend > abs_divisor));
1154     } else {
1155         env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1156     }
1157     env->PSW_USB_V = env->PSW_USB_V << 31;
1158     env->PSW_USB_SV |= env->PSW_USB_V;
1159     env->PSW_USB_AV = 0;
1160
1161     return ret;
1162 }
1163
1164 uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1165 {
1166     uint64_t ret = sextract32(r1, 0, 32);
1167
1168     ret = ret << 24;
1169     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1170         ret |= 0xffffff;
1171     }
1172     /* calc overflow */
1173     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
1174     env->PSW_USB_V = env->PSW_USB_V << 31;
1175     env->PSW_USB_SV |= env->PSW_USB_V;
1176     env->PSW_USB_AV = 0;
1177
1178     return ret;
1179 }
1180
1181 uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1182 {
1183     uint64_t ret;
1184     int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1185     int32_t quotient_sign;
1186
1187     ret = sextract32(r1, 0, 32);
1188     ret = ret << 16;
1189     quotient_sign = 0;
1190     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1191         ret |= 0xffff;
1192         quotient_sign = 1;
1193     }
1194
1195     abs_sig_dividend = abs(r1) >> 7;
1196     abs_base_dividend = abs(r1) & 0x7f;
1197     abs_divisor = abs(r1);
1198     /* calc overflow */
1199     env->PSW_USB_V = 0;
1200     if ((quotient_sign) && (abs_divisor)) {
1201         env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1202                          (abs_base_dividend >= abs_divisor)) ||
1203                          (abs_sig_dividend > abs_divisor));
1204     } else {
1205         env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1206     }
1207     env->PSW_USB_V = env->PSW_USB_V << 31;
1208     env->PSW_USB_SV |= env->PSW_USB_V;
1209     env->PSW_USB_AV = 0;
1210
1211     return ret;
1212 }
1213
1214 uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1215 {
1216     uint64_t ret = sextract32(r1, 0, 32);
1217
1218     ret = ret << 16;
1219     if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1220         ret |= 0xffff;
1221     }
1222     /* calc overflow */
1223     env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
1224     env->PSW_USB_V = env->PSW_USB_V << 31;
1225     env->PSW_USB_SV |= env->PSW_USB_V;
1226     env->PSW_USB_AV = 0;
1227
1228     return ret;
1229 }
1230
1231 uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
1232                       uint32_t arg10, uint32_t arg11, uint32_t n)
1233 {
1234     uint64_t ret;
1235     uint32_t result0, result1;
1236
1237     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
1238                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
1239     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
1240                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
1241     if (sc1) {
1242         result1 = 0x7fffffff;
1243     } else {
1244         result1 = (((uint32_t)(arg00 * arg10)) << n);
1245     }
1246     if (sc0) {
1247         result0 = 0x7fffffff;
1248     } else {
1249         result0 = (((uint32_t)(arg01 * arg11)) << n);
1250     }
1251     ret = (((uint64_t)result1 << 32)) | result0;
1252     return ret;
1253 }
1254
1255 uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
1256                        uint32_t arg10, uint32_t arg11, uint32_t n)
1257 {
1258     uint64_t ret;
1259     int64_t result0, result1;
1260
1261     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
1262                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
1263     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
1264                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
1265
1266     if (sc1) {
1267         result1 = 0x7fffffff;
1268     } else {
1269         result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
1270     }
1271     if (sc0) {
1272         result0 = 0x7fffffff;
1273     } else {
1274         result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
1275     }
1276     ret = (result1 + result0);
1277     ret = ret << 16;
1278     return ret;
1279 }
1280 uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
1281                        uint32_t arg10, uint32_t arg11, uint32_t n)
1282 {
1283     uint32_t result0, result1;
1284
1285     int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
1286                   ((arg10 & 0xffff) == 0x8000) && (n == 1);
1287     int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
1288                   ((arg11 & 0xffff) == 0x8000) && (n == 1);
1289
1290     if (sc1) {
1291         result1 = 0x7fffffff;
1292     } else {
1293         result1 = ((arg00 * arg10) << n) + 0x8000;
1294     }
1295     if (sc0) {
1296         result0 = 0x7fffffff;
1297     } else {
1298         result0 = ((arg01 * arg11) << n) + 0x8000;
1299     }
1300     return (result1 & 0xffff0000) | (result0 >> 16);
1301 }
1302
1303 /* context save area (CSA) related helpers */
1304
1305 static int cdc_increment(target_ulong *psw)
1306 {
1307     if ((*psw & MASK_PSW_CDC) == 0x7f) {
1308         return 0;
1309     }
1310
1311     (*psw)++;
1312     /* check for overflow */
1313     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
1314     int mask = (1u << (7 - lo)) - 1;
1315     int count = *psw & mask;
1316     if (count == 0) {
1317         (*psw)--;
1318         return 1;
1319     }
1320     return 0;
1321 }
1322
1323 static int cdc_decrement(target_ulong *psw)
1324 {
1325     if ((*psw & MASK_PSW_CDC) == 0x7f) {
1326         return 0;
1327     }
1328     /* check for underflow */
1329     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
1330     int mask = (1u << (7 - lo)) - 1;
1331     int count = *psw & mask;
1332     if (count == 0) {
1333         return 1;
1334     }
1335     (*psw)--;
1336     return 0;
1337 }
1338
1339 static bool cdc_zero(target_ulong *psw)
1340 {
1341     int cdc = *psw & MASK_PSW_CDC;
1342     /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
1343        7'b1111111, otherwise returns FALSE. */
1344     if (cdc == 0x7f) {
1345         return true;
1346     }
1347     /* find CDC.COUNT */
1348     int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
1349     int mask = (1u << (7 - lo)) - 1;
1350     int count = *psw & mask;
1351     return count == 0;
1352 }
1353
1354 static void save_context_upper(CPUTriCoreState *env, int ea)
1355 {
1356     cpu_stl_data(env, ea, env->PCXI);
1357     cpu_stl_data(env, ea+4, env->PSW);
1358     cpu_stl_data(env, ea+8, env->gpr_a[10]);
1359     cpu_stl_data(env, ea+12, env->gpr_a[11]);
1360     cpu_stl_data(env, ea+16, env->gpr_d[8]);
1361     cpu_stl_data(env, ea+20, env->gpr_d[9]);
1362     cpu_stl_data(env, ea+24, env->gpr_d[10]);
1363     cpu_stl_data(env, ea+28, env->gpr_d[11]);
1364     cpu_stl_data(env, ea+32, env->gpr_a[12]);
1365     cpu_stl_data(env, ea+36, env->gpr_a[13]);
1366     cpu_stl_data(env, ea+40, env->gpr_a[14]);
1367     cpu_stl_data(env, ea+44, env->gpr_a[15]);
1368     cpu_stl_data(env, ea+48, env->gpr_d[12]);
1369     cpu_stl_data(env, ea+52, env->gpr_d[13]);
1370     cpu_stl_data(env, ea+56, env->gpr_d[14]);
1371     cpu_stl_data(env, ea+60, env->gpr_d[15]);
1372 }
1373
1374 static void save_context_lower(CPUTriCoreState *env, int ea)
1375 {
1376     cpu_stl_data(env, ea, env->PCXI);
1377     cpu_stl_data(env, ea+4, env->gpr_a[11]);
1378     cpu_stl_data(env, ea+8, env->gpr_a[2]);
1379     cpu_stl_data(env, ea+12, env->gpr_a[3]);
1380     cpu_stl_data(env, ea+16, env->gpr_d[0]);
1381     cpu_stl_data(env, ea+20, env->gpr_d[1]);
1382     cpu_stl_data(env, ea+24, env->gpr_d[2]);
1383     cpu_stl_data(env, ea+28, env->gpr_d[3]);
1384     cpu_stl_data(env, ea+32, env->gpr_a[4]);
1385     cpu_stl_data(env, ea+36, env->gpr_a[5]);
1386     cpu_stl_data(env, ea+40, env->gpr_a[6]);
1387     cpu_stl_data(env, ea+44, env->gpr_a[7]);
1388     cpu_stl_data(env, ea+48, env->gpr_d[4]);
1389     cpu_stl_data(env, ea+52, env->gpr_d[5]);
1390     cpu_stl_data(env, ea+56, env->gpr_d[6]);
1391     cpu_stl_data(env, ea+60, env->gpr_d[7]);
1392 }
1393
1394 static void restore_context_upper(CPUTriCoreState *env, int ea,
1395                                   target_ulong *new_PCXI, target_ulong *new_PSW)
1396 {
1397     *new_PCXI = cpu_ldl_data(env, ea);
1398     *new_PSW = cpu_ldl_data(env, ea+4);
1399     env->gpr_a[10] = cpu_ldl_data(env, ea+8);
1400     env->gpr_a[11] = cpu_ldl_data(env, ea+12);
1401     env->gpr_d[8]  = cpu_ldl_data(env, ea+16);
1402     env->gpr_d[9]  = cpu_ldl_data(env, ea+20);
1403     env->gpr_d[10] = cpu_ldl_data(env, ea+24);
1404     env->gpr_d[11] = cpu_ldl_data(env, ea+28);
1405     env->gpr_a[12] = cpu_ldl_data(env, ea+32);
1406     env->gpr_a[13] = cpu_ldl_data(env, ea+36);
1407     env->gpr_a[14] = cpu_ldl_data(env, ea+40);
1408     env->gpr_a[15] = cpu_ldl_data(env, ea+44);
1409     env->gpr_d[12] = cpu_ldl_data(env, ea+48);
1410     env->gpr_d[13] = cpu_ldl_data(env, ea+52);
1411     env->gpr_d[14] = cpu_ldl_data(env, ea+56);
1412     env->gpr_d[15] = cpu_ldl_data(env, ea+60);
1413 }
1414
1415 static void restore_context_lower(CPUTriCoreState *env, int ea,
1416                                   target_ulong *ra, target_ulong *pcxi)
1417 {
1418     *pcxi = cpu_ldl_data(env, ea);
1419     *ra = cpu_ldl_data(env, ea+4);
1420     env->gpr_a[2] = cpu_ldl_data(env, ea+8);
1421     env->gpr_a[3] = cpu_ldl_data(env, ea+12);
1422     env->gpr_d[0] = cpu_ldl_data(env, ea+16);
1423     env->gpr_d[1] = cpu_ldl_data(env, ea+20);
1424     env->gpr_d[2] = cpu_ldl_data(env, ea+24);
1425     env->gpr_d[3] = cpu_ldl_data(env, ea+28);
1426     env->gpr_a[4] = cpu_ldl_data(env, ea+32);
1427     env->gpr_a[5] = cpu_ldl_data(env, ea+36);
1428     env->gpr_a[6] = cpu_ldl_data(env, ea+40);
1429     env->gpr_a[7] = cpu_ldl_data(env, ea+44);
1430     env->gpr_d[4] = cpu_ldl_data(env, ea+48);
1431     env->gpr_d[5] = cpu_ldl_data(env, ea+52);
1432     env->gpr_d[6] = cpu_ldl_data(env, ea+56);
1433     env->gpr_d[7] = cpu_ldl_data(env, ea+60);
1434 }
1435
1436 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
1437 {
1438     target_ulong tmp_FCX;
1439     target_ulong ea;
1440     target_ulong new_FCX;
1441     target_ulong psw;
1442
1443     psw = psw_read(env);
1444     /* if (FCX == 0) trap(FCU); */
1445     if (env->FCX == 0) {
1446         /* FCU trap */
1447     }
1448     /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
1449     if (psw & MASK_PSW_CDE) {
1450         if (cdc_increment(&psw)) {
1451             /* CDO trap */
1452         }
1453     }
1454     /* PSW.CDE = 1;*/
1455     psw |= MASK_PSW_CDE;
1456     /* tmp_FCX = FCX; */
1457     tmp_FCX = env->FCX;
1458     /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
1459     ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
1460          ((env->FCX & MASK_FCX_FCXO) << 6);
1461     /* new_FCX = M(EA, word); */
1462     new_FCX = cpu_ldl_data(env, ea);
1463     /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
1464                            A[12], A[13], A[14], A[15], D[12], D[13], D[14],
1465                            D[15]}; */
1466     save_context_upper(env, ea);
1467
1468     /* PCXI.PCPN = ICR.CCPN; */
1469     env->PCXI = (env->PCXI & 0xffffff) +
1470                 ((env->ICR & MASK_ICR_CCPN) << 24);
1471     /* PCXI.PIE = ICR.IE; */
1472     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
1473                 ((env->ICR & MASK_ICR_IE) << 15));
1474     /* PCXI.UL = 1; */
1475     env->PCXI |= MASK_PCXI_UL;
1476
1477     /* PCXI[19: 0] = FCX[19: 0]; */
1478     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
1479     /* FCX[19: 0] = new_FCX[19: 0]; */
1480     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
1481     /* A[11] = next_pc[31: 0]; */
1482     env->gpr_a[11] = next_pc;
1483
1484     /* if (tmp_FCX == LCX) trap(FCD);*/
1485     if (tmp_FCX == env->LCX) {
1486         /* FCD trap */
1487     }
1488     psw_write(env, psw);
1489 }
1490
1491 void helper_ret(CPUTriCoreState *env)
1492 {
1493     target_ulong ea;
1494     target_ulong new_PCXI;
1495     target_ulong new_PSW, psw;
1496
1497     psw = psw_read(env);
1498      /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
1499     if (env->PSW & MASK_PSW_CDE) {
1500         if (cdc_decrement(&(env->PSW))) {
1501             /* CDU trap */
1502         }
1503     }
1504     /*   if (PCXI[19: 0] == 0) then trap(CSU); */
1505     if ((env->PCXI & 0xfffff) == 0) {
1506         /* CSU trap */
1507     }
1508     /* if (PCXI.UL == 0) then trap(CTYP); */
1509     if ((env->PCXI & MASK_PCXI_UL) == 0) {
1510         /* CTYP trap */
1511     }
1512     /* PC = {A11 [31: 1], 1’b0}; */
1513     env->PC = env->gpr_a[11] & 0xfffffffe;
1514
1515     /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
1516     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
1517          ((env->PCXI & MASK_PCXI_PCXO) << 6);
1518     /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1519         A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
1520     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1521     /* M(EA, word) = FCX; */
1522     cpu_stl_data(env, ea, env->FCX);
1523     /* FCX[19: 0] = PCXI[19: 0]; */
1524     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
1525     /* PCXI = new_PCXI; */
1526     env->PCXI = new_PCXI;
1527
1528     if (tricore_feature(env, TRICORE_FEATURE_13)) {
1529         /* PSW = new_PSW */
1530         psw_write(env, new_PSW);
1531     } else {
1532         /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
1533         psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
1534     }
1535 }
1536
1537 void helper_bisr(CPUTriCoreState *env, uint32_t const9)
1538 {
1539     target_ulong tmp_FCX;
1540     target_ulong ea;
1541     target_ulong new_FCX;
1542
1543     if (env->FCX == 0) {
1544         /* FCU trap */
1545     }
1546
1547     tmp_FCX = env->FCX;
1548     ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
1549
1550     /* new_FCX = M(EA, word); */
1551     new_FCX = cpu_ldl_data(env, ea);
1552     /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
1553                            , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
1554     save_context_lower(env, ea);
1555
1556
1557     /* PCXI.PCPN = ICR.CCPN */
1558     env->PCXI = (env->PCXI & 0xffffff) +
1559                  ((env->ICR & MASK_ICR_CCPN) << 24);
1560     /* PCXI.PIE  = ICR.IE */
1561     env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
1562                  ((env->ICR & MASK_ICR_IE) << 15));
1563     /* PCXI.UL = 0 */
1564     env->PCXI &= ~(MASK_PCXI_UL);
1565     /* PCXI[19: 0] = FCX[19: 0] */
1566     env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
1567     /* FXC[19: 0] = new_FCX[19: 0] */
1568     env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
1569     /* ICR.IE = 1 */
1570     env->ICR |= MASK_ICR_IE;
1571
1572     env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
1573
1574     if (tmp_FCX == env->LCX) {
1575         /* FCD trap */
1576     }
1577 }
1578
1579 void helper_rfe(CPUTriCoreState *env)
1580 {
1581     target_ulong ea;
1582     target_ulong new_PCXI;
1583     target_ulong new_PSW;
1584     /* if (PCXI[19: 0] == 0) then trap(CSU); */
1585     if ((env->PCXI & 0xfffff) == 0) {
1586         /* raise csu trap */
1587     }
1588     /* if (PCXI.UL == 0) then trap(CTYP); */
1589     if ((env->PCXI & MASK_PCXI_UL) == 0) {
1590         /* raise CTYP trap */
1591     }
1592     /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
1593     if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
1594         /* raise MNG trap */
1595     }
1596     /* ICR.IE = PCXI.PIE; */
1597     env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
1598     /* ICR.CCPN = PCXI.PCPN; */
1599     env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
1600                ((env->PCXI & MASK_PCXI_PCPN) >> 24);
1601     /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
1602     ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
1603          ((env->PCXI & MASK_PCXI_PCXO) << 6);
1604     /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1605       A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
1606     restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1607     /* M(EA, word) = FCX;*/
1608     cpu_stl_data(env, ea, env->FCX);
1609     /* FCX[19: 0] = PCXI[19: 0]; */
1610     env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
1611     /* PCXI = new_PCXI; */
1612     env->PCXI = new_PCXI;
1613     /* write psw */
1614     psw_write(env, new_PSW);
1615 }
1616
1617 void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
1618 {
1619     uint32_t dummy;
1620     /* insn doesn't load PCXI and RA */
1621     restore_context_lower(env, ea, &dummy, &dummy);
1622 }
1623
1624 void helper_lducx(CPUTriCoreState *env, uint32_t ea)
1625 {
1626     uint32_t dummy;
1627     /* insn doesn't load PCXI and PSW */
1628     restore_context_upper(env, ea, &dummy, &dummy);
1629 }
1630
1631 void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
1632 {
1633     save_context_lower(env, ea);
1634 }
1635
1636 void helper_stucx(CPUTriCoreState *env, uint32_t ea)
1637 {
1638     save_context_upper(env, ea);
1639 }
1640
1641 void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
1642 {
1643     psw_write(env, arg);
1644 }
1645
1646 uint32_t helper_psw_read(CPUTriCoreState *env)
1647 {
1648     return psw_read(env);
1649 }
1650
1651
1652 static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
1653                                                         uint32_t exception,
1654                                                         int error_code,
1655                                                         uintptr_t pc)
1656 {
1657     CPUState *cs = CPU(tricore_env_get_cpu(env));
1658     cs->exception_index = exception;
1659     env->error_code = error_code;
1660
1661     if (pc) {
1662         /* now we have a real cpu fault */
1663         cpu_restore_state(cs, pc);
1664     }
1665
1666     cpu_loop_exit(cs);
1667 }
1668
1669 void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
1670               uintptr_t retaddr)
1671 {
1672     int ret;
1673     ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
1674     if (ret) {
1675         TriCoreCPU *cpu = TRICORE_CPU(cs);
1676         CPUTriCoreState *env = &cpu->env;
1677         do_raise_exception_err(env, cs->exception_index,
1678                                env->error_code, retaddr);
1679     }
1680 }
This page took 0.1165 seconds and 4 git commands to generate.