4 #include "host-utils.h"
7 static int vfp_gdb_get_reg(CPUARMState
*env
, uint8_t *buf
, int reg
)
11 /* VFP data registers are always little-endian. */
12 nregs
= arm_feature(env
, ARM_FEATURE_VFP3
) ? 32 : 16;
14 stfq_le_p(buf
, env
->vfp
.regs
[reg
]);
17 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
18 /* Aliases for Q regs. */
21 stfq_le_p(buf
, env
->vfp
.regs
[(reg
- 32) * 2]);
22 stfq_le_p(buf
+ 8, env
->vfp
.regs
[(reg
- 32) * 2 + 1]);
26 switch (reg
- nregs
) {
27 case 0: stl_p(buf
, env
->vfp
.xregs
[ARM_VFP_FPSID
]); return 4;
28 case 1: stl_p(buf
, env
->vfp
.xregs
[ARM_VFP_FPSCR
]); return 4;
29 case 2: stl_p(buf
, env
->vfp
.xregs
[ARM_VFP_FPEXC
]); return 4;
34 static int vfp_gdb_set_reg(CPUARMState
*env
, uint8_t *buf
, int reg
)
38 nregs
= arm_feature(env
, ARM_FEATURE_VFP3
) ? 32 : 16;
40 env
->vfp
.regs
[reg
] = ldfq_le_p(buf
);
43 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
46 env
->vfp
.regs
[(reg
- 32) * 2] = ldfq_le_p(buf
);
47 env
->vfp
.regs
[(reg
- 32) * 2 + 1] = ldfq_le_p(buf
+ 8);
51 switch (reg
- nregs
) {
52 case 0: env
->vfp
.xregs
[ARM_VFP_FPSID
] = ldl_p(buf
); return 4;
53 case 1: env
->vfp
.xregs
[ARM_VFP_FPSCR
] = ldl_p(buf
); return 4;
54 case 2: env
->vfp
.xregs
[ARM_VFP_FPEXC
] = ldl_p(buf
) & (1 << 30); return 4;
59 ARMCPU
*cpu_arm_init(const char *cpu_model
)
63 static int inited
= 0;
65 if (!object_class_by_name(cpu_model
)) {
68 cpu
= ARM_CPU(object_new(cpu_model
));
70 env
->cpu_model_str
= cpu_model
;
73 if (tcg_enabled() && !inited
) {
79 if (arm_feature(env
, ARM_FEATURE_NEON
)) {
80 gdb_register_coprocessor(env
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
81 51, "arm-neon.xml", 0);
82 } else if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
83 gdb_register_coprocessor(env
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
84 35, "arm-vfp3.xml", 0);
85 } else if (arm_feature(env
, ARM_FEATURE_VFP
)) {
86 gdb_register_coprocessor(env
, vfp_gdb_get_reg
, vfp_gdb_set_reg
,
87 19, "arm-vfp.xml", 0);
93 typedef struct ARMCPUListState
{
94 fprintf_function cpu_fprintf
;
98 /* Sort alphabetically by type name, except for "any". */
99 static gint
arm_cpu_list_compare(gconstpointer a
, gconstpointer b
)
101 ObjectClass
*class_a
= (ObjectClass
*)a
;
102 ObjectClass
*class_b
= (ObjectClass
*)b
;
103 const char *name_a
, *name_b
;
105 name_a
= object_class_get_name(class_a
);
106 name_b
= object_class_get_name(class_b
);
107 if (strcmp(name_a
, "any") == 0) {
109 } else if (strcmp(name_b
, "any") == 0) {
112 return strcmp(name_a
, name_b
);
116 static void arm_cpu_list_entry(gpointer data
, gpointer user_data
)
118 ObjectClass
*oc
= data
;
119 ARMCPUListState
*s
= user_data
;
121 (*s
->cpu_fprintf
)(s
->file
, " %s\n",
122 object_class_get_name(oc
));
125 void arm_cpu_list(FILE *f
, fprintf_function cpu_fprintf
)
127 ARMCPUListState s
= {
129 .cpu_fprintf
= cpu_fprintf
,
133 list
= object_class_get_list(TYPE_ARM_CPU
, false);
134 list
= g_slist_sort(list
, arm_cpu_list_compare
);
135 (*cpu_fprintf
)(f
, "Available CPUs:\n");
136 g_slist_foreach(list
, arm_cpu_list_entry
, &s
);
140 static int bad_mode_switch(CPUARMState
*env
, int mode
)
142 /* Return true if it is not valid for us to switch to
143 * this CPU mode (ie all the UNPREDICTABLE cases in
144 * the ARM ARM CPSRWriteByInstr pseudocode).
147 case ARM_CPU_MODE_USR
:
148 case ARM_CPU_MODE_SYS
:
149 case ARM_CPU_MODE_SVC
:
150 case ARM_CPU_MODE_ABT
:
151 case ARM_CPU_MODE_UND
:
152 case ARM_CPU_MODE_IRQ
:
153 case ARM_CPU_MODE_FIQ
:
160 uint32_t cpsr_read(CPUARMState
*env
)
164 return env
->uncached_cpsr
| (env
->NF
& 0x80000000) | (ZF
<< 30) |
165 (env
->CF
<< 29) | ((env
->VF
& 0x80000000) >> 3) | (env
->QF
<< 27)
166 | (env
->thumb
<< 5) | ((env
->condexec_bits
& 3) << 25)
167 | ((env
->condexec_bits
& 0xfc) << 8)
171 void cpsr_write(CPUARMState
*env
, uint32_t val
, uint32_t mask
)
173 if (mask
& CPSR_NZCV
) {
174 env
->ZF
= (~val
) & CPSR_Z
;
176 env
->CF
= (val
>> 29) & 1;
177 env
->VF
= (val
<< 3) & 0x80000000;
180 env
->QF
= ((val
& CPSR_Q
) != 0);
182 env
->thumb
= ((val
& CPSR_T
) != 0);
183 if (mask
& CPSR_IT_0_1
) {
184 env
->condexec_bits
&= ~3;
185 env
->condexec_bits
|= (val
>> 25) & 3;
187 if (mask
& CPSR_IT_2_7
) {
188 env
->condexec_bits
&= 3;
189 env
->condexec_bits
|= (val
>> 8) & 0xfc;
191 if (mask
& CPSR_GE
) {
192 env
->GE
= (val
>> 16) & 0xf;
195 if ((env
->uncached_cpsr
^ val
) & mask
& CPSR_M
) {
196 if (bad_mode_switch(env
, val
& CPSR_M
)) {
197 /* Attempt to switch to an invalid mode: this is UNPREDICTABLE.
198 * We choose to ignore the attempt and leave the CPSR M field
203 switch_mode(env
, val
& CPSR_M
);
206 mask
&= ~CACHED_CPSR_BITS
;
207 env
->uncached_cpsr
= (env
->uncached_cpsr
& ~mask
) | (val
& mask
);
210 /* Sign/zero extend */
211 uint32_t HELPER(sxtb16
)(uint32_t x
)
214 res
= (uint16_t)(int8_t)x
;
215 res
|= (uint32_t)(int8_t)(x
>> 16) << 16;
219 uint32_t HELPER(uxtb16
)(uint32_t x
)
222 res
= (uint16_t)(uint8_t)x
;
223 res
|= (uint32_t)(uint8_t)(x
>> 16) << 16;
227 uint32_t HELPER(clz
)(uint32_t x
)
232 int32_t HELPER(sdiv
)(int32_t num
, int32_t den
)
236 if (num
== INT_MIN
&& den
== -1)
241 uint32_t HELPER(udiv
)(uint32_t num
, uint32_t den
)
248 uint32_t HELPER(rbit
)(uint32_t x
)
250 x
= ((x
& 0xff000000) >> 24)
251 | ((x
& 0x00ff0000) >> 8)
252 | ((x
& 0x0000ff00) << 8)
253 | ((x
& 0x000000ff) << 24);
254 x
= ((x
& 0xf0f0f0f0) >> 4)
255 | ((x
& 0x0f0f0f0f) << 4);
256 x
= ((x
& 0x88888888) >> 3)
257 | ((x
& 0x44444444) >> 1)
258 | ((x
& 0x22222222) << 1)
259 | ((x
& 0x11111111) << 3);
263 uint32_t HELPER(abs
)(uint32_t x
)
265 return ((int32_t)x
< 0) ? -x
: x
;
268 #if defined(CONFIG_USER_ONLY)
270 void do_interrupt (CPUARMState
*env
)
272 env
->exception_index
= -1;
275 int cpu_arm_handle_mmu_fault (CPUARMState
*env
, target_ulong address
, int rw
,
279 env
->exception_index
= EXCP_PREFETCH_ABORT
;
280 env
->cp15
.c6_insn
= address
;
282 env
->exception_index
= EXCP_DATA_ABORT
;
283 env
->cp15
.c6_data
= address
;
288 /* These should probably raise undefined insn exceptions. */
289 void HELPER(set_cp
)(CPUARMState
*env
, uint32_t insn
, uint32_t val
)
291 int op1
= (insn
>> 8) & 0xf;
292 cpu_abort(env
, "cp%i insn %08x\n", op1
, insn
);
296 uint32_t HELPER(get_cp
)(CPUARMState
*env
, uint32_t insn
)
298 int op1
= (insn
>> 8) & 0xf;
299 cpu_abort(env
, "cp%i insn %08x\n", op1
, insn
);
303 void HELPER(set_cp15
)(CPUARMState
*env
, uint32_t insn
, uint32_t val
)
305 cpu_abort(env
, "cp15 insn %08x\n", insn
);
308 uint32_t HELPER(get_cp15
)(CPUARMState
*env
, uint32_t insn
)
310 cpu_abort(env
, "cp15 insn %08x\n", insn
);
313 /* These should probably raise undefined insn exceptions. */
314 void HELPER(v7m_msr
)(CPUARMState
*env
, uint32_t reg
, uint32_t val
)
316 cpu_abort(env
, "v7m_mrs %d\n", reg
);
319 uint32_t HELPER(v7m_mrs
)(CPUARMState
*env
, uint32_t reg
)
321 cpu_abort(env
, "v7m_mrs %d\n", reg
);
325 void switch_mode(CPUARMState
*env
, int mode
)
327 if (mode
!= ARM_CPU_MODE_USR
)
328 cpu_abort(env
, "Tried to switch out of user mode\n");
331 void HELPER(set_r13_banked
)(CPUARMState
*env
, uint32_t mode
, uint32_t val
)
333 cpu_abort(env
, "banked r13 write\n");
336 uint32_t HELPER(get_r13_banked
)(CPUARMState
*env
, uint32_t mode
)
338 cpu_abort(env
, "banked r13 read\n");
344 /* Map CPU modes onto saved register banks. */
345 static inline int bank_number(CPUARMState
*env
, int mode
)
348 case ARM_CPU_MODE_USR
:
349 case ARM_CPU_MODE_SYS
:
351 case ARM_CPU_MODE_SVC
:
353 case ARM_CPU_MODE_ABT
:
355 case ARM_CPU_MODE_UND
:
357 case ARM_CPU_MODE_IRQ
:
359 case ARM_CPU_MODE_FIQ
:
362 cpu_abort(env
, "Bad mode %x\n", mode
);
366 void switch_mode(CPUARMState
*env
, int mode
)
371 old_mode
= env
->uncached_cpsr
& CPSR_M
;
372 if (mode
== old_mode
)
375 if (old_mode
== ARM_CPU_MODE_FIQ
) {
376 memcpy (env
->fiq_regs
, env
->regs
+ 8, 5 * sizeof(uint32_t));
377 memcpy (env
->regs
+ 8, env
->usr_regs
, 5 * sizeof(uint32_t));
378 } else if (mode
== ARM_CPU_MODE_FIQ
) {
379 memcpy (env
->usr_regs
, env
->regs
+ 8, 5 * sizeof(uint32_t));
380 memcpy (env
->regs
+ 8, env
->fiq_regs
, 5 * sizeof(uint32_t));
383 i
= bank_number(env
, old_mode
);
384 env
->banked_r13
[i
] = env
->regs
[13];
385 env
->banked_r14
[i
] = env
->regs
[14];
386 env
->banked_spsr
[i
] = env
->spsr
;
388 i
= bank_number(env
, mode
);
389 env
->regs
[13] = env
->banked_r13
[i
];
390 env
->regs
[14] = env
->banked_r14
[i
];
391 env
->spsr
= env
->banked_spsr
[i
];
394 static void v7m_push(CPUARMState
*env
, uint32_t val
)
397 stl_phys(env
->regs
[13], val
);
400 static uint32_t v7m_pop(CPUARMState
*env
)
403 val
= ldl_phys(env
->regs
[13]);
408 /* Switch to V7M main or process stack pointer. */
409 static void switch_v7m_sp(CPUARMState
*env
, int process
)
412 if (env
->v7m
.current_sp
!= process
) {
413 tmp
= env
->v7m
.other_sp
;
414 env
->v7m
.other_sp
= env
->regs
[13];
416 env
->v7m
.current_sp
= process
;
420 static void do_v7m_exception_exit(CPUARMState
*env
)
425 type
= env
->regs
[15];
426 if (env
->v7m
.exception
!= 0)
427 armv7m_nvic_complete_irq(env
->nvic
, env
->v7m
.exception
);
429 /* Switch to the target stack. */
430 switch_v7m_sp(env
, (type
& 4) != 0);
432 env
->regs
[0] = v7m_pop(env
);
433 env
->regs
[1] = v7m_pop(env
);
434 env
->regs
[2] = v7m_pop(env
);
435 env
->regs
[3] = v7m_pop(env
);
436 env
->regs
[12] = v7m_pop(env
);
437 env
->regs
[14] = v7m_pop(env
);
438 env
->regs
[15] = v7m_pop(env
);
440 xpsr_write(env
, xpsr
, 0xfffffdff);
441 /* Undo stack alignment. */
444 /* ??? The exception return type specifies Thread/Handler mode. However
445 this is also implied by the xPSR value. Not sure what to do
446 if there is a mismatch. */
447 /* ??? Likewise for mismatches between the CONTROL register and the stack
451 static void do_interrupt_v7m(CPUARMState
*env
)
453 uint32_t xpsr
= xpsr_read(env
);
458 if (env
->v7m
.current_sp
)
460 if (env
->v7m
.exception
== 0)
463 /* For exceptions we just mark as pending on the NVIC, and let that
465 /* TODO: Need to escalate if the current priority is higher than the
466 one we're raising. */
467 switch (env
->exception_index
) {
469 armv7m_nvic_set_pending(env
->nvic
, ARMV7M_EXCP_USAGE
);
473 armv7m_nvic_set_pending(env
->nvic
, ARMV7M_EXCP_SVC
);
475 case EXCP_PREFETCH_ABORT
:
476 case EXCP_DATA_ABORT
:
477 armv7m_nvic_set_pending(env
->nvic
, ARMV7M_EXCP_MEM
);
480 if (semihosting_enabled
) {
482 nr
= arm_lduw_code(env
->regs
[15], env
->bswap_code
) & 0xff;
485 env
->regs
[0] = do_arm_semihosting(env
);
489 armv7m_nvic_set_pending(env
->nvic
, ARMV7M_EXCP_DEBUG
);
492 env
->v7m
.exception
= armv7m_nvic_acknowledge_irq(env
->nvic
);
494 case EXCP_EXCEPTION_EXIT
:
495 do_v7m_exception_exit(env
);
498 cpu_abort(env
, "Unhandled exception 0x%x\n", env
->exception_index
);
499 return; /* Never happens. Keep compiler happy. */
502 /* Align stack pointer. */
503 /* ??? Should only do this if Configuration Control Register
504 STACKALIGN bit is set. */
505 if (env
->regs
[13] & 4) {
509 /* Switch to the handler mode. */
511 v7m_push(env
, env
->regs
[15]);
512 v7m_push(env
, env
->regs
[14]);
513 v7m_push(env
, env
->regs
[12]);
514 v7m_push(env
, env
->regs
[3]);
515 v7m_push(env
, env
->regs
[2]);
516 v7m_push(env
, env
->regs
[1]);
517 v7m_push(env
, env
->regs
[0]);
518 switch_v7m_sp(env
, 0);
520 env
->condexec_bits
= 0;
522 addr
= ldl_phys(env
->v7m
.vecbase
+ env
->v7m
.exception
* 4);
523 env
->regs
[15] = addr
& 0xfffffffe;
524 env
->thumb
= addr
& 1;
527 /* Handle a CPU exception. */
528 void do_interrupt(CPUARMState
*env
)
536 do_interrupt_v7m(env
);
539 /* TODO: Vectored interrupt controller. */
540 switch (env
->exception_index
) {
542 new_mode
= ARM_CPU_MODE_UND
;
551 if (semihosting_enabled
) {
552 /* Check for semihosting interrupt. */
554 mask
= arm_lduw_code(env
->regs
[15] - 2, env
->bswap_code
) & 0xff;
556 mask
= arm_ldl_code(env
->regs
[15] - 4, env
->bswap_code
)
559 /* Only intercept calls from privileged modes, to provide some
560 semblance of security. */
561 if (((mask
== 0x123456 && !env
->thumb
)
562 || (mask
== 0xab && env
->thumb
))
563 && (env
->uncached_cpsr
& CPSR_M
) != ARM_CPU_MODE_USR
) {
564 env
->regs
[0] = do_arm_semihosting(env
);
568 new_mode
= ARM_CPU_MODE_SVC
;
571 /* The PC already points to the next instruction. */
575 /* See if this is a semihosting syscall. */
576 if (env
->thumb
&& semihosting_enabled
) {
577 mask
= arm_lduw_code(env
->regs
[15], env
->bswap_code
) & 0xff;
579 && (env
->uncached_cpsr
& CPSR_M
) != ARM_CPU_MODE_USR
) {
581 env
->regs
[0] = do_arm_semihosting(env
);
585 env
->cp15
.c5_insn
= 2;
586 /* Fall through to prefetch abort. */
587 case EXCP_PREFETCH_ABORT
:
588 new_mode
= ARM_CPU_MODE_ABT
;
590 mask
= CPSR_A
| CPSR_I
;
593 case EXCP_DATA_ABORT
:
594 new_mode
= ARM_CPU_MODE_ABT
;
596 mask
= CPSR_A
| CPSR_I
;
600 new_mode
= ARM_CPU_MODE_IRQ
;
602 /* Disable IRQ and imprecise data aborts. */
603 mask
= CPSR_A
| CPSR_I
;
607 new_mode
= ARM_CPU_MODE_FIQ
;
609 /* Disable FIQ, IRQ and imprecise data aborts. */
610 mask
= CPSR_A
| CPSR_I
| CPSR_F
;
614 cpu_abort(env
, "Unhandled exception 0x%x\n", env
->exception_index
);
615 return; /* Never happens. Keep compiler happy. */
618 if (env
->cp15
.c1_sys
& (1 << 13)) {
621 switch_mode (env
, new_mode
);
622 env
->spsr
= cpsr_read(env
);
624 env
->condexec_bits
= 0;
625 /* Switch to the new mode, and to the correct instruction set. */
626 env
->uncached_cpsr
= (env
->uncached_cpsr
& ~CPSR_M
) | new_mode
;
627 env
->uncached_cpsr
|= mask
;
628 /* this is a lie, as the was no c1_sys on V4T/V5, but who cares
629 * and we should just guard the thumb mode on V4 */
630 if (arm_feature(env
, ARM_FEATURE_V4T
)) {
631 env
->thumb
= (env
->cp15
.c1_sys
& (1 << 30)) != 0;
633 env
->regs
[14] = env
->regs
[15] + offset
;
634 env
->regs
[15] = addr
;
635 env
->interrupt_request
|= CPU_INTERRUPT_EXITTB
;
638 /* Check section/page access permissions.
639 Returns the page protection flags, or zero if the access is not
641 static inline int check_ap(CPUARMState
*env
, int ap
, int domain_prot
,
642 int access_type
, int is_user
)
646 if (domain_prot
== 3) {
647 return PAGE_READ
| PAGE_WRITE
;
650 if (access_type
== 1)
657 if (access_type
== 1)
659 switch ((env
->cp15
.c1_sys
>> 8) & 3) {
661 return is_user
? 0 : PAGE_READ
;
668 return is_user
? 0 : PAGE_READ
| PAGE_WRITE
;
673 return PAGE_READ
| PAGE_WRITE
;
675 return PAGE_READ
| PAGE_WRITE
;
676 case 4: /* Reserved. */
679 return is_user
? 0 : prot_ro
;
683 if (!arm_feature (env
, ARM_FEATURE_V6K
))
691 static uint32_t get_level1_table_address(CPUARMState
*env
, uint32_t address
)
695 if (address
& env
->cp15
.c2_mask
)
696 table
= env
->cp15
.c2_base1
& 0xffffc000;
698 table
= env
->cp15
.c2_base0
& env
->cp15
.c2_base_mask
;
700 table
|= (address
>> 18) & 0x3ffc;
704 static int get_phys_addr_v5(CPUARMState
*env
, uint32_t address
, int access_type
,
705 int is_user
, uint32_t *phys_ptr
, int *prot
,
706 target_ulong
*page_size
)
717 /* Pagetable walk. */
718 /* Lookup l1 descriptor. */
719 table
= get_level1_table_address(env
, address
);
720 desc
= ldl_phys(table
);
722 domain
= (desc
>> 5) & 0x0f;
723 domain_prot
= (env
->cp15
.c3
>> (domain
* 2)) & 3;
725 /* Section translation fault. */
729 if (domain_prot
== 0 || domain_prot
== 2) {
731 code
= 9; /* Section domain fault. */
733 code
= 11; /* Page domain fault. */
738 phys_addr
= (desc
& 0xfff00000) | (address
& 0x000fffff);
739 ap
= (desc
>> 10) & 3;
741 *page_size
= 1024 * 1024;
743 /* Lookup l2 entry. */
745 /* Coarse pagetable. */
746 table
= (desc
& 0xfffffc00) | ((address
>> 10) & 0x3fc);
748 /* Fine pagetable. */
749 table
= (desc
& 0xfffff000) | ((address
>> 8) & 0xffc);
751 desc
= ldl_phys(table
);
753 case 0: /* Page translation fault. */
756 case 1: /* 64k page. */
757 phys_addr
= (desc
& 0xffff0000) | (address
& 0xffff);
758 ap
= (desc
>> (4 + ((address
>> 13) & 6))) & 3;
759 *page_size
= 0x10000;
761 case 2: /* 4k page. */
762 phys_addr
= (desc
& 0xfffff000) | (address
& 0xfff);
763 ap
= (desc
>> (4 + ((address
>> 13) & 6))) & 3;
766 case 3: /* 1k page. */
768 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
769 phys_addr
= (desc
& 0xfffff000) | (address
& 0xfff);
771 /* Page translation fault. */
776 phys_addr
= (desc
& 0xfffffc00) | (address
& 0x3ff);
778 ap
= (desc
>> 4) & 3;
782 /* Never happens, but compiler isn't smart enough to tell. */
787 *prot
= check_ap(env
, ap
, domain_prot
, access_type
, is_user
);
789 /* Access permission fault. */
793 *phys_ptr
= phys_addr
;
796 return code
| (domain
<< 4);
799 static int get_phys_addr_v6(CPUARMState
*env
, uint32_t address
, int access_type
,
800 int is_user
, uint32_t *phys_ptr
, int *prot
,
801 target_ulong
*page_size
)
813 /* Pagetable walk. */
814 /* Lookup l1 descriptor. */
815 table
= get_level1_table_address(env
, address
);
816 desc
= ldl_phys(table
);
819 /* Section translation fault. */
823 } else if (type
== 2 && (desc
& (1 << 18))) {
827 /* Section or page. */
828 domain
= (desc
>> 5) & 0x0f;
830 domain_prot
= (env
->cp15
.c3
>> (domain
* 2)) & 3;
831 if (domain_prot
== 0 || domain_prot
== 2) {
833 code
= 9; /* Section domain fault. */
835 code
= 11; /* Page domain fault. */
839 if (desc
& (1 << 18)) {
841 phys_addr
= (desc
& 0xff000000) | (address
& 0x00ffffff);
842 *page_size
= 0x1000000;
845 phys_addr
= (desc
& 0xfff00000) | (address
& 0x000fffff);
846 *page_size
= 0x100000;
848 ap
= ((desc
>> 10) & 3) | ((desc
>> 13) & 4);
849 xn
= desc
& (1 << 4);
852 /* Lookup l2 entry. */
853 table
= (desc
& 0xfffffc00) | ((address
>> 10) & 0x3fc);
854 desc
= ldl_phys(table
);
855 ap
= ((desc
>> 4) & 3) | ((desc
>> 7) & 4);
857 case 0: /* Page translation fault. */
860 case 1: /* 64k page. */
861 phys_addr
= (desc
& 0xffff0000) | (address
& 0xffff);
862 xn
= desc
& (1 << 15);
863 *page_size
= 0x10000;
865 case 2: case 3: /* 4k page. */
866 phys_addr
= (desc
& 0xfffff000) | (address
& 0xfff);
871 /* Never happens, but compiler isn't smart enough to tell. */
876 if (domain_prot
== 3) {
877 *prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
879 if (xn
&& access_type
== 2)
882 /* The simplified model uses AP[0] as an access control bit. */
883 if ((env
->cp15
.c1_sys
& (1 << 29)) && (ap
& 1) == 0) {
884 /* Access flag fault. */
885 code
= (code
== 15) ? 6 : 3;
888 *prot
= check_ap(env
, ap
, domain_prot
, access_type
, is_user
);
890 /* Access permission fault. */
897 *phys_ptr
= phys_addr
;
900 return code
| (domain
<< 4);
903 static int get_phys_addr_mpu(CPUARMState
*env
, uint32_t address
, int access_type
,
904 int is_user
, uint32_t *phys_ptr
, int *prot
)
911 for (n
= 7; n
>= 0; n
--) {
912 base
= env
->cp15
.c6_region
[n
];
915 mask
= 1 << ((base
>> 1) & 0x1f);
916 /* Keep this shift separate from the above to avoid an
917 (undefined) << 32. */
918 mask
= (mask
<< 1) - 1;
919 if (((base
^ address
) & ~mask
) == 0)
925 if (access_type
== 2) {
926 mask
= env
->cp15
.c5_insn
;
928 mask
= env
->cp15
.c5_data
;
930 mask
= (mask
>> (n
* 4)) & 0xf;
937 *prot
= PAGE_READ
| PAGE_WRITE
;
945 *prot
= PAGE_READ
| PAGE_WRITE
;
956 /* Bad permission. */
963 static inline int get_phys_addr(CPUARMState
*env
, uint32_t address
,
964 int access_type
, int is_user
,
965 uint32_t *phys_ptr
, int *prot
,
966 target_ulong
*page_size
)
968 /* Fast Context Switch Extension. */
969 if (address
< 0x02000000)
970 address
+= env
->cp15
.c13_fcse
;
972 if ((env
->cp15
.c1_sys
& 1) == 0) {
973 /* MMU/MPU disabled. */
975 *prot
= PAGE_READ
| PAGE_WRITE
| PAGE_EXEC
;
976 *page_size
= TARGET_PAGE_SIZE
;
978 } else if (arm_feature(env
, ARM_FEATURE_MPU
)) {
979 *page_size
= TARGET_PAGE_SIZE
;
980 return get_phys_addr_mpu(env
, address
, access_type
, is_user
, phys_ptr
,
982 } else if (env
->cp15
.c1_sys
& (1 << 23)) {
983 return get_phys_addr_v6(env
, address
, access_type
, is_user
, phys_ptr
,
986 return get_phys_addr_v5(env
, address
, access_type
, is_user
, phys_ptr
,
991 int cpu_arm_handle_mmu_fault (CPUARMState
*env
, target_ulong address
,
992 int access_type
, int mmu_idx
)
995 target_ulong page_size
;
999 is_user
= mmu_idx
== MMU_USER_IDX
;
1000 ret
= get_phys_addr(env
, address
, access_type
, is_user
, &phys_addr
, &prot
,
1003 /* Map a single [sub]page. */
1004 phys_addr
&= ~(uint32_t)0x3ff;
1005 address
&= ~(uint32_t)0x3ff;
1006 tlb_set_page (env
, address
, phys_addr
, prot
, mmu_idx
, page_size
);
1010 if (access_type
== 2) {
1011 env
->cp15
.c5_insn
= ret
;
1012 env
->cp15
.c6_insn
= address
;
1013 env
->exception_index
= EXCP_PREFETCH_ABORT
;
1015 env
->cp15
.c5_data
= ret
;
1016 if (access_type
== 1 && arm_feature(env
, ARM_FEATURE_V6
))
1017 env
->cp15
.c5_data
|= (1 << 11);
1018 env
->cp15
.c6_data
= address
;
1019 env
->exception_index
= EXCP_DATA_ABORT
;
1024 target_phys_addr_t
cpu_get_phys_page_debug(CPUARMState
*env
, target_ulong addr
)
1027 target_ulong page_size
;
1031 ret
= get_phys_addr(env
, addr
, 0, 0, &phys_addr
, &prot
, &page_size
);
1039 void HELPER(set_cp
)(CPUARMState
*env
, uint32_t insn
, uint32_t val
)
1041 int cp_num
= (insn
>> 8) & 0xf;
1042 int cp_info
= (insn
>> 5) & 7;
1043 int src
= (insn
>> 16) & 0xf;
1044 int operand
= insn
& 0xf;
1046 if (env
->cp
[cp_num
].cp_write
)
1047 env
->cp
[cp_num
].cp_write(env
->cp
[cp_num
].opaque
,
1048 cp_info
, src
, operand
, val
);
1051 uint32_t HELPER(get_cp
)(CPUARMState
*env
, uint32_t insn
)
1053 int cp_num
= (insn
>> 8) & 0xf;
1054 int cp_info
= (insn
>> 5) & 7;
1055 int dest
= (insn
>> 16) & 0xf;
1056 int operand
= insn
& 0xf;
1058 if (env
->cp
[cp_num
].cp_read
)
1059 return env
->cp
[cp_num
].cp_read(env
->cp
[cp_num
].opaque
,
1060 cp_info
, dest
, operand
);
1064 /* Return basic MPU access permission bits. */
1065 static uint32_t simple_mpu_ap_bits(uint32_t val
)
1072 for (i
= 0; i
< 16; i
+= 2) {
1073 ret
|= (val
>> i
) & mask
;
1079 /* Pad basic MPU access permission bits to extended format. */
1080 static uint32_t extended_mpu_ap_bits(uint32_t val
)
1087 for (i
= 0; i
< 16; i
+= 2) {
1088 ret
|= (val
& mask
) << i
;
1094 void HELPER(set_cp15
)(CPUARMState
*env
, uint32_t insn
, uint32_t val
)
1100 op1
= (insn
>> 21) & 7;
1101 op2
= (insn
>> 5) & 7;
1103 switch ((insn
>> 16) & 0xf) {
1106 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
1108 if (arm_feature(env
, ARM_FEATURE_OMAPCP
))
1110 if (arm_feature(env
, ARM_FEATURE_V7
)
1111 && op1
== 2 && crm
== 0 && op2
== 0) {
1112 env
->cp15
.c0_cssel
= val
& 0xf;
1116 case 1: /* System configuration. */
1117 if (arm_feature(env
, ARM_FEATURE_V7
)
1118 && op1
== 0 && crm
== 1 && op2
== 0) {
1119 env
->cp15
.c1_scr
= val
;
1122 if (arm_feature(env
, ARM_FEATURE_OMAPCP
))
1126 if (!arm_feature(env
, ARM_FEATURE_XSCALE
) || crm
== 0)
1127 env
->cp15
.c1_sys
= val
;
1128 /* ??? Lots of these bits are not implemented. */
1129 /* This may enable/disable the MMU, so do a TLB flush. */
1132 case 1: /* Auxiliary control register. */
1133 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
1134 env
->cp15
.c1_xscaleauxcr
= val
;
1137 /* Not implemented. */
1140 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
1142 if (env
->cp15
.c1_coproc
!= val
) {
1143 env
->cp15
.c1_coproc
= val
;
1144 /* ??? Is this safe when called from within a TB? */
1152 case 2: /* MMU Page table control / MPU cache control. */
1153 if (arm_feature(env
, ARM_FEATURE_MPU
)) {
1156 env
->cp15
.c2_data
= val
;
1159 env
->cp15
.c2_insn
= val
;
1167 env
->cp15
.c2_base0
= val
;
1170 env
->cp15
.c2_base1
= val
;
1174 env
->cp15
.c2_control
= val
;
1175 env
->cp15
.c2_mask
= ~(((uint32_t)0xffffffffu
) >> val
);
1176 env
->cp15
.c2_base_mask
= ~((uint32_t)0x3fffu
>> val
);
1183 case 3: /* MMU Domain access control / MPU write buffer control. */
1185 tlb_flush(env
, 1); /* Flush TLB as domain not tracked in TLB */
1187 case 4: /* Reserved. */
1189 case 5: /* MMU Fault status / MPU access permission. */
1190 if (arm_feature(env
, ARM_FEATURE_OMAPCP
))
1194 if (arm_feature(env
, ARM_FEATURE_MPU
))
1195 val
= extended_mpu_ap_bits(val
);
1196 env
->cp15
.c5_data
= val
;
1199 if (arm_feature(env
, ARM_FEATURE_MPU
))
1200 val
= extended_mpu_ap_bits(val
);
1201 env
->cp15
.c5_insn
= val
;
1204 if (!arm_feature(env
, ARM_FEATURE_MPU
))
1206 env
->cp15
.c5_data
= val
;
1209 if (!arm_feature(env
, ARM_FEATURE_MPU
))
1211 env
->cp15
.c5_insn
= val
;
1217 case 6: /* MMU Fault address / MPU base/size. */
1218 if (arm_feature(env
, ARM_FEATURE_MPU
)) {
1221 env
->cp15
.c6_region
[crm
] = val
;
1223 if (arm_feature(env
, ARM_FEATURE_OMAPCP
))
1227 env
->cp15
.c6_data
= val
;
1229 case 1: /* ??? This is WFAR on armv6 */
1231 env
->cp15
.c6_insn
= val
;
1238 case 7: /* Cache control. */
1239 env
->cp15
.c15_i_max
= 0x000;
1240 env
->cp15
.c15_i_min
= 0xff0;
1244 /* No cache, so nothing to do except VA->PA translations. */
1245 if (arm_feature(env
, ARM_FEATURE_VAPA
)) {
1248 if (arm_feature(env
, ARM_FEATURE_V7
)) {
1249 env
->cp15
.c7_par
= val
& 0xfffff6ff;
1251 env
->cp15
.c7_par
= val
& 0xfffff1ff;
1256 target_ulong page_size
;
1258 int ret
, is_user
= op2
& 2;
1259 int access_type
= op2
& 1;
1262 /* Other states are only available with TrustZone */
1265 ret
= get_phys_addr(env
, val
, access_type
, is_user
,
1266 &phys_addr
, &prot
, &page_size
);
1268 /* We do not set any attribute bits in the PAR */
1269 if (page_size
== (1 << 24)
1270 && arm_feature(env
, ARM_FEATURE_V7
)) {
1271 env
->cp15
.c7_par
= (phys_addr
& 0xff000000) | 1 << 1;
1273 env
->cp15
.c7_par
= phys_addr
& 0xfffff000;
1276 env
->cp15
.c7_par
= ((ret
& (10 << 1)) >> 5) |
1277 ((ret
& (12 << 1)) >> 6) |
1278 ((ret
& 0xf) << 1) | 1;
1285 case 8: /* MMU TLB control. */
1287 case 0: /* Invalidate all (TLBIALL) */
1290 case 1: /* Invalidate single TLB entry by MVA and ASID (TLBIMVA) */
1291 tlb_flush_page(env
, val
& TARGET_PAGE_MASK
);
1293 case 2: /* Invalidate by ASID (TLBIASID) */
1294 tlb_flush(env
, val
== 0);
1296 case 3: /* Invalidate single entry by MVA, all ASIDs (TLBIMVAA) */
1297 tlb_flush_page(env
, val
& TARGET_PAGE_MASK
);
1304 if (arm_feature(env
, ARM_FEATURE_OMAPCP
))
1306 if (arm_feature(env
, ARM_FEATURE_STRONGARM
))
1307 break; /* Ignore ReadBuffer access */
1309 case 0: /* Cache lockdown. */
1311 case 0: /* L1 cache. */
1314 env
->cp15
.c9_data
= val
;
1317 env
->cp15
.c9_insn
= val
;
1323 case 1: /* L2 cache. */
1324 /* Ignore writes to L2 lockdown/auxiliary registers. */
1330 case 1: /* TCM memory region registers. */
1331 /* Not implemented. */
1333 case 12: /* Performance monitor control */
1334 /* Performance monitors are implementation defined in v7,
1335 * but with an ARM recommended set of registers, which we
1336 * follow (although we don't actually implement any counters)
1338 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
1342 case 0: /* performance monitor control register */
1343 /* only the DP, X, D and E bits are writable */
1344 env
->cp15
.c9_pmcr
&= ~0x39;
1345 env
->cp15
.c9_pmcr
|= (val
& 0x39);
1347 case 1: /* Count enable set register */
1349 env
->cp15
.c9_pmcnten
|= val
;
1351 case 2: /* Count enable clear */
1353 env
->cp15
.c9_pmcnten
&= ~val
;
1355 case 3: /* Overflow flag status */
1356 env
->cp15
.c9_pmovsr
&= ~val
;
1358 case 4: /* Software increment */
1359 /* RAZ/WI since we don't implement the software-count event */
1361 case 5: /* Event counter selection register */
1362 /* Since we don't implement any events, writing to this register
1363 * is actually UNPREDICTABLE. So we choose to RAZ/WI.
1370 case 13: /* Performance counters */
1371 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
1375 case 0: /* Cycle count register: not implemented, so RAZ/WI */
1377 case 1: /* Event type select */
1378 env
->cp15
.c9_pmxevtyper
= val
& 0xff;
1380 case 2: /* Event count register */
1381 /* Unimplemented (we have no events), RAZ/WI */
1387 case 14: /* Performance monitor control */
1388 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
1392 case 0: /* user enable */
1393 env
->cp15
.c9_pmuserenr
= val
& 1;
1394 /* changes access rights for cp registers, so flush tbs */
1397 case 1: /* interrupt enable set */
1398 /* We have no event counters so only the C bit can be changed */
1400 env
->cp15
.c9_pminten
|= val
;
1402 case 2: /* interrupt enable clear */
1404 env
->cp15
.c9_pminten
&= ~val
;
1412 case 10: /* MMU TLB lockdown. */
1413 /* ??? TLB lockdown not implemented. */
1415 case 12: /* Reserved. */
1417 case 13: /* Process ID. */
1420 /* Unlike real hardware the qemu TLB uses virtual addresses,
1421 not modified virtual addresses, so this causes a TLB flush.
1423 if (env
->cp15
.c13_fcse
!= val
)
1425 env
->cp15
.c13_fcse
= val
;
1428 /* This changes the ASID, so do a TLB flush. */
1429 if (env
->cp15
.c13_context
!= val
1430 && !arm_feature(env
, ARM_FEATURE_MPU
))
1432 env
->cp15
.c13_context
= val
;
1438 case 14: /* Generic timer */
1439 if (arm_feature(env
, ARM_FEATURE_GENERIC_TIMER
)) {
1440 /* Dummy implementation: RAZ/WI for all */
1444 case 15: /* Implementation specific. */
1445 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
1446 if (op2
== 0 && crm
== 1) {
1447 if (env
->cp15
.c15_cpar
!= (val
& 0x3fff)) {
1448 /* Changes cp0 to cp13 behavior, so needs a TB flush. */
1450 env
->cp15
.c15_cpar
= val
& 0x3fff;
1456 if (arm_feature(env
, ARM_FEATURE_OMAPCP
)) {
1460 case 1: /* Set TI925T configuration. */
1461 env
->cp15
.c15_ticonfig
= val
& 0xe7;
1462 env
->cp15
.c0_cpuid
= (val
& (1 << 5)) ? /* OS_TYPE bit */
1463 ARM_CPUID_TI915T
: ARM_CPUID_TI925T
;
1465 case 2: /* Set I_max. */
1466 env
->cp15
.c15_i_max
= val
;
1468 case 3: /* Set I_min. */
1469 env
->cp15
.c15_i_min
= val
;
1471 case 4: /* Set thread-ID. */
1472 env
->cp15
.c15_threadid
= val
& 0xffff;
1474 case 8: /* Wait-for-interrupt (deprecated). */
1475 cpu_interrupt(env
, CPU_INTERRUPT_HALT
);
1481 if (ARM_CPUID(env
) == ARM_CPUID_CORTEXA9
) {
1484 if ((op1
== 0) && (op2
== 0)) {
1485 env
->cp15
.c15_power_control
= val
;
1486 } else if ((op1
== 0) && (op2
== 1)) {
1487 env
->cp15
.c15_diagnostic
= val
;
1488 } else if ((op1
== 0) && (op2
== 2)) {
1489 env
->cp15
.c15_power_diagnostic
= val
;
1499 /* ??? For debugging only. Should raise illegal instruction exception. */
1500 cpu_abort(env
, "Unimplemented cp15 register write (c%d, c%d, {%d, %d})\n",
1501 (insn
>> 16) & 0xf, crm
, op1
, op2
);
1504 uint32_t HELPER(get_cp15
)(CPUARMState
*env
, uint32_t insn
)
1510 op1
= (insn
>> 21) & 7;
1511 op2
= (insn
>> 5) & 7;
1513 switch ((insn
>> 16) & 0xf) {
1514 case 0: /* ID codes. */
1520 case 0: /* Device ID. */
1521 return env
->cp15
.c0_cpuid
;
1522 case 1: /* Cache Type. */
1523 return env
->cp15
.c0_cachetype
;
1524 case 2: /* TCM status. */
1526 case 3: /* TLB type register. */
1527 return 0; /* No lockable TLB entries. */
1529 /* The MPIDR was standardised in v7; prior to
1530 * this it was implemented only in the 11MPCore.
1531 * For all other pre-v7 cores it does not exist.
1533 if (arm_feature(env
, ARM_FEATURE_V7
) ||
1534 ARM_CPUID(env
) == ARM_CPUID_ARM11MPCORE
) {
1535 int mpidr
= env
->cpu_index
;
1536 /* We don't support setting cluster ID ([8..11])
1537 * so these bits always RAZ.
1539 if (arm_feature(env
, ARM_FEATURE_V7MP
)) {
1541 /* Cores which are uniprocessor (non-coherent)
1542 * but still implement the MP extensions set
1543 * bit 30. (For instance, A9UP.) However we do
1544 * not currently model any of those cores.
1549 /* otherwise fall through to the unimplemented-reg case */
1554 if (!arm_feature(env
, ARM_FEATURE_V6
))
1556 return env
->cp15
.c0_c1
[op2
];
1558 if (!arm_feature(env
, ARM_FEATURE_V6
))
1560 return env
->cp15
.c0_c2
[op2
];
1561 case 3: case 4: case 5: case 6: case 7:
1567 /* These registers aren't documented on arm11 cores. However
1568 Linux looks at them anyway. */
1569 if (!arm_feature(env
, ARM_FEATURE_V6
))
1573 if (!arm_feature(env
, ARM_FEATURE_V7
))
1578 return env
->cp15
.c0_ccsid
[env
->cp15
.c0_cssel
];
1580 return env
->cp15
.c0_clid
;
1586 if (op2
!= 0 || crm
!= 0)
1588 return env
->cp15
.c0_cssel
;
1592 case 1: /* System configuration. */
1593 if (arm_feature(env
, ARM_FEATURE_V7
)
1594 && op1
== 0 && crm
== 1 && op2
== 0) {
1595 return env
->cp15
.c1_scr
;
1597 if (arm_feature(env
, ARM_FEATURE_OMAPCP
))
1600 case 0: /* Control register. */
1601 return env
->cp15
.c1_sys
;
1602 case 1: /* Auxiliary control register. */
1603 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
1604 return env
->cp15
.c1_xscaleauxcr
;
1605 if (!arm_feature(env
, ARM_FEATURE_AUXCR
))
1607 switch (ARM_CPUID(env
)) {
1608 case ARM_CPUID_ARM1026
:
1610 case ARM_CPUID_ARM1136
:
1611 case ARM_CPUID_ARM1136_R2
:
1612 case ARM_CPUID_ARM1176
:
1614 case ARM_CPUID_ARM11MPCORE
:
1616 case ARM_CPUID_CORTEXA8
:
1618 case ARM_CPUID_CORTEXA9
:
1619 case ARM_CPUID_CORTEXA15
:
1624 case 2: /* Coprocessor access register. */
1625 if (arm_feature(env
, ARM_FEATURE_XSCALE
))
1627 return env
->cp15
.c1_coproc
;
1631 case 2: /* MMU Page table control / MPU cache control. */
1632 if (arm_feature(env
, ARM_FEATURE_MPU
)) {
1635 return env
->cp15
.c2_data
;
1638 return env
->cp15
.c2_insn
;
1646 return env
->cp15
.c2_base0
;
1648 return env
->cp15
.c2_base1
;
1650 return env
->cp15
.c2_control
;
1655 case 3: /* MMU Domain access control / MPU write buffer control. */
1656 return env
->cp15
.c3
;
1657 case 4: /* Reserved. */
1659 case 5: /* MMU Fault status / MPU access permission. */
1660 if (arm_feature(env
, ARM_FEATURE_OMAPCP
))
1664 if (arm_feature(env
, ARM_FEATURE_MPU
))
1665 return simple_mpu_ap_bits(env
->cp15
.c5_data
);
1666 return env
->cp15
.c5_data
;
1668 if (arm_feature(env
, ARM_FEATURE_MPU
))
1669 return simple_mpu_ap_bits(env
->cp15
.c5_insn
);
1670 return env
->cp15
.c5_insn
;
1672 if (!arm_feature(env
, ARM_FEATURE_MPU
))
1674 return env
->cp15
.c5_data
;
1676 if (!arm_feature(env
, ARM_FEATURE_MPU
))
1678 return env
->cp15
.c5_insn
;
1682 case 6: /* MMU Fault address. */
1683 if (arm_feature(env
, ARM_FEATURE_MPU
)) {
1686 return env
->cp15
.c6_region
[crm
];
1688 if (arm_feature(env
, ARM_FEATURE_OMAPCP
))
1692 return env
->cp15
.c6_data
;
1694 if (arm_feature(env
, ARM_FEATURE_V6
)) {
1695 /* Watchpoint Fault Adrress. */
1696 return 0; /* Not implemented. */
1698 /* Instruction Fault Adrress. */
1699 /* Arm9 doesn't have an IFAR, but implementing it anyway
1700 shouldn't do any harm. */
1701 return env
->cp15
.c6_insn
;
1704 if (arm_feature(env
, ARM_FEATURE_V6
)) {
1705 /* Instruction Fault Adrress. */
1706 return env
->cp15
.c6_insn
;
1714 case 7: /* Cache control. */
1715 if (crm
== 4 && op1
== 0 && op2
== 0) {
1716 return env
->cp15
.c7_par
;
1718 /* FIXME: Should only clear Z flag if destination is r15. */
1721 case 8: /* MMU TLB control. */
1725 case 0: /* Cache lockdown */
1727 case 0: /* L1 cache. */
1728 if (arm_feature(env
, ARM_FEATURE_OMAPCP
)) {
1733 return env
->cp15
.c9_data
;
1735 return env
->cp15
.c9_insn
;
1739 case 1: /* L2 cache */
1740 /* L2 Lockdown and Auxiliary control. */
1743 /* L2 cache lockdown (A8 only) */
1746 /* L2 cache auxiliary control (A8) or control (A15) */
1747 if (ARM_CPUID(env
) == ARM_CPUID_CORTEXA15
) {
1748 /* Linux wants the number of processors from here.
1749 * Might as well set the interrupt-controller bit too.
1751 return ((smp_cpus
- 1) << 24) | (1 << 23);
1755 /* L2 cache extended control (A15) */
1764 case 12: /* Performance monitor control */
1765 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
1769 case 0: /* performance monitor control register */
1770 return env
->cp15
.c9_pmcr
;
1771 case 1: /* count enable set */
1772 case 2: /* count enable clear */
1773 return env
->cp15
.c9_pmcnten
;
1774 case 3: /* overflow flag status */
1775 return env
->cp15
.c9_pmovsr
;
1776 case 4: /* software increment */
1777 case 5: /* event counter selection register */
1778 return 0; /* Unimplemented, RAZ/WI */
1782 case 13: /* Performance counters */
1783 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
1787 case 1: /* Event type select */
1788 return env
->cp15
.c9_pmxevtyper
;
1789 case 0: /* Cycle count register */
1790 case 2: /* Event count register */
1791 /* Unimplemented, so RAZ/WI */
1796 case 14: /* Performance monitor control */
1797 if (!arm_feature(env
, ARM_FEATURE_V7
)) {
1801 case 0: /* user enable */
1802 return env
->cp15
.c9_pmuserenr
;
1803 case 1: /* interrupt enable set */
1804 case 2: /* interrupt enable clear */
1805 return env
->cp15
.c9_pminten
;
1813 case 10: /* MMU TLB lockdown. */
1814 /* ??? TLB lockdown not implemented. */
1816 case 11: /* TCM DMA control. */
1817 case 12: /* Reserved. */
1819 case 13: /* Process ID. */
1822 return env
->cp15
.c13_fcse
;
1824 return env
->cp15
.c13_context
;
1828 case 14: /* Generic timer */
1829 if (arm_feature(env
, ARM_FEATURE_GENERIC_TIMER
)) {
1830 /* Dummy implementation: RAZ/WI for all */
1834 case 15: /* Implementation specific. */
1835 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
1836 if (op2
== 0 && crm
== 1)
1837 return env
->cp15
.c15_cpar
;
1841 if (arm_feature(env
, ARM_FEATURE_OMAPCP
)) {
1845 case 1: /* Read TI925T configuration. */
1846 return env
->cp15
.c15_ticonfig
;
1847 case 2: /* Read I_max. */
1848 return env
->cp15
.c15_i_max
;
1849 case 3: /* Read I_min. */
1850 return env
->cp15
.c15_i_min
;
1851 case 4: /* Read thread-ID. */
1852 return env
->cp15
.c15_threadid
;
1853 case 8: /* TI925T_status */
1856 /* TODO: Peripheral port remap register:
1857 * On OMAP2 mcr p15, 0, rn, c15, c2, 4 sets up the interrupt
1858 * controller base address at $rn & ~0xfff and map size of
1859 * 0x200 << ($rn & 0xfff), when MMU is off. */
1862 if (ARM_CPUID(env
) == ARM_CPUID_CORTEXA9
) {
1865 if ((op1
== 4) && (op2
== 0)) {
1866 /* The config_base_address should hold the value of
1867 * the peripheral base. ARM should get this from a CPU
1868 * object property, but that support isn't available in
1869 * December 2011. Default to 0 for now and board models
1870 * that care can set it by a private hook */
1871 return env
->cp15
.c15_config_base_address
;
1872 } else if ((op1
== 0) && (op2
== 0)) {
1873 /* power_control should be set to maximum latency. Again,
1874 default to 0 and set by private hook */
1875 return env
->cp15
.c15_power_control
;
1876 } else if ((op1
== 0) && (op2
== 1)) {
1877 return env
->cp15
.c15_diagnostic
;
1878 } else if ((op1
== 0) && (op2
== 2)) {
1879 return env
->cp15
.c15_power_diagnostic
;
1882 case 1: /* NEON Busy */
1884 case 5: /* tlb lockdown */
1887 if ((op1
== 5) && (op2
== 2)) {
1899 /* ??? For debugging only. Should raise illegal instruction exception. */
1900 cpu_abort(env
, "Unimplemented cp15 register read (c%d, c%d, {%d, %d})\n",
1901 (insn
>> 16) & 0xf, crm
, op1
, op2
);
1905 void HELPER(set_r13_banked
)(CPUARMState
*env
, uint32_t mode
, uint32_t val
)
1907 if ((env
->uncached_cpsr
& CPSR_M
) == mode
) {
1908 env
->regs
[13] = val
;
1910 env
->banked_r13
[bank_number(env
, mode
)] = val
;
1914 uint32_t HELPER(get_r13_banked
)(CPUARMState
*env
, uint32_t mode
)
1916 if ((env
->uncached_cpsr
& CPSR_M
) == mode
) {
1917 return env
->regs
[13];
1919 return env
->banked_r13
[bank_number(env
, mode
)];
1923 uint32_t HELPER(v7m_mrs
)(CPUARMState
*env
, uint32_t reg
)
1927 return xpsr_read(env
) & 0xf8000000;
1929 return xpsr_read(env
) & 0xf80001ff;
1931 return xpsr_read(env
) & 0xff00fc00;
1933 return xpsr_read(env
) & 0xff00fdff;
1935 return xpsr_read(env
) & 0x000001ff;
1937 return xpsr_read(env
) & 0x0700fc00;
1939 return xpsr_read(env
) & 0x0700edff;
1941 return env
->v7m
.current_sp
? env
->v7m
.other_sp
: env
->regs
[13];
1943 return env
->v7m
.current_sp
? env
->regs
[13] : env
->v7m
.other_sp
;
1944 case 16: /* PRIMASK */
1945 return (env
->uncached_cpsr
& CPSR_I
) != 0;
1946 case 17: /* BASEPRI */
1947 case 18: /* BASEPRI_MAX */
1948 return env
->v7m
.basepri
;
1949 case 19: /* FAULTMASK */
1950 return (env
->uncached_cpsr
& CPSR_F
) != 0;
1951 case 20: /* CONTROL */
1952 return env
->v7m
.control
;
1954 /* ??? For debugging only. */
1955 cpu_abort(env
, "Unimplemented system register read (%d)\n", reg
);
1960 void HELPER(v7m_msr
)(CPUARMState
*env
, uint32_t reg
, uint32_t val
)
1964 xpsr_write(env
, val
, 0xf8000000);
1967 xpsr_write(env
, val
, 0xf8000000);
1970 xpsr_write(env
, val
, 0xfe00fc00);
1973 xpsr_write(env
, val
, 0xfe00fc00);
1976 /* IPSR bits are readonly. */
1979 xpsr_write(env
, val
, 0x0600fc00);
1982 xpsr_write(env
, val
, 0x0600fc00);
1985 if (env
->v7m
.current_sp
)
1986 env
->v7m
.other_sp
= val
;
1988 env
->regs
[13] = val
;
1991 if (env
->v7m
.current_sp
)
1992 env
->regs
[13] = val
;
1994 env
->v7m
.other_sp
= val
;
1996 case 16: /* PRIMASK */
1998 env
->uncached_cpsr
|= CPSR_I
;
2000 env
->uncached_cpsr
&= ~CPSR_I
;
2002 case 17: /* BASEPRI */
2003 env
->v7m
.basepri
= val
& 0xff;
2005 case 18: /* BASEPRI_MAX */
2007 if (val
!= 0 && (val
< env
->v7m
.basepri
|| env
->v7m
.basepri
== 0))
2008 env
->v7m
.basepri
= val
;
2010 case 19: /* FAULTMASK */
2012 env
->uncached_cpsr
|= CPSR_F
;
2014 env
->uncached_cpsr
&= ~CPSR_F
;
2016 case 20: /* CONTROL */
2017 env
->v7m
.control
= val
& 3;
2018 switch_v7m_sp(env
, (val
& 2) != 0);
2021 /* ??? For debugging only. */
2022 cpu_abort(env
, "Unimplemented system register write (%d)\n", reg
);
2027 void cpu_arm_set_cp_io(CPUARMState
*env
, int cpnum
,
2028 ARMReadCPFunc
*cp_read
, ARMWriteCPFunc
*cp_write
,
2031 if (cpnum
< 0 || cpnum
> 14) {
2032 cpu_abort(env
, "Bad coprocessor number: %i\n", cpnum
);
2036 env
->cp
[cpnum
].cp_read
= cp_read
;
2037 env
->cp
[cpnum
].cp_write
= cp_write
;
2038 env
->cp
[cpnum
].opaque
= opaque
;
2043 /* Note that signed overflow is undefined in C. The following routines are
2044 careful to use unsigned types where modulo arithmetic is required.
2045 Failure to do so _will_ break on newer gcc. */
2047 /* Signed saturating arithmetic. */
2049 /* Perform 16-bit signed saturating addition. */
2050 static inline uint16_t add16_sat(uint16_t a
, uint16_t b
)
2055 if (((res
^ a
) & 0x8000) && !((a
^ b
) & 0x8000)) {
2064 /* Perform 8-bit signed saturating addition. */
2065 static inline uint8_t add8_sat(uint8_t a
, uint8_t b
)
2070 if (((res
^ a
) & 0x80) && !((a
^ b
) & 0x80)) {
2079 /* Perform 16-bit signed saturating subtraction. */
2080 static inline uint16_t sub16_sat(uint16_t a
, uint16_t b
)
2085 if (((res
^ a
) & 0x8000) && ((a
^ b
) & 0x8000)) {
2094 /* Perform 8-bit signed saturating subtraction. */
2095 static inline uint8_t sub8_sat(uint8_t a
, uint8_t b
)
2100 if (((res
^ a
) & 0x80) && ((a
^ b
) & 0x80)) {
2109 #define ADD16(a, b, n) RESULT(add16_sat(a, b), n, 16);
2110 #define SUB16(a, b, n) RESULT(sub16_sat(a, b), n, 16);
2111 #define ADD8(a, b, n) RESULT(add8_sat(a, b), n, 8);
2112 #define SUB8(a, b, n) RESULT(sub8_sat(a, b), n, 8);
2115 #include "op_addsub.h"
2117 /* Unsigned saturating arithmetic. */
2118 static inline uint16_t add16_usat(uint16_t a
, uint16_t b
)
2127 static inline uint16_t sub16_usat(uint16_t a
, uint16_t b
)
2135 static inline uint8_t add8_usat(uint8_t a
, uint8_t b
)
2144 static inline uint8_t sub8_usat(uint8_t a
, uint8_t b
)
2152 #define ADD16(a, b, n) RESULT(add16_usat(a, b), n, 16);
2153 #define SUB16(a, b, n) RESULT(sub16_usat(a, b), n, 16);
2154 #define ADD8(a, b, n) RESULT(add8_usat(a, b), n, 8);
2155 #define SUB8(a, b, n) RESULT(sub8_usat(a, b), n, 8);
2158 #include "op_addsub.h"
2160 /* Signed modulo arithmetic. */
2161 #define SARITH16(a, b, n, op) do { \
2163 sum = (int32_t)(int16_t)(a) op (int32_t)(int16_t)(b); \
2164 RESULT(sum, n, 16); \
2166 ge |= 3 << (n * 2); \
2169 #define SARITH8(a, b, n, op) do { \
2171 sum = (int32_t)(int8_t)(a) op (int32_t)(int8_t)(b); \
2172 RESULT(sum, n, 8); \
2178 #define ADD16(a, b, n) SARITH16(a, b, n, +)
2179 #define SUB16(a, b, n) SARITH16(a, b, n, -)
2180 #define ADD8(a, b, n) SARITH8(a, b, n, +)
2181 #define SUB8(a, b, n) SARITH8(a, b, n, -)
2185 #include "op_addsub.h"
2187 /* Unsigned modulo arithmetic. */
2188 #define ADD16(a, b, n) do { \
2190 sum = (uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b); \
2191 RESULT(sum, n, 16); \
2192 if ((sum >> 16) == 1) \
2193 ge |= 3 << (n * 2); \
2196 #define ADD8(a, b, n) do { \
2198 sum = (uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b); \
2199 RESULT(sum, n, 8); \
2200 if ((sum >> 8) == 1) \
2204 #define SUB16(a, b, n) do { \
2206 sum = (uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b); \
2207 RESULT(sum, n, 16); \
2208 if ((sum >> 16) == 0) \
2209 ge |= 3 << (n * 2); \
2212 #define SUB8(a, b, n) do { \
2214 sum = (uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b); \
2215 RESULT(sum, n, 8); \
2216 if ((sum >> 8) == 0) \
2223 #include "op_addsub.h"
2225 /* Halved signed arithmetic. */
2226 #define ADD16(a, b, n) \
2227 RESULT(((int32_t)(int16_t)(a) + (int32_t)(int16_t)(b)) >> 1, n, 16)
2228 #define SUB16(a, b, n) \
2229 RESULT(((int32_t)(int16_t)(a) - (int32_t)(int16_t)(b)) >> 1, n, 16)
2230 #define ADD8(a, b, n) \
2231 RESULT(((int32_t)(int8_t)(a) + (int32_t)(int8_t)(b)) >> 1, n, 8)
2232 #define SUB8(a, b, n) \
2233 RESULT(((int32_t)(int8_t)(a) - (int32_t)(int8_t)(b)) >> 1, n, 8)
2236 #include "op_addsub.h"
2238 /* Halved unsigned arithmetic. */
2239 #define ADD16(a, b, n) \
2240 RESULT(((uint32_t)(uint16_t)(a) + (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2241 #define SUB16(a, b, n) \
2242 RESULT(((uint32_t)(uint16_t)(a) - (uint32_t)(uint16_t)(b)) >> 1, n, 16)
2243 #define ADD8(a, b, n) \
2244 RESULT(((uint32_t)(uint8_t)(a) + (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2245 #define SUB8(a, b, n) \
2246 RESULT(((uint32_t)(uint8_t)(a) - (uint32_t)(uint8_t)(b)) >> 1, n, 8)
2249 #include "op_addsub.h"
2251 static inline uint8_t do_usad(uint8_t a
, uint8_t b
)
2259 /* Unsigned sum of absolute byte differences. */
2260 uint32_t HELPER(usad8
)(uint32_t a
, uint32_t b
)
2263 sum
= do_usad(a
, b
);
2264 sum
+= do_usad(a
>> 8, b
>> 8);
2265 sum
+= do_usad(a
>> 16, b
>>16);
2266 sum
+= do_usad(a
>> 24, b
>> 24);
2270 /* For ARMv6 SEL instruction. */
2271 uint32_t HELPER(sel_flags
)(uint32_t flags
, uint32_t a
, uint32_t b
)
2284 return (a
& mask
) | (b
& ~mask
);
2287 uint32_t HELPER(logicq_cc
)(uint64_t val
)
2289 return (val
>> 32) | (val
!= 0);
2292 /* VFP support. We follow the convention used for VFP instrunctions:
2293 Single precition routines have a "s" suffix, double precision a
2296 /* Convert host exception flags to vfp form. */
2297 static inline int vfp_exceptbits_from_host(int host_bits
)
2299 int target_bits
= 0;
2301 if (host_bits
& float_flag_invalid
)
2303 if (host_bits
& float_flag_divbyzero
)
2305 if (host_bits
& float_flag_overflow
)
2307 if (host_bits
& (float_flag_underflow
| float_flag_output_denormal
))
2309 if (host_bits
& float_flag_inexact
)
2310 target_bits
|= 0x10;
2311 if (host_bits
& float_flag_input_denormal
)
2312 target_bits
|= 0x80;
2316 uint32_t HELPER(vfp_get_fpscr
)(CPUARMState
*env
)
2321 fpscr
= (env
->vfp
.xregs
[ARM_VFP_FPSCR
] & 0xffc8ffff)
2322 | (env
->vfp
.vec_len
<< 16)
2323 | (env
->vfp
.vec_stride
<< 20);
2324 i
= get_float_exception_flags(&env
->vfp
.fp_status
);
2325 i
|= get_float_exception_flags(&env
->vfp
.standard_fp_status
);
2326 fpscr
|= vfp_exceptbits_from_host(i
);
2330 uint32_t vfp_get_fpscr(CPUARMState
*env
)
2332 return HELPER(vfp_get_fpscr
)(env
);
2335 /* Convert vfp exception flags to target form. */
2336 static inline int vfp_exceptbits_to_host(int target_bits
)
2340 if (target_bits
& 1)
2341 host_bits
|= float_flag_invalid
;
2342 if (target_bits
& 2)
2343 host_bits
|= float_flag_divbyzero
;
2344 if (target_bits
& 4)
2345 host_bits
|= float_flag_overflow
;
2346 if (target_bits
& 8)
2347 host_bits
|= float_flag_underflow
;
2348 if (target_bits
& 0x10)
2349 host_bits
|= float_flag_inexact
;
2350 if (target_bits
& 0x80)
2351 host_bits
|= float_flag_input_denormal
;
2355 void HELPER(vfp_set_fpscr
)(CPUARMState
*env
, uint32_t val
)
2360 changed
= env
->vfp
.xregs
[ARM_VFP_FPSCR
];
2361 env
->vfp
.xregs
[ARM_VFP_FPSCR
] = (val
& 0xffc8ffff);
2362 env
->vfp
.vec_len
= (val
>> 16) & 7;
2363 env
->vfp
.vec_stride
= (val
>> 20) & 3;
2366 if (changed
& (3 << 22)) {
2367 i
= (val
>> 22) & 3;
2370 i
= float_round_nearest_even
;
2376 i
= float_round_down
;
2379 i
= float_round_to_zero
;
2382 set_float_rounding_mode(i
, &env
->vfp
.fp_status
);
2384 if (changed
& (1 << 24)) {
2385 set_flush_to_zero((val
& (1 << 24)) != 0, &env
->vfp
.fp_status
);
2386 set_flush_inputs_to_zero((val
& (1 << 24)) != 0, &env
->vfp
.fp_status
);
2388 if (changed
& (1 << 25))
2389 set_default_nan_mode((val
& (1 << 25)) != 0, &env
->vfp
.fp_status
);
2391 i
= vfp_exceptbits_to_host(val
);
2392 set_float_exception_flags(i
, &env
->vfp
.fp_status
);
2393 set_float_exception_flags(0, &env
->vfp
.standard_fp_status
);
2396 void vfp_set_fpscr(CPUARMState
*env
, uint32_t val
)
2398 HELPER(vfp_set_fpscr
)(env
, val
);
2401 #define VFP_HELPER(name, p) HELPER(glue(glue(vfp_,name),p))
2403 #define VFP_BINOP(name) \
2404 float32 VFP_HELPER(name, s)(float32 a, float32 b, void *fpstp) \
2406 float_status *fpst = fpstp; \
2407 return float32_ ## name(a, b, fpst); \
2409 float64 VFP_HELPER(name, d)(float64 a, float64 b, void *fpstp) \
2411 float_status *fpst = fpstp; \
2412 return float64_ ## name(a, b, fpst); \
2420 float32
VFP_HELPER(neg
, s
)(float32 a
)
2422 return float32_chs(a
);
2425 float64
VFP_HELPER(neg
, d
)(float64 a
)
2427 return float64_chs(a
);
2430 float32
VFP_HELPER(abs
, s
)(float32 a
)
2432 return float32_abs(a
);
2435 float64
VFP_HELPER(abs
, d
)(float64 a
)
2437 return float64_abs(a
);
2440 float32
VFP_HELPER(sqrt
, s
)(float32 a
, CPUARMState
*env
)
2442 return float32_sqrt(a
, &env
->vfp
.fp_status
);
2445 float64
VFP_HELPER(sqrt
, d
)(float64 a
, CPUARMState
*env
)
2447 return float64_sqrt(a
, &env
->vfp
.fp_status
);
2450 /* XXX: check quiet/signaling case */
2451 #define DO_VFP_cmp(p, type) \
2452 void VFP_HELPER(cmp, p)(type a, type b, CPUARMState *env) \
2455 switch(type ## _compare_quiet(a, b, &env->vfp.fp_status)) { \
2456 case 0: flags = 0x6; break; \
2457 case -1: flags = 0x8; break; \
2458 case 1: flags = 0x2; break; \
2459 default: case 2: flags = 0x3; break; \
2461 env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2462 | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2464 void VFP_HELPER(cmpe, p)(type a, type b, CPUARMState *env) \
2467 switch(type ## _compare(a, b, &env->vfp.fp_status)) { \
2468 case 0: flags = 0x6; break; \
2469 case -1: flags = 0x8; break; \
2470 case 1: flags = 0x2; break; \
2471 default: case 2: flags = 0x3; break; \
2473 env->vfp.xregs[ARM_VFP_FPSCR] = (flags << 28) \
2474 | (env->vfp.xregs[ARM_VFP_FPSCR] & 0x0fffffff); \
2476 DO_VFP_cmp(s
, float32
)
2477 DO_VFP_cmp(d
, float64
)
2480 /* Integer to float and float to integer conversions */
2482 #define CONV_ITOF(name, fsz, sign) \
2483 float##fsz HELPER(name)(uint32_t x, void *fpstp) \
2485 float_status *fpst = fpstp; \
2486 return sign##int32_to_##float##fsz((sign##int32_t)x, fpst); \
2489 #define CONV_FTOI(name, fsz, sign, round) \
2490 uint32_t HELPER(name)(float##fsz x, void *fpstp) \
2492 float_status *fpst = fpstp; \
2493 if (float##fsz##_is_any_nan(x)) { \
2494 float_raise(float_flag_invalid, fpst); \
2497 return float##fsz##_to_##sign##int32##round(x, fpst); \
2500 #define FLOAT_CONVS(name, p, fsz, sign) \
2501 CONV_ITOF(vfp_##name##to##p, fsz, sign) \
2502 CONV_FTOI(vfp_to##name##p, fsz, sign, ) \
2503 CONV_FTOI(vfp_to##name##z##p, fsz, sign, _round_to_zero)
2505 FLOAT_CONVS(si
, s
, 32, )
2506 FLOAT_CONVS(si
, d
, 64, )
2507 FLOAT_CONVS(ui
, s
, 32, u
)
2508 FLOAT_CONVS(ui
, d
, 64, u
)
2514 /* floating point conversion */
2515 float64
VFP_HELPER(fcvtd
, s
)(float32 x
, CPUARMState
*env
)
2517 float64 r
= float32_to_float64(x
, &env
->vfp
.fp_status
);
2518 /* ARM requires that S<->D conversion of any kind of NaN generates
2519 * a quiet NaN by forcing the most significant frac bit to 1.
2521 return float64_maybe_silence_nan(r
);
2524 float32
VFP_HELPER(fcvts
, d
)(float64 x
, CPUARMState
*env
)
2526 float32 r
= float64_to_float32(x
, &env
->vfp
.fp_status
);
2527 /* ARM requires that S<->D conversion of any kind of NaN generates
2528 * a quiet NaN by forcing the most significant frac bit to 1.
2530 return float32_maybe_silence_nan(r
);
2533 /* VFP3 fixed point conversion. */
2534 #define VFP_CONV_FIX(name, p, fsz, itype, sign) \
2535 float##fsz HELPER(vfp_##name##to##p)(uint##fsz##_t x, uint32_t shift, \
2538 float_status *fpst = fpstp; \
2540 tmp = sign##int32_to_##float##fsz((itype##_t)x, fpst); \
2541 return float##fsz##_scalbn(tmp, -(int)shift, fpst); \
2543 uint##fsz##_t HELPER(vfp_to##name##p)(float##fsz x, uint32_t shift, \
2546 float_status *fpst = fpstp; \
2548 if (float##fsz##_is_any_nan(x)) { \
2549 float_raise(float_flag_invalid, fpst); \
2552 tmp = float##fsz##_scalbn(x, shift, fpst); \
2553 return float##fsz##_to_##itype##_round_to_zero(tmp, fpst); \
2556 VFP_CONV_FIX(sh
, d
, 64, int16
, )
2557 VFP_CONV_FIX(sl
, d
, 64, int32
, )
2558 VFP_CONV_FIX(uh
, d
, 64, uint16
, u
)
2559 VFP_CONV_FIX(ul
, d
, 64, uint32
, u
)
2560 VFP_CONV_FIX(sh
, s
, 32, int16
, )
2561 VFP_CONV_FIX(sl
, s
, 32, int32
, )
2562 VFP_CONV_FIX(uh
, s
, 32, uint16
, u
)
2563 VFP_CONV_FIX(ul
, s
, 32, uint32
, u
)
2566 /* Half precision conversions. */
2567 static float32
do_fcvt_f16_to_f32(uint32_t a
, CPUARMState
*env
, float_status
*s
)
2569 int ieee
= (env
->vfp
.xregs
[ARM_VFP_FPSCR
] & (1 << 26)) == 0;
2570 float32 r
= float16_to_float32(make_float16(a
), ieee
, s
);
2572 return float32_maybe_silence_nan(r
);
2577 static uint32_t do_fcvt_f32_to_f16(float32 a
, CPUARMState
*env
, float_status
*s
)
2579 int ieee
= (env
->vfp
.xregs
[ARM_VFP_FPSCR
] & (1 << 26)) == 0;
2580 float16 r
= float32_to_float16(a
, ieee
, s
);
2582 r
= float16_maybe_silence_nan(r
);
2584 return float16_val(r
);
2587 float32
HELPER(neon_fcvt_f16_to_f32
)(uint32_t a
, CPUARMState
*env
)
2589 return do_fcvt_f16_to_f32(a
, env
, &env
->vfp
.standard_fp_status
);
2592 uint32_t HELPER(neon_fcvt_f32_to_f16
)(float32 a
, CPUARMState
*env
)
2594 return do_fcvt_f32_to_f16(a
, env
, &env
->vfp
.standard_fp_status
);
2597 float32
HELPER(vfp_fcvt_f16_to_f32
)(uint32_t a
, CPUARMState
*env
)
2599 return do_fcvt_f16_to_f32(a
, env
, &env
->vfp
.fp_status
);
2602 uint32_t HELPER(vfp_fcvt_f32_to_f16
)(float32 a
, CPUARMState
*env
)
2604 return do_fcvt_f32_to_f16(a
, env
, &env
->vfp
.fp_status
);
2607 #define float32_two make_float32(0x40000000)
2608 #define float32_three make_float32(0x40400000)
2609 #define float32_one_point_five make_float32(0x3fc00000)
2611 float32
HELPER(recps_f32
)(float32 a
, float32 b
, CPUARMState
*env
)
2613 float_status
*s
= &env
->vfp
.standard_fp_status
;
2614 if ((float32_is_infinity(a
) && float32_is_zero_or_denormal(b
)) ||
2615 (float32_is_infinity(b
) && float32_is_zero_or_denormal(a
))) {
2616 if (!(float32_is_zero(a
) || float32_is_zero(b
))) {
2617 float_raise(float_flag_input_denormal
, s
);
2621 return float32_sub(float32_two
, float32_mul(a
, b
, s
), s
);
2624 float32
HELPER(rsqrts_f32
)(float32 a
, float32 b
, CPUARMState
*env
)
2626 float_status
*s
= &env
->vfp
.standard_fp_status
;
2628 if ((float32_is_infinity(a
) && float32_is_zero_or_denormal(b
)) ||
2629 (float32_is_infinity(b
) && float32_is_zero_or_denormal(a
))) {
2630 if (!(float32_is_zero(a
) || float32_is_zero(b
))) {
2631 float_raise(float_flag_input_denormal
, s
);
2633 return float32_one_point_five
;
2635 product
= float32_mul(a
, b
, s
);
2636 return float32_div(float32_sub(float32_three
, product
, s
), float32_two
, s
);
2641 /* Constants 256 and 512 are used in some helpers; we avoid relying on
2642 * int->float conversions at run-time. */
2643 #define float64_256 make_float64(0x4070000000000000LL)
2644 #define float64_512 make_float64(0x4080000000000000LL)
2646 /* The algorithm that must be used to calculate the estimate
2647 * is specified by the ARM ARM.
2649 static float64
recip_estimate(float64 a
, CPUARMState
*env
)
2651 /* These calculations mustn't set any fp exception flags,
2652 * so we use a local copy of the fp_status.
2654 float_status dummy_status
= env
->vfp
.standard_fp_status
;
2655 float_status
*s
= &dummy_status
;
2656 /* q = (int)(a * 512.0) */
2657 float64 q
= float64_mul(float64_512
, a
, s
);
2658 int64_t q_int
= float64_to_int64_round_to_zero(q
, s
);
2660 /* r = 1.0 / (((double)q + 0.5) / 512.0) */
2661 q
= int64_to_float64(q_int
, s
);
2662 q
= float64_add(q
, float64_half
, s
);
2663 q
= float64_div(q
, float64_512
, s
);
2664 q
= float64_div(float64_one
, q
, s
);
2666 /* s = (int)(256.0 * r + 0.5) */
2667 q
= float64_mul(q
, float64_256
, s
);
2668 q
= float64_add(q
, float64_half
, s
);
2669 q_int
= float64_to_int64_round_to_zero(q
, s
);
2671 /* return (double)s / 256.0 */
2672 return float64_div(int64_to_float64(q_int
, s
), float64_256
, s
);
2675 float32
HELPER(recpe_f32
)(float32 a
, CPUARMState
*env
)
2677 float_status
*s
= &env
->vfp
.standard_fp_status
;
2679 uint32_t val32
= float32_val(a
);
2682 int a_exp
= (val32
& 0x7f800000) >> 23;
2683 int sign
= val32
& 0x80000000;
2685 if (float32_is_any_nan(a
)) {
2686 if (float32_is_signaling_nan(a
)) {
2687 float_raise(float_flag_invalid
, s
);
2689 return float32_default_nan
;
2690 } else if (float32_is_infinity(a
)) {
2691 return float32_set_sign(float32_zero
, float32_is_neg(a
));
2692 } else if (float32_is_zero_or_denormal(a
)) {
2693 if (!float32_is_zero(a
)) {
2694 float_raise(float_flag_input_denormal
, s
);
2696 float_raise(float_flag_divbyzero
, s
);
2697 return float32_set_sign(float32_infinity
, float32_is_neg(a
));
2698 } else if (a_exp
>= 253) {
2699 float_raise(float_flag_underflow
, s
);
2700 return float32_set_sign(float32_zero
, float32_is_neg(a
));
2703 f64
= make_float64((0x3feULL
<< 52)
2704 | ((int64_t)(val32
& 0x7fffff) << 29));
2706 result_exp
= 253 - a_exp
;
2708 f64
= recip_estimate(f64
, env
);
2711 | ((result_exp
& 0xff) << 23)
2712 | ((float64_val(f64
) >> 29) & 0x7fffff);
2713 return make_float32(val32
);
2716 /* The algorithm that must be used to calculate the estimate
2717 * is specified by the ARM ARM.
2719 static float64
recip_sqrt_estimate(float64 a
, CPUARMState
*env
)
2721 /* These calculations mustn't set any fp exception flags,
2722 * so we use a local copy of the fp_status.
2724 float_status dummy_status
= env
->vfp
.standard_fp_status
;
2725 float_status
*s
= &dummy_status
;
2729 if (float64_lt(a
, float64_half
, s
)) {
2730 /* range 0.25 <= a < 0.5 */
2732 /* a in units of 1/512 rounded down */
2733 /* q0 = (int)(a * 512.0); */
2734 q
= float64_mul(float64_512
, a
, s
);
2735 q_int
= float64_to_int64_round_to_zero(q
, s
);
2737 /* reciprocal root r */
2738 /* r = 1.0 / sqrt(((double)q0 + 0.5) / 512.0); */
2739 q
= int64_to_float64(q_int
, s
);
2740 q
= float64_add(q
, float64_half
, s
);
2741 q
= float64_div(q
, float64_512
, s
);
2742 q
= float64_sqrt(q
, s
);
2743 q
= float64_div(float64_one
, q
, s
);
2745 /* range 0.5 <= a < 1.0 */
2747 /* a in units of 1/256 rounded down */
2748 /* q1 = (int)(a * 256.0); */
2749 q
= float64_mul(float64_256
, a
, s
);
2750 int64_t q_int
= float64_to_int64_round_to_zero(q
, s
);
2752 /* reciprocal root r */
2753 /* r = 1.0 /sqrt(((double)q1 + 0.5) / 256); */
2754 q
= int64_to_float64(q_int
, s
);
2755 q
= float64_add(q
, float64_half
, s
);
2756 q
= float64_div(q
, float64_256
, s
);
2757 q
= float64_sqrt(q
, s
);
2758 q
= float64_div(float64_one
, q
, s
);
2760 /* r in units of 1/256 rounded to nearest */
2761 /* s = (int)(256.0 * r + 0.5); */
2763 q
= float64_mul(q
, float64_256
,s
);
2764 q
= float64_add(q
, float64_half
, s
);
2765 q_int
= float64_to_int64_round_to_zero(q
, s
);
2767 /* return (double)s / 256.0;*/
2768 return float64_div(int64_to_float64(q_int
, s
), float64_256
, s
);
2771 float32
HELPER(rsqrte_f32
)(float32 a
, CPUARMState
*env
)
2773 float_status
*s
= &env
->vfp
.standard_fp_status
;
2779 val
= float32_val(a
);
2781 if (float32_is_any_nan(a
)) {
2782 if (float32_is_signaling_nan(a
)) {
2783 float_raise(float_flag_invalid
, s
);
2785 return float32_default_nan
;
2786 } else if (float32_is_zero_or_denormal(a
)) {
2787 if (!float32_is_zero(a
)) {
2788 float_raise(float_flag_input_denormal
, s
);
2790 float_raise(float_flag_divbyzero
, s
);
2791 return float32_set_sign(float32_infinity
, float32_is_neg(a
));
2792 } else if (float32_is_neg(a
)) {
2793 float_raise(float_flag_invalid
, s
);
2794 return float32_default_nan
;
2795 } else if (float32_is_infinity(a
)) {
2796 return float32_zero
;
2799 /* Normalize to a double-precision value between 0.25 and 1.0,
2800 * preserving the parity of the exponent. */
2801 if ((val
& 0x800000) == 0) {
2802 f64
= make_float64(((uint64_t)(val
& 0x80000000) << 32)
2804 | ((uint64_t)(val
& 0x7fffff) << 29));
2806 f64
= make_float64(((uint64_t)(val
& 0x80000000) << 32)
2808 | ((uint64_t)(val
& 0x7fffff) << 29));
2811 result_exp
= (380 - ((val
& 0x7f800000) >> 23)) / 2;
2813 f64
= recip_sqrt_estimate(f64
, env
);
2815 val64
= float64_val(f64
);
2817 val
= ((result_exp
& 0xff) << 23)
2818 | ((val64
>> 29) & 0x7fffff);
2819 return make_float32(val
);
2822 uint32_t HELPER(recpe_u32
)(uint32_t a
, CPUARMState
*env
)
2826 if ((a
& 0x80000000) == 0) {
2830 f64
= make_float64((0x3feULL
<< 52)
2831 | ((int64_t)(a
& 0x7fffffff) << 21));
2833 f64
= recip_estimate (f64
, env
);
2835 return 0x80000000 | ((float64_val(f64
) >> 21) & 0x7fffffff);
2838 uint32_t HELPER(rsqrte_u32
)(uint32_t a
, CPUARMState
*env
)
2842 if ((a
& 0xc0000000) == 0) {
2846 if (a
& 0x80000000) {
2847 f64
= make_float64((0x3feULL
<< 52)
2848 | ((uint64_t)(a
& 0x7fffffff) << 21));
2849 } else { /* bits 31-30 == '01' */
2850 f64
= make_float64((0x3fdULL
<< 52)
2851 | ((uint64_t)(a
& 0x3fffffff) << 22));
2854 f64
= recip_sqrt_estimate(f64
, env
);
2856 return 0x80000000 | ((float64_val(f64
) >> 21) & 0x7fffffff);
2859 /* VFPv4 fused multiply-accumulate */
2860 float32
VFP_HELPER(muladd
, s
)(float32 a
, float32 b
, float32 c
, void *fpstp
)
2862 float_status
*fpst
= fpstp
;
2863 return float32_muladd(a
, b
, c
, 0, fpst
);
2866 float64
VFP_HELPER(muladd
, d
)(float64 a
, float64 b
, float64 c
, void *fpstp
)
2868 float_status
*fpst
= fpstp
;
2869 return float64_muladd(a
, b
, c
, 0, fpst
);
2872 void HELPER(set_teecr
)(CPUARMState
*env
, uint32_t val
)
2875 if (env
->teecr
!= val
) {