root / target-sparc / op_helper.c @ d3c61721
History | View | Annotate | Download (4.7 kB)
1 |
#include <math.h> |
---|---|
2 |
#include <fenv.h> |
3 |
#include "exec.h" |
4 |
|
5 |
//#define DEBUG_MMU
|
6 |
|
7 |
#ifdef USE_INT_TO_FLOAT_HELPERS
|
8 |
void do_fitos(void) |
9 |
{ |
10 |
FT0 = (float) *((int32_t *)&FT1);
|
11 |
} |
12 |
|
13 |
void do_fitod(void) |
14 |
{ |
15 |
DT0 = (double) *((int32_t *)&FT1);
|
16 |
} |
17 |
#endif
|
18 |
|
19 |
void do_fabss(void) |
20 |
{ |
21 |
FT0 = fabsf(FT1); |
22 |
} |
23 |
|
24 |
void do_fsqrts(void) |
25 |
{ |
26 |
FT0 = sqrtf(FT1); |
27 |
} |
28 |
|
29 |
void do_fsqrtd(void) |
30 |
{ |
31 |
DT0 = sqrt(DT1); |
32 |
} |
33 |
|
34 |
void do_fcmps (void) |
35 |
{ |
36 |
if (isnan(FT0) || isnan(FT1)) {
|
37 |
T0 = FSR_FCC1 | FSR_FCC0; |
38 |
env->fsr &= ~(FSR_FCC1 | FSR_FCC0); |
39 |
env->fsr |= T0; |
40 |
if (env->fsr & FSR_NVM) {
|
41 |
raise_exception(TT_FP_EXCP); |
42 |
} else {
|
43 |
env->fsr |= FSR_NVA; |
44 |
} |
45 |
} else if (FT0 < FT1) { |
46 |
T0 = FSR_FCC0; |
47 |
} else if (FT0 > FT1) { |
48 |
T0 = FSR_FCC1; |
49 |
} else {
|
50 |
T0 = 0;
|
51 |
} |
52 |
env->fsr = T0; |
53 |
} |
54 |
|
55 |
void do_fcmpd (void) |
56 |
{ |
57 |
if (isnan(DT0) || isnan(DT1)) {
|
58 |
T0 = FSR_FCC1 | FSR_FCC0; |
59 |
env->fsr &= ~(FSR_FCC1 | FSR_FCC0); |
60 |
env->fsr |= T0; |
61 |
if (env->fsr & FSR_NVM) {
|
62 |
raise_exception(TT_FP_EXCP); |
63 |
} else {
|
64 |
env->fsr |= FSR_NVA; |
65 |
} |
66 |
} else if (DT0 < DT1) { |
67 |
T0 = FSR_FCC0; |
68 |
} else if (DT0 > DT1) { |
69 |
T0 = FSR_FCC1; |
70 |
} else {
|
71 |
T0 = 0;
|
72 |
} |
73 |
env->fsr = T0; |
74 |
} |
75 |
|
76 |
void helper_ld_asi(int asi, int size, int sign) |
77 |
{ |
78 |
uint32_t ret; |
79 |
|
80 |
switch (asi) {
|
81 |
case 3: /* MMU probe */ |
82 |
{ |
83 |
int mmulev;
|
84 |
|
85 |
mmulev = (T0 >> 8) & 15; |
86 |
if (mmulev > 4) |
87 |
ret = 0;
|
88 |
else {
|
89 |
ret = mmu_probe(T0, mmulev); |
90 |
//bswap32s(&ret);
|
91 |
} |
92 |
#ifdef DEBUG_MMU
|
93 |
printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
|
94 |
#endif
|
95 |
} |
96 |
break;
|
97 |
case 4: /* read MMU regs */ |
98 |
{ |
99 |
int reg = (T0 >> 8) & 0xf; |
100 |
|
101 |
ret = env->mmuregs[reg]; |
102 |
if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/ |
103 |
env->mmuregs[4] = 0; |
104 |
} |
105 |
break;
|
106 |
case 0x20 ... 0x2f: /* MMU passthrough */ |
107 |
cpu_physical_memory_read(T0, (void *) &ret, size);
|
108 |
if (size == 4) |
109 |
bswap32s(&ret); |
110 |
else if (size == 2) |
111 |
bswap16s((uint16_t *)&ret); |
112 |
break;
|
113 |
default:
|
114 |
ret = 0;
|
115 |
break;
|
116 |
} |
117 |
T1 = ret; |
118 |
} |
119 |
|
120 |
void helper_st_asi(int asi, int size, int sign) |
121 |
{ |
122 |
switch(asi) {
|
123 |
case 3: /* MMU flush */ |
124 |
{ |
125 |
int mmulev;
|
126 |
|
127 |
mmulev = (T0 >> 8) & 15; |
128 |
switch (mmulev) {
|
129 |
case 0: // flush page |
130 |
tlb_flush_page(cpu_single_env, T0 & 0xfffff000);
|
131 |
break;
|
132 |
case 1: // flush segment (256k) |
133 |
case 2: // flush region (16M) |
134 |
case 3: // flush context (4G) |
135 |
case 4: // flush entire |
136 |
tlb_flush(cpu_single_env, 1);
|
137 |
break;
|
138 |
default:
|
139 |
break;
|
140 |
} |
141 |
dump_mmu(); |
142 |
return;
|
143 |
} |
144 |
case 4: /* write MMU regs */ |
145 |
{ |
146 |
int reg = (T0 >> 8) & 0xf, oldreg; |
147 |
|
148 |
oldreg = env->mmuregs[reg]; |
149 |
if (reg == 0) { |
150 |
env->mmuregs[reg] &= ~(MMU_E | MMU_NF); |
151 |
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF); |
152 |
} else
|
153 |
env->mmuregs[reg] = T1; |
154 |
if (oldreg != env->mmuregs[reg]) {
|
155 |
#if 0
|
156 |
// XXX: Only if MMU mapping change, we may need to flush?
|
157 |
tlb_flush(cpu_single_env, 1);
|
158 |
cpu_loop_exit();
|
159 |
FORCE_RET();
|
160 |
#endif
|
161 |
} |
162 |
dump_mmu(); |
163 |
return;
|
164 |
} |
165 |
case 0x17: /* Block copy, sta access */ |
166 |
{ |
167 |
// value (T1) = src
|
168 |
// address (T0) = dst
|
169 |
// copy 32 bytes
|
170 |
int src = T1, dst = T0;
|
171 |
uint8_t temp[32];
|
172 |
|
173 |
bswap32s(&src); |
174 |
|
175 |
cpu_physical_memory_read(src, (void *) &temp, 32); |
176 |
cpu_physical_memory_write(dst, (void *) &temp, 32); |
177 |
} |
178 |
return;
|
179 |
case 0x1f: /* Block fill, stda access */ |
180 |
{ |
181 |
// value (T1, T2)
|
182 |
// address (T0) = dst
|
183 |
// fill 32 bytes
|
184 |
int i, dst = T0;
|
185 |
uint64_t val; |
186 |
|
187 |
val = (((uint64_t)T1) << 32) | T2;
|
188 |
bswap64s(&val); |
189 |
|
190 |
for (i = 0; i < 32; i += 8, dst += 8) { |
191 |
cpu_physical_memory_write(dst, (void *) &val, 8); |
192 |
} |
193 |
} |
194 |
return;
|
195 |
case 0x20 ... 0x2f: /* MMU passthrough */ |
196 |
{ |
197 |
int temp = T1;
|
198 |
if (size == 4) |
199 |
bswap32s(&temp); |
200 |
else if (size == 2) |
201 |
bswap16s((uint16_t *)&temp); |
202 |
|
203 |
cpu_physical_memory_write(T0, (void *) &temp, size);
|
204 |
} |
205 |
return;
|
206 |
default:
|
207 |
return;
|
208 |
} |
209 |
} |
210 |
|
211 |
void helper_rett()
|
212 |
{ |
213 |
int cwp;
|
214 |
env->psret = 1;
|
215 |
cwp = (env->cwp + 1) & (NWINDOWS - 1); |
216 |
if (env->wim & (1 << cwp)) { |
217 |
raise_exception(TT_WIN_UNF); |
218 |
} |
219 |
set_cwp(cwp); |
220 |
env->psrs = env->psrps; |
221 |
} |
222 |
|
223 |
void helper_ldfsr(void) |
224 |
{ |
225 |
switch (env->fsr & FSR_RD_MASK) {
|
226 |
case FSR_RD_NEAREST:
|
227 |
fesetround(FE_TONEAREST); |
228 |
break;
|
229 |
case FSR_RD_ZERO:
|
230 |
fesetround(FE_TOWARDZERO); |
231 |
break;
|
232 |
case FSR_RD_POS:
|
233 |
fesetround(FE_UPWARD); |
234 |
break;
|
235 |
case FSR_RD_NEG:
|
236 |
fesetround(FE_DOWNWARD); |
237 |
break;
|
238 |
} |
239 |
} |
240 |
|
241 |
void cpu_get_fp64(uint64_t *pmant, uint16_t *pexp, double f) |
242 |
{ |
243 |
int exptemp;
|
244 |
|
245 |
*pmant = ldexp(frexp(f, &exptemp), 53);
|
246 |
*pexp = exptemp; |
247 |
} |
248 |
|
249 |
double cpu_put_fp64(uint64_t mant, uint16_t exp)
|
250 |
{ |
251 |
return ldexp((double) mant, exp - 53); |
252 |
} |
253 |
|
254 |
void helper_debug()
|
255 |
{ |
256 |
env->exception_index = EXCP_DEBUG; |
257 |
cpu_loop_exit(); |
258 |
} |