2 * Alpha emulation cpu helpers for qemu.
4 * Copyright (c) 2007 Jocelyn Mayer
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/>.
26 #include "softfloat.h"
28 uint64_t cpu_alpha_load_fpcr (CPUState
*env
)
33 t
= env
->fpcr_exc_status
;
36 if (t
& float_flag_invalid
) {
39 if (t
& float_flag_divbyzero
) {
42 if (t
& float_flag_overflow
) {
45 if (t
& float_flag_underflow
) {
48 if (t
& float_flag_inexact
) {
53 t
= env
->fpcr_exc_mask
;
54 if (t
& float_flag_invalid
) {
57 if (t
& float_flag_divbyzero
) {
60 if (t
& float_flag_overflow
) {
63 if (t
& float_flag_underflow
) {
66 if (t
& float_flag_inexact
) {
70 switch (env
->fpcr_dyn_round
) {
71 case float_round_nearest_even
:
74 case float_round_down
:
80 case float_round_to_zero
:
81 r
|= FPCR_DYN_CHOPPED
;
98 void cpu_alpha_store_fpcr (CPUState
*env
, uint64_t val
)
103 if (val
& FPCR_INV
) {
104 t
|= float_flag_invalid
;
106 if (val
& FPCR_DZE
) {
107 t
|= float_flag_divbyzero
;
109 if (val
& FPCR_OVF
) {
110 t
|= float_flag_overflow
;
112 if (val
& FPCR_UNF
) {
113 t
|= float_flag_underflow
;
115 if (val
& FPCR_INE
) {
116 t
|= float_flag_inexact
;
118 env
->fpcr_exc_status
= t
;
121 if (val
& FPCR_INVD
) {
122 t
|= float_flag_invalid
;
124 if (val
& FPCR_DZED
) {
125 t
|= float_flag_divbyzero
;
127 if (val
& FPCR_OVFD
) {
128 t
|= float_flag_overflow
;
130 if (val
& FPCR_UNFD
) {
131 t
|= float_flag_underflow
;
133 if (val
& FPCR_INED
) {
134 t
|= float_flag_inexact
;
136 env
->fpcr_exc_mask
= t
;
138 switch (val
& FPCR_DYN_MASK
) {
139 case FPCR_DYN_CHOPPED
:
140 t
= float_round_to_zero
;
143 t
= float_round_down
;
145 case FPCR_DYN_NORMAL
:
146 t
= float_round_nearest_even
;
152 env
->fpcr_dyn_round
= t
;
154 env
->fpcr_flush_to_zero
155 = (val
& (FPCR_UNDZ
|FPCR_UNFD
)) == (FPCR_UNDZ
|FPCR_UNFD
);
157 env
->fpcr_dnz
= (val
& FPCR_DNZ
) != 0;
158 env
->fpcr_dnod
= (val
& FPCR_DNOD
) != 0;
159 env
->fpcr_undz
= (val
& FPCR_UNDZ
) != 0;
162 #if defined(CONFIG_USER_ONLY)
164 int cpu_alpha_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
165 int mmu_idx
, int is_softmmu
)
168 env
->exception_index
= EXCP_ITB_MISS
;
170 env
->exception_index
= EXCP_DFAULT
;
171 env
->trap_arg0
= address
;
175 void do_interrupt (CPUState
*env
)
177 env
->exception_index
= -1;
182 target_phys_addr_t
cpu_get_phys_page_debug (CPUState
*env
, target_ulong addr
)
187 int cpu_alpha_handle_mmu_fault (CPUState
*env
, target_ulong address
, int rw
,
188 int mmu_idx
, int is_softmmu
)
193 void do_interrupt (CPUState
*env
)
199 void cpu_dump_state (CPUState
*env
, FILE *f
, fprintf_function cpu_fprintf
,
202 static const char *linux_reg_names
[] = {
203 "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ",
204 "t7 ", "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "fp ",
205 "a0 ", "a1 ", "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ",
206 "t10", "t11", "ra ", "t12", "at ", "gp ", "sp ", "zero",
210 cpu_fprintf(f
, " PC " TARGET_FMT_lx
" PS %02x\n",
212 for (i
= 0; i
< 31; i
++) {
213 cpu_fprintf(f
, "IR%02d %s " TARGET_FMT_lx
" ", i
,
214 linux_reg_names
[i
], env
->ir
[i
]);
216 cpu_fprintf(f
, "\n");
219 cpu_fprintf(f
, "lock_a " TARGET_FMT_lx
" lock_v " TARGET_FMT_lx
"\n",
220 env
->lock_addr
, env
->lock_value
);
222 for (i
= 0; i
< 31; i
++) {
223 cpu_fprintf(f
, "FIR%02d " TARGET_FMT_lx
" ", i
,
224 *((uint64_t *)(&env
->fir
[i
])));
226 cpu_fprintf(f
, "\n");
228 cpu_fprintf(f
, "\n");