target-alpha: Enable the alpha-softmmu target.
[qemu.git] / target-alpha / helper.c
blob5c3263bd7debb1a3dbcfda57231e8ad599ae1f8d
1 /*
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/>.
20 #include <stdint.h>
21 #include <stdlib.h>
22 #include <stdio.h>
24 #include "cpu.h"
25 #include "exec-all.h"
26 #include "softfloat.h"
28 uint64_t cpu_alpha_load_fpcr (CPUState *env)
30 uint64_t r = 0;
31 uint8_t t;
33 t = env->fpcr_exc_status;
34 if (t) {
35 r = FPCR_SUM;
36 if (t & float_flag_invalid) {
37 r |= FPCR_INV;
39 if (t & float_flag_divbyzero) {
40 r |= FPCR_DZE;
42 if (t & float_flag_overflow) {
43 r |= FPCR_OVF;
45 if (t & float_flag_underflow) {
46 r |= FPCR_UNF;
48 if (t & float_flag_inexact) {
49 r |= FPCR_INE;
53 t = env->fpcr_exc_mask;
54 if (t & float_flag_invalid) {
55 r |= FPCR_INVD;
57 if (t & float_flag_divbyzero) {
58 r |= FPCR_DZED;
60 if (t & float_flag_overflow) {
61 r |= FPCR_OVFD;
63 if (t & float_flag_underflow) {
64 r |= FPCR_UNFD;
66 if (t & float_flag_inexact) {
67 r |= FPCR_INED;
70 switch (env->fpcr_dyn_round) {
71 case float_round_nearest_even:
72 r |= FPCR_DYN_NORMAL;
73 break;
74 case float_round_down:
75 r |= FPCR_DYN_MINUS;
76 break;
77 case float_round_up:
78 r |= FPCR_DYN_PLUS;
79 break;
80 case float_round_to_zero:
81 r |= FPCR_DYN_CHOPPED;
82 break;
85 if (env->fpcr_dnz) {
86 r |= FPCR_DNZ;
88 if (env->fpcr_dnod) {
89 r |= FPCR_DNOD;
91 if (env->fpcr_undz) {
92 r |= FPCR_UNDZ;
95 return r;
98 void cpu_alpha_store_fpcr (CPUState *env, uint64_t val)
100 uint8_t t;
102 t = 0;
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;
120 t = 0;
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;
141 break;
142 case FPCR_DYN_MINUS:
143 t = float_round_down;
144 break;
145 case FPCR_DYN_NORMAL:
146 t = float_round_nearest_even;
147 break;
148 case FPCR_DYN_PLUS:
149 t = float_round_up;
150 break;
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)
167 if (rw == 2)
168 env->exception_index = EXCP_ITB_MISS;
169 else
170 env->exception_index = EXCP_DFAULT;
171 env->trap_arg0 = address;
172 return 1;
175 void do_interrupt (CPUState *env)
177 env->exception_index = -1;
180 #else
182 target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
184 return -1;
187 int cpu_alpha_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
188 int mmu_idx, int is_softmmu)
190 return 0;
193 void do_interrupt (CPUState *env)
195 abort();
197 #endif
199 void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
200 int flags)
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",
208 int i;
210 cpu_fprintf(f, " PC " TARGET_FMT_lx " PS %02x\n",
211 env->pc, env->ps);
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]);
215 if ((i % 3) == 2)
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])));
225 if ((i % 3) == 2)
226 cpu_fprintf(f, "\n");
228 cpu_fprintf(f, "\n");