]> git.proxmox.com Git - mirror_qemu.git/blame - target-tricore/op_helper.c
target-tricore: Add missing ULL suffix on 64 bit constant
[mirror_qemu.git] / target-tricore / op_helper.c
CommitLineData
48e06fe0
BK
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
3a16ecb0
BK
23/* Addressing mode helper */
24
25static 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
38uint32_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
46uint32_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
e4e39176
BK
59static 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
83static 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}
0974257e 105
d5de7839
BK
106static 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
137static 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}
0974257e 166
2692802a
BK
167target_ulong helper_add_ssov(CPUTriCoreState *env, target_ulong r1,
168 target_ulong r2)
169{
2692802a
BK
170 int64_t t1 = sextract64(r1, 0, 32);
171 int64_t t2 = sextract64(r2, 0, 32);
172 int64_t result = t1 + t2;
e4e39176 173 return ssov32(env, result);
2692802a
BK
174}
175
d5de7839
BK
176target_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
0974257e
BK
186target_ulong helper_add_suov(CPUTriCoreState *env, target_ulong r1,
187 target_ulong r2)
188{
0974257e
BK
189 int64_t t1 = extract64(r1, 0, 32);
190 int64_t t2 = extract64(r2, 0, 32);
191 int64_t result = t1 + t2;
e4e39176 192 return suov32(env, result);
0974257e
BK
193}
194
d5de7839
BK
195target_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
2692802a
BK
205target_ulong helper_sub_ssov(CPUTriCoreState *env, target_ulong r1,
206 target_ulong r2)
207{
2692802a
BK
208 int64_t t1 = sextract64(r1, 0, 32);
209 int64_t t2 = sextract64(r2, 0, 32);
210 int64_t result = t1 - t2;
e4e39176 211 return ssov32(env, result);
2692802a
BK
212}
213
d5de7839
BK
214target_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
0974257e
BK
224target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,
225 target_ulong r2)
226{
0974257e
BK
227 int64_t t1 = extract64(r1, 0, 32);
228 int64_t t2 = extract64(r2, 0, 32);
229 int64_t result = t1 - t2;
e4e39176 230 return suov32(env, result);
0974257e
BK
231}
232
d5de7839
BK
233target_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
0974257e
BK
243target_ulong helper_mul_ssov(CPUTriCoreState *env, target_ulong r1,
244 target_ulong r2)
245{
0974257e
BK
246 int64_t t1 = sextract64(r1, 0, 32);
247 int64_t t2 = sextract64(r2, 0, 32);
248 int64_t result = t1 * t2;
e4e39176 249 return ssov32(env, result);
0974257e
BK
250}
251
252target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,
253 target_ulong r2)
254{
0974257e
BK
255 int64_t t1 = extract64(r1, 0, 32);
256 int64_t t2 = extract64(r2, 0, 32);
257 int64_t result = t1 * t2;
e4e39176 258 return suov32(env, result);
0974257e
BK
259}
260
261target_ulong helper_sha_ssov(CPUTriCoreState *env, target_ulong r1,
262 target_ulong r2)
263{
0974257e
BK
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 }
e4e39176 274 return ssov32(env, result);
0974257e
BK
275}
276
d5de7839
BK
277uint32_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
284uint32_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
0974257e
BK
297target_ulong helper_absdif_ssov(CPUTriCoreState *env, target_ulong r1,
298 target_ulong r2)
299{
0974257e
BK
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 }
e4e39176 309 return ssov32(env, result);
0974257e 310}
328f1f0f 311
d5de7839
BK
312uint32_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
328f1f0f
BK
337target_ulong helper_madd32_ssov(CPUTriCoreState *env, target_ulong r1,
338 target_ulong r2, target_ulong r3)
339{
328f1f0f
BK
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);
e4e39176 346 return ssov32(env, result);
328f1f0f
BK
347}
348
349target_ulong helper_madd32_suov(CPUTriCoreState *env, target_ulong r1,
350 target_ulong r2, target_ulong r3)
351{
328f1f0f
BK
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);
e4e39176 358 return suov32(env, result);
328f1f0f
BK
359}
360
361uint64_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
393uint64_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
417target_ulong helper_msub32_ssov(CPUTriCoreState *env, target_ulong r1,
418 target_ulong r2, target_ulong r3)
419{
328f1f0f
BK
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);
e4e39176 426 return ssov32(env, result);
328f1f0f
BK
427}
428
429target_ulong helper_msub32_suov(CPUTriCoreState *env, target_ulong r1,
430 target_ulong r2, target_ulong r3)
431{
328f1f0f
BK
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);
e4e39176 438 return suov32(env, result);
328f1f0f
BK
439}
440
441uint64_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
472uint64_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
d5de7839
BK
496uint32_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
519uint32_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
542uint32_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
566uint32_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
591uint32_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
617uint32_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
642uint32_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
668uint32_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
693uint32_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
710uint32_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
725uint32_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
737uint32_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
747uint32_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
761uint32_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
775uint32_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
790uint32_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) \
806uint32_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 \
820uint32_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 \
835uint32_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 \
853uint32_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
871EXTREMA_H_B(max, >)
872EXTREMA_H_B(min, <)
873
874#undef EXTREMA_H_B
875
0b79a781
BK
876uint32_t helper_clo(target_ulong r1)
877{
878 return clo32(r1);
879}
880
881uint32_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
899uint32_t helper_clz(target_ulong r1)
900{
901 return clz32(r1);
902}
903
904uint32_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
922uint32_t helper_cls(target_ulong r1)
923{
924 return clrsb32(r1);
925}
926
927uint32_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
945uint32_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
958uint32_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
978uint32_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 */
452e3d49 997 env->PSW_USB_C = ((result & 0xffffffff00000000ULL) != 0);
0b79a781
BK
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
1016uint32_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
e2bed107
BK
1036uint32_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
1050uint64_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
1067uint32_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
1103uint64_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
1131uint64_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
1164uint64_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
1181uint64_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
1214uint64_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
9655b932
BK
1231uint64_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
1255uint64_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}
1280uint32_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
9a31922b
BK
1303/* context save area (CSA) related helpers */
1304
1305static 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
1323static 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
44ea3430
BK
1339static 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
030c58df 1354static void save_context_upper(CPUTriCoreState *env, int ea)
9a31922b 1355{
9a31922b
BK
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]);
9a31922b
BK
1372}
1373
030c58df 1374static void save_context_lower(CPUTriCoreState *env, int ea)
5de93515 1375{
5de93515 1376 cpu_stl_data(env, ea, env->PCXI);
030c58df 1377 cpu_stl_data(env, ea+4, env->gpr_a[11]);
5de93515
BK
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
9a31922b
BK
1394static 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);
9a31922b
BK
1413}
1414
59543d4e
BK
1415static 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
9a31922b
BK
1436void 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);
030c58df
BK
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);
9a31922b
BK
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
1491void 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],
030c58df 1519 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
9a31922b 1520 restore_context_upper(env, ea, &new_PCXI, &new_PSW);
030c58df
BK
1521 /* M(EA, word) = FCX; */
1522 cpu_stl_data(env, ea, env->FCX);
9a31922b
BK
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
5de93515
BK
1537void 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
030c58df
BK
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
5de93515
BK
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
44ea3430
BK
1579void 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],
030c58df 1605 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
44ea3430 1606 restore_context_upper(env, ea, &new_PCXI, &new_PSW);
030c58df
BK
1607 /* M(EA, word) = FCX;*/
1608 cpu_stl_data(env, ea, env->FCX);
44ea3430
BK
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
59543d4e
BK
1617void 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
1624void 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
1631void helper_stlcx(CPUTriCoreState *env, uint32_t ea)
1632{
1633 save_context_lower(env, ea);
1634}
1635
1636void helper_stucx(CPUTriCoreState *env, uint32_t ea)
1637{
1638 save_context_upper(env, ea);
1639}
1640
2b2f7d97
BK
1641void helper_psw_write(CPUTriCoreState *env, uint32_t arg)
1642{
1643 psw_write(env, arg);
1644}
1645
1646uint32_t helper_psw_read(CPUTriCoreState *env)
1647{
1648 return psw_read(env);
1649}
1650
1651
2d30267e
BK
1652static 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
48e06fe0
BK
1669void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
1670 uintptr_t retaddr)
1671{
2d30267e
BK
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 }
48e06fe0 1680}