1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include "qemu/osdep.h"
20#include "qemu/main-loop.h"
21#include "cpu.h"
22#include "exec/helper-proto.h"
23#include "internals.h"
24#include "exec/exec-all.h"
25#include "exec/cpu_ldst.h"
26
27#define SIGNBIT (uint32_t)0x80000000
28#define SIGNBIT64 ((uint64_t)1 << 63)
29
30void raise_exception(CPUARMState *env, uint32_t excp,
31 uint32_t syndrome, uint32_t target_el)
32{
33 CPUState *cs = env_cpu(env);
34
35 if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
36
37
38
39
40
41
42 target_el = 2;
43 if (syn_get_ec(syndrome) == EC_ADVSIMDFPACCESSTRAP) {
44 syndrome = syn_uncategorized();
45 }
46 }
47
48 assert(!excp_is_internal(excp));
49 cs->exception_index = excp;
50 env->exception.syndrome = syndrome;
51 env->exception.target_el = target_el;
52 cpu_loop_exit(cs);
53}
54
55void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
56 uint32_t target_el, uintptr_t ra)
57{
58 CPUState *cs = env_cpu(env);
59
60
61
62
63
64
65 cpu_restore_state(cs, ra, true);
66 raise_exception(env, excp, syndrome, target_el);
67}
68
69uint64_t HELPER(neon_tbl)(CPUARMState *env, uint32_t desc,
70 uint64_t ireg, uint64_t def)
71{
72 uint64_t tmp, val = 0;
73 uint32_t maxindex = ((desc & 3) + 1) * 8;
74 uint32_t base_reg = desc >> 2;
75 uint32_t shift, index, reg;
76
77 for (shift = 0; shift < 64; shift += 8) {
78 index = (ireg >> shift) & 0xff;
79 if (index < maxindex) {
80 reg = base_reg + (index >> 3);
81 tmp = *aa32_vfp_dreg(env, reg);
82 tmp = ((tmp >> ((index & 7) << 3)) & 0xff) << shift;
83 } else {
84 tmp = def & (0xffull << shift);
85 }
86 val |= tmp;
87 }
88 return val;
89}
90
91void HELPER(v8m_stackcheck)(CPUARMState *env, uint32_t newvalue)
92{
93
94
95
96
97 if (newvalue < v7m_sp_limit(env)) {
98
99
100
101
102
103 raise_exception_ra(env, EXCP_STKOF, 0, 1, GETPC());
104 }
105}
106
107uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
108{
109 uint32_t res = a + b;
110 if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
111 env->QF = 1;
112 return res;
113}
114
115uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
116{
117 uint32_t res = a + b;
118 if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
119 env->QF = 1;
120 res = ~(((int32_t)a >> 31) ^ SIGNBIT);
121 }
122 return res;
123}
124
125uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
126{
127 uint32_t res = a - b;
128 if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
129 env->QF = 1;
130 res = ~(((int32_t)a >> 31) ^ SIGNBIT);
131 }
132 return res;
133}
134
135uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
136{
137 uint32_t res = a + b;
138 if (res < a) {
139 env->QF = 1;
140 res = ~0;
141 }
142 return res;
143}
144
145uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
146{
147 uint32_t res = a - b;
148 if (res > a) {
149 env->QF = 1;
150 res = 0;
151 }
152 return res;
153}
154
155
156static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift)
157{
158 int32_t top;
159 uint32_t mask;
160
161 top = val >> shift;
162 mask = (1u << shift) - 1;
163 if (top > 0) {
164 env->QF = 1;
165 return mask;
166 } else if (top < -1) {
167 env->QF = 1;
168 return ~mask;
169 }
170 return val;
171}
172
173
174static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift)
175{
176 uint32_t max;
177
178 max = (1u << shift) - 1;
179 if (val < 0) {
180 env->QF = 1;
181 return 0;
182 } else if (val > max) {
183 env->QF = 1;
184 return max;
185 }
186 return val;
187}
188
189
190uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift)
191{
192 return do_ssat(env, x, shift);
193}
194
195
196uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift)
197{
198 uint32_t res;
199
200 res = (uint16_t)do_ssat(env, (int16_t)x, shift);
201 res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16;
202 return res;
203}
204
205
206uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift)
207{
208 return do_usat(env, x, shift);
209}
210
211
212uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
213{
214 uint32_t res;
215
216 res = (uint16_t)do_usat(env, (int16_t)x, shift);
217 res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16;
218 return res;
219}
220
221void HELPER(setend)(CPUARMState *env)
222{
223 env->uncached_cpsr ^= CPSR_E;
224 arm_rebuild_hflags(env);
225}
226
227void HELPER(check_bxj_trap)(CPUARMState *env, uint32_t rm)
228{
229
230
231
232
233 if (env->cp15.hstr_el2 & HSTR_TJDBX) {
234
235
236
237
238 uint32_t syn = syn_bxjtrap(1, 0xe, rm);
239 raise_exception_ra(env, EXCP_HYP_TRAP, syn, 2, GETPC());
240 }
241}
242
243#ifndef CONFIG_USER_ONLY
244
245
246
247
248static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
249{
250 int cur_el = arm_current_el(env);
251 uint64_t mask;
252
253 if (arm_feature(env, ARM_FEATURE_M)) {
254
255 return 0;
256 }
257
258
259
260
261 if (cur_el < 1 && arm_feature(env, ARM_FEATURE_V8)) {
262 int target_el;
263
264 mask = is_wfe ? SCTLR_nTWE : SCTLR_nTWI;
265 if (arm_is_secure_below_el3(env) && !arm_el_is_aa64(env, 3)) {
266
267 target_el = 3;
268 } else {
269 target_el = 1;
270 }
271
272 if (!(env->cp15.sctlr_el[target_el] & mask)) {
273 return target_el;
274 }
275 }
276
277
278
279
280
281 if (cur_el < 2) {
282 mask = is_wfe ? HCR_TWE : HCR_TWI;
283 if (arm_hcr_el2_eff(env) & mask) {
284 return 2;
285 }
286 }
287
288
289 if (cur_el < 3) {
290 mask = (is_wfe) ? SCR_TWE : SCR_TWI;
291 if (env->cp15.scr_el3 & mask) {
292 return 3;
293 }
294 }
295
296 return 0;
297}
298#endif
299
300void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
301{
302#ifdef CONFIG_USER_ONLY
303
304
305
306
307
308
309
310
311 return;
312#else
313 CPUState *cs = env_cpu(env);
314 int target_el = check_wfx_trap(env, false);
315
316 if (cpu_has_work(cs)) {
317
318
319
320 return;
321 }
322
323 if (target_el) {
324 if (env->aarch64) {
325 env->pc -= insn_len;
326 } else {
327 env->regs[15] -= insn_len;
328 }
329
330 raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2),
331 target_el);
332 }
333
334 cs->exception_index = EXCP_HLT;
335 cs->halted = 1;
336 cpu_loop_exit(cs);
337#endif
338}
339
340void HELPER(wfe)(CPUARMState *env)
341{
342
343
344
345
346
347
348
349 HELPER(yield)(env);
350}
351
352void HELPER(yield)(CPUARMState *env)
353{
354 CPUState *cs = env_cpu(env);
355
356
357
358
359
360 cs->exception_index = EXCP_YIELD;
361 cpu_loop_exit(cs);
362}
363
364
365
366
367
368
369
370void HELPER(exception_internal)(CPUARMState *env, uint32_t excp)
371{
372 CPUState *cs = env_cpu(env);
373
374 assert(excp_is_internal(excp));
375 cs->exception_index = excp;
376 cpu_loop_exit(cs);
377}
378
379
380void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
381 uint32_t syndrome, uint32_t target_el)
382{
383 raise_exception(env, excp, syndrome, target_el);
384}
385
386
387
388
389void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
390{
391 int debug_el = arm_debug_target_el(env);
392 int cur_el = arm_current_el(env);
393
394
395 env->exception.fsr = arm_debug_exception_fsr(env);
396
397
398
399
400 env->exception.vaddress = 0;
401
402
403
404
405
406
407
408
409 if (debug_el < cur_el) {
410 debug_el = cur_el;
411 }
412 raise_exception(env, EXCP_BKPT, syndrome, debug_el);
413}
414
415uint32_t HELPER(cpsr_read)(CPUARMState *env)
416{
417 return cpsr_read(env) & ~CPSR_EXEC;
418}
419
420void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
421{
422 cpsr_write(env, val, mask, CPSRWriteByInstr);
423
424 arm_rebuild_hflags(env);
425}
426
427
428void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
429{
430 uint32_t mask;
431
432 qemu_mutex_lock_iothread();
433 arm_call_pre_el_change_hook(env_archcpu(env));
434 qemu_mutex_unlock_iothread();
435
436 mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar);
437 cpsr_write(env, val, mask, CPSRWriteExceptionReturn);
438
439
440
441
442
443
444 env->regs[15] &= (env->thumb ? ~1 : ~3);
445 arm_rebuild_hflags(env);
446
447 qemu_mutex_lock_iothread();
448 arm_call_el_change_hook(env_archcpu(env));
449 qemu_mutex_unlock_iothread();
450}
451
452
453uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
454{
455 uint32_t val;
456
457 if (regno == 13) {
458 val = env->banked_r13[BANK_USRSYS];
459 } else if (regno == 14) {
460 val = env->banked_r14[BANK_USRSYS];
461 } else if (regno >= 8
462 && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
463 val = env->usr_regs[regno - 8];
464 } else {
465 val = env->regs[regno];
466 }
467 return val;
468}
469
470void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
471{
472 if (regno == 13) {
473 env->banked_r13[BANK_USRSYS] = val;
474 } else if (regno == 14) {
475 env->banked_r14[BANK_USRSYS] = val;
476 } else if (regno >= 8
477 && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
478 env->usr_regs[regno - 8] = val;
479 } else {
480 env->regs[regno] = val;
481 }
482}
483
484void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
485{
486 if ((env->uncached_cpsr & CPSR_M) == mode) {
487 env->regs[13] = val;
488 } else {
489 env->banked_r13[bank_number(mode)] = val;
490 }
491}
492
493uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
494{
495 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SYS) {
496
497
498
499 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
500 exception_target_el(env));
501 }
502
503 if ((env->uncached_cpsr & CPSR_M) == mode) {
504 return env->regs[13];
505 } else {
506 return env->banked_r13[bank_number(mode)];
507 }
508}
509
510static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
511 uint32_t regno)
512{
513
514
515
516
517
518 int curmode = env->uncached_cpsr & CPSR_M;
519
520 if (regno == 17) {
521
522 if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
523 goto undef;
524 }
525 return;
526 }
527
528 if (curmode == tgtmode) {
529 goto undef;
530 }
531
532 if (tgtmode == ARM_CPU_MODE_USR) {
533 switch (regno) {
534 case 8 ... 12:
535 if (curmode != ARM_CPU_MODE_FIQ) {
536 goto undef;
537 }
538 break;
539 case 13:
540 if (curmode == ARM_CPU_MODE_SYS) {
541 goto undef;
542 }
543 break;
544 case 14:
545 if (curmode == ARM_CPU_MODE_HYP || curmode == ARM_CPU_MODE_SYS) {
546 goto undef;
547 }
548 break;
549 default:
550 break;
551 }
552 }
553
554 if (tgtmode == ARM_CPU_MODE_HYP) {
555
556 if (curmode != ARM_CPU_MODE_MON) {
557 goto undef;
558 }
559 }
560
561 return;
562
563undef:
564 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
565 exception_target_el(env));
566}
567
568void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
569 uint32_t regno)
570{
571 msr_mrs_banked_exc_checks(env, tgtmode, regno);
572
573 switch (regno) {
574 case 16:
575 env->banked_spsr[bank_number(tgtmode)] = value;
576 break;
577 case 17:
578 env->elr_el[2] = value;
579 break;
580 case 13:
581 env->banked_r13[bank_number(tgtmode)] = value;
582 break;
583 case 14:
584 env->banked_r14[r14_bank_number(tgtmode)] = value;
585 break;
586 case 8 ... 12:
587 switch (tgtmode) {
588 case ARM_CPU_MODE_USR:
589 env->usr_regs[regno - 8] = value;
590 break;
591 case ARM_CPU_MODE_FIQ:
592 env->fiq_regs[regno - 8] = value;
593 break;
594 default:
595 g_assert_not_reached();
596 }
597 break;
598 default:
599 g_assert_not_reached();
600 }
601}
602
603uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
604{
605 msr_mrs_banked_exc_checks(env, tgtmode, regno);
606
607 switch (regno) {
608 case 16:
609 return env->banked_spsr[bank_number(tgtmode)];
610 case 17:
611 return env->elr_el[2];
612 case 13:
613 return env->banked_r13[bank_number(tgtmode)];
614 case 14:
615 return env->banked_r14[r14_bank_number(tgtmode)];
616 case 8 ... 12:
617 switch (tgtmode) {
618 case ARM_CPU_MODE_USR:
619 return env->usr_regs[regno - 8];
620 case ARM_CPU_MODE_FIQ:
621 return env->fiq_regs[regno - 8];
622 default:
623 g_assert_not_reached();
624 }
625 default:
626 g_assert_not_reached();
627 }
628}
629
630void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
631 uint32_t isread)
632{
633 const ARMCPRegInfo *ri = rip;
634 int target_el;
635
636 if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
637 && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
638 raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
639 }
640
641
642
643
644
645 if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
646 (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
647 uint32_t mask = 1 << ri->crn;
648
649 if (ri->type & ARM_CP_64BIT) {
650 mask = 1 << ri->crm;
651 }
652
653
654 mask &= ~((1 << 4) | (1 << 14));
655
656 if (env->cp15.hstr_el2 & mask) {
657 target_el = 2;
658 goto exept;
659 }
660 }
661
662 if (!ri->accessfn) {
663 return;
664 }
665
666 switch (ri->accessfn(env, ri, isread)) {
667 case CP_ACCESS_OK:
668 return;
669 case CP_ACCESS_TRAP:
670 target_el = exception_target_el(env);
671 break;
672 case CP_ACCESS_TRAP_EL2:
673
674
675
676 assert(arm_current_el(env) != 3);
677 target_el = 2;
678 break;
679 case CP_ACCESS_TRAP_EL3:
680 target_el = 3;
681 break;
682 case CP_ACCESS_TRAP_UNCATEGORIZED:
683 target_el = exception_target_el(env);
684 syndrome = syn_uncategorized();
685 break;
686 case CP_ACCESS_TRAP_UNCATEGORIZED_EL2:
687 target_el = 2;
688 syndrome = syn_uncategorized();
689 break;
690 case CP_ACCESS_TRAP_UNCATEGORIZED_EL3:
691 target_el = 3;
692 syndrome = syn_uncategorized();
693 break;
694 case CP_ACCESS_TRAP_FP_EL2:
695 target_el = 2;
696
697
698
699
700
701 syndrome = syn_fp_access_trap(1, 0xe, false);
702 break;
703 case CP_ACCESS_TRAP_FP_EL3:
704 target_el = 3;
705 syndrome = syn_fp_access_trap(1, 0xe, false);
706 break;
707 default:
708 g_assert_not_reached();
709 }
710
711exept:
712 raise_exception(env, EXCP_UDEF, syndrome, target_el);
713}
714
715void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
716{
717 const ARMCPRegInfo *ri = rip;
718
719 if (ri->type & ARM_CP_IO) {
720 qemu_mutex_lock_iothread();
721 ri->writefn(env, ri, value);
722 qemu_mutex_unlock_iothread();
723 } else {
724 ri->writefn(env, ri, value);
725 }
726}
727
728uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
729{
730 const ARMCPRegInfo *ri = rip;
731 uint32_t res;
732
733 if (ri->type & ARM_CP_IO) {
734 qemu_mutex_lock_iothread();
735 res = ri->readfn(env, ri);
736 qemu_mutex_unlock_iothread();
737 } else {
738 res = ri->readfn(env, ri);
739 }
740
741 return res;
742}
743
744void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
745{
746 const ARMCPRegInfo *ri = rip;
747
748 if (ri->type & ARM_CP_IO) {
749 qemu_mutex_lock_iothread();
750 ri->writefn(env, ri, value);
751 qemu_mutex_unlock_iothread();
752 } else {
753 ri->writefn(env, ri, value);
754 }
755}
756
757uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
758{
759 const ARMCPRegInfo *ri = rip;
760 uint64_t res;
761
762 if (ri->type & ARM_CP_IO) {
763 qemu_mutex_lock_iothread();
764 res = ri->readfn(env, ri);
765 qemu_mutex_unlock_iothread();
766 } else {
767 res = ri->readfn(env, ri);
768 }
769
770 return res;
771}
772
773void HELPER(pre_hvc)(CPUARMState *env)
774{
775 ARMCPU *cpu = env_archcpu(env);
776 int cur_el = arm_current_el(env);
777
778 bool secure = false;
779 bool undef;
780
781 if (arm_is_psci_call(cpu, EXCP_HVC)) {
782
783
784
785 return;
786 }
787
788 if (!arm_feature(env, ARM_FEATURE_EL2)) {
789
790 undef = true;
791 } else if (arm_feature(env, ARM_FEATURE_EL3)) {
792
793 undef = !(env->cp15.scr_el3 & SCR_HCE);
794 } else {
795 undef = env->cp15.hcr_el2 & HCR_HCD;
796 }
797
798
799
800
801
802
803 if (secure && (!is_a64(env) || cur_el == 1)) {
804 undef = true;
805 }
806
807 if (undef) {
808 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
809 exception_target_el(env));
810 }
811}
812
813void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
814{
815 ARMCPU *cpu = env_archcpu(env);
816 int cur_el = arm_current_el(env);
817 bool secure = arm_is_secure(env);
818 bool smd_flag = env->cp15.scr_el3 & SCR_SMD;
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857 bool smd = arm_feature(env, ARM_FEATURE_AARCH64) ? smd_flag
858 : smd_flag && !secure;
859
860 if (!arm_feature(env, ARM_FEATURE_EL3) &&
861 cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
862
863
864
865
866
867
868
869
870 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
871 exception_target_el(env));
872 }
873
874 if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) {
875
876
877
878
879
880 raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
881 }
882
883
884
885
886
887 if (!arm_is_psci_call(cpu, EXCP_SMC) &&
888 (smd || !arm_feature(env, ARM_FEATURE_EL3))) {
889 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
890 exception_target_el(env));
891 }
892}
893
894
895
896
897
898
899
900uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
901{
902 int shift = i & 0xff;
903 if (shift >= 32) {
904 if (shift == 32)
905 env->CF = x & 1;
906 else
907 env->CF = 0;
908 return 0;
909 } else if (shift != 0) {
910 env->CF = (x >> (32 - shift)) & 1;
911 return x << shift;
912 }
913 return x;
914}
915
916uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i)
917{
918 int shift = i & 0xff;
919 if (shift >= 32) {
920 if (shift == 32)
921 env->CF = (x >> 31) & 1;
922 else
923 env->CF = 0;
924 return 0;
925 } else if (shift != 0) {
926 env->CF = (x >> (shift - 1)) & 1;
927 return x >> shift;
928 }
929 return x;
930}
931
932uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i)
933{
934 int shift = i & 0xff;
935 if (shift >= 32) {
936 env->CF = (x >> 31) & 1;
937 return (int32_t)x >> 31;
938 } else if (shift != 0) {
939 env->CF = (x >> (shift - 1)) & 1;
940 return (int32_t)x >> shift;
941 }
942 return x;
943}
944
945uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
946{
947 int shift1, shift;
948 shift1 = i & 0xff;
949 shift = shift1 & 0x1f;
950 if (shift == 0) {
951 if (shift1 != 0)
952 env->CF = (x >> 31) & 1;
953 return x;
954 } else {
955 env->CF = (x >> (shift - 1)) & 1;
956 return ((uint32_t)x >> shift) | (x << (32 - shift));
957 }
958}
959
960void HELPER(probe_access)(CPUARMState *env, target_ulong ptr,
961 uint32_t access_type, uint32_t mmu_idx,
962 uint32_t size)
963{
964 uint32_t in_page = -((uint32_t)ptr | TARGET_PAGE_SIZE);
965 uintptr_t ra = GETPC();
966
967 if (likely(size <= in_page)) {
968 probe_access(env, ptr, size, access_type, mmu_idx, ra);
969 } else {
970 probe_access(env, ptr, in_page, access_type, mmu_idx, ra);
971 probe_access(env, ptr + in_page, size - in_page,
972 access_type, mmu_idx, ra);
973 }
974}
975