target/arm: Convert Neon VCVT fixed-point to gvec
[qemu.git] / target / arm / op_helper.c
1 /*
2 * ARM helper routines
3 *
4 * Copyright (c) 2005-2007 CodeSourcery, LLC
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18 */
19 #include "qemu/osdep.h"
20 #include "qemu/log.h"
21 #include "qemu/main-loop.h"
22 #include "cpu.h"
23 #include "exec/helper-proto.h"
24 #include "internals.h"
25 #include "exec/exec-all.h"
26 #include "exec/cpu_ldst.h"
27
28 #define SIGNBIT (uint32_t)0x80000000
29 #define SIGNBIT64 ((uint64_t)1 << 63)
30
31 static CPUState *do_raise_exception(CPUARMState *env, uint32_t excp,
32 uint32_t syndrome, uint32_t target_el)
33 {
34 CPUState *cs = env_cpu(env);
35
36 if (target_el == 1 && (arm_hcr_el2_eff(env) & HCR_TGE)) {
37 /*
38 * Redirect NS EL1 exceptions to NS EL2. These are reported with
39 * their original syndrome register value, with the exception of
40 * SIMD/FP access traps, which are reported as uncategorized
41 * (see DDI0478C.a D1.10.4)
42 */
43 target_el = 2;
44 if (syn_get_ec(syndrome) == EC_ADVSIMDFPACCESSTRAP) {
45 syndrome = syn_uncategorized();
46 }
47 }
48
49 assert(!excp_is_internal(excp));
50 cs->exception_index = excp;
51 env->exception.syndrome = syndrome;
52 env->exception.target_el = target_el;
53
54 return cs;
55 }
56
57 void raise_exception(CPUARMState *env, uint32_t excp,
58 uint32_t syndrome, uint32_t target_el)
59 {
60 CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
61 cpu_loop_exit(cs);
62 }
63
64 void raise_exception_ra(CPUARMState *env, uint32_t excp, uint32_t syndrome,
65 uint32_t target_el, uintptr_t ra)
66 {
67 CPUState *cs = do_raise_exception(env, excp, syndrome, target_el);
68 cpu_loop_exit_restore(cs, ra);
69 }
70
71 uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def, void *vn,
72 uint32_t maxindex)
73 {
74 uint32_t val, shift;
75 uint64_t *table = vn;
76
77 val = 0;
78 for (shift = 0; shift < 32; shift += 8) {
79 uint32_t index = (ireg >> shift) & 0xff;
80 if (index < maxindex) {
81 uint32_t tmp = (table[index >> 3] >> ((index & 7) << 3)) & 0xff;
82 val |= tmp << shift;
83 } else {
84 val |= def & (0xff << shift);
85 }
86 }
87 return val;
88 }
89
90 void HELPER(v8m_stackcheck)(CPUARMState *env, uint32_t newvalue)
91 {
92 /*
93 * Perform the v8M stack limit check for SP updates from translated code,
94 * raising an exception if the limit is breached.
95 */
96 if (newvalue < v7m_sp_limit(env)) {
97 CPUState *cs = env_cpu(env);
98
99 /*
100 * Stack limit exceptions are a rare case, so rather than syncing
101 * PC/condbits before the call, we use cpu_restore_state() to
102 * get them right before raising the exception.
103 */
104 cpu_restore_state(cs, GETPC(), true);
105 raise_exception(env, EXCP_STKOF, 0, 1);
106 }
107 }
108
109 uint32_t HELPER(add_setq)(CPUARMState *env, uint32_t a, uint32_t b)
110 {
111 uint32_t res = a + b;
112 if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT))
113 env->QF = 1;
114 return res;
115 }
116
117 uint32_t HELPER(add_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
118 {
119 uint32_t res = a + b;
120 if (((res ^ a) & SIGNBIT) && !((a ^ b) & SIGNBIT)) {
121 env->QF = 1;
122 res = ~(((int32_t)a >> 31) ^ SIGNBIT);
123 }
124 return res;
125 }
126
127 uint32_t HELPER(sub_saturate)(CPUARMState *env, uint32_t a, uint32_t b)
128 {
129 uint32_t res = a - b;
130 if (((res ^ a) & SIGNBIT) && ((a ^ b) & SIGNBIT)) {
131 env->QF = 1;
132 res = ~(((int32_t)a >> 31) ^ SIGNBIT);
133 }
134 return res;
135 }
136
137 uint32_t HELPER(add_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
138 {
139 uint32_t res = a + b;
140 if (res < a) {
141 env->QF = 1;
142 res = ~0;
143 }
144 return res;
145 }
146
147 uint32_t HELPER(sub_usaturate)(CPUARMState *env, uint32_t a, uint32_t b)
148 {
149 uint32_t res = a - b;
150 if (res > a) {
151 env->QF = 1;
152 res = 0;
153 }
154 return res;
155 }
156
157 /* Signed saturation. */
158 static inline uint32_t do_ssat(CPUARMState *env, int32_t val, int shift)
159 {
160 int32_t top;
161 uint32_t mask;
162
163 top = val >> shift;
164 mask = (1u << shift) - 1;
165 if (top > 0) {
166 env->QF = 1;
167 return mask;
168 } else if (top < -1) {
169 env->QF = 1;
170 return ~mask;
171 }
172 return val;
173 }
174
175 /* Unsigned saturation. */
176 static inline uint32_t do_usat(CPUARMState *env, int32_t val, int shift)
177 {
178 uint32_t max;
179
180 max = (1u << shift) - 1;
181 if (val < 0) {
182 env->QF = 1;
183 return 0;
184 } else if (val > max) {
185 env->QF = 1;
186 return max;
187 }
188 return val;
189 }
190
191 /* Signed saturate. */
192 uint32_t HELPER(ssat)(CPUARMState *env, uint32_t x, uint32_t shift)
193 {
194 return do_ssat(env, x, shift);
195 }
196
197 /* Dual halfword signed saturate. */
198 uint32_t HELPER(ssat16)(CPUARMState *env, uint32_t x, uint32_t shift)
199 {
200 uint32_t res;
201
202 res = (uint16_t)do_ssat(env, (int16_t)x, shift);
203 res |= do_ssat(env, ((int32_t)x) >> 16, shift) << 16;
204 return res;
205 }
206
207 /* Unsigned saturate. */
208 uint32_t HELPER(usat)(CPUARMState *env, uint32_t x, uint32_t shift)
209 {
210 return do_usat(env, x, shift);
211 }
212
213 /* Dual halfword unsigned saturate. */
214 uint32_t HELPER(usat16)(CPUARMState *env, uint32_t x, uint32_t shift)
215 {
216 uint32_t res;
217
218 res = (uint16_t)do_usat(env, (int16_t)x, shift);
219 res |= do_usat(env, ((int32_t)x) >> 16, shift) << 16;
220 return res;
221 }
222
223 void HELPER(setend)(CPUARMState *env)
224 {
225 env->uncached_cpsr ^= CPSR_E;
226 arm_rebuild_hflags(env);
227 }
228
229 /* Function checks whether WFx (WFI/WFE) instructions are set up to be trapped.
230 * The function returns the target EL (1-3) if the instruction is to be trapped;
231 * otherwise it returns 0 indicating it is not trapped.
232 */
233 static inline int check_wfx_trap(CPUARMState *env, bool is_wfe)
234 {
235 int cur_el = arm_current_el(env);
236 uint64_t mask;
237
238 if (arm_feature(env, ARM_FEATURE_M)) {
239 /* M profile cores can never trap WFI/WFE. */
240 return 0;
241 }
242
243 /* If we are currently in EL0 then we need to check if SCTLR is set up for
244 * WFx instructions being trapped to EL1. These trap bits don't exist in v7.
245 */
246 if (cur_el < 1 && arm_feature(env, ARM_FEATURE_V8)) {
247 int target_el;
248
249 mask = is_wfe ? SCTLR_nTWE : SCTLR_nTWI;
250 if (arm_is_secure_below_el3(env) && !arm_el_is_aa64(env, 3)) {
251 /* Secure EL0 and Secure PL1 is at EL3 */
252 target_el = 3;
253 } else {
254 target_el = 1;
255 }
256
257 if (!(env->cp15.sctlr_el[target_el] & mask)) {
258 return target_el;
259 }
260 }
261
262 /* We are not trapping to EL1; trap to EL2 if HCR_EL2 requires it
263 * No need for ARM_FEATURE check as if HCR_EL2 doesn't exist the
264 * bits will be zero indicating no trap.
265 */
266 if (cur_el < 2) {
267 mask = is_wfe ? HCR_TWE : HCR_TWI;
268 if (arm_hcr_el2_eff(env) & mask) {
269 return 2;
270 }
271 }
272
273 /* We are not trapping to EL1 or EL2; trap to EL3 if SCR_EL3 requires it */
274 if (cur_el < 3) {
275 mask = (is_wfe) ? SCR_TWE : SCR_TWI;
276 if (env->cp15.scr_el3 & mask) {
277 return 3;
278 }
279 }
280
281 return 0;
282 }
283
284 void HELPER(wfi)(CPUARMState *env, uint32_t insn_len)
285 {
286 CPUState *cs = env_cpu(env);
287 int target_el = check_wfx_trap(env, false);
288
289 if (cpu_has_work(cs)) {
290 /* Don't bother to go into our "low power state" if
291 * we would just wake up immediately.
292 */
293 return;
294 }
295
296 if (target_el) {
297 if (env->aarch64) {
298 env->pc -= insn_len;
299 } else {
300 env->regs[15] -= insn_len;
301 }
302
303 raise_exception(env, EXCP_UDEF, syn_wfx(1, 0xe, 0, insn_len == 2),
304 target_el);
305 }
306
307 cs->exception_index = EXCP_HLT;
308 cs->halted = 1;
309 cpu_loop_exit(cs);
310 }
311
312 void HELPER(wfe)(CPUARMState *env)
313 {
314 /* This is a hint instruction that is semantically different
315 * from YIELD even though we currently implement it identically.
316 * Don't actually halt the CPU, just yield back to top
317 * level loop. This is not going into a "low power state"
318 * (ie halting until some event occurs), so we never take
319 * a configurable trap to a different exception level.
320 */
321 HELPER(yield)(env);
322 }
323
324 void HELPER(yield)(CPUARMState *env)
325 {
326 CPUState *cs = env_cpu(env);
327
328 /* This is a non-trappable hint instruction that generally indicates
329 * that the guest is currently busy-looping. Yield control back to the
330 * top level loop so that a more deserving VCPU has a chance to run.
331 */
332 cs->exception_index = EXCP_YIELD;
333 cpu_loop_exit(cs);
334 }
335
336 /* Raise an internal-to-QEMU exception. This is limited to only
337 * those EXCP values which are special cases for QEMU to interrupt
338 * execution and not to be used for exceptions which are passed to
339 * the guest (those must all have syndrome information and thus should
340 * use exception_with_syndrome).
341 */
342 void HELPER(exception_internal)(CPUARMState *env, uint32_t excp)
343 {
344 CPUState *cs = env_cpu(env);
345
346 assert(excp_is_internal(excp));
347 cs->exception_index = excp;
348 cpu_loop_exit(cs);
349 }
350
351 /* Raise an exception with the specified syndrome register value */
352 void HELPER(exception_with_syndrome)(CPUARMState *env, uint32_t excp,
353 uint32_t syndrome, uint32_t target_el)
354 {
355 raise_exception(env, excp, syndrome, target_el);
356 }
357
358 /* Raise an EXCP_BKPT with the specified syndrome register value,
359 * targeting the correct exception level for debug exceptions.
360 */
361 void HELPER(exception_bkpt_insn)(CPUARMState *env, uint32_t syndrome)
362 {
363 int debug_el = arm_debug_target_el(env);
364 int cur_el = arm_current_el(env);
365
366 /* FSR will only be used if the debug target EL is AArch32. */
367 env->exception.fsr = arm_debug_exception_fsr(env);
368 /* FAR is UNKNOWN: clear vaddress to avoid potentially exposing
369 * values to the guest that it shouldn't be able to see at its
370 * exception/security level.
371 */
372 env->exception.vaddress = 0;
373 /*
374 * Other kinds of architectural debug exception are ignored if
375 * they target an exception level below the current one (in QEMU
376 * this is checked by arm_generate_debug_exceptions()). Breakpoint
377 * instructions are special because they always generate an exception
378 * to somewhere: if they can't go to the configured debug exception
379 * level they are taken to the current exception level.
380 */
381 if (debug_el < cur_el) {
382 debug_el = cur_el;
383 }
384 raise_exception(env, EXCP_BKPT, syndrome, debug_el);
385 }
386
387 uint32_t HELPER(cpsr_read)(CPUARMState *env)
388 {
389 /*
390 * We store the ARMv8 PSTATE.SS bit in env->uncached_cpsr.
391 * This is convenient for populating SPSR_ELx, but must be
392 * hidden from aarch32 mode, where it is not visible.
393 *
394 * TODO: ARMv8.4-DIT -- need to move SS somewhere else.
395 */
396 return cpsr_read(env) & ~(CPSR_EXEC | PSTATE_SS);
397 }
398
399 void HELPER(cpsr_write)(CPUARMState *env, uint32_t val, uint32_t mask)
400 {
401 cpsr_write(env, val, mask, CPSRWriteByInstr);
402 /* TODO: Not all cpsr bits are relevant to hflags. */
403 arm_rebuild_hflags(env);
404 }
405
406 /* Write the CPSR for a 32-bit exception return */
407 void HELPER(cpsr_write_eret)(CPUARMState *env, uint32_t val)
408 {
409 uint32_t mask;
410
411 qemu_mutex_lock_iothread();
412 arm_call_pre_el_change_hook(env_archcpu(env));
413 qemu_mutex_unlock_iothread();
414
415 mask = aarch32_cpsr_valid_mask(env->features, &env_archcpu(env)->isar);
416 cpsr_write(env, val, mask, CPSRWriteExceptionReturn);
417
418 /* Generated code has already stored the new PC value, but
419 * without masking out its low bits, because which bits need
420 * masking depends on whether we're returning to Thumb or ARM
421 * state. Do the masking now.
422 */
423 env->regs[15] &= (env->thumb ? ~1 : ~3);
424 arm_rebuild_hflags(env);
425
426 qemu_mutex_lock_iothread();
427 arm_call_el_change_hook(env_archcpu(env));
428 qemu_mutex_unlock_iothread();
429 }
430
431 /* Access to user mode registers from privileged modes. */
432 uint32_t HELPER(get_user_reg)(CPUARMState *env, uint32_t regno)
433 {
434 uint32_t val;
435
436 if (regno == 13) {
437 val = env->banked_r13[BANK_USRSYS];
438 } else if (regno == 14) {
439 val = env->banked_r14[BANK_USRSYS];
440 } else if (regno >= 8
441 && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
442 val = env->usr_regs[regno - 8];
443 } else {
444 val = env->regs[regno];
445 }
446 return val;
447 }
448
449 void HELPER(set_user_reg)(CPUARMState *env, uint32_t regno, uint32_t val)
450 {
451 if (regno == 13) {
452 env->banked_r13[BANK_USRSYS] = val;
453 } else if (regno == 14) {
454 env->banked_r14[BANK_USRSYS] = val;
455 } else if (regno >= 8
456 && (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_FIQ) {
457 env->usr_regs[regno - 8] = val;
458 } else {
459 env->regs[regno] = val;
460 }
461 }
462
463 void HELPER(set_r13_banked)(CPUARMState *env, uint32_t mode, uint32_t val)
464 {
465 if ((env->uncached_cpsr & CPSR_M) == mode) {
466 env->regs[13] = val;
467 } else {
468 env->banked_r13[bank_number(mode)] = val;
469 }
470 }
471
472 uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
473 {
474 if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_SYS) {
475 /* SRS instruction is UNPREDICTABLE from System mode; we UNDEF.
476 * Other UNPREDICTABLE and UNDEF cases were caught at translate time.
477 */
478 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
479 exception_target_el(env));
480 }
481
482 if ((env->uncached_cpsr & CPSR_M) == mode) {
483 return env->regs[13];
484 } else {
485 return env->banked_r13[bank_number(mode)];
486 }
487 }
488
489 static void msr_mrs_banked_exc_checks(CPUARMState *env, uint32_t tgtmode,
490 uint32_t regno)
491 {
492 /* Raise an exception if the requested access is one of the UNPREDICTABLE
493 * cases; otherwise return. This broadly corresponds to the pseudocode
494 * BankedRegisterAccessValid() and SPSRAccessValid(),
495 * except that we have already handled some cases at translate time.
496 */
497 int curmode = env->uncached_cpsr & CPSR_M;
498
499 if (regno == 17) {
500 /* ELR_Hyp: a special case because access from tgtmode is OK */
501 if (curmode != ARM_CPU_MODE_HYP && curmode != ARM_CPU_MODE_MON) {
502 goto undef;
503 }
504 return;
505 }
506
507 if (curmode == tgtmode) {
508 goto undef;
509 }
510
511 if (tgtmode == ARM_CPU_MODE_USR) {
512 switch (regno) {
513 case 8 ... 12:
514 if (curmode != ARM_CPU_MODE_FIQ) {
515 goto undef;
516 }
517 break;
518 case 13:
519 if (curmode == ARM_CPU_MODE_SYS) {
520 goto undef;
521 }
522 break;
523 case 14:
524 if (curmode == ARM_CPU_MODE_HYP || curmode == ARM_CPU_MODE_SYS) {
525 goto undef;
526 }
527 break;
528 default:
529 break;
530 }
531 }
532
533 if (tgtmode == ARM_CPU_MODE_HYP) {
534 /* SPSR_Hyp, r13_hyp: accessible from Monitor mode only */
535 if (curmode != ARM_CPU_MODE_MON) {
536 goto undef;
537 }
538 }
539
540 return;
541
542 undef:
543 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
544 exception_target_el(env));
545 }
546
547 void HELPER(msr_banked)(CPUARMState *env, uint32_t value, uint32_t tgtmode,
548 uint32_t regno)
549 {
550 msr_mrs_banked_exc_checks(env, tgtmode, regno);
551
552 switch (regno) {
553 case 16: /* SPSRs */
554 env->banked_spsr[bank_number(tgtmode)] = value;
555 break;
556 case 17: /* ELR_Hyp */
557 env->elr_el[2] = value;
558 break;
559 case 13:
560 env->banked_r13[bank_number(tgtmode)] = value;
561 break;
562 case 14:
563 env->banked_r14[r14_bank_number(tgtmode)] = value;
564 break;
565 case 8 ... 12:
566 switch (tgtmode) {
567 case ARM_CPU_MODE_USR:
568 env->usr_regs[regno - 8] = value;
569 break;
570 case ARM_CPU_MODE_FIQ:
571 env->fiq_regs[regno - 8] = value;
572 break;
573 default:
574 g_assert_not_reached();
575 }
576 break;
577 default:
578 g_assert_not_reached();
579 }
580 }
581
582 uint32_t HELPER(mrs_banked)(CPUARMState *env, uint32_t tgtmode, uint32_t regno)
583 {
584 msr_mrs_banked_exc_checks(env, tgtmode, regno);
585
586 switch (regno) {
587 case 16: /* SPSRs */
588 return env->banked_spsr[bank_number(tgtmode)];
589 case 17: /* ELR_Hyp */
590 return env->elr_el[2];
591 case 13:
592 return env->banked_r13[bank_number(tgtmode)];
593 case 14:
594 return env->banked_r14[r14_bank_number(tgtmode)];
595 case 8 ... 12:
596 switch (tgtmode) {
597 case ARM_CPU_MODE_USR:
598 return env->usr_regs[regno - 8];
599 case ARM_CPU_MODE_FIQ:
600 return env->fiq_regs[regno - 8];
601 default:
602 g_assert_not_reached();
603 }
604 default:
605 g_assert_not_reached();
606 }
607 }
608
609 void HELPER(access_check_cp_reg)(CPUARMState *env, void *rip, uint32_t syndrome,
610 uint32_t isread)
611 {
612 const ARMCPRegInfo *ri = rip;
613 int target_el;
614
615 if (arm_feature(env, ARM_FEATURE_XSCALE) && ri->cp < 14
616 && extract32(env->cp15.c15_cpar, ri->cp, 1) == 0) {
617 raise_exception(env, EXCP_UDEF, syndrome, exception_target_el(env));
618 }
619
620 /*
621 * Check for an EL2 trap due to HSTR_EL2. We expect EL0 accesses
622 * to sysregs non accessible at EL0 to have UNDEF-ed already.
623 */
624 if (!is_a64(env) && arm_current_el(env) < 2 && ri->cp == 15 &&
625 (arm_hcr_el2_eff(env) & (HCR_E2H | HCR_TGE)) != (HCR_E2H | HCR_TGE)) {
626 uint32_t mask = 1 << ri->crn;
627
628 if (ri->type & ARM_CP_64BIT) {
629 mask = 1 << ri->crm;
630 }
631
632 /* T4 and T14 are RES0 */
633 mask &= ~((1 << 4) | (1 << 14));
634
635 if (env->cp15.hstr_el2 & mask) {
636 target_el = 2;
637 goto exept;
638 }
639 }
640
641 if (!ri->accessfn) {
642 return;
643 }
644
645 switch (ri->accessfn(env, ri, isread)) {
646 case CP_ACCESS_OK:
647 return;
648 case CP_ACCESS_TRAP:
649 target_el = exception_target_el(env);
650 break;
651 case CP_ACCESS_TRAP_EL2:
652 /* Requesting a trap to EL2 when we're in EL3 or S-EL0/1 is
653 * a bug in the access function.
654 */
655 assert(!arm_is_secure(env) && arm_current_el(env) != 3);
656 target_el = 2;
657 break;
658 case CP_ACCESS_TRAP_EL3:
659 target_el = 3;
660 break;
661 case CP_ACCESS_TRAP_UNCATEGORIZED:
662 target_el = exception_target_el(env);
663 syndrome = syn_uncategorized();
664 break;
665 case CP_ACCESS_TRAP_UNCATEGORIZED_EL2:
666 target_el = 2;
667 syndrome = syn_uncategorized();
668 break;
669 case CP_ACCESS_TRAP_UNCATEGORIZED_EL3:
670 target_el = 3;
671 syndrome = syn_uncategorized();
672 break;
673 case CP_ACCESS_TRAP_FP_EL2:
674 target_el = 2;
675 /* Since we are an implementation that takes exceptions on a trapped
676 * conditional insn only if the insn has passed its condition code
677 * check, we take the IMPDEF choice to always report CV=1 COND=0xe
678 * (which is also the required value for AArch64 traps).
679 */
680 syndrome = syn_fp_access_trap(1, 0xe, false);
681 break;
682 case CP_ACCESS_TRAP_FP_EL3:
683 target_el = 3;
684 syndrome = syn_fp_access_trap(1, 0xe, false);
685 break;
686 default:
687 g_assert_not_reached();
688 }
689
690 exept:
691 raise_exception(env, EXCP_UDEF, syndrome, target_el);
692 }
693
694 void HELPER(set_cp_reg)(CPUARMState *env, void *rip, uint32_t value)
695 {
696 const ARMCPRegInfo *ri = rip;
697
698 if (ri->type & ARM_CP_IO) {
699 qemu_mutex_lock_iothread();
700 ri->writefn(env, ri, value);
701 qemu_mutex_unlock_iothread();
702 } else {
703 ri->writefn(env, ri, value);
704 }
705 }
706
707 uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)
708 {
709 const ARMCPRegInfo *ri = rip;
710 uint32_t res;
711
712 if (ri->type & ARM_CP_IO) {
713 qemu_mutex_lock_iothread();
714 res = ri->readfn(env, ri);
715 qemu_mutex_unlock_iothread();
716 } else {
717 res = ri->readfn(env, ri);
718 }
719
720 return res;
721 }
722
723 void HELPER(set_cp_reg64)(CPUARMState *env, void *rip, uint64_t value)
724 {
725 const ARMCPRegInfo *ri = rip;
726
727 if (ri->type & ARM_CP_IO) {
728 qemu_mutex_lock_iothread();
729 ri->writefn(env, ri, value);
730 qemu_mutex_unlock_iothread();
731 } else {
732 ri->writefn(env, ri, value);
733 }
734 }
735
736 uint64_t HELPER(get_cp_reg64)(CPUARMState *env, void *rip)
737 {
738 const ARMCPRegInfo *ri = rip;
739 uint64_t res;
740
741 if (ri->type & ARM_CP_IO) {
742 qemu_mutex_lock_iothread();
743 res = ri->readfn(env, ri);
744 qemu_mutex_unlock_iothread();
745 } else {
746 res = ri->readfn(env, ri);
747 }
748
749 return res;
750 }
751
752 void HELPER(pre_hvc)(CPUARMState *env)
753 {
754 ARMCPU *cpu = env_archcpu(env);
755 int cur_el = arm_current_el(env);
756 /* FIXME: Use actual secure state. */
757 bool secure = false;
758 bool undef;
759
760 if (arm_is_psci_call(cpu, EXCP_HVC)) {
761 /* If PSCI is enabled and this looks like a valid PSCI call then
762 * that overrides the architecturally mandated HVC behaviour.
763 */
764 return;
765 }
766
767 if (!arm_feature(env, ARM_FEATURE_EL2)) {
768 /* If EL2 doesn't exist, HVC always UNDEFs */
769 undef = true;
770 } else if (arm_feature(env, ARM_FEATURE_EL3)) {
771 /* EL3.HCE has priority over EL2.HCD. */
772 undef = !(env->cp15.scr_el3 & SCR_HCE);
773 } else {
774 undef = env->cp15.hcr_el2 & HCR_HCD;
775 }
776
777 /* In ARMv7 and ARMv8/AArch32, HVC is undef in secure state.
778 * For ARMv8/AArch64, HVC is allowed in EL3.
779 * Note that we've already trapped HVC from EL0 at translation
780 * time.
781 */
782 if (secure && (!is_a64(env) || cur_el == 1)) {
783 undef = true;
784 }
785
786 if (undef) {
787 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
788 exception_target_el(env));
789 }
790 }
791
792 void HELPER(pre_smc)(CPUARMState *env, uint32_t syndrome)
793 {
794 ARMCPU *cpu = env_archcpu(env);
795 int cur_el = arm_current_el(env);
796 bool secure = arm_is_secure(env);
797 bool smd_flag = env->cp15.scr_el3 & SCR_SMD;
798
799 /*
800 * SMC behaviour is summarized in the following table.
801 * This helper handles the "Trap to EL2" and "Undef insn" cases.
802 * The "Trap to EL3" and "PSCI call" cases are handled in the exception
803 * helper.
804 *
805 * -> ARM_FEATURE_EL3 and !SMD
806 * HCR_TSC && NS EL1 !HCR_TSC || !NS EL1
807 *
808 * Conduit SMC, valid call Trap to EL2 PSCI Call
809 * Conduit SMC, inval call Trap to EL2 Trap to EL3
810 * Conduit not SMC Trap to EL2 Trap to EL3
811 *
812 *
813 * -> ARM_FEATURE_EL3 and SMD
814 * HCR_TSC && NS EL1 !HCR_TSC || !NS EL1
815 *
816 * Conduit SMC, valid call Trap to EL2 PSCI Call
817 * Conduit SMC, inval call Trap to EL2 Undef insn
818 * Conduit not SMC Trap to EL2 Undef insn
819 *
820 *
821 * -> !ARM_FEATURE_EL3
822 * HCR_TSC && NS EL1 !HCR_TSC || !NS EL1
823 *
824 * Conduit SMC, valid call Trap to EL2 PSCI Call
825 * Conduit SMC, inval call Trap to EL2 Undef insn
826 * Conduit not SMC Undef insn Undef insn
827 */
828
829 /* On ARMv8 with EL3 AArch64, SMD applies to both S and NS state.
830 * On ARMv8 with EL3 AArch32, or ARMv7 with the Virtualization
831 * extensions, SMD only applies to NS state.
832 * On ARMv7 without the Virtualization extensions, the SMD bit
833 * doesn't exist, but we forbid the guest to set it to 1 in scr_write(),
834 * so we need not special case this here.
835 */
836 bool smd = arm_feature(env, ARM_FEATURE_AARCH64) ? smd_flag
837 : smd_flag && !secure;
838
839 if (!arm_feature(env, ARM_FEATURE_EL3) &&
840 cpu->psci_conduit != QEMU_PSCI_CONDUIT_SMC) {
841 /* If we have no EL3 then SMC always UNDEFs and can't be
842 * trapped to EL2. PSCI-via-SMC is a sort of ersatz EL3
843 * firmware within QEMU, and we want an EL2 guest to be able
844 * to forbid its EL1 from making PSCI calls into QEMU's
845 * "firmware" via HCR.TSC, so for these purposes treat
846 * PSCI-via-SMC as implying an EL3.
847 * This handles the very last line of the previous table.
848 */
849 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
850 exception_target_el(env));
851 }
852
853 if (cur_el == 1 && (arm_hcr_el2_eff(env) & HCR_TSC)) {
854 /* In NS EL1, HCR controlled routing to EL2 has priority over SMD.
855 * We also want an EL2 guest to be able to forbid its EL1 from
856 * making PSCI calls into QEMU's "firmware" via HCR.TSC.
857 * This handles all the "Trap to EL2" cases of the previous table.
858 */
859 raise_exception(env, EXCP_HYP_TRAP, syndrome, 2);
860 }
861
862 /* Catch the two remaining "Undef insn" cases of the previous table:
863 * - PSCI conduit is SMC but we don't have a valid PCSI call,
864 * - We don't have EL3 or SMD is set.
865 */
866 if (!arm_is_psci_call(cpu, EXCP_SMC) &&
867 (smd || !arm_feature(env, ARM_FEATURE_EL3))) {
868 raise_exception(env, EXCP_UDEF, syn_uncategorized(),
869 exception_target_el(env));
870 }
871 }
872
873 /* ??? Flag setting arithmetic is awkward because we need to do comparisons.
874 The only way to do that in TCG is a conditional branch, which clobbers
875 all our temporaries. For now implement these as helper functions. */
876
877 /* Similarly for variable shift instructions. */
878
879 uint32_t HELPER(shl_cc)(CPUARMState *env, uint32_t x, uint32_t i)
880 {
881 int shift = i & 0xff;
882 if (shift >= 32) {
883 if (shift == 32)
884 env->CF = x & 1;
885 else
886 env->CF = 0;
887 return 0;
888 } else if (shift != 0) {
889 env->CF = (x >> (32 - shift)) & 1;
890 return x << shift;
891 }
892 return x;
893 }
894
895 uint32_t HELPER(shr_cc)(CPUARMState *env, uint32_t x, uint32_t i)
896 {
897 int shift = i & 0xff;
898 if (shift >= 32) {
899 if (shift == 32)
900 env->CF = (x >> 31) & 1;
901 else
902 env->CF = 0;
903 return 0;
904 } else if (shift != 0) {
905 env->CF = (x >> (shift - 1)) & 1;
906 return x >> shift;
907 }
908 return x;
909 }
910
911 uint32_t HELPER(sar_cc)(CPUARMState *env, uint32_t x, uint32_t i)
912 {
913 int shift = i & 0xff;
914 if (shift >= 32) {
915 env->CF = (x >> 31) & 1;
916 return (int32_t)x >> 31;
917 } else if (shift != 0) {
918 env->CF = (x >> (shift - 1)) & 1;
919 return (int32_t)x >> shift;
920 }
921 return x;
922 }
923
924 uint32_t HELPER(ror_cc)(CPUARMState *env, uint32_t x, uint32_t i)
925 {
926 int shift1, shift;
927 shift1 = i & 0xff;
928 shift = shift1 & 0x1f;
929 if (shift == 0) {
930 if (shift1 != 0)
931 env->CF = (x >> 31) & 1;
932 return x;
933 } else {
934 env->CF = (x >> (shift - 1)) & 1;
935 return ((uint32_t)x >> shift) | (x << (32 - shift));
936 }
937 }
938
939 void HELPER(probe_access)(CPUARMState *env, target_ulong ptr,
940 uint32_t access_type, uint32_t mmu_idx,
941 uint32_t size)
942 {
943 uint32_t in_page = -((uint32_t)ptr | TARGET_PAGE_SIZE);
944 uintptr_t ra = GETPC();
945
946 if (likely(size <= in_page)) {
947 probe_access(env, ptr, size, access_type, mmu_idx, ra);
948 } else {
949 probe_access(env, ptr, in_page, access_type, mmu_idx, ra);
950 probe_access(env, ptr + in_page, size - in_page,
951 access_type, mmu_idx, ra);
952 }
953 }