summaryrefslogtreecommitdiff
path: root/target-arm/translate-a64.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-02-26 17:20:06 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-02-26 17:20:06 +0000
commit9cfa0b4e4c3076683b6c528a1a3b43d5a202a497 (patch)
treeee64227b9a748713fab27c7fc75d2812d4fdad5d /target-arm/translate-a64.c
parent4cc35614a056839df8b0675cd16f55e758cd570d (diff)
downloadqemu-9cfa0b4e4c3076683b6c528a1a3b43d5a202a497.tar.gz
target-arm: A64: Implement MSR (immediate) instructions
Implement the MSR (immediate) instructions, which can update the PSTATE SP and DAIF fields. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
Diffstat (limited to 'target-arm/translate-a64.c')
-rw-r--r--target-arm/translate-a64.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 2f47ec5a72..08ac6591b6 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -1128,7 +1128,30 @@ static void handle_sync(DisasContext *s, uint32_t insn,
static void handle_msr_i(DisasContext *s, uint32_t insn,
unsigned int op1, unsigned int op2, unsigned int crm)
{
- unsupported_encoding(s, insn);
+ int op = op1 << 3 | op2;
+ switch (op) {
+ case 0x05: /* SPSel */
+ if (s->current_pl == 0) {
+ unallocated_encoding(s);
+ return;
+ }
+ /* fall through */
+ case 0x1e: /* DAIFSet */
+ case 0x1f: /* DAIFClear */
+ {
+ TCGv_i32 tcg_imm = tcg_const_i32(crm);
+ TCGv_i32 tcg_op = tcg_const_i32(op);
+ gen_a64_set_pc_im(s->pc - 4);
+ gen_helper_msr_i_pstate(cpu_env, tcg_op, tcg_imm);
+ tcg_temp_free_i32(tcg_imm);
+ tcg_temp_free_i32(tcg_op);
+ s->is_jmp = DISAS_UPDATE;
+ break;
+ }
+ default:
+ unallocated_encoding(s);
+ return;
+ }
}
static void gen_get_nzcv(TCGv_i64 tcg_rt)