Revision e80cfcfc target-sparc/op_helper.c
b/target-sparc/op_helper.c | ||
---|---|---|
2 | 2 |
#include <fenv.h> |
3 | 3 |
#include "exec.h" |
4 | 4 |
|
5 |
//#define DEBUG_MMU |
|
6 |
|
|
5 | 7 |
#ifdef USE_INT_TO_FLOAT_HELPERS |
6 | 8 |
void do_fitos(void) |
7 | 9 |
{ |
... | ... | |
33 | 35 |
{ |
34 | 36 |
if (isnan(FT0) || isnan(FT1)) { |
35 | 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 |
} |
|
36 | 45 |
} else if (FT0 < FT1) { |
37 | 46 |
T0 = FSR_FCC0; |
38 | 47 |
} else if (FT0 > FT1) { |
... | ... | |
47 | 56 |
{ |
48 | 57 |
if (isnan(DT0) || isnan(DT1)) { |
49 | 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 |
} |
|
50 | 66 |
} else if (DT0 < DT1) { |
51 | 67 |
T0 = FSR_FCC0; |
52 | 68 |
} else if (DT0 > DT1) { |
... | ... | |
59 | 75 |
|
60 | 76 |
void helper_ld_asi(int asi, int size, int sign) |
61 | 77 |
{ |
62 |
switch(asi) { |
|
78 |
uint32_t ret; |
|
79 |
|
|
80 |
switch (asi) { |
|
63 | 81 |
case 3: /* MMU probe */ |
64 |
T1 = 0; |
|
65 |
return; |
|
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; |
|
66 | 97 |
case 4: /* read MMU regs */ |
67 | 98 |
{ |
68 |
int temp, reg = (T0 >> 8) & 0xf;
|
|
99 |
int reg = (T0 >> 8) & 0xf; |
|
69 | 100 |
|
70 |
temp = env->mmuregs[reg];
|
|
101 |
ret = env->mmuregs[reg];
|
|
71 | 102 |
if (reg == 3 || reg == 4) /* Fault status, addr cleared on read*/ |
72 |
env->mmuregs[reg] = 0; |
|
73 |
T1 = temp; |
|
103 |
env->mmuregs[4] = 0; |
|
74 | 104 |
} |
75 |
return;
|
|
105 |
break;
|
|
76 | 106 |
case 0x20 ... 0x2f: /* MMU passthrough */ |
77 |
{ |
|
78 |
int temp; |
|
79 |
|
|
80 |
cpu_physical_memory_read(T0, (void *) &temp, size); |
|
81 |
bswap32s(&temp); |
|
82 |
T1 = temp; |
|
83 |
} |
|
84 |
return; |
|
107 |
cpu_physical_memory_read(T0, (void *) &ret, size); |
|
108 |
if (size == 4) |
|
109 |
bswap32s(&ret); |
|
110 |
else if (size == 2) |
|
111 |
bswap16s(&ret); |
|
112 |
break; |
|
85 | 113 |
default: |
86 |
T1 = 0;
|
|
87 |
return;
|
|
114 |
ret = 0;
|
|
115 |
break;
|
|
88 | 116 |
} |
117 |
T1 = ret; |
|
89 | 118 |
} |
90 | 119 |
|
91 | 120 |
void helper_st_asi(int asi, int size, int sign) |
92 | 121 |
{ |
93 | 122 |
switch(asi) { |
94 | 123 |
case 3: /* MMU flush */ |
95 |
return; |
|
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 |
} |
|
96 | 144 |
case 4: /* write MMU regs */ |
97 | 145 |
{ |
98 |
int reg = (T0 >> 8) & 0xf; |
|
146 |
int reg = (T0 >> 8) & 0xf, oldreg; |
|
147 |
|
|
148 |
oldreg = env->mmuregs[reg]; |
|
99 | 149 |
if (reg == 0) { |
100 | 150 |
env->mmuregs[reg] &= ~(MMU_E | MMU_NF); |
101 | 151 |
env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF); |
102 | 152 |
} else |
103 | 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(); |
|
104 | 163 |
return; |
105 | 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; |
|
106 | 195 |
case 0x20 ... 0x2f: /* MMU passthrough */ |
107 | 196 |
{ |
108 | 197 |
int temp = T1; |
109 |
|
|
110 |
bswap32s(&temp); |
|
198 |
if (size == 4) |
|
199 |
bswap32s(&temp); |
|
200 |
else if (size == 2) |
|
201 |
bswap16s(&temp); |
|
202 |
|
|
111 | 203 |
cpu_physical_memory_write(T0, (void *) &temp, size); |
112 | 204 |
} |
113 | 205 |
return; |
... | ... | |
116 | 208 |
} |
117 | 209 |
} |
118 | 210 |
|
119 |
#if 0 |
|
120 |
void do_ldd_raw(uint32_t addr) |
|
121 |
{ |
|
122 |
T1 = ldl_raw((void *) addr); |
|
123 |
T0 = ldl_raw((void *) (addr + 4)); |
|
124 |
} |
|
125 |
|
|
126 |
#if !defined(CONFIG_USER_ONLY) |
|
127 |
void do_ldd_user(uint32_t addr) |
|
128 |
{ |
|
129 |
T1 = ldl_user((void *) addr); |
|
130 |
T0 = ldl_user((void *) (addr + 4)); |
|
131 |
} |
|
132 |
void do_ldd_kernel(uint32_t addr) |
|
133 |
{ |
|
134 |
T1 = ldl_kernel((void *) addr); |
|
135 |
T0 = ldl_kernel((void *) (addr + 4)); |
|
136 |
} |
|
137 |
#endif |
|
138 |
#endif |
|
139 |
|
|
140 | 211 |
void helper_rett() |
141 | 212 |
{ |
142 | 213 |
int cwp; |
... | ... | |
166 | 237 |
break; |
167 | 238 |
} |
168 | 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 |
} |
Also available in: Unified diff