target-tricore: calculate av bits before saturation
[qemu/ar7.git] / target-tricore / op_helper.c
blobdcc65b1385af8b9de0bbe5d6061122357b1fa31c
1 /*
2 * Copyright (c) 2012-2014 Bastian Koppelmann C-Lab/University Paderborn
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.
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.
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/>.
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"
23 /* Addressing mode helper */
25 static uint16_t reverse16(uint16_t val)
27 uint8_t high = (uint8_t)(val >> 8);
28 uint8_t low = (uint8_t)(val & 0xff);
30 uint16_t rh, rl;
32 rl = (uint16_t)((high * 0x0202020202ULL & 0x010884422010ULL) % 1023);
33 rh = (uint16_t)((low * 0x0202020202ULL & 0x010884422010ULL) % 1023);
35 return (rh << 8) | rl;
38 uint32_t helper_br_update(uint32_t reg)
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;
46 uint32_t helper_circ_update(uint32_t reg, uint32_t off)
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;
56 return reg - index + new_index;
59 static uint32_t ssov32(CPUTriCoreState *env, int64_t arg)
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;
78 env->PSW_USB_AV = arg ^ arg * 2u;
79 env->PSW_USB_SAV |= env->PSW_USB_AV;
80 return ret;
83 static uint32_t suov32(CPUTriCoreState *env, int64_t arg)
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;
101 env->PSW_USB_AV = arg ^ arg * 2u;
102 env->PSW_USB_SAV |= env->PSW_USB_AV;
103 return ret;
106 static uint32_t ssov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
108 int32_t max_pos = INT16_MAX;
109 int32_t max_neg = INT16_MIN;
110 int32_t av0, av1;
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;
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;
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);
137 static uint32_t suov16(CPUTriCoreState *env, int32_t hw0, int32_t hw1)
139 int32_t max_pos = UINT16_MAX;
140 int32_t av0, av1;
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;
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;
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);
167 target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
168 target_ulong r2)
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);
176 target_ulong helper_add_h_ssov(CPUTriCoreState *env, target_ulong r1,
177 target_ulong r2)
179 int32_t ret_hw0, ret_hw1;
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);
186 target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
187 target_ulong r2)
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);
195 target_ulong helper_add_h_suov(CPUTriCoreState *env, target_ulong r1,
196 target_ulong r2)
198 int32_t ret_hw0, ret_hw1;
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);
205 target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
206 target_ulong r2)
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);
214 target_ulong helper_sub_h_ssov(CPUTriCoreState *env, target_ulong r1,
215 target_ulong r2)
217 int32_t ret_hw0, ret_hw1;
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);
224 target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
225 target_ulong r2)
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);
233 target_ulong helper_sub_h_suov(CPUTriCoreState *env, target_ulong r1,
234 target_ulong r2)
236 int32_t ret_hw0, ret_hw1;
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);
243 target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
244 target_ulong r2)
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);
252 target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
253 target_ulong r2)
255 int64_t t1 = extract64(r1, 0, 32);
256 int64_t t2 = extract64(r2, 0, 32);
257 int64_t result = t1 * t2;
259 return suov32(env, result);
262 target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
263 target_ulong r2)
265 int64_t t1 = sextract64(r1, 0, 32);
266 int32_t t2 = sextract64(r2, 0, 6);
267 int64_t result;
268 if (t2 == 0) {
269 result = t1;
270 } else if (t2 > 0) {
271 result = t1 << t2;
272 } else {
273 result = t1 >> -t2;
275 return ssov32(env, result);
278 uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
280 target_ulong result;
281 result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
282 return ssov32(env, result);
285 uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
287 int32_t ret_h0, ret_h1;
289 ret_h0 = sextract32(r1, 0, 16);
290 ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
292 ret_h1 = sextract32(r1, 16, 16);
293 ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
295 return ssov16(env, ret_h0, ret_h1);
298 target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
299 target_ulong r2)
301 int64_t t1 = sextract64(r1, 0, 32);
302 int64_t t2 = sextract64(r2, 0, 32);
303 int64_t result;
305 if (t1 > t2) {
306 result = t1 - t2;
307 } else {
308 result = t2 - t1;
310 return ssov32(env, result);
313 uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
314 target_ulong r2)
316 int32_t t1, t2;
317 int32_t ret_h0, ret_h1;
319 t1 = sextract32(r1, 0, 16);
320 t2 = sextract32(r2, 0, 16);
321 if (t1 > t2) {
322 ret_h0 = t1 - t2;
323 } else {
324 ret_h0 = t2 - t1;
327 t1 = sextract32(r1, 16, 16);
328 t2 = sextract32(r2, 16, 16);
329 if (t1 > t2) {
330 ret_h1 = t1 - t2;
331 } else {
332 ret_h1 = t2 - t1;
335 return ssov16(env, ret_h0, ret_h1);
338 target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
339 target_ulong r2, target_ulong r3)
341 int64_t t1 = sextract64(r1, 0, 32);
342 int64_t t2 = sextract64(r2, 0, 32);
343 int64_t t3 = sextract64(r3, 0, 32);
344 int64_t result;
346 result = t2 + (t1 * t3);
347 return ssov32(env, result);
350 target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
351 target_ulong r2, target_ulong r3)
353 uint64_t t1 = extract64(r1, 0, 32);
354 uint64_t t2 = extract64(r2, 0, 32);
355 uint64_t t3 = extract64(r3, 0, 32);
356 int64_t result;
358 result = t2 + (t1 * t3);
359 return suov32(env, result);
362 uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
363 uint64_t r2, target_ulong r3)
365 uint64_t ret, ovf;
366 int64_t t1 = sextract64(r1, 0, 32);
367 int64_t t3 = sextract64(r3, 0, 32);
368 int64_t mul;
370 mul = t1 * t3;
371 ret = mul + r2;
372 ovf = (ret ^ mul) & ~(mul ^ r2);
374 t1 = ret >> 32;
375 env->PSW_USB_AV = t1 ^ t1 * 2u;
376 env->PSW_USB_SAV |= env->PSW_USB_AV;
378 if ((int64_t)ovf < 0) {
379 env->PSW_USB_V = (1 << 31);
380 env->PSW_USB_SV = (1 << 31);
381 /* ext_ret > MAX_INT */
382 if (mul >= 0) {
383 ret = INT64_MAX;
384 /* ext_ret < MIN_INT */
385 } else {
386 ret = INT64_MIN;
388 } else {
389 env->PSW_USB_V = 0;
392 return ret;
395 uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
396 uint64_t r2, target_ulong r3)
398 uint64_t ret, mul;
399 uint64_t t1 = extract64(r1, 0, 32);
400 uint64_t t3 = extract64(r3, 0, 32);
402 mul = t1 * t3;
403 ret = mul + r2;
405 t1 = ret >> 32;
406 env->PSW_USB_AV = t1 ^ t1 * 2u;
407 env->PSW_USB_SAV |= env->PSW_USB_AV;
409 if (ret < r2) {
410 env->PSW_USB_V = (1 << 31);
411 env->PSW_USB_SV = (1 << 31);
412 /* saturate */
413 ret = UINT64_MAX;
414 } else {
415 env->PSW_USB_V = 0;
417 return ret;
420 target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
421 target_ulong r2, target_ulong r3)
423 int64_t t1 = sextract64(r1, 0, 32);
424 int64_t t2 = sextract64(r2, 0, 32);
425 int64_t t3 = sextract64(r3, 0, 32);
426 int64_t result;
428 result = t2 - (t1 * t3);
429 return ssov32(env, result);
432 target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
433 target_ulong r2, target_ulong r3)
435 int64_t t1 = extract64(r1, 0, 32);
436 int64_t t2 = extract64(r2, 0, 32);
437 int64_t t3 = extract64(r3, 0, 32);
438 int64_t result;
440 result = t2 - (t1 * t3);
441 return suov32(env, result);
444 uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
445 uint64_t r2, target_ulong r3)
447 uint64_t ret, ovf;
448 int64_t t1 = sextract64(r1, 0, 32);
449 int64_t t3 = sextract64(r3, 0, 32);
450 int64_t mul;
452 mul = t1 * t3;
453 ret = r2 - mul;
454 ovf = (ret ^ r2) & (mul ^ r2);
456 t1 = ret >> 32;
457 env->PSW_USB_AV = t1 ^ t1 * 2u;
458 env->PSW_USB_SAV |= env->PSW_USB_AV;
460 if ((int64_t)ovf < 0) {
461 env->PSW_USB_V = (1 << 31);
462 env->PSW_USB_SV = (1 << 31);
463 /* ext_ret > MAX_INT */
464 if (mul < 0) {
465 ret = INT64_MAX;
466 /* ext_ret < MIN_INT */
467 } else {
468 ret = INT64_MIN;
470 } else {
471 env->PSW_USB_V = 0;
473 return ret;
476 uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
477 uint64_t r2, target_ulong r3)
479 uint64_t ret, mul;
480 uint64_t t1 = extract64(r1, 0, 32);
481 uint64_t t3 = extract64(r3, 0, 32);
483 mul = t1 * t3;
484 ret = r2 - mul;
486 t1 = ret >> 32;
487 env->PSW_USB_AV = t1 ^ t1 * 2u;
488 env->PSW_USB_SAV |= env->PSW_USB_AV;
490 if (ret > r2) {
491 env->PSW_USB_V = (1 << 31);
492 env->PSW_USB_SV = (1 << 31);
493 /* saturate */
494 ret = 0;
495 } else {
496 env->PSW_USB_V = 0;
498 return ret;
501 uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
503 int32_t b, i;
504 int32_t ovf = 0;
505 int32_t avf = 0;
506 int32_t ret = 0;
508 for (i = 0; i < 4; i++) {
509 b = sextract32(arg, i * 8, 8);
510 b = (b >= 0) ? b : (0 - b);
511 ovf |= (b > 0x7F) || (b < -0x80);
512 avf |= b ^ b * 2u;
513 ret |= (b & 0xff) << (i * 8);
516 env->PSW_USB_V = ovf << 31;
517 env->PSW_USB_SV |= env->PSW_USB_V;
518 env->PSW_USB_AV = avf << 24;
519 env->PSW_USB_SAV |= env->PSW_USB_AV;
521 return ret;
524 uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
526 int32_t h, i;
527 int32_t ovf = 0;
528 int32_t avf = 0;
529 int32_t ret = 0;
531 for (i = 0; i < 2; i++) {
532 h = sextract32(arg, i * 16, 16);
533 h = (h >= 0) ? h : (0 - h);
534 ovf |= (h > 0x7FFF) || (h < -0x8000);
535 avf |= h ^ h * 2u;
536 ret |= (h & 0xffff) << (i * 16);
539 env->PSW_USB_V = ovf << 31;
540 env->PSW_USB_SV |= env->PSW_USB_V;
541 env->PSW_USB_AV = avf << 16;
542 env->PSW_USB_SAV |= env->PSW_USB_AV;
544 return ret;
547 uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
549 int32_t b, i;
550 int32_t extr_r2;
551 int32_t ovf = 0;
552 int32_t avf = 0;
553 int32_t ret = 0;
555 for (i = 0; i < 4; i++) {
556 extr_r2 = sextract32(r2, i * 8, 8);
557 b = sextract32(r1, i * 8, 8);
558 b = (b > extr_r2) ? (b - extr_r2) : (extr_r2 - b);
559 ovf |= (b > 0x7F) || (b < -0x80);
560 avf |= b ^ b * 2u;
561 ret |= (b & 0xff) << (i * 8);
564 env->PSW_USB_V = ovf << 31;
565 env->PSW_USB_SV |= env->PSW_USB_V;
566 env->PSW_USB_AV = avf << 24;
567 env->PSW_USB_SAV |= env->PSW_USB_AV;
568 return ret;
571 uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
573 int32_t h, i;
574 int32_t extr_r2;
575 int32_t ovf = 0;
576 int32_t avf = 0;
577 int32_t ret = 0;
579 for (i = 0; i < 2; i++) {
580 extr_r2 = sextract32(r2, i * 16, 16);
581 h = sextract32(r1, i * 16, 16);
582 h = (h > extr_r2) ? (h - extr_r2) : (extr_r2 - h);
583 ovf |= (h > 0x7FFF) || (h < -0x8000);
584 avf |= h ^ h * 2u;
585 ret |= (h & 0xffff) << (i * 16);
588 env->PSW_USB_V = ovf << 31;
589 env->PSW_USB_SV |= env->PSW_USB_V;
590 env->PSW_USB_AV = avf << 16;
591 env->PSW_USB_SAV |= env->PSW_USB_AV;
593 return ret;
596 uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
598 int32_t b, i;
599 int32_t extr_r1, extr_r2;
600 int32_t ovf = 0;
601 int32_t avf = 0;
602 uint32_t ret = 0;
604 for (i = 0; i < 4; i++) {
605 extr_r1 = sextract32(r1, i * 8, 8);
606 extr_r2 = sextract32(r2, i * 8, 8);
608 b = extr_r1 + extr_r2;
609 ovf |= ((b > 0x7f) || (b < -0x80));
610 avf |= b ^ b * 2u;
611 ret |= ((b & 0xff) << (i*8));
614 env->PSW_USB_V = (ovf << 31);
615 env->PSW_USB_SV |= env->PSW_USB_V;
616 env->PSW_USB_AV = avf << 24;
617 env->PSW_USB_SAV |= env->PSW_USB_AV;
619 return ret;
622 uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
624 int32_t h, i;
625 int32_t extr_r1, extr_r2;
626 int32_t ovf = 0;
627 int32_t avf = 0;
628 int32_t ret = 0;
630 for (i = 0; i < 2; i++) {
631 extr_r1 = sextract32(r1, i * 16, 16);
632 extr_r2 = sextract32(r2, i * 16, 16);
633 h = extr_r1 + extr_r2;
634 ovf |= ((h > 0x7fff) || (h < -0x8000));
635 avf |= h ^ h * 2u;
636 ret |= (h & 0xffff) << (i * 16);
639 env->PSW_USB_V = (ovf << 31);
640 env->PSW_USB_SV |= env->PSW_USB_V;
641 env->PSW_USB_AV = (avf << 16);
642 env->PSW_USB_SAV |= env->PSW_USB_AV;
644 return ret;
647 uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
649 int32_t b, i;
650 int32_t extr_r1, extr_r2;
651 int32_t ovf = 0;
652 int32_t avf = 0;
653 uint32_t ret = 0;
655 for (i = 0; i < 4; i++) {
656 extr_r1 = sextract32(r1, i * 8, 8);
657 extr_r2 = sextract32(r2, i * 8, 8);
659 b = extr_r1 - extr_r2;
660 ovf |= ((b > 0x7f) || (b < -0x80));
661 avf |= b ^ b * 2u;
662 ret |= ((b & 0xff) << (i*8));
665 env->PSW_USB_V = (ovf << 31);
666 env->PSW_USB_SV |= env->PSW_USB_V;
667 env->PSW_USB_AV = avf << 24;
668 env->PSW_USB_SAV |= env->PSW_USB_AV;
670 return ret;
673 uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
675 int32_t h, i;
676 int32_t extr_r1, extr_r2;
677 int32_t ovf = 0;
678 int32_t avf = 0;
679 int32_t ret = 0;
681 for (i = 0; i < 2; i++) {
682 extr_r1 = sextract32(r1, i * 16, 16);
683 extr_r2 = sextract32(r2, i * 16, 16);
684 h = extr_r1 - extr_r2;
685 ovf |= ((h > 0x7fff) || (h < -0x8000));
686 avf |= h ^ h * 2u;
687 ret |= (h & 0xffff) << (i * 16);
690 env->PSW_USB_V = (ovf << 31);
691 env->PSW_USB_SV |= env->PSW_USB_V;
692 env->PSW_USB_AV = avf << 16;
693 env->PSW_USB_SAV |= env->PSW_USB_AV;
695 return ret;
698 uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
700 int32_t ret;
701 int32_t i, msk;
703 ret = 0;
704 msk = 0xff;
705 for (i = 0; i < 4; i++) {
706 if ((r1 & msk) == (r2 & msk)) {
707 ret |= msk;
709 msk = msk << 8;
712 return ret;
715 uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
717 int32_t ret = 0;
719 if ((r1 & 0xffff) == (r2 & 0xffff)) {
720 ret = 0xffff;
723 if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
724 ret |= 0xffff0000;
727 return ret;
730 uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
732 int32_t i;
733 uint32_t ret = 0;
735 for (i = 0; i < 4; i++) {
736 ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8));
739 return ret;
742 uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
744 uint32_t ret;
746 ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16));
747 ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16));
749 return ret;
752 uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
754 int32_t i;
755 uint32_t ret = 0;
757 for (i = 0; i < 4; i++) {
758 if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) {
759 ret |= (0xff << (i * 8));
763 return ret;
766 uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
768 int32_t i;
769 uint32_t ret = 0;
771 for (i = 0; i < 4; i++) {
772 if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) {
773 ret |= (0xff << (i * 8));
777 return ret;
780 uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
782 uint32_t ret = 0;
784 if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) {
785 ret |= 0xffff;
788 if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) {
789 ret |= 0xffff0000;
792 return ret;
795 uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
797 uint32_t ret = 0;
799 if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) {
800 ret |= 0xffff;
803 if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) {
804 ret |= 0xffff0000;
807 return ret;
810 #define EXTREMA_H_B(name, op) \
811 uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
813 int32_t i, extr_r1, extr_r2; \
814 uint32_t ret = 0; \
816 for (i = 0; i < 4; i++) { \
817 extr_r1 = sextract32(r1, i * 8, 8); \
818 extr_r2 = sextract32(r2, i * 8, 8); \
819 extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
820 ret |= (extr_r1 & 0xff) << (i * 8); \
822 return ret; \
825 uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
827 int32_t i; \
828 uint32_t extr_r1, extr_r2; \
829 uint32_t ret = 0; \
831 for (i = 0; i < 4; i++) { \
832 extr_r1 = extract32(r1, i * 8, 8); \
833 extr_r2 = extract32(r2, i * 8, 8); \
834 extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
835 ret |= (extr_r1 & 0xff) << (i * 8); \
837 return ret; \
840 uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
842 int32_t extr_r1, extr_r2; \
843 uint32_t ret = 0; \
845 extr_r1 = sextract32(r1, 0, 16); \
846 extr_r2 = sextract32(r2, 0, 16); \
847 ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
848 ret = ret & 0xffff; \
850 extr_r1 = sextract32(r1, 16, 16); \
851 extr_r2 = sextract32(r2, 16, 16); \
852 extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
853 ret |= extr_r1 << 16; \
855 return ret; \
858 uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
860 uint32_t extr_r1, extr_r2; \
861 uint32_t ret = 0; \
863 extr_r1 = extract32(r1, 0, 16); \
864 extr_r2 = extract32(r2, 0, 16); \
865 ret = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
866 ret = ret & 0xffff; \
868 extr_r1 = extract32(r1, 16, 16); \
869 extr_r2 = extract32(r2, 16, 16); \
870 extr_r1 = (extr_r1 op extr_r2) ? extr_r1 : extr_r2; \
871 ret |= extr_r1 << (16); \
873 return ret; \
876 EXTREMA_H_B(max, >)
877 EXTREMA_H_B(min, <)
879 #undef EXTREMA_H_B
881 uint32_t helper_clo(target_ulong r1)
883 return clo32(r1);
886 uint32_t helper_clo_h(target_ulong r1)
888 uint32_t ret_hw0 = extract32(r1, 0, 16);
889 uint32_t ret_hw1 = extract32(r1, 16, 16);
891 ret_hw0 = clo32(ret_hw0 << 16);
892 ret_hw1 = clo32(ret_hw1 << 16);
894 if (ret_hw0 > 16) {
895 ret_hw0 = 16;
897 if (ret_hw1 > 16) {
898 ret_hw1 = 16;
901 return ret_hw0 | (ret_hw1 << 16);
904 uint32_t helper_clz(target_ulong r1)
906 return clz32(r1);
909 uint32_t helper_clz_h(target_ulong r1)
911 uint32_t ret_hw0 = extract32(r1, 0, 16);
912 uint32_t ret_hw1 = extract32(r1, 16, 16);
914 ret_hw0 = clz32(ret_hw0 << 16);
915 ret_hw1 = clz32(ret_hw1 << 16);
917 if (ret_hw0 > 16) {
918 ret_hw0 = 16;
920 if (ret_hw1 > 16) {
921 ret_hw1 = 16;
924 return ret_hw0 | (ret_hw1 << 16);
927 uint32_t helper_cls(target_ulong r1)
929 return clrsb32(r1);
932 uint32_t helper_cls_h(target_ulong r1)
934 uint32_t ret_hw0 = extract32(r1, 0, 16);
935 uint32_t ret_hw1 = extract32(r1, 16, 16);
937 ret_hw0 = clrsb32(ret_hw0 << 16);
938 ret_hw1 = clrsb32(ret_hw1 << 16);
940 if (ret_hw0 > 15) {
941 ret_hw0 = 15;
943 if (ret_hw1 > 15) {
944 ret_hw1 = 15;
947 return ret_hw0 | (ret_hw1 << 16);
950 uint32_t helper_sh(target_ulong r1, target_ulong r2)
952 int32_t shift_count = sextract32(r2, 0, 6);
954 if (shift_count == -32) {
955 return 0;
956 } else if (shift_count < 0) {
957 return r1 >> -shift_count;
958 } else {
959 return r1 << shift_count;
963 uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
965 int32_t ret_hw0, ret_hw1;
966 int32_t shift_count;
968 shift_count = sextract32(r2, 0, 5);
970 if (shift_count == -16) {
971 return 0;
972 } else if (shift_count < 0) {
973 ret_hw0 = extract32(r1, 0, 16) >> -shift_count;
974 ret_hw1 = extract32(r1, 16, 16) >> -shift_count;
975 return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
976 } else {
977 ret_hw0 = extract32(r1, 0, 16) << shift_count;
978 ret_hw1 = extract32(r1, 16, 16) << shift_count;
979 return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
983 uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
985 int32_t shift_count;
986 int64_t result, t1;
987 uint32_t ret;
989 shift_count = sextract32(r2, 0, 6);
990 t1 = sextract32(r1, 0, 32);
992 if (shift_count == 0) {
993 env->PSW_USB_C = env->PSW_USB_V = 0;
994 ret = r1;
995 } else if (shift_count == -32) {
996 env->PSW_USB_C = r1;
997 env->PSW_USB_V = 0;
998 ret = t1 >> 31;
999 } else if (shift_count > 0) {
1000 result = t1 << shift_count;
1001 /* calc carry */
1002 env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
1003 /* calc v */
1004 env->PSW_USB_V = (((result > 0x7fffffffLL) ||
1005 (result < -0x80000000LL)) << 31);
1006 /* calc sv */
1007 env->PSW_USB_SV |= env->PSW_USB_V;
1008 ret = (uint32_t)result;
1009 } else {
1010 env->PSW_USB_V = 0;
1011 env->PSW_USB_C = (r1 & ((1 << -shift_count) - 1));
1012 ret = t1 >> -shift_count;
1015 env->PSW_USB_AV = ret ^ ret * 2u;
1016 env->PSW_USB_SAV |= env->PSW_USB_AV;
1018 return ret;
1021 uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
1023 int32_t shift_count;
1024 int32_t ret_hw0, ret_hw1;
1026 shift_count = sextract32(r2, 0, 5);
1028 if (shift_count == 0) {
1029 return r1;
1030 } else if (shift_count < 0) {
1031 ret_hw0 = sextract32(r1, 0, 16) >> -shift_count;
1032 ret_hw1 = sextract32(r1, 16, 16) >> -shift_count;
1033 return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1034 } else {
1035 ret_hw0 = sextract32(r1, 0, 16) << shift_count;
1036 ret_hw1 = sextract32(r1, 16, 16) << shift_count;
1037 return (ret_hw0 & 0xffff) | (ret_hw1 << 16);
1041 uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1043 uint32_t i, ret;
1045 ret = 0;
1046 for (i = 0; i < 16; i++) {
1047 ret |= (r1 & 1) << (2 * i + 1);
1048 ret |= (r2 & 1) << (2 * i);
1049 r1 = r1 >> 1;
1050 r2 = r2 >> 1;
1052 return ret;
1055 uint64_t helper_bsplit(uint32_t r1)
1057 int32_t i;
1058 uint64_t ret;
1060 ret = 0;
1061 for (i = 0; i < 32; i = i + 2) {
1062 /* even */
1063 ret |= (r1 & 1) << (i/2);
1064 r1 = r1 >> 1;
1065 /* odd */
1066 ret |= (uint64_t)(r1 & 1) << (i/2 + 32);
1067 r1 = r1 >> 1;
1069 return ret;
1072 uint32_t helper_parity(target_ulong r1)
1074 uint32_t ret;
1075 uint32_t nOnes, i;
1077 ret = 0;
1078 nOnes = 0;
1079 for (i = 0; i < 8; i++) {
1080 ret ^= (r1 & 1);
1081 r1 = r1 >> 1;
1083 /* second byte */
1084 nOnes = 0;
1085 for (i = 0; i < 8; i++) {
1086 nOnes ^= (r1 & 1);
1087 r1 = r1 >> 1;
1089 ret |= nOnes << 8;
1090 /* third byte */
1091 nOnes = 0;
1092 for (i = 0; i < 8; i++) {
1093 nOnes ^= (r1 & 1);
1094 r1 = r1 >> 1;
1096 ret |= nOnes << 16;
1097 /* fourth byte */
1098 nOnes = 0;
1099 for (i = 0; i < 8; i++) {
1100 nOnes ^= (r1 & 1);
1101 r1 = r1 >> 1;
1103 ret |= nOnes << 24;
1105 return ret;
1108 uint64_t helper_unpack(target_ulong arg1)
1110 int32_t fp_exp = extract32(arg1, 23, 8);
1111 int32_t fp_frac = extract32(arg1, 0, 23);
1112 uint64_t ret;
1113 int32_t int_exp, int_mant;
1115 if (fp_exp == 255) {
1116 int_exp = 255;
1117 int_mant = (fp_frac << 7);
1118 } else if ((fp_exp == 0) && (fp_frac == 0)) {
1119 int_exp = -127;
1120 int_mant = 0;
1121 } else if ((fp_exp == 0) && (fp_frac != 0)) {
1122 int_exp = -126;
1123 int_mant = (fp_frac << 7);
1124 } else {
1125 int_exp = fp_exp - 127;
1126 int_mant = (fp_frac << 7);
1127 int_mant |= (1 << 30);
1129 ret = int_exp;
1130 ret = ret << 32;
1131 ret |= int_mant;
1133 return ret;
1136 uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1138 uint64_t ret;
1139 int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1140 int32_t quotient_sign;
1142 ret = sextract32(r1, 0, 32);
1143 ret = ret << 24;
1144 quotient_sign = 0;
1145 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1146 ret |= 0xffffff;
1147 quotient_sign = 1;
1150 abs_sig_dividend = abs(r1) >> 7;
1151 abs_base_dividend = abs(r1) & 0x7f;
1152 abs_divisor = abs(r1);
1153 /* calc overflow */
1154 env->PSW_USB_V = 0;
1155 if ((quotient_sign) && (abs_divisor)) {
1156 env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1157 (abs_base_dividend >= abs_divisor)) ||
1158 (abs_sig_dividend > abs_divisor));
1159 } else {
1160 env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1162 env->PSW_USB_V = env->PSW_USB_V << 31;
1163 env->PSW_USB_SV |= env->PSW_USB_V;
1164 env->PSW_USB_AV = 0;
1166 return ret;
1169 uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1171 uint64_t ret = sextract32(r1, 0, 32);
1173 ret = ret << 24;
1174 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1175 ret |= 0xffffff;
1177 /* calc overflow */
1178 env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffffff80)));
1179 env->PSW_USB_V = env->PSW_USB_V << 31;
1180 env->PSW_USB_SV |= env->PSW_USB_V;
1181 env->PSW_USB_AV = 0;
1183 return ret;
1186 uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1188 uint64_t ret;
1189 int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1190 int32_t quotient_sign;
1192 ret = sextract32(r1, 0, 32);
1193 ret = ret << 16;
1194 quotient_sign = 0;
1195 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1196 ret |= 0xffff;
1197 quotient_sign = 1;
1200 abs_sig_dividend = abs(r1) >> 7;
1201 abs_base_dividend = abs(r1) & 0x7f;
1202 abs_divisor = abs(r1);
1203 /* calc overflow */
1204 env->PSW_USB_V = 0;
1205 if ((quotient_sign) && (abs_divisor)) {
1206 env->PSW_USB_V = (((abs_sig_dividend == abs_divisor) &&
1207 (abs_base_dividend >= abs_divisor)) ||
1208 (abs_sig_dividend > abs_divisor));
1209 } else {
1210 env->PSW_USB_V = (abs_sig_dividend >= abs_divisor);
1212 env->PSW_USB_V = env->PSW_USB_V << 31;
1213 env->PSW_USB_SV |= env->PSW_USB_V;
1214 env->PSW_USB_AV = 0;
1216 return ret;
1219 uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1221 uint64_t ret = sextract32(r1, 0, 32);
1223 ret = ret << 16;
1224 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1225 ret |= 0xffff;
1227 /* calc overflow */
1228 env->PSW_USB_V = ((r2 == 0) || ((r2 == 0xffffffff) && (r1 == 0xffff8000)));
1229 env->PSW_USB_V = env->PSW_USB_V << 31;
1230 env->PSW_USB_SV |= env->PSW_USB_V;
1231 env->PSW_USB_AV = 0;
1233 return ret;
1236 uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
1237 uint32_t arg10, uint32_t arg11, uint32_t n)
1239 uint64_t ret;
1240 uint32_t result0, result1;
1242 int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
1243 ((arg10 & 0xffff) == 0x8000) && (n == 1);
1244 int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
1245 ((arg11 & 0xffff) == 0x8000) && (n == 1);
1246 if (sc1) {
1247 result1 = 0x7fffffff;
1248 } else {
1249 result1 = (((uint32_t)(arg00 * arg10)) << n);
1251 if (sc0) {
1252 result0 = 0x7fffffff;
1253 } else {
1254 result0 = (((uint32_t)(arg01 * arg11)) << n);
1256 ret = (((uint64_t)result1 << 32)) | result0;
1257 return ret;
1260 uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
1261 uint32_t arg10, uint32_t arg11, uint32_t n)
1263 uint64_t ret;
1264 int64_t result0, result1;
1266 int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
1267 ((arg10 & 0xffff) == 0x8000) && (n == 1);
1268 int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
1269 ((arg11 & 0xffff) == 0x8000) && (n == 1);
1271 if (sc1) {
1272 result1 = 0x7fffffff;
1273 } else {
1274 result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
1276 if (sc0) {
1277 result0 = 0x7fffffff;
1278 } else {
1279 result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
1281 ret = (result1 + result0);
1282 ret = ret << 16;
1283 return ret;
1285 uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
1286 uint32_t arg10, uint32_t arg11, uint32_t n)
1288 uint32_t result0, result1;
1290 int32_t sc1 = ((arg00 & 0xffff) == 0x8000) &&
1291 ((arg10 & 0xffff) == 0x8000) && (n == 1);
1292 int32_t sc0 = ((arg01 & 0xffff) == 0x8000) &&
1293 ((arg11 & 0xffff) == 0x8000) && (n == 1);
1295 if (sc1) {
1296 result1 = 0x7fffffff;
1297 } else {
1298 result1 = ((arg00 * arg10) << n) + 0x8000;
1300 if (sc0) {
1301 result0 = 0x7fffffff;
1302 } else {
1303 result0 = ((arg01 * arg11) << n) + 0x8000;
1305 return (result1 & 0xffff0000) | (result0 >> 16);
1308 /* context save area (CSA) related helpers */
1310 static int cdc_increment(target_ulong *psw)
1312 if ((*psw & MASK_PSW_CDC) == 0x7f) {
1313 return 0;
1316 (*psw)++;
1317 /* check for overflow */
1318 int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
1319 int mask = (1u << (7 - lo)) - 1;
1320 int count = *psw & mask;
1321 if (count == 0) {
1322 (*psw)--;
1323 return 1;
1325 return 0;
1328 static int cdc_decrement(target_ulong *psw)
1330 if ((*psw & MASK_PSW_CDC) == 0x7f) {
1331 return 0;
1333 /* check for underflow */
1334 int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
1335 int mask = (1u << (7 - lo)) - 1;
1336 int count = *psw & mask;
1337 if (count == 0) {
1338 return 1;
1340 (*psw)--;
1341 return 0;
1344 static bool cdc_zero(target_ulong *psw)
1346 int cdc = *psw & MASK_PSW_CDC;
1347 /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
1348 7'b1111111, otherwise returns FALSE. */
1349 if (cdc == 0x7f) {
1350 return true;
1352 /* find CDC.COUNT */
1353 int lo = clo32((*psw & MASK_PSW_CDC) << (32 - 7));
1354 int mask = (1u << (7 - lo)) - 1;
1355 int count = *psw & mask;
1356 return count == 0;
1359 static void save_context_upper(CPUTriCoreState *env, int ea)
1361 cpu_stl_data(env, ea, env->PCXI);
1362 cpu_stl_data(env, ea+4, env->PSW);
1363 cpu_stl_data(env, ea+8, env->gpr_a[10]);
1364 cpu_stl_data(env, ea+12, env->gpr_a[11]);
1365 cpu_stl_data(env, ea+16, env->gpr_d[8]);
1366 cpu_stl_data(env, ea+20, env->gpr_d[9]);
1367 cpu_stl_data(env, ea+24, env->gpr_d[10]);
1368 cpu_stl_data(env, ea+28, env->gpr_d[11]);
1369 cpu_stl_data(env, ea+32, env->gpr_a[12]);
1370 cpu_stl_data(env, ea+36, env->gpr_a[13]);
1371 cpu_stl_data(env, ea+40, env->gpr_a[14]);
1372 cpu_stl_data(env, ea+44, env->gpr_a[15]);
1373 cpu_stl_data(env, ea+48, env->gpr_d[12]);
1374 cpu_stl_data(env, ea+52, env->gpr_d[13]);
1375 cpu_stl_data(env, ea+56, env->gpr_d[14]);
1376 cpu_stl_data(env, ea+60, env->gpr_d[15]);
1379 static void save_context_lower(CPUTriCoreState *env, int ea)
1381 cpu_stl_data(env, ea, env->PCXI);
1382 cpu_stl_data(env, ea+4, env->gpr_a[11]);
1383 cpu_stl_data(env, ea+8, env->gpr_a[2]);
1384 cpu_stl_data(env, ea+12, env->gpr_a[3]);
1385 cpu_stl_data(env, ea+16, env->gpr_d[0]);
1386 cpu_stl_data(env, ea+20, env->gpr_d[1]);
1387 cpu_stl_data(env, ea+24, env->gpr_d[2]);
1388 cpu_stl_data(env, ea+28, env->gpr_d[3]);
1389 cpu_stl_data(env, ea+32, env->gpr_a[4]);
1390 cpu_stl_data(env, ea+36, env->gpr_a[5]);
1391 cpu_stl_data(env, ea+40, env->gpr_a[6]);
1392 cpu_stl_data(env, ea+44, env->gpr_a[7]);
1393 cpu_stl_data(env, ea+48, env->gpr_d[4]);
1394 cpu_stl_data(env, ea+52, env->gpr_d[5]);
1395 cpu_stl_data(env, ea+56, env->gpr_d[6]);
1396 cpu_stl_data(env, ea+60, env->gpr_d[7]);
1399 static void restore_context_upper(CPUTriCoreState *env, int ea,
1400 target_ulong *new_PCXI, target_ulong *new_PSW)
1402 *new_PCXI = cpu_ldl_data(env, ea);
1403 *new_PSW = cpu_ldl_data(env, ea+4);
1404 env->gpr_a[10] = cpu_ldl_data(env, ea+8);
1405 env->gpr_a[11] = cpu_ldl_data(env, ea+12);
1406 env->gpr_d[8] = cpu_ldl_data(env, ea+16);
1407 env->gpr_d[9] = cpu_ldl_data(env, ea+20);
1408 env->gpr_d[10] = cpu_ldl_data(env, ea+24);
1409 env->gpr_d[11] = cpu_ldl_data(env, ea+28);
1410 env->gpr_a[12] = cpu_ldl_data(env, ea+32);
1411 env->gpr_a[13] = cpu_ldl_data(env, ea+36);
1412 env->gpr_a[14] = cpu_ldl_data(env, ea+40);
1413 env->gpr_a[15] = cpu_ldl_data(env, ea+44);
1414 env->gpr_d[12] = cpu_ldl_data(env, ea+48);
1415 env->gpr_d[13] = cpu_ldl_data(env, ea+52);
1416 env->gpr_d[14] = cpu_ldl_data(env, ea+56);
1417 env->gpr_d[15] = cpu_ldl_data(env, ea+60);
1420 static void restore_context_lower(CPUTriCoreState *env, int ea,
1421 target_ulong *ra, target_ulong *pcxi)
1423 *pcxi = cpu_ldl_data(env, ea);
1424 *ra = cpu_ldl_data(env, ea+4);
1425 env->gpr_a[2] = cpu_ldl_data(env, ea+8);
1426 env->gpr_a[3] = cpu_ldl_data(env, ea+12);
1427 env->gpr_d[0] = cpu_ldl_data(env, ea+16);
1428 env->gpr_d[1] = cpu_ldl_data(env, ea+20);
1429 env->gpr_d[2] = cpu_ldl_data(env, ea+24);
1430 env->gpr_d[3] = cpu_ldl_data(env, ea+28);
1431 env->gpr_a[4] = cpu_ldl_data(env, ea+32);
1432 env->gpr_a[5] = cpu_ldl_data(env, ea+36);
1433 env->gpr_a[6] = cpu_ldl_data(env, ea+40);
1434 env->gpr_a[7] = cpu_ldl_data(env, ea+44);
1435 env->gpr_d[4] = cpu_ldl_data(env, ea+48);
1436 env->gpr_d[5] = cpu_ldl_data(env, ea+52);
1437 env->gpr_d[6] = cpu_ldl_data(env, ea+56);
1438 env->gpr_d[7] = cpu_ldl_data(env, ea+60);
1441 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
1443 target_ulong tmp_FCX;
1444 target_ulong ea;
1445 target_ulong new_FCX;
1446 target_ulong psw;
1448 psw = psw_read(env);
1449 /* if (FCX == 0) trap(FCU); */
1450 if (env->FCX == 0) {
1451 /* FCU trap */
1453 /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
1454 if (psw & MASK_PSW_CDE) {
1455 if (cdc_increment(&psw)) {
1456 /* CDO trap */
1459 /* PSW.CDE = 1;*/
1460 psw |= MASK_PSW_CDE;
1461 /* tmp_FCX = FCX; */
1462 tmp_FCX = env->FCX;
1463 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
1464 ea = ((env->FCX & MASK_FCX_FCXS) << 12) +
1465 ((env->FCX & MASK_FCX_FCXO) << 6);
1466 /* new_FCX = M(EA, word); */
1467 new_FCX = cpu_ldl_data(env, ea);
1468 /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
1469 A[12], A[13], A[14], A[15], D[12], D[13], D[14],
1470 D[15]}; */
1471 save_context_upper(env, ea);
1473 /* PCXI.PCPN = ICR.CCPN; */
1474 env->PCXI = (env->PCXI & 0xffffff) +
1475 ((env->ICR & MASK_ICR_CCPN) << 24);
1476 /* PCXI.PIE = ICR.IE; */
1477 env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
1478 ((env->ICR & MASK_ICR_IE) << 15));
1479 /* PCXI.UL = 1; */
1480 env->PCXI |= MASK_PCXI_UL;
1482 /* PCXI[19: 0] = FCX[19: 0]; */
1483 env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
1484 /* FCX[19: 0] = new_FCX[19: 0]; */
1485 env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
1486 /* A[11] = next_pc[31: 0]; */
1487 env->gpr_a[11] = next_pc;
1489 /* if (tmp_FCX == LCX) trap(FCD);*/
1490 if (tmp_FCX == env->LCX) {
1491 /* FCD trap */
1493 psw_write(env, psw);
1496 void helper_ret(CPUTriCoreState *env)
1498 target_ulong ea;
1499 target_ulong new_PCXI;
1500 target_ulong new_PSW, psw;
1502 psw = psw_read(env);
1503 /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
1504 if (env->PSW & MASK_PSW_CDE) {
1505 if (cdc_decrement(&(env->PSW))) {
1506 /* CDU trap */
1509 /* if (PCXI[19: 0] == 0) then trap(CSU); */
1510 if ((env->PCXI & 0xfffff) == 0) {
1511 /* CSU trap */
1513 /* if (PCXI.UL == 0) then trap(CTYP); */
1514 if ((env->PCXI & MASK_PCXI_UL) == 0) {
1515 /* CTYP trap */
1517 /* PC = {A11 [31: 1], 1’b0}; */
1518 env->PC = env->gpr_a[11] & 0xfffffffe;
1520 /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
1521 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
1522 ((env->PCXI & MASK_PCXI_PCXO) << 6);
1523 /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1524 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
1525 restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1526 /* M(EA, word) = FCX; */
1527 cpu_stl_data(env, ea, env->FCX);
1528 /* FCX[19: 0] = PCXI[19: 0]; */
1529 env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
1530 /* PCXI = new_PCXI; */
1531 env->PCXI = new_PCXI;
1533 if (tricore_feature(env, TRICORE_FEATURE_13)) {
1534 /* PSW = new_PSW */
1535 psw_write(env, new_PSW);
1536 } else {
1537 /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
1538 psw_write(env, (new_PSW & ~(0x3000000)) + (psw & (0x3000000)));
1542 void helper_bisr(CPUTriCoreState *env, uint32_t const9)
1544 target_ulong tmp_FCX;
1545 target_ulong ea;
1546 target_ulong new_FCX;
1548 if (env->FCX == 0) {
1549 /* FCU trap */
1552 tmp_FCX = env->FCX;
1553 ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
1555 /* new_FCX = M(EA, word); */
1556 new_FCX = cpu_ldl_data(env, ea);
1557 /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
1558 , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
1559 save_context_lower(env, ea);
1562 /* PCXI.PCPN = ICR.CCPN */
1563 env->PCXI = (env->PCXI & 0xffffff) +
1564 ((env->ICR & MASK_ICR_CCPN) << 24);
1565 /* PCXI.PIE = ICR.IE */
1566 env->PCXI = ((env->PCXI & ~MASK_PCXI_PIE) +
1567 ((env->ICR & MASK_ICR_IE) << 15));
1568 /* PCXI.UL = 0 */
1569 env->PCXI &= ~(MASK_PCXI_UL);
1570 /* PCXI[19: 0] = FCX[19: 0] */
1571 env->PCXI = (env->PCXI & 0xfff00000) + (env->FCX & 0xfffff);
1572 /* FXC[19: 0] = new_FCX[19: 0] */
1573 env->FCX = (env->FCX & 0xfff00000) + (new_FCX & 0xfffff);
1574 /* ICR.IE = 1 */
1575 env->ICR |= MASK_ICR_IE;
1577 env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
1579 if (tmp_FCX == env->LCX) {
1580 /* FCD trap */
1584 void helper_rfe(CPUTriCoreState *env)
1586 target_ulong ea;
1587 target_ulong new_PCXI;
1588 target_ulong new_PSW;
1589 /* if (PCXI[19: 0] == 0) then trap(CSU); */
1590 if ((env->PCXI & 0xfffff) == 0) {
1591 /* raise csu trap */
1593 /* if (PCXI.UL == 0) then trap(CTYP); */
1594 if ((env->PCXI & MASK_PCXI_UL) == 0) {
1595 /* raise CTYP trap */
1597 /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
1598 if (!cdc_zero(&(env->PSW)) && (env->PSW & MASK_PSW_CDE)) {
1599 /* raise MNG trap */
1601 /* ICR.IE = PCXI.PIE; */
1602 env->ICR = (env->ICR & ~MASK_ICR_IE) + ((env->PCXI & MASK_PCXI_PIE) >> 15);
1603 /* ICR.CCPN = PCXI.PCPN; */
1604 env->ICR = (env->ICR & ~MASK_ICR_CCPN) +
1605 ((env->PCXI & MASK_PCXI_PCPN) >> 24);
1606 /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
1607 ea = ((env->PCXI & MASK_PCXI_PCXS) << 12) +
1608 ((env->PCXI & MASK_PCXI_PCXO) << 6);
1609 /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
1610 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
1611 restore_context_upper(env, ea, &new_PCXI, &new_PSW);
1612 /* M(EA, word) = FCX;*/
1613 cpu_stl_data(env, ea, env->FCX);
1614 /* FCX[19: 0] = PCXI[19: 0]; */
1615 env->FCX = (env->FCX & 0xfff00000) + (env->PCXI & 0x000fffff);
1616 /* PCXI = new_PCXI; */
1617 env->PCXI = new_PCXI;
1618 /* write psw */
1619 psw_write(env, new_PSW);
1622 void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
1624 uint32_t dummy;
1625 /* insn doesn't load PCXI and RA */
1626 restore_context_lower(env, ea, &dummy, &dummy);
1629 void helper_lducx(CPUTriCoreState *env, uint32_t ea)
1631 uint32_t dummy;
1632 /* insn doesn't load PCXI and PSW */
1633 restore_context_upper(env, ea, &dummy, &dummy);
1636 void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
1638 save_context_lower(env, ea);
1641 void helper_stucx(CPUTriCoreState *env, uint32_t ea)
1643 save_context_upper(env, ea);
1646 void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
1648 psw_write(env, arg);
1651 uint32_t helper_psw_read(CPUTriCoreState *env)
1653 return psw_read(env);
1657 static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
1658 uint32_t exception,
1659 int error_code,
1660 uintptr_t pc)
1662 CPUState *cs = CPU(tricore_env_get_cpu(env));
1663 cs->exception_index = exception;
1664 env->error_code = error_code;
1666 if (pc) {
1667 /* now we have a real cpu fault */
1668 cpu_restore_state(cs, pc);
1671 cpu_loop_exit(cs);
1674 void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
1675 uintptr_t retaddr)
1677 int ret;
1678 ret = cpu_tricore_handle_mmu_fault(cs, addr, is_write, mmu_idx);
1679 if (ret) {
1680 TriCoreCPU *cpu = TRICORE_CPU(cs);
1681 CPUTriCoreState *env = &cpu->env;
1682 do_raise_exception_err(env, cs->exception_index,
1683 env->error_code, retaddr);