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