]>
git.proxmox.com Git - mirror_qemu.git/blob - target/hppa/op_helper.c
2 * Helpers for HPPA instructions.
4 * Copyright (c) 2016 Richard Henderson <rth@twiddle.net>
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.
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.
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/>.
20 #include "qemu/osdep.h"
22 #include "exec/exec-all.h"
23 #include "exec/helper-proto.h"
24 #include "exec/cpu_ldst.h"
26 void QEMU_NORETURN
HELPER(excp
)(CPUHPPAState
*env
, int excp
)
28 HPPACPU
*cpu
= hppa_env_get_cpu(env
);
29 CPUState
*cs
= CPU(cpu
);
31 cs
->exception_index
= excp
;
35 static void QEMU_NORETURN
dynexcp(CPUHPPAState
*env
, int excp
, uintptr_t ra
)
37 HPPACPU
*cpu
= hppa_env_get_cpu(env
);
38 CPUState
*cs
= CPU(cpu
);
40 cs
->exception_index
= excp
;
41 cpu_loop_exit_restore(cs
, ra
);
44 void HELPER(tsv
)(CPUHPPAState
*env
, target_ulong cond
)
46 if (unlikely((target_long
)cond
< 0)) {
47 dynexcp(env
, EXCP_SIGFPE
, GETPC());
51 void HELPER(tcond
)(CPUHPPAState
*env
, target_ulong cond
)
54 dynexcp(env
, EXCP_SIGFPE
, GETPC());
58 static void atomic_store_3(CPUHPPAState
*env
, target_ulong addr
, uint32_t val
,
59 uint32_t mask
, uintptr_t ra
)
61 uint32_t old
, new, cmp
;
63 #ifdef CONFIG_USER_ONLY
64 uint32_t *haddr
= g2h(addr
- 1);
67 new = (old
& ~mask
) | (val
& mask
);
68 cmp
= atomic_cmpxchg(haddr
, old
, new);
75 #error "Not implemented."
79 void HELPER(stby_b
)(CPUHPPAState
*env
, target_ulong addr
, target_ulong val
)
81 uintptr_t ra
= GETPC();
85 cpu_stb_data_ra(env
, addr
, val
, ra
);
88 cpu_stw_data_ra(env
, addr
, val
, ra
);
91 /* The 3 byte store must appear atomic. */
93 atomic_store_3(env
, addr
, val
, 0x00ffffffu
, ra
);
95 cpu_stb_data_ra(env
, addr
, val
>> 16, ra
);
96 cpu_stw_data_ra(env
, addr
+ 1, val
, ra
);
100 cpu_stl_data_ra(env
, addr
, val
, ra
);
105 void HELPER(stby_e
)(CPUHPPAState
*env
, target_ulong addr
, target_ulong val
)
107 uintptr_t ra
= GETPC();
111 /* The 3 byte store must appear atomic. */
113 atomic_store_3(env
, addr
- 3, val
, 0xffffff00u
, ra
);
115 cpu_stw_data_ra(env
, addr
- 3, val
>> 16, ra
);
116 cpu_stb_data_ra(env
, addr
- 1, val
>> 8, ra
);
120 cpu_stw_data_ra(env
, addr
- 2, val
>> 16, ra
);
123 cpu_stb_data_ra(env
, addr
- 1, val
>> 24, ra
);
126 /* Nothing is stored, but protection is checked and the
127 cacheline is marked dirty. */
128 #ifndef CONFIG_USER_ONLY
129 probe_write(env
, addr
, cpu_mmu_index(env
, 0), ra
);
135 target_ulong
HELPER(probe_r
)(target_ulong addr
)
137 return page_check_range(addr
, 1, PAGE_READ
);
140 target_ulong
HELPER(probe_w
)(target_ulong addr
)
142 return page_check_range(addr
, 1, PAGE_WRITE
);
145 void HELPER(loaded_fr0
)(CPUHPPAState
*env
)
147 uint32_t shadow
= env
->fr
[0] >> 32;
150 env
->fr0_shadow
= shadow
;
152 switch (extract32(shadow
, 9, 2)) {
154 rm
= float_round_nearest_even
;
157 rm
= float_round_to_zero
;
163 rm
= float_round_down
;
166 set_float_rounding_mode(rm
, &env
->fp_status
);
168 d
= extract32(shadow
, 5, 1);
169 set_flush_to_zero(d
, &env
->fp_status
);
170 set_flush_inputs_to_zero(d
, &env
->fp_status
);
173 void cpu_hppa_loaded_fr0(CPUHPPAState
*env
)
175 helper_loaded_fr0(env
);