acpi: build_append_nameseg(): add padding if necessary
[qemu/ar7.git] / target-tricore / op_helper.c
blob13e27291c1cb72fd776876931dba7f8fce5daa75
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;
258 return suov32(env, result);
261 target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
262 target_ulong r2)
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;
274 return ssov32(env, result);
277 uint32_t helper_abs_ssov(CPUTriCoreState *env, target_ulong r1)
279 target_ulong result;
280 result = ((int32_t)r1 >= 0) ? r1 : (0 - r1);
281 return ssov32(env, result);
284 uint32_t helper_abs_h_ssov(CPUTriCoreState *env, target_ulong r1)
286 int32_t ret_h0, ret_h1;
288 ret_h0 = sextract32(r1, 0, 16);
289 ret_h0 = (ret_h0 >= 0) ? ret_h0 : (0 - ret_h0);
291 ret_h1 = sextract32(r1, 16, 16);
292 ret_h1 = (ret_h1 >= 0) ? ret_h1 : (0 - ret_h1);
294 return ssov16(env, ret_h0, ret_h1);
297 target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
298 target_ulong r2)
300 int64_t t1 = sextract64(r1, 0, 32);
301 int64_t t2 = sextract64(r2, 0, 32);
302 int64_t result;
304 if (t1 > t2) {
305 result = t1 - t2;
306 } else {
307 result = t2 - t1;
309 return ssov32(env, result);
312 uint32_t helper_absdif_h_ssov(CPUTriCoreState *env, target_ulong r1,
313 target_ulong r2)
315 int32_t t1, t2;
316 int32_t ret_h0, ret_h1;
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;
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;
334 return ssov16(env, ret_h0, ret_h1);
337 target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
338 target_ulong r2, target_ulong r3)
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;
345 result = t2 + (t1 * t3);
346 return ssov32(env, result);
349 target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
350 target_ulong r2, target_ulong r3)
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;
357 result = t2 + (t1 * t3);
358 return suov32(env, result);
361 uint64_t helper_madd64_ssov(CPUTriCoreState *env, target_ulong r1,
362 uint64_t r2, target_ulong r3)
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;
369 mul = t1 * t3;
370 ret = mul + r2;
371 ovf = (ret ^ mul) & ~(mul ^ r2);
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;
383 } else {
384 env->PSW_USB_V = 0;
386 t1 = ret >> 32;
387 env->PSW_USB_AV = t1 ^ t1 * 2u;
388 env->PSW_USB_SAV |= env->PSW_USB_AV;
390 return ret;
393 uint64_t helper_madd64_suov(CPUTriCoreState *env, target_ulong r1,
394 uint64_t r2, target_ulong r3)
396 uint64_t ret, mul;
397 uint64_t t1 = extract64(r1, 0, 32);
398 uint64_t t3 = extract64(r3, 0, 32);
400 mul = t1 * t3;
401 ret = mul + r2;
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;
411 t1 = ret >> 32;
412 env->PSW_USB_AV = t1 ^ t1 * 2u;
413 env->PSW_USB_SAV |= env->PSW_USB_AV;
414 return ret;
417 target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
418 target_ulong r2, target_ulong r3)
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;
425 result = t2 - (t1 * t3);
426 return ssov32(env, result);
429 target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
430 target_ulong r2, target_ulong r3)
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;
437 result = t2 - (t1 * t3);
438 return suov32(env, result);
441 uint64_t helper_msub64_ssov(CPUTriCoreState *env, target_ulong r1,
442 uint64_t r2, target_ulong r3)
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;
449 mul = t1 * t3;
450 ret = r2 - mul;
451 ovf = (ret ^ r2) & (mul ^ r2);
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;
463 } else {
464 env->PSW_USB_V = 0;
466 t1 = ret >> 32;
467 env->PSW_USB_AV = t1 ^ t1 * 2u;
468 env->PSW_USB_SAV |= env->PSW_USB_AV;
469 return ret;
472 uint64_t helper_msub64_suov(CPUTriCoreState *env, target_ulong r1,
473 uint64_t r2, target_ulong r3)
475 uint64_t ret, mul;
476 uint64_t t1 = extract64(r1, 0, 32);
477 uint64_t t3 = extract64(r3, 0, 32);
479 mul = t1 * t3;
480 ret = r2 - mul;
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;
490 t1 = ret >> 32;
491 env->PSW_USB_AV = t1 ^ t1 * 2u;
492 env->PSW_USB_SAV |= env->PSW_USB_AV;
493 return ret;
496 uint32_t helper_abs_b(CPUTriCoreState *env, target_ulong arg)
498 int32_t b, i;
499 int32_t ovf = 0;
500 int32_t avf = 0;
501 int32_t ret = 0;
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);
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;
516 return ret;
519 uint32_t helper_abs_h(CPUTriCoreState *env, target_ulong arg)
521 int32_t h, i;
522 int32_t ovf = 0;
523 int32_t avf = 0;
524 int32_t ret = 0;
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);
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;
539 return ret;
542 uint32_t helper_absdif_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
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;
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);
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;
566 uint32_t helper_absdif_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
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;
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);
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;
588 return ret;
591 uint32_t helper_add_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
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;
599 for (i = 0; i < 4; i++) {
600 extr_r1 = sextract32(r1, i * 8, 8);
601 extr_r2 = sextract32(r2, i * 8, 8);
603 b = extr_r1 + extr_r2;
604 ovf |= ((b > 0x7f) || (b < -0x80));
605 avf |= b ^ b * 2u;
606 ret |= ((b & 0xff) << (i*8));
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;
614 return ret;
617 uint32_t helper_add_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
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;
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);
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;
639 return ret;
642 uint32_t helper_sub_b(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
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;
650 for (i = 0; i < 4; i++) {
651 extr_r1 = sextract32(r1, i * 8, 8);
652 extr_r2 = sextract32(r2, i * 8, 8);
654 b = extr_r1 - extr_r2;
655 ovf |= ((b > 0x7f) || (b < -0x80));
656 avf |= b ^ b * 2u;
657 ret |= ((b & 0xff) << (i*8));
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;
665 return ret;
668 uint32_t helper_sub_h(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
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;
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);
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;
690 return ret;
693 uint32_t helper_eq_b(target_ulong r1, target_ulong r2)
695 int32_t ret;
696 int32_t i, msk;
698 ret = 0;
699 msk = 0xff;
700 for (i = 0; i < 4; i++) {
701 if ((r1 & msk) == (r2 & msk)) {
702 ret |= msk;
704 msk = msk << 8;
707 return ret;
710 uint32_t helper_eq_h(target_ulong r1, target_ulong r2)
712 int32_t ret = 0;
714 if ((r1 & 0xffff) == (r2 & 0xffff)) {
715 ret = 0xffff;
718 if ((r1 & 0xffff0000) == (r2 & 0xffff0000)) {
719 ret |= 0xffff0000;
722 return ret;
725 uint32_t helper_eqany_b(target_ulong r1, target_ulong r2)
727 int32_t i;
728 uint32_t ret = 0;
730 for (i = 0; i < 4; i++) {
731 ret |= (sextract32(r1, i * 8, 8) == sextract32(r2, i * 8, 8));
734 return ret;
737 uint32_t helper_eqany_h(target_ulong r1, target_ulong r2)
739 uint32_t ret;
741 ret = (sextract32(r1, 0, 16) == sextract32(r2, 0, 16));
742 ret |= (sextract32(r1, 16, 16) == sextract32(r2, 16, 16));
744 return ret;
747 uint32_t helper_lt_b(target_ulong r1, target_ulong r2)
749 int32_t i;
750 uint32_t ret = 0;
752 for (i = 0; i < 4; i++) {
753 if (sextract32(r1, i * 8, 8) < sextract32(r2, i * 8, 8)) {
754 ret |= (0xff << (i * 8));
758 return ret;
761 uint32_t helper_lt_bu(target_ulong r1, target_ulong r2)
763 int32_t i;
764 uint32_t ret = 0;
766 for (i = 0; i < 4; i++) {
767 if (extract32(r1, i * 8, 8) < extract32(r2, i * 8, 8)) {
768 ret |= (0xff << (i * 8));
772 return ret;
775 uint32_t helper_lt_h(target_ulong r1, target_ulong r2)
777 uint32_t ret = 0;
779 if (sextract32(r1, 0, 16) < sextract32(r2, 0, 16)) {
780 ret |= 0xffff;
783 if (sextract32(r1, 16, 16) < sextract32(r2, 16, 16)) {
784 ret |= 0xffff0000;
787 return ret;
790 uint32_t helper_lt_hu(target_ulong r1, target_ulong r2)
792 uint32_t ret = 0;
794 if (extract32(r1, 0, 16) < extract32(r2, 0, 16)) {
795 ret |= 0xffff;
798 if (extract32(r1, 16, 16) < extract32(r2, 16, 16)) {
799 ret |= 0xffff0000;
802 return ret;
805 #define EXTREMA_H_B(name, op) \
806 uint32_t helper_##name ##_b(target_ulong r1, target_ulong r2) \
808 int32_t i, extr_r1, extr_r2; \
809 uint32_t ret = 0; \
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); \
817 return ret; \
820 uint32_t helper_##name ##_bu(target_ulong r1, target_ulong r2)\
822 int32_t i; \
823 uint32_t extr_r1, extr_r2; \
824 uint32_t ret = 0; \
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); \
832 return ret; \
835 uint32_t helper_##name ##_h(target_ulong r1, target_ulong r2) \
837 int32_t extr_r1, extr_r2; \
838 uint32_t ret = 0; \
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; \
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; \
850 return ret; \
853 uint32_t helper_##name ##_hu(target_ulong r1, target_ulong r2)\
855 uint32_t extr_r1, extr_r2; \
856 uint32_t ret = 0; \
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; \
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); \
868 return ret; \
871 EXTREMA_H_B(max, >)
872 EXTREMA_H_B(min, <)
874 #undef EXTREMA_H_B
876 uint32_t helper_clo(target_ulong r1)
878 return clo32(r1);
881 uint32_t helper_clo_h(target_ulong r1)
883 uint32_t ret_hw0 = extract32(r1, 0, 16);
884 uint32_t ret_hw1 = extract32(r1, 16, 16);
886 ret_hw0 = clo32(ret_hw0 << 16);
887 ret_hw1 = clo32(ret_hw1 << 16);
889 if (ret_hw0 > 16) {
890 ret_hw0 = 16;
892 if (ret_hw1 > 16) {
893 ret_hw1 = 16;
896 return ret_hw0 | (ret_hw1 << 16);
899 uint32_t helper_clz(target_ulong r1)
901 return clz32(r1);
904 uint32_t helper_clz_h(target_ulong r1)
906 uint32_t ret_hw0 = extract32(r1, 0, 16);
907 uint32_t ret_hw1 = extract32(r1, 16, 16);
909 ret_hw0 = clz32(ret_hw0 << 16);
910 ret_hw1 = clz32(ret_hw1 << 16);
912 if (ret_hw0 > 16) {
913 ret_hw0 = 16;
915 if (ret_hw1 > 16) {
916 ret_hw1 = 16;
919 return ret_hw0 | (ret_hw1 << 16);
922 uint32_t helper_cls(target_ulong r1)
924 return clrsb32(r1);
927 uint32_t helper_cls_h(target_ulong r1)
929 uint32_t ret_hw0 = extract32(r1, 0, 16);
930 uint32_t ret_hw1 = extract32(r1, 16, 16);
932 ret_hw0 = clrsb32(ret_hw0 << 16);
933 ret_hw1 = clrsb32(ret_hw1 << 16);
935 if (ret_hw0 > 15) {
936 ret_hw0 = 15;
938 if (ret_hw1 > 15) {
939 ret_hw1 = 15;
942 return ret_hw0 | (ret_hw1 << 16);
945 uint32_t helper_sh(target_ulong r1, target_ulong r2)
947 int32_t shift_count = sextract32(r2, 0, 6);
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;
958 uint32_t helper_sh_h(target_ulong r1, target_ulong r2)
960 int32_t ret_hw0, ret_hw1;
961 int32_t shift_count;
963 shift_count = sextract32(r2, 0, 5);
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);
978 uint32_t helper_sha(CPUTriCoreState *env, target_ulong r1, target_ulong r2)
980 int32_t shift_count;
981 int64_t result, t1;
982 uint32_t ret;
984 shift_count = sextract32(r2, 0, 6);
985 t1 = sextract32(r1, 0, 32);
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;
1010 env->PSW_USB_AV = ret ^ ret * 2u;
1011 env->PSW_USB_SAV |= env->PSW_USB_AV;
1013 return ret;
1016 uint32_t helper_sha_h(target_ulong r1, target_ulong r2)
1018 int32_t shift_count;
1019 int32_t ret_hw0, ret_hw1;
1021 shift_count = sextract32(r2, 0, 5);
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);
1036 uint32_t helper_bmerge(target_ulong r1, target_ulong r2)
1038 uint32_t i, ret;
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;
1047 return ret;
1050 uint64_t helper_bsplit(uint32_t r1)
1052 int32_t i;
1053 uint64_t ret;
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;
1064 return ret;
1067 uint32_t helper_parity(target_ulong r1)
1069 uint32_t ret;
1070 uint32_t nOnes, i;
1072 ret = 0;
1073 nOnes = 0;
1074 for (i = 0; i < 8; i++) {
1075 ret ^= (r1 & 1);
1076 r1 = r1 >> 1;
1078 /* second byte */
1079 nOnes = 0;
1080 for (i = 0; i < 8; i++) {
1081 nOnes ^= (r1 & 1);
1082 r1 = r1 >> 1;
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;
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;
1098 ret |= nOnes << 24;
1100 return ret;
1103 uint64_t helper_unpack(target_ulong arg1)
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;
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);
1124 ret = int_exp;
1125 ret = ret << 32;
1126 ret |= int_mant;
1128 return ret;
1131 uint64_t helper_dvinit_b_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1133 uint64_t ret;
1134 int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1135 int32_t quotient_sign;
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;
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);
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;
1161 return ret;
1164 uint64_t helper_dvinit_b_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1166 uint64_t ret = sextract32(r1, 0, 32);
1168 ret = ret << 24;
1169 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1170 ret |= 0xffffff;
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;
1178 return ret;
1181 uint64_t helper_dvinit_h_13(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1183 uint64_t ret;
1184 int32_t abs_sig_dividend, abs_base_dividend, abs_divisor;
1185 int32_t quotient_sign;
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;
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);
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;
1211 return ret;
1214 uint64_t helper_dvinit_h_131(CPUTriCoreState *env, uint32_t r1, uint32_t r2)
1216 uint64_t ret = sextract32(r1, 0, 32);
1218 ret = ret << 16;
1219 if (!((r1 & 0x80000000) == (r2 & 0x80000000))) {
1220 ret |= 0xffff;
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;
1228 return ret;
1231 uint64_t helper_mul_h(uint32_t arg00, uint32_t arg01,
1232 uint32_t arg10, uint32_t arg11, uint32_t n)
1234 uint64_t ret;
1235 uint32_t result0, result1;
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);
1246 if (sc0) {
1247 result0 = 0x7fffffff;
1248 } else {
1249 result0 = (((uint32_t)(arg01 * arg11)) << n);
1251 ret = (((uint64_t)result1 << 32)) | result0;
1252 return ret;
1255 uint64_t helper_mulm_h(uint32_t arg00, uint32_t arg01,
1256 uint32_t arg10, uint32_t arg11, uint32_t n)
1258 uint64_t ret;
1259 int64_t result0, result1;
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);
1266 if (sc1) {
1267 result1 = 0x7fffffff;
1268 } else {
1269 result1 = (((int32_t)arg00 * (int32_t)arg10) << n);
1271 if (sc0) {
1272 result0 = 0x7fffffff;
1273 } else {
1274 result0 = (((int32_t)arg01 * (int32_t)arg11) << n);
1276 ret = (result1 + result0);
1277 ret = ret << 16;
1278 return ret;
1280 uint32_t helper_mulr_h(uint32_t arg00, uint32_t arg01,
1281 uint32_t arg10, uint32_t arg11, uint32_t n)
1283 uint32_t result0, result1;
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);
1290 if (sc1) {
1291 result1 = 0x7fffffff;
1292 } else {
1293 result1 = ((arg00 * arg10) << n) + 0x8000;
1295 if (sc0) {
1296 result0 = 0x7fffffff;
1297 } else {
1298 result0 = ((arg01 * arg11) << n) + 0x8000;
1300 return (result1 & 0xffff0000) | (result0 >> 16);
1303 /* context save area (CSA) related helpers */
1305 static int cdc_increment(target_ulong *psw)
1307 if ((*psw & MASK_PSW_CDC) == 0x7f) {
1308 return 0;
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;
1320 return 0;
1323 static int cdc_decrement(target_ulong *psw)
1325 if ((*psw & MASK_PSW_CDC) == 0x7f) {
1326 return 0;
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;
1335 (*psw)--;
1336 return 0;
1339 static bool cdc_zero(target_ulong *psw)
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;
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;
1354 static void save_context_upper(CPUTriCoreState *env, int ea)
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]);
1374 static void save_context_lower(CPUTriCoreState *env, int ea)
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]);
1394 static void restore_context_upper(CPUTriCoreState *env, int ea,
1395 target_ulong *new_PCXI, target_ulong *new_PSW)
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);
1415 static void restore_context_lower(CPUTriCoreState *env, int ea,
1416 target_ulong *ra, target_ulong *pcxi)
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);
1436 void helper_call(CPUTriCoreState *env, uint32_t next_pc)
1438 target_ulong tmp_FCX;
1439 target_ulong ea;
1440 target_ulong new_FCX;
1441 target_ulong psw;
1443 psw = psw_read(env);
1444 /* if (FCX == 0) trap(FCU); */
1445 if (env->FCX == 0) {
1446 /* FCU trap */
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 */
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);
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;
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;
1484 /* if (tmp_FCX == LCX) trap(FCD);*/
1485 if (tmp_FCX == env->LCX) {
1486 /* FCD trap */
1488 psw_write(env, psw);
1491 void helper_ret(CPUTriCoreState *env)
1493 target_ulong ea;
1494 target_ulong new_PCXI;
1495 target_ulong new_PSW, psw;
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 */
1504 /* if (PCXI[19: 0] == 0) then trap(CSU); */
1505 if ((env->PCXI & 0xfffff) == 0) {
1506 /* CSU trap */
1508 /* if (PCXI.UL == 0) then trap(CTYP); */
1509 if ((env->PCXI & MASK_PCXI_UL) == 0) {
1510 /* CTYP trap */
1512 /* PC = {A11 [31: 1], 1’b0}; */
1513 env->PC = env->gpr_a[11] & 0xfffffffe;
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;
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)));
1537 void helper_bisr(CPUTriCoreState *env, uint32_t const9)
1539 target_ulong tmp_FCX;
1540 target_ulong ea;
1541 target_ulong new_FCX;
1543 if (env->FCX == 0) {
1544 /* FCU trap */
1547 tmp_FCX = env->FCX;
1548 ea = ((env->FCX & 0xf0000) << 12) + ((env->FCX & 0xffff) << 6);
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);
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;
1572 env->ICR |= const9; /* ICR.CCPN = const9[7: 0];*/
1574 if (tmp_FCX == env->LCX) {
1575 /* FCD trap */
1579 void helper_rfe(CPUTriCoreState *env)
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 */
1588 /* if (PCXI.UL == 0) then trap(CTYP); */
1589 if ((env->PCXI & MASK_PCXI_UL) == 0) {
1590 /* raise CTYP trap */
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 */
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);
1617 void helper_ldlcx(CPUTriCoreState *env, uint32_t ea)
1619 uint32_t dummy;
1620 /* insn doesn't load PCXI and RA */
1621 restore_context_lower(env, ea, &dummy, &dummy);
1624 void helper_lducx(CPUTriCoreState *env, uint32_t ea)
1626 uint32_t dummy;
1627 /* insn doesn't load PCXI and PSW */
1628 restore_context_upper(env, ea, &dummy, &dummy);
1631 void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
1633 save_context_lower(env, ea);
1636 void helper_stucx(CPUTriCoreState *env, uint32_t ea)
1638 save_context_upper(env, ea);
1641 void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
1643 psw_write(env, arg);
1646 uint32_t helper_psw_read(CPUTriCoreState *env)
1648 return psw_read(env);
1652 static inline void QEMU_NORETURN do_raise_exception_err(CPUTriCoreState *env,
1653 uint32_t exception,
1654 int error_code,
1655 uintptr_t pc)
1657 CPUState *cs = CPU(tricore_env_get_cpu(env));
1658 cs->exception_index = exception;
1659 env->error_code = error_code;
1661 if (pc) {
1662 /* now we have a real cpu fault */
1663 cpu_restore_state(cs, pc);
1666 cpu_loop_exit(cs);
1669 void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
1670 uintptr_t retaddr)
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);