summaryrefslogtreecommitdiff
path: root/target-arm/internals.h
diff options
context:
space:
mode:
authorEdgar E. Iglesias <edgar.iglesias@xilinx.com>2014-08-04 14:41:54 +0100
committerPeter Maydell <peter.maydell@linaro.org>2014-08-04 14:41:54 +0100
commit9208b9617f18b56ba4eb32928ae8f6439ba38a24 (patch)
treece1ddd6748cdb2761a558a5099347f5d243dcf81 /target-arm/internals.h
parent9db11cef8c557ccc6e0a3e7eca786b197eed5f59 (diff)
downloadqemu-9208b9617f18b56ba4eb32928ae8f6439ba38a24.tar.gz
target-arm: A64: Break out aarch64_save/restore_sp
Break out code to save/restore AArch64 SP into functions. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@xilinx.com> Reviewed-by: Greg Bellows <greg.bellows@linaro.org> Message-id: 1402994746-8328-2-git-send-email-edgar.iglesias@gmail.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target-arm/internals.h')
-rw-r--r--target-arm/internals.h29
1 files changed, 20 insertions, 9 deletions
diff --git a/target-arm/internals.h b/target-arm/internals.h
index 564b5fa602..08fa69757d 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -105,6 +105,24 @@ enum arm_fprounding {
int arm_rmode_to_sf(int rmode);
+static inline void aarch64_save_sp(CPUARMState *env, int el)
+{
+ if (env->pstate & PSTATE_SP) {
+ env->sp_el[el] = env->xregs[31];
+ } else {
+ env->sp_el[0] = env->xregs[31];
+ }
+}
+
+static inline void aarch64_restore_sp(CPUARMState *env, int el)
+{
+ if (env->pstate & PSTATE_SP) {
+ env->xregs[31] = env->sp_el[el];
+ } else {
+ env->xregs[31] = env->sp_el[0];
+ }
+}
+
static inline void update_spsel(CPUARMState *env, uint32_t imm)
{
unsigned int cur_el = arm_current_pl(env);
@@ -114,21 +132,14 @@ static inline void update_spsel(CPUARMState *env, uint32_t imm)
if (!((imm ^ env->pstate) & PSTATE_SP)) {
return;
}
+ aarch64_save_sp(env, cur_el);
env->pstate = deposit32(env->pstate, 0, 1, imm);
/* We rely on illegal updates to SPsel from EL0 to get trapped
* at translation time.
*/
assert(cur_el >= 1 && cur_el <= 3);
- if (env->pstate & PSTATE_SP) {
- /* Switch from using SP_EL0 to using SP_ELx */
- env->sp_el[0] = env->xregs[31];
- env->xregs[31] = env->sp_el[cur_el];
- } else {
- /* Switch from SP_EL0 to SP_ELx */
- env->sp_el[cur_el] = env->xregs[31];
- env->xregs[31] = env->sp_el[0];
- }
+ aarch64_restore_sp(env, cur_el);
}
/* Valid Syndrome Register EC field values */