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/>.
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);
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
;
56 return reg
- index
+ new_index
;
59 #define SSOV(env, ret, arg, len) do { \
60 int64_t max_pos = INT##len ##_MAX; \
61 int64_t max_neg = INT##len ##_MIN; \
62 if (arg > max_pos) { \
63 env->PSW_USB_V = (1 << 31); \
64 env->PSW_USB_SV = (1 << 31); \
65 ret = (target_ulong)max_pos; \
67 if (arg < max_neg) { \
68 env->PSW_USB_V = (1 << 31); \
69 env->PSW_USB_SV = (1 << 31); \
70 ret = (target_ulong)max_neg; \
73 ret = (target_ulong)arg; \
76 env->PSW_USB_AV = arg ^ arg * 2u; \
77 env->PSW_USB_SAV |= env->PSW_USB_AV; \
80 #define SUOV(env, ret, arg, len) do { \
81 int64_t max_pos = UINT##len ##_MAX; \
82 if (arg > max_pos) { \
83 env->PSW_USB_V = (1 << 31); \
84 env->PSW_USB_SV = (1 << 31); \
85 ret = (target_ulong)max_pos; \
88 env->PSW_USB_V = (1 << 31); \
89 env->PSW_USB_SV = (1 << 31); \
93 ret = (target_ulong)arg; \
96 env->PSW_USB_AV = arg ^ arg * 2u; \
97 env->PSW_USB_SAV |= env->PSW_USB_AV; \
101 target_ulong
helper_add_ssov(CPUTriCoreState
*env
, target_ulong r1
,
105 int64_t t1
= sextract64(r1
, 0, 32);
106 int64_t t2
= sextract64(r2
, 0, 32);
107 int64_t result
= t1
+ t2
;
108 SSOV(env
, ret
, result
, 32);
112 target_ulong
helper_add_suov(CPUTriCoreState
*env
, target_ulong r1
,
116 int64_t t1
= extract64(r1
, 0, 32);
117 int64_t t2
= extract64(r2
, 0, 32);
118 int64_t result
= t1
+ t2
;
119 SUOV(env
, ret
, result
, 32);
123 target_ulong
helper_sub_ssov(CPUTriCoreState
*env
, target_ulong r1
,
127 int64_t t1
= sextract64(r1
, 0, 32);
128 int64_t t2
= sextract64(r2
, 0, 32);
129 int64_t result
= t1
- t2
;
130 SSOV(env
, ret
, result
, 32);
134 target_ulong
helper_sub_suov(CPUTriCoreState
*env
, target_ulong r1
,
138 int64_t t1
= extract64(r1
, 0, 32);
139 int64_t t2
= extract64(r2
, 0, 32);
140 int64_t result
= t1
- t2
;
141 SUOV(env
, ret
, result
, 32);
145 target_ulong
helper_mul_ssov(CPUTriCoreState
*env
, target_ulong r1
,
149 int64_t t1
= sextract64(r1
, 0, 32);
150 int64_t t2
= sextract64(r2
, 0, 32);
151 int64_t result
= t1
* t2
;
152 SSOV(env
, ret
, result
, 32);
156 target_ulong
helper_mul_suov(CPUTriCoreState
*env
, target_ulong r1
,
160 int64_t t1
= extract64(r1
, 0, 32);
161 int64_t t2
= extract64(r2
, 0, 32);
162 int64_t result
= t1
* t2
;
163 SUOV(env
, ret
, result
, 32);
167 target_ulong
helper_sha_ssov(CPUTriCoreState
*env
, target_ulong r1
,
171 int64_t t1
= sextract64(r1
, 0, 32);
172 int32_t t2
= sextract64(r2
, 0, 6);
181 SSOV(env
, ret
, result
, 32);
185 target_ulong
helper_absdif_ssov(CPUTriCoreState
*env
, target_ulong r1
,
189 int64_t t1
= sextract64(r1
, 0, 32);
190 int64_t t2
= sextract64(r2
, 0, 32);
198 SSOV(env
, ret
, result
, 32);
202 target_ulong
helper_madd32_ssov(CPUTriCoreState
*env
, target_ulong r1
,
203 target_ulong r2
, target_ulong r3
)
206 int64_t t1
= sextract64(r1
, 0, 32);
207 int64_t t2
= sextract64(r2
, 0, 32);
208 int64_t t3
= sextract64(r3
, 0, 32);
211 result
= t2
+ (t1
* t3
);
212 SSOV(env
, ret
, result
, 32);
216 target_ulong
helper_madd32_suov(CPUTriCoreState
*env
, target_ulong r1
,
217 target_ulong r2
, target_ulong r3
)
220 uint64_t t1
= extract64(r1
, 0, 32);
221 uint64_t t2
= extract64(r2
, 0, 32);
222 uint64_t t3
= extract64(r3
, 0, 32);
225 result
= t2
+ (t1
* t3
);
226 SUOV(env
, ret
, result
, 32);
230 uint64_t helper_madd64_ssov(CPUTriCoreState
*env
, target_ulong r1
,
231 uint64_t r2
, target_ulong r3
)
234 int64_t t1
= sextract64(r1
, 0, 32);
235 int64_t t3
= sextract64(r3
, 0, 32);
240 ovf
= (ret
^ mul
) & ~(mul
^ r2
);
242 if ((int64_t)ovf
< 0) {
243 env
->PSW_USB_V
= (1 << 31);
244 env
->PSW_USB_SV
= (1 << 31);
245 /* ext_ret > MAX_INT */
248 /* ext_ret < MIN_INT */
256 env
->PSW_USB_AV
= t1
^ t1
* 2u;
257 env
->PSW_USB_SAV
|= env
->PSW_USB_AV
;
262 uint64_t helper_madd64_suov(CPUTriCoreState
*env
, target_ulong r1
,
263 uint64_t r2
, target_ulong r3
)
266 uint64_t t1
= extract64(r1
, 0, 32);
267 uint64_t t3
= extract64(r3
, 0, 32);
273 env
->PSW_USB_V
= (1 << 31);
274 env
->PSW_USB_SV
= (1 << 31);
281 env
->PSW_USB_AV
= t1
^ t1
* 2u;
282 env
->PSW_USB_SAV
|= env
->PSW_USB_AV
;
286 target_ulong
helper_msub32_ssov(CPUTriCoreState
*env
, target_ulong r1
,
287 target_ulong r2
, target_ulong r3
)
290 int64_t t1
= sextract64(r1
, 0, 32);
291 int64_t t2
= sextract64(r2
, 0, 32);
292 int64_t t3
= sextract64(r3
, 0, 32);
295 result
= t2
- (t1
* t3
);
296 SSOV(env
, ret
, result
, 32);
300 target_ulong
helper_msub32_suov(CPUTriCoreState
*env
, target_ulong r1
,
301 target_ulong r2
, target_ulong r3
)
304 int64_t t1
= extract64(r1
, 0, 32);
305 int64_t t2
= extract64(r2
, 0, 32);
306 int64_t t3
= extract64(r3
, 0, 32);
309 result
= t2
- (t1
* t3
);
310 SUOV(env
, ret
, result
, 32);
314 uint64_t helper_msub64_ssov(CPUTriCoreState
*env
, target_ulong r1
,
315 uint64_t r2
, target_ulong r3
)
318 int64_t t1
= sextract64(r1
, 0, 32);
319 int64_t t3
= sextract64(r3
, 0, 32);
324 ovf
= (ret
^ r2
) & (mul
^ r2
);
326 if ((int64_t)ovf
< 0) {
327 env
->PSW_USB_V
= (1 << 31);
328 env
->PSW_USB_SV
= (1 << 31);
329 /* ext_ret > MAX_INT */
332 /* ext_ret < MIN_INT */
340 env
->PSW_USB_AV
= t1
^ t1
* 2u;
341 env
->PSW_USB_SAV
|= env
->PSW_USB_AV
;
345 uint64_t helper_msub64_suov(CPUTriCoreState
*env
, target_ulong r1
,
346 uint64_t r2
, target_ulong r3
)
349 uint64_t t1
= extract64(r1
, 0, 32);
350 uint64_t t3
= extract64(r3
, 0, 32);
356 env
->PSW_USB_V
= (1 << 31);
357 env
->PSW_USB_SV
= (1 << 31);
364 env
->PSW_USB_AV
= t1
^ t1
* 2u;
365 env
->PSW_USB_SAV
|= env
->PSW_USB_AV
;
369 /* context save area (CSA) related helpers */
371 static int cdc_increment(target_ulong
*psw
)
373 if ((*psw
& MASK_PSW_CDC
) == 0x7f) {
378 /* check for overflow */
379 int lo
= clo32((*psw
& MASK_PSW_CDC
) << (32 - 7));
380 int mask
= (1u << (7 - lo
)) - 1;
381 int count
= *psw
& mask
;
389 static int cdc_decrement(target_ulong
*psw
)
391 if ((*psw
& MASK_PSW_CDC
) == 0x7f) {
394 /* check for underflow */
395 int lo
= clo32((*psw
& MASK_PSW_CDC
) << (32 - 7));
396 int mask
= (1u << (7 - lo
)) - 1;
397 int count
= *psw
& mask
;
405 static bool cdc_zero(target_ulong
*psw
)
407 int cdc
= *psw
& MASK_PSW_CDC
;
408 /* Returns TRUE if PSW.CDC.COUNT == 0 or if PSW.CDC ==
409 7'b1111111, otherwise returns FALSE. */
414 int lo
= clo32((*psw
& MASK_PSW_CDC
) << (32 - 7));
415 int mask
= (1u << (7 - lo
)) - 1;
416 int count
= *psw
& mask
;
420 static void save_context_upper(CPUTriCoreState
*env
, int ea
)
422 cpu_stl_data(env
, ea
, env
->PCXI
);
423 cpu_stl_data(env
, ea
+4, env
->PSW
);
424 cpu_stl_data(env
, ea
+8, env
->gpr_a
[10]);
425 cpu_stl_data(env
, ea
+12, env
->gpr_a
[11]);
426 cpu_stl_data(env
, ea
+16, env
->gpr_d
[8]);
427 cpu_stl_data(env
, ea
+20, env
->gpr_d
[9]);
428 cpu_stl_data(env
, ea
+24, env
->gpr_d
[10]);
429 cpu_stl_data(env
, ea
+28, env
->gpr_d
[11]);
430 cpu_stl_data(env
, ea
+32, env
->gpr_a
[12]);
431 cpu_stl_data(env
, ea
+36, env
->gpr_a
[13]);
432 cpu_stl_data(env
, ea
+40, env
->gpr_a
[14]);
433 cpu_stl_data(env
, ea
+44, env
->gpr_a
[15]);
434 cpu_stl_data(env
, ea
+48, env
->gpr_d
[12]);
435 cpu_stl_data(env
, ea
+52, env
->gpr_d
[13]);
436 cpu_stl_data(env
, ea
+56, env
->gpr_d
[14]);
437 cpu_stl_data(env
, ea
+60, env
->gpr_d
[15]);
440 static void save_context_lower(CPUTriCoreState
*env
, int ea
)
442 cpu_stl_data(env
, ea
, env
->PCXI
);
443 cpu_stl_data(env
, ea
+4, env
->gpr_a
[11]);
444 cpu_stl_data(env
, ea
+8, env
->gpr_a
[2]);
445 cpu_stl_data(env
, ea
+12, env
->gpr_a
[3]);
446 cpu_stl_data(env
, ea
+16, env
->gpr_d
[0]);
447 cpu_stl_data(env
, ea
+20, env
->gpr_d
[1]);
448 cpu_stl_data(env
, ea
+24, env
->gpr_d
[2]);
449 cpu_stl_data(env
, ea
+28, env
->gpr_d
[3]);
450 cpu_stl_data(env
, ea
+32, env
->gpr_a
[4]);
451 cpu_stl_data(env
, ea
+36, env
->gpr_a
[5]);
452 cpu_stl_data(env
, ea
+40, env
->gpr_a
[6]);
453 cpu_stl_data(env
, ea
+44, env
->gpr_a
[7]);
454 cpu_stl_data(env
, ea
+48, env
->gpr_d
[4]);
455 cpu_stl_data(env
, ea
+52, env
->gpr_d
[5]);
456 cpu_stl_data(env
, ea
+56, env
->gpr_d
[6]);
457 cpu_stl_data(env
, ea
+60, env
->gpr_d
[7]);
460 static void restore_context_upper(CPUTriCoreState
*env
, int ea
,
461 target_ulong
*new_PCXI
, target_ulong
*new_PSW
)
463 *new_PCXI
= cpu_ldl_data(env
, ea
);
464 *new_PSW
= cpu_ldl_data(env
, ea
+4);
465 env
->gpr_a
[10] = cpu_ldl_data(env
, ea
+8);
466 env
->gpr_a
[11] = cpu_ldl_data(env
, ea
+12);
467 env
->gpr_d
[8] = cpu_ldl_data(env
, ea
+16);
468 env
->gpr_d
[9] = cpu_ldl_data(env
, ea
+20);
469 env
->gpr_d
[10] = cpu_ldl_data(env
, ea
+24);
470 env
->gpr_d
[11] = cpu_ldl_data(env
, ea
+28);
471 env
->gpr_a
[12] = cpu_ldl_data(env
, ea
+32);
472 env
->gpr_a
[13] = cpu_ldl_data(env
, ea
+36);
473 env
->gpr_a
[14] = cpu_ldl_data(env
, ea
+40);
474 env
->gpr_a
[15] = cpu_ldl_data(env
, ea
+44);
475 env
->gpr_d
[12] = cpu_ldl_data(env
, ea
+48);
476 env
->gpr_d
[13] = cpu_ldl_data(env
, ea
+52);
477 env
->gpr_d
[14] = cpu_ldl_data(env
, ea
+56);
478 env
->gpr_d
[15] = cpu_ldl_data(env
, ea
+60);
481 static void restore_context_lower(CPUTriCoreState
*env
, int ea
,
482 target_ulong
*ra
, target_ulong
*pcxi
)
484 *pcxi
= cpu_ldl_data(env
, ea
);
485 *ra
= cpu_ldl_data(env
, ea
+4);
486 env
->gpr_a
[2] = cpu_ldl_data(env
, ea
+8);
487 env
->gpr_a
[3] = cpu_ldl_data(env
, ea
+12);
488 env
->gpr_d
[0] = cpu_ldl_data(env
, ea
+16);
489 env
->gpr_d
[1] = cpu_ldl_data(env
, ea
+20);
490 env
->gpr_d
[2] = cpu_ldl_data(env
, ea
+24);
491 env
->gpr_d
[3] = cpu_ldl_data(env
, ea
+28);
492 env
->gpr_a
[4] = cpu_ldl_data(env
, ea
+32);
493 env
->gpr_a
[5] = cpu_ldl_data(env
, ea
+36);
494 env
->gpr_a
[6] = cpu_ldl_data(env
, ea
+40);
495 env
->gpr_a
[7] = cpu_ldl_data(env
, ea
+44);
496 env
->gpr_d
[4] = cpu_ldl_data(env
, ea
+48);
497 env
->gpr_d
[5] = cpu_ldl_data(env
, ea
+52);
498 env
->gpr_d
[6] = cpu_ldl_data(env
, ea
+56);
499 env
->gpr_d
[7] = cpu_ldl_data(env
, ea
+60);
502 void helper_call(CPUTriCoreState
*env
, uint32_t next_pc
)
504 target_ulong tmp_FCX
;
506 target_ulong new_FCX
;
510 /* if (FCX == 0) trap(FCU); */
514 /* if (PSW.CDE) then if (cdc_increment()) then trap(CDO); */
515 if (psw
& MASK_PSW_CDE
) {
516 if (cdc_increment(&psw
)) {
524 /* EA = {FCX.FCXS, 6'b0, FCX.FCXO, 6'b0}; */
525 ea
= ((env
->FCX
& MASK_FCX_FCXS
) << 12) +
526 ((env
->FCX
& MASK_FCX_FCXO
) << 6);
527 /* new_FCX = M(EA, word); */
528 new_FCX
= cpu_ldl_data(env
, ea
);
529 /* M(EA, 16 * word) = {PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11],
530 A[12], A[13], A[14], A[15], D[12], D[13], D[14],
532 save_context_upper(env
, ea
);
534 /* PCXI.PCPN = ICR.CCPN; */
535 env
->PCXI
= (env
->PCXI
& 0xffffff) +
536 ((env
->ICR
& MASK_ICR_CCPN
) << 24);
537 /* PCXI.PIE = ICR.IE; */
538 env
->PCXI
= ((env
->PCXI
& ~MASK_PCXI_PIE
) +
539 ((env
->ICR
& MASK_ICR_IE
) << 15));
541 env
->PCXI
|= MASK_PCXI_UL
;
543 /* PCXI[19: 0] = FCX[19: 0]; */
544 env
->PCXI
= (env
->PCXI
& 0xfff00000) + (env
->FCX
& 0xfffff);
545 /* FCX[19: 0] = new_FCX[19: 0]; */
546 env
->FCX
= (env
->FCX
& 0xfff00000) + (new_FCX
& 0xfffff);
547 /* A[11] = next_pc[31: 0]; */
548 env
->gpr_a
[11] = next_pc
;
550 /* if (tmp_FCX == LCX) trap(FCD);*/
551 if (tmp_FCX
== env
->LCX
) {
557 void helper_ret(CPUTriCoreState
*env
)
560 target_ulong new_PCXI
;
561 target_ulong new_PSW
, psw
;
564 /* if (PSW.CDE) then if (cdc_decrement()) then trap(CDU);*/
565 if (env
->PSW
& MASK_PSW_CDE
) {
566 if (cdc_decrement(&(env
->PSW
))) {
570 /* if (PCXI[19: 0] == 0) then trap(CSU); */
571 if ((env
->PCXI
& 0xfffff) == 0) {
574 /* if (PCXI.UL == 0) then trap(CTYP); */
575 if ((env
->PCXI
& MASK_PCXI_UL
) == 0) {
578 /* PC = {A11 [31: 1], 1’b0}; */
579 env
->PC
= env
->gpr_a
[11] & 0xfffffffe;
581 /* EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0}; */
582 ea
= ((env
->PCXI
& MASK_PCXI_PCXS
) << 12) +
583 ((env
->PCXI
& MASK_PCXI_PCXO
) << 6);
584 /* {new_PCXI, new_PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
585 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
586 restore_context_upper(env
, ea
, &new_PCXI
, &new_PSW
);
587 /* M(EA, word) = FCX; */
588 cpu_stl_data(env
, ea
, env
->FCX
);
589 /* FCX[19: 0] = PCXI[19: 0]; */
590 env
->FCX
= (env
->FCX
& 0xfff00000) + (env
->PCXI
& 0x000fffff);
591 /* PCXI = new_PCXI; */
592 env
->PCXI
= new_PCXI
;
594 if (tricore_feature(env
, TRICORE_FEATURE_13
)) {
596 psw_write(env
, new_PSW
);
598 /* PSW = {new_PSW[31:26], PSW[25:24], new_PSW[23:0]}; */
599 psw_write(env
, (new_PSW
& ~(0x3000000)) + (psw
& (0x3000000)));
603 void helper_bisr(CPUTriCoreState
*env
, uint32_t const9
)
605 target_ulong tmp_FCX
;
607 target_ulong new_FCX
;
614 ea
= ((env
->FCX
& 0xf0000) << 12) + ((env
->FCX
& 0xffff) << 6);
616 /* new_FCX = M(EA, word); */
617 new_FCX
= cpu_ldl_data(env
, ea
);
618 /* M(EA, 16 * word) = {PCXI, A[11], A[2], A[3], D[0], D[1], D[2], D[3], A[4]
619 , A[5], A[6], A[7], D[4], D[5], D[6], D[7]}; */
620 save_context_lower(env
, ea
);
623 /* PCXI.PCPN = ICR.CCPN */
624 env
->PCXI
= (env
->PCXI
& 0xffffff) +
625 ((env
->ICR
& MASK_ICR_CCPN
) << 24);
626 /* PCXI.PIE = ICR.IE */
627 env
->PCXI
= ((env
->PCXI
& ~MASK_PCXI_PIE
) +
628 ((env
->ICR
& MASK_ICR_IE
) << 15));
630 env
->PCXI
&= ~(MASK_PCXI_UL
);
631 /* PCXI[19: 0] = FCX[19: 0] */
632 env
->PCXI
= (env
->PCXI
& 0xfff00000) + (env
->FCX
& 0xfffff);
633 /* FXC[19: 0] = new_FCX[19: 0] */
634 env
->FCX
= (env
->FCX
& 0xfff00000) + (new_FCX
& 0xfffff);
636 env
->ICR
|= MASK_ICR_IE
;
638 env
->ICR
|= const9
; /* ICR.CCPN = const9[7: 0];*/
640 if (tmp_FCX
== env
->LCX
) {
645 void helper_rfe(CPUTriCoreState
*env
)
648 target_ulong new_PCXI
;
649 target_ulong new_PSW
;
650 /* if (PCXI[19: 0] == 0) then trap(CSU); */
651 if ((env
->PCXI
& 0xfffff) == 0) {
654 /* if (PCXI.UL == 0) then trap(CTYP); */
655 if ((env
->PCXI
& MASK_PCXI_UL
) == 0) {
656 /* raise CTYP trap */
658 /* if (!cdc_zero() AND PSW.CDE) then trap(NEST); */
659 if (!cdc_zero(&(env
->PSW
)) && (env
->PSW
& MASK_PSW_CDE
)) {
662 /* ICR.IE = PCXI.PIE; */
663 env
->ICR
= (env
->ICR
& ~MASK_ICR_IE
) + ((env
->PCXI
& MASK_PCXI_PIE
) >> 15);
664 /* ICR.CCPN = PCXI.PCPN; */
665 env
->ICR
= (env
->ICR
& ~MASK_ICR_CCPN
) +
666 ((env
->PCXI
& MASK_PCXI_PCPN
) >> 24);
667 /*EA = {PCXI.PCXS, 6'b0, PCXI.PCXO, 6'b0};*/
668 ea
= ((env
->PCXI
& MASK_PCXI_PCXS
) << 12) +
669 ((env
->PCXI
& MASK_PCXI_PCXO
) << 6);
670 /*{new_PCXI, PSW, A[10], A[11], D[8], D[9], D[10], D[11], A[12],
671 A[13], A[14], A[15], D[12], D[13], D[14], D[15]} = M(EA, 16 * word); */
672 restore_context_upper(env
, ea
, &new_PCXI
, &new_PSW
);
673 /* M(EA, word) = FCX;*/
674 cpu_stl_data(env
, ea
, env
->FCX
);
675 /* FCX[19: 0] = PCXI[19: 0]; */
676 env
->FCX
= (env
->FCX
& 0xfff00000) + (env
->PCXI
& 0x000fffff);
677 /* PCXI = new_PCXI; */
678 env
->PCXI
= new_PCXI
;
680 psw_write(env
, new_PSW
);
683 void helper_ldlcx(CPUTriCoreState
*env
, uint32_t ea
)
686 /* insn doesn't load PCXI and RA */
687 restore_context_lower(env
, ea
, &dummy
, &dummy
);
690 void helper_lducx(CPUTriCoreState
*env
, uint32_t ea
)
693 /* insn doesn't load PCXI and PSW */
694 restore_context_upper(env
, ea
, &dummy
, &dummy
);
697 void helper_stlcx(CPUTriCoreState
*env
, uint32_t ea
)
699 save_context_lower(env
, ea
);
702 void helper_stucx(CPUTriCoreState
*env
, uint32_t ea
)
704 save_context_upper(env
, ea
);
707 void helper_psw_write(CPUTriCoreState
*env
, uint32_t arg
)
712 uint32_t helper_psw_read(CPUTriCoreState
*env
)
714 return psw_read(env
);
718 static inline void QEMU_NORETURN
do_raise_exception_err(CPUTriCoreState
*env
,
723 CPUState
*cs
= CPU(tricore_env_get_cpu(env
));
724 cs
->exception_index
= exception
;
725 env
->error_code
= error_code
;
728 /* now we have a real cpu fault */
729 cpu_restore_state(cs
, pc
);
735 void tlb_fill(CPUState
*cs
, target_ulong addr
, int is_write
, int mmu_idx
,
739 ret
= cpu_tricore_handle_mmu_fault(cs
, addr
, is_write
, mmu_idx
);
741 TriCoreCPU
*cpu
= TRICORE_CPU(cs
);
742 CPUTriCoreState
*env
= &cpu
->env
;
743 do_raise_exception_err(env
, cs
->exception_index
,
744 env
->error_code
, retaddr
);