Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 26a76461

History | View | Annotate | Download (22.1 kB)

1 e8af50a3 bellard
#include "exec.h"
2 e8af50a3 bellard
3 83469015 bellard
//#define DEBUG_PCALL
4 e80cfcfc bellard
//#define DEBUG_MMU
5 e80cfcfc bellard
6 9d893301 bellard
void raise_exception(int tt)
7 9d893301 bellard
{
8 9d893301 bellard
    env->exception_index = tt;
9 9d893301 bellard
    cpu_loop_exit();
10 9d893301 bellard
}   
11 9d893301 bellard
12 a0c4cb4a bellard
#ifdef USE_INT_TO_FLOAT_HELPERS
13 a0c4cb4a bellard
void do_fitos(void)
14 a0c4cb4a bellard
{
15 65ce8c2f bellard
    FT0 = int32_to_float32(*((int32_t *)&FT1));
16 a0c4cb4a bellard
}
17 a0c4cb4a bellard
18 a0c4cb4a bellard
void do_fitod(void)
19 a0c4cb4a bellard
{
20 65ce8c2f bellard
    DT0 = int32_to_float64(*((int32_t *)&FT1));
21 a0c4cb4a bellard
}
22 a0c4cb4a bellard
#endif
23 a0c4cb4a bellard
24 a0c4cb4a bellard
void do_fabss(void)
25 e8af50a3 bellard
{
26 7a0e1f41 bellard
    FT0 = float32_abs(FT1);
27 e8af50a3 bellard
}
28 e8af50a3 bellard
29 3475187d bellard
#ifdef TARGET_SPARC64
30 3475187d bellard
void do_fabsd(void)
31 3475187d bellard
{
32 3475187d bellard
    DT0 = float64_abs(DT1);
33 3475187d bellard
}
34 3475187d bellard
#endif
35 3475187d bellard
36 a0c4cb4a bellard
void do_fsqrts(void)
37 e8af50a3 bellard
{
38 7a0e1f41 bellard
    FT0 = float32_sqrt(FT1, &env->fp_status);
39 e8af50a3 bellard
}
40 e8af50a3 bellard
41 a0c4cb4a bellard
void do_fsqrtd(void)
42 e8af50a3 bellard
{
43 7a0e1f41 bellard
    DT0 = float64_sqrt(DT1, &env->fp_status);
44 e8af50a3 bellard
}
45 e8af50a3 bellard
46 65ce8c2f bellard
#define GEN_FCMP(name, size, reg1, reg2, FS)                            \
47 65ce8c2f bellard
    void glue(do_, name) (void)                                         \
48 65ce8c2f bellard
    {                                                                   \
49 65ce8c2f bellard
        env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                     \
50 65ce8c2f bellard
        switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) {   \
51 65ce8c2f bellard
        case float_relation_unordered:                                  \
52 65ce8c2f bellard
            T0 = (FSR_FCC1 | FSR_FCC0) << FS;                           \
53 65ce8c2f bellard
            if (env->fsr & FSR_NVM) {                                   \
54 65ce8c2f bellard
                env->fsr |= T0;                                         \
55 65ce8c2f bellard
                raise_exception(TT_FP_EXCP);                            \
56 65ce8c2f bellard
            } else {                                                    \
57 65ce8c2f bellard
                env->fsr |= FSR_NVA;                                    \
58 65ce8c2f bellard
            }                                                           \
59 65ce8c2f bellard
            break;                                                      \
60 65ce8c2f bellard
        case float_relation_less:                                       \
61 65ce8c2f bellard
            T0 = FSR_FCC0 << FS;                                        \
62 65ce8c2f bellard
            break;                                                      \
63 65ce8c2f bellard
        case float_relation_greater:                                    \
64 65ce8c2f bellard
            T0 = FSR_FCC1 << FS;                                        \
65 65ce8c2f bellard
            break;                                                      \
66 65ce8c2f bellard
        default:                                                        \
67 65ce8c2f bellard
            T0 = 0;                                                     \
68 65ce8c2f bellard
            break;                                                      \
69 65ce8c2f bellard
        }                                                               \
70 65ce8c2f bellard
        env->fsr |= T0;                                                 \
71 e8af50a3 bellard
    }
72 e8af50a3 bellard
73 65ce8c2f bellard
GEN_FCMP(fcmps, float32, FT0, FT1, 0);
74 65ce8c2f bellard
GEN_FCMP(fcmpd, float64, DT0, DT1, 0);
75 3475187d bellard
76 3475187d bellard
#ifdef TARGET_SPARC64
77 65ce8c2f bellard
GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22);
78 65ce8c2f bellard
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22);
79 3475187d bellard
80 65ce8c2f bellard
GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24);
81 65ce8c2f bellard
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24);
82 3475187d bellard
83 65ce8c2f bellard
GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26);
84 65ce8c2f bellard
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26);
85 3475187d bellard
#endif
86 3475187d bellard
87 24741ef3 bellard
#if defined(CONFIG_USER_ONLY) 
88 24741ef3 bellard
void helper_ld_asi(int asi, int size, int sign)
89 24741ef3 bellard
{
90 24741ef3 bellard
}
91 24741ef3 bellard
92 24741ef3 bellard
void helper_st_asi(int asi, int size, int sign)
93 24741ef3 bellard
{
94 24741ef3 bellard
}
95 24741ef3 bellard
#else
96 3475187d bellard
#ifndef TARGET_SPARC64
97 a0c4cb4a bellard
void helper_ld_asi(int asi, int size, int sign)
98 e8af50a3 bellard
{
99 83469015 bellard
    uint32_t ret = 0;
100 e80cfcfc bellard
101 e80cfcfc bellard
    switch (asi) {
102 e8af50a3 bellard
    case 3: /* MMU probe */
103 e80cfcfc bellard
        {
104 e80cfcfc bellard
            int mmulev;
105 e80cfcfc bellard
106 e80cfcfc bellard
            mmulev = (T0 >> 8) & 15;
107 e80cfcfc bellard
            if (mmulev > 4)
108 e80cfcfc bellard
                ret = 0;
109 e80cfcfc bellard
            else {
110 ee5bbe38 bellard
                ret = mmu_probe(env, T0, mmulev);
111 e80cfcfc bellard
                //bswap32s(&ret);
112 e80cfcfc bellard
            }
113 e80cfcfc bellard
#ifdef DEBUG_MMU
114 e80cfcfc bellard
            printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
115 e80cfcfc bellard
#endif
116 e80cfcfc bellard
        }
117 e80cfcfc bellard
        break;
118 e8af50a3 bellard
    case 4: /* read MMU regs */
119 e8af50a3 bellard
        {
120 e80cfcfc bellard
            int reg = (T0 >> 8) & 0xf;
121 e8af50a3 bellard
            
122 e80cfcfc bellard
            ret = env->mmuregs[reg];
123 55754d9e bellard
            if (reg == 3) /* Fault status cleared on read */
124 55754d9e bellard
                env->mmuregs[reg] = 0;
125 55754d9e bellard
#ifdef DEBUG_MMU
126 55754d9e bellard
            printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
127 55754d9e bellard
#endif
128 e8af50a3 bellard
        }
129 e80cfcfc bellard
        break;
130 e8af50a3 bellard
    case 0x20 ... 0x2f: /* MMU passthrough */
131 02aab46a bellard
        switch(size) {
132 02aab46a bellard
        case 1:
133 02aab46a bellard
            ret = ldub_phys(T0);
134 02aab46a bellard
            break;
135 02aab46a bellard
        case 2:
136 02aab46a bellard
            ret = lduw_phys(T0 & ~1);
137 02aab46a bellard
            break;
138 02aab46a bellard
        default:
139 02aab46a bellard
        case 4:
140 02aab46a bellard
            ret = ldl_phys(T0 & ~3);
141 02aab46a bellard
            break;
142 9e61bde5 bellard
        case 8:
143 9e61bde5 bellard
            ret = ldl_phys(T0 & ~3);
144 9e61bde5 bellard
            T0 = ldl_phys((T0 + 4) & ~3);
145 9e61bde5 bellard
            break;
146 02aab46a bellard
        }
147 e80cfcfc bellard
        break;
148 e8af50a3 bellard
    default:
149 e80cfcfc bellard
        ret = 0;
150 e80cfcfc bellard
        break;
151 e8af50a3 bellard
    }
152 e80cfcfc bellard
    T1 = ret;
153 e8af50a3 bellard
}
154 e8af50a3 bellard
155 a0c4cb4a bellard
void helper_st_asi(int asi, int size, int sign)
156 e8af50a3 bellard
{
157 e8af50a3 bellard
    switch(asi) {
158 e8af50a3 bellard
    case 3: /* MMU flush */
159 e80cfcfc bellard
        {
160 e80cfcfc bellard
            int mmulev;
161 e80cfcfc bellard
162 e80cfcfc bellard
            mmulev = (T0 >> 8) & 15;
163 55754d9e bellard
#ifdef DEBUG_MMU
164 55754d9e bellard
            printf("mmu flush level %d\n", mmulev);
165 55754d9e bellard
#endif
166 e80cfcfc bellard
            switch (mmulev) {
167 e80cfcfc bellard
            case 0: // flush page
168 55754d9e bellard
                tlb_flush_page(env, T0 & 0xfffff000);
169 e80cfcfc bellard
                break;
170 e80cfcfc bellard
            case 1: // flush segment (256k)
171 e80cfcfc bellard
            case 2: // flush region (16M)
172 e80cfcfc bellard
            case 3: // flush context (4G)
173 e80cfcfc bellard
            case 4: // flush entire
174 55754d9e bellard
                tlb_flush(env, 1);
175 e80cfcfc bellard
                break;
176 e80cfcfc bellard
            default:
177 e80cfcfc bellard
                break;
178 e80cfcfc bellard
            }
179 55754d9e bellard
#ifdef DEBUG_MMU
180 ee5bbe38 bellard
            dump_mmu(env);
181 55754d9e bellard
#endif
182 e80cfcfc bellard
            return;
183 e80cfcfc bellard
        }
184 e8af50a3 bellard
    case 4: /* write MMU regs */
185 e8af50a3 bellard
        {
186 83469015 bellard
            int reg = (T0 >> 8) & 0xf;
187 83469015 bellard
            uint32_t oldreg;
188 e80cfcfc bellard
            
189 e80cfcfc bellard
            oldreg = env->mmuregs[reg];
190 55754d9e bellard
            switch(reg) {
191 55754d9e bellard
            case 0:
192 e8af50a3 bellard
                env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
193 e8af50a3 bellard
                env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
194 6f7e9aec bellard
                // Mappings generated during no-fault mode or MMU
195 6f7e9aec bellard
                // disabled mode are invalid in normal mode
196 6f7e9aec bellard
                if (oldreg != env->mmuregs[reg])
197 55754d9e bellard
                    tlb_flush(env, 1);
198 55754d9e bellard
                break;
199 55754d9e bellard
            case 2:
200 e8af50a3 bellard
                env->mmuregs[reg] = T1;
201 55754d9e bellard
                if (oldreg != env->mmuregs[reg]) {
202 55754d9e bellard
                    /* we flush when the MMU context changes because
203 55754d9e bellard
                       QEMU has no MMU context support */
204 55754d9e bellard
                    tlb_flush(env, 1);
205 55754d9e bellard
                }
206 55754d9e bellard
                break;
207 55754d9e bellard
            case 3:
208 55754d9e bellard
            case 4:
209 55754d9e bellard
                break;
210 55754d9e bellard
            default:
211 55754d9e bellard
                env->mmuregs[reg] = T1;
212 55754d9e bellard
                break;
213 55754d9e bellard
            }
214 55754d9e bellard
#ifdef DEBUG_MMU
215 55754d9e bellard
            if (oldreg != env->mmuregs[reg]) {
216 55754d9e bellard
                printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
217 55754d9e bellard
            }
218 ee5bbe38 bellard
            dump_mmu(env);
219 55754d9e bellard
#endif
220 e8af50a3 bellard
            return;
221 e8af50a3 bellard
        }
222 e80cfcfc bellard
    case 0x17: /* Block copy, sta access */
223 e80cfcfc bellard
        {
224 e80cfcfc bellard
            // value (T1) = src
225 e80cfcfc bellard
            // address (T0) = dst
226 e80cfcfc bellard
            // copy 32 bytes
227 83469015 bellard
            uint32_t src = T1, dst = T0;
228 e80cfcfc bellard
            uint8_t temp[32];
229 e80cfcfc bellard
            
230 49be8030 bellard
            tswap32s(&src);
231 e80cfcfc bellard
232 e80cfcfc bellard
            cpu_physical_memory_read(src, (void *) &temp, 32);
233 e80cfcfc bellard
            cpu_physical_memory_write(dst, (void *) &temp, 32);
234 e80cfcfc bellard
        }
235 e80cfcfc bellard
        return;
236 e80cfcfc bellard
    case 0x1f: /* Block fill, stda access */
237 e80cfcfc bellard
        {
238 e80cfcfc bellard
            // value (T1, T2)
239 e80cfcfc bellard
            // address (T0) = dst
240 e80cfcfc bellard
            // fill 32 bytes
241 83469015 bellard
            int i;
242 83469015 bellard
            uint32_t dst = T0;
243 e80cfcfc bellard
            uint64_t val;
244 e80cfcfc bellard
            
245 e80cfcfc bellard
            val = (((uint64_t)T1) << 32) | T2;
246 49be8030 bellard
            tswap64s(&val);
247 e80cfcfc bellard
248 e80cfcfc bellard
            for (i = 0; i < 32; i += 8, dst += 8) {
249 e80cfcfc bellard
                cpu_physical_memory_write(dst, (void *) &val, 8);
250 e80cfcfc bellard
            }
251 e80cfcfc bellard
        }
252 e80cfcfc bellard
        return;
253 e8af50a3 bellard
    case 0x20 ... 0x2f: /* MMU passthrough */
254 e8af50a3 bellard
        {
255 02aab46a bellard
            switch(size) {
256 02aab46a bellard
            case 1:
257 02aab46a bellard
                stb_phys(T0, T1);
258 02aab46a bellard
                break;
259 02aab46a bellard
            case 2:
260 02aab46a bellard
                stw_phys(T0 & ~1, T1);
261 02aab46a bellard
                break;
262 02aab46a bellard
            case 4:
263 02aab46a bellard
            default:
264 02aab46a bellard
                stl_phys(T0 & ~3, T1);
265 02aab46a bellard
                break;
266 9e61bde5 bellard
            case 8:
267 9e61bde5 bellard
                stl_phys(T0 & ~3, T1);
268 9e61bde5 bellard
                stl_phys((T0 + 4) & ~3, T2);
269 9e61bde5 bellard
                break;
270 02aab46a bellard
            }
271 e8af50a3 bellard
        }
272 e8af50a3 bellard
        return;
273 e8af50a3 bellard
    default:
274 e8af50a3 bellard
        return;
275 e8af50a3 bellard
    }
276 e8af50a3 bellard
}
277 e8af50a3 bellard
278 3475187d bellard
#else
279 3475187d bellard
280 3475187d bellard
void helper_ld_asi(int asi, int size, int sign)
281 3475187d bellard
{
282 83469015 bellard
    uint64_t ret = 0;
283 3475187d bellard
284 3475187d bellard
    if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
285 83469015 bellard
        raise_exception(TT_PRIV_ACT);
286 3475187d bellard
287 3475187d bellard
    switch (asi) {
288 3475187d bellard
    case 0x14: // Bypass
289 3475187d bellard
    case 0x15: // Bypass, non-cacheable
290 3475187d bellard
        {
291 02aab46a bellard
            switch(size) {
292 02aab46a bellard
            case 1:
293 02aab46a bellard
                ret = ldub_phys(T0);
294 02aab46a bellard
                break;
295 02aab46a bellard
            case 2:
296 02aab46a bellard
                ret = lduw_phys(T0 & ~1);
297 02aab46a bellard
                break;
298 02aab46a bellard
            case 4:
299 02aab46a bellard
                ret = ldl_phys(T0 & ~3);
300 02aab46a bellard
                break;
301 02aab46a bellard
            default:
302 02aab46a bellard
            case 8:
303 02aab46a bellard
                ret = ldq_phys(T0 & ~7);
304 02aab46a bellard
                break;
305 02aab46a bellard
            }
306 3475187d bellard
            break;
307 3475187d bellard
        }
308 83469015 bellard
    case 0x04: // Nucleus
309 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
310 83469015 bellard
    case 0x10: // As if user primary
311 83469015 bellard
    case 0x11: // As if user secondary
312 83469015 bellard
    case 0x18: // As if user primary LE
313 83469015 bellard
    case 0x19: // As if user secondary LE
314 3475187d bellard
    case 0x1c: // Bypass LE
315 3475187d bellard
    case 0x1d: // Bypass, non-cacheable LE
316 83469015 bellard
    case 0x24: // Nucleus quad LDD 128 bit atomic
317 83469015 bellard
    case 0x2c: // Nucleus quad LDD 128 bit atomic
318 83469015 bellard
    case 0x4a: // UPA config
319 83469015 bellard
    case 0x82: // Primary no-fault
320 83469015 bellard
    case 0x83: // Secondary no-fault
321 83469015 bellard
    case 0x88: // Primary LE
322 83469015 bellard
    case 0x89: // Secondary LE
323 83469015 bellard
    case 0x8a: // Primary no-fault LE
324 83469015 bellard
    case 0x8b: // Secondary no-fault LE
325 3475187d bellard
        // XXX
326 3475187d bellard
        break;
327 3475187d bellard
    case 0x45: // LSU
328 3475187d bellard
        ret = env->lsu;
329 3475187d bellard
        break;
330 3475187d bellard
    case 0x50: // I-MMU regs
331 3475187d bellard
        {
332 3475187d bellard
            int reg = (T0 >> 3) & 0xf;
333 3475187d bellard
334 3475187d bellard
            ret = env->immuregs[reg];
335 3475187d bellard
            break;
336 3475187d bellard
        }
337 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer
338 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer
339 3475187d bellard
    case 0x55: // I-MMU data access
340 83469015 bellard
        // XXX
341 3475187d bellard
        break;
342 83469015 bellard
    case 0x56: // I-MMU tag read
343 83469015 bellard
        {
344 83469015 bellard
            unsigned int i;
345 83469015 bellard
            
346 83469015 bellard
            for (i = 0; i < 64; i++) {
347 83469015 bellard
                // Valid, ctx match, vaddr match
348 83469015 bellard
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
349 83469015 bellard
                    env->itlb_tag[i] == T0) {
350 83469015 bellard
                    ret = env->itlb_tag[i];
351 83469015 bellard
                    break;
352 83469015 bellard
                }
353 83469015 bellard
            }
354 83469015 bellard
            break;
355 83469015 bellard
        }
356 3475187d bellard
    case 0x58: // D-MMU regs
357 3475187d bellard
        {
358 3475187d bellard
            int reg = (T0 >> 3) & 0xf;
359 3475187d bellard
360 3475187d bellard
            ret = env->dmmuregs[reg];
361 3475187d bellard
            break;
362 3475187d bellard
        }
363 83469015 bellard
    case 0x5e: // D-MMU tag read
364 83469015 bellard
        {
365 83469015 bellard
            unsigned int i;
366 83469015 bellard
            
367 83469015 bellard
            for (i = 0; i < 64; i++) {
368 83469015 bellard
                // Valid, ctx match, vaddr match
369 83469015 bellard
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
370 83469015 bellard
                    env->dtlb_tag[i] == T0) {
371 83469015 bellard
                    ret = env->dtlb_tag[i];
372 83469015 bellard
                    break;
373 83469015 bellard
                }
374 83469015 bellard
            }
375 83469015 bellard
            break;
376 83469015 bellard
        }
377 3475187d bellard
    case 0x59: // D-MMU 8k TSB pointer
378 3475187d bellard
    case 0x5a: // D-MMU 64k TSB pointer
379 3475187d bellard
    case 0x5b: // D-MMU data pointer
380 3475187d bellard
    case 0x5d: // D-MMU data access
381 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
382 83469015 bellard
    case 0x49: // Interrupt data receive
383 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
384 83469015 bellard
        // XXX
385 3475187d bellard
        break;
386 3475187d bellard
    case 0x54: // I-MMU data in, WO
387 3475187d bellard
    case 0x57: // I-MMU demap, WO
388 3475187d bellard
    case 0x5c: // D-MMU data in, WO
389 3475187d bellard
    case 0x5f: // D-MMU demap, WO
390 83469015 bellard
    case 0x77: // Interrupt vector, WO
391 3475187d bellard
    default:
392 3475187d bellard
        ret = 0;
393 3475187d bellard
        break;
394 3475187d bellard
    }
395 3475187d bellard
    T1 = ret;
396 3475187d bellard
}
397 3475187d bellard
398 3475187d bellard
void helper_st_asi(int asi, int size, int sign)
399 3475187d bellard
{
400 3475187d bellard
    if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
401 83469015 bellard
        raise_exception(TT_PRIV_ACT);
402 3475187d bellard
403 3475187d bellard
    switch(asi) {
404 3475187d bellard
    case 0x14: // Bypass
405 3475187d bellard
    case 0x15: // Bypass, non-cacheable
406 3475187d bellard
        {
407 02aab46a bellard
            switch(size) {
408 02aab46a bellard
            case 1:
409 02aab46a bellard
                stb_phys(T0, T1);
410 02aab46a bellard
                break;
411 02aab46a bellard
            case 2:
412 02aab46a bellard
                stw_phys(T0 & ~1, T1);
413 02aab46a bellard
                break;
414 02aab46a bellard
            case 4:
415 02aab46a bellard
                stl_phys(T0 & ~3, T1);
416 02aab46a bellard
                break;
417 02aab46a bellard
            case 8:
418 02aab46a bellard
            default:
419 02aab46a bellard
                stq_phys(T0 & ~7, T1);
420 02aab46a bellard
                break;
421 02aab46a bellard
            }
422 3475187d bellard
        }
423 3475187d bellard
        return;
424 83469015 bellard
    case 0x04: // Nucleus
425 83469015 bellard
    case 0x0c: // Nucleus Little Endian (LE)
426 83469015 bellard
    case 0x10: // As if user primary
427 83469015 bellard
    case 0x11: // As if user secondary
428 83469015 bellard
    case 0x18: // As if user primary LE
429 83469015 bellard
    case 0x19: // As if user secondary LE
430 3475187d bellard
    case 0x1c: // Bypass LE
431 3475187d bellard
    case 0x1d: // Bypass, non-cacheable LE
432 83469015 bellard
    case 0x24: // Nucleus quad LDD 128 bit atomic
433 83469015 bellard
    case 0x2c: // Nucleus quad LDD 128 bit atomic
434 83469015 bellard
    case 0x4a: // UPA config
435 83469015 bellard
    case 0x88: // Primary LE
436 83469015 bellard
    case 0x89: // Secondary LE
437 3475187d bellard
        // XXX
438 3475187d bellard
        return;
439 3475187d bellard
    case 0x45: // LSU
440 3475187d bellard
        {
441 3475187d bellard
            uint64_t oldreg;
442 3475187d bellard
443 3475187d bellard
            oldreg = env->lsu;
444 3475187d bellard
            env->lsu = T1 & (DMMU_E | IMMU_E);
445 3475187d bellard
            // Mappings generated during D/I MMU disabled mode are
446 3475187d bellard
            // invalid in normal mode
447 83469015 bellard
            if (oldreg != env->lsu) {
448 83469015 bellard
#ifdef DEBUG_MMU
449 26a76461 bellard
                printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
450 83469015 bellard
                dump_mmu(env);
451 83469015 bellard
#endif
452 3475187d bellard
                tlb_flush(env, 1);
453 83469015 bellard
            }
454 3475187d bellard
            return;
455 3475187d bellard
        }
456 3475187d bellard
    case 0x50: // I-MMU regs
457 3475187d bellard
        {
458 3475187d bellard
            int reg = (T0 >> 3) & 0xf;
459 3475187d bellard
            uint64_t oldreg;
460 3475187d bellard
            
461 3475187d bellard
            oldreg = env->immuregs[reg];
462 3475187d bellard
            switch(reg) {
463 3475187d bellard
            case 0: // RO
464 3475187d bellard
            case 4:
465 3475187d bellard
                return;
466 3475187d bellard
            case 1: // Not in I-MMU
467 3475187d bellard
            case 2:
468 3475187d bellard
            case 7:
469 3475187d bellard
            case 8:
470 3475187d bellard
                return;
471 3475187d bellard
            case 3: // SFSR
472 3475187d bellard
                if ((T1 & 1) == 0)
473 3475187d bellard
                    T1 = 0; // Clear SFSR
474 3475187d bellard
                break;
475 3475187d bellard
            case 5: // TSB access
476 3475187d bellard
            case 6: // Tag access
477 3475187d bellard
            default:
478 3475187d bellard
                break;
479 3475187d bellard
            }
480 3475187d bellard
            env->immuregs[reg] = T1;
481 3475187d bellard
#ifdef DEBUG_MMU
482 3475187d bellard
            if (oldreg != env->immuregs[reg]) {
483 26a76461 bellard
                printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
484 3475187d bellard
            }
485 ee5bbe38 bellard
            dump_mmu(env);
486 3475187d bellard
#endif
487 3475187d bellard
            return;
488 3475187d bellard
        }
489 3475187d bellard
    case 0x54: // I-MMU data in
490 3475187d bellard
        {
491 3475187d bellard
            unsigned int i;
492 3475187d bellard
493 3475187d bellard
            // Try finding an invalid entry
494 3475187d bellard
            for (i = 0; i < 64; i++) {
495 3475187d bellard
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
496 3475187d bellard
                    env->itlb_tag[i] = env->immuregs[6];
497 3475187d bellard
                    env->itlb_tte[i] = T1;
498 3475187d bellard
                    return;
499 3475187d bellard
                }
500 3475187d bellard
            }
501 3475187d bellard
            // Try finding an unlocked entry
502 3475187d bellard
            for (i = 0; i < 64; i++) {
503 3475187d bellard
                if ((env->itlb_tte[i] & 0x40) == 0) {
504 3475187d bellard
                    env->itlb_tag[i] = env->immuregs[6];
505 3475187d bellard
                    env->itlb_tte[i] = T1;
506 3475187d bellard
                    return;
507 3475187d bellard
                }
508 3475187d bellard
            }
509 3475187d bellard
            // error state?
510 3475187d bellard
            return;
511 3475187d bellard
        }
512 3475187d bellard
    case 0x55: // I-MMU data access
513 3475187d bellard
        {
514 3475187d bellard
            unsigned int i = (T0 >> 3) & 0x3f;
515 3475187d bellard
516 3475187d bellard
            env->itlb_tag[i] = env->immuregs[6];
517 3475187d bellard
            env->itlb_tte[i] = T1;
518 3475187d bellard
            return;
519 3475187d bellard
        }
520 3475187d bellard
    case 0x57: // I-MMU demap
521 83469015 bellard
        // XXX
522 3475187d bellard
        return;
523 3475187d bellard
    case 0x58: // D-MMU regs
524 3475187d bellard
        {
525 3475187d bellard
            int reg = (T0 >> 3) & 0xf;
526 3475187d bellard
            uint64_t oldreg;
527 3475187d bellard
            
528 3475187d bellard
            oldreg = env->dmmuregs[reg];
529 3475187d bellard
            switch(reg) {
530 3475187d bellard
            case 0: // RO
531 3475187d bellard
            case 4:
532 3475187d bellard
                return;
533 3475187d bellard
            case 3: // SFSR
534 3475187d bellard
                if ((T1 & 1) == 0) {
535 3475187d bellard
                    T1 = 0; // Clear SFSR, Fault address
536 3475187d bellard
                    env->dmmuregs[4] = 0;
537 3475187d bellard
                }
538 3475187d bellard
                env->dmmuregs[reg] = T1;
539 3475187d bellard
                break;
540 3475187d bellard
            case 1: // Primary context
541 3475187d bellard
            case 2: // Secondary context
542 3475187d bellard
            case 5: // TSB access
543 3475187d bellard
            case 6: // Tag access
544 3475187d bellard
            case 7: // Virtual Watchpoint
545 3475187d bellard
            case 8: // Physical Watchpoint
546 3475187d bellard
            default:
547 3475187d bellard
                break;
548 3475187d bellard
            }
549 3475187d bellard
            env->dmmuregs[reg] = T1;
550 3475187d bellard
#ifdef DEBUG_MMU
551 3475187d bellard
            if (oldreg != env->dmmuregs[reg]) {
552 26a76461 bellard
                printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
553 3475187d bellard
            }
554 ee5bbe38 bellard
            dump_mmu(env);
555 3475187d bellard
#endif
556 3475187d bellard
            return;
557 3475187d bellard
        }
558 3475187d bellard
    case 0x5c: // D-MMU data in
559 3475187d bellard
        {
560 3475187d bellard
            unsigned int i;
561 3475187d bellard
562 3475187d bellard
            // Try finding an invalid entry
563 3475187d bellard
            for (i = 0; i < 64; i++) {
564 3475187d bellard
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
565 3475187d bellard
                    env->dtlb_tag[i] = env->dmmuregs[6];
566 3475187d bellard
                    env->dtlb_tte[i] = T1;
567 3475187d bellard
                    return;
568 3475187d bellard
                }
569 3475187d bellard
            }
570 3475187d bellard
            // Try finding an unlocked entry
571 3475187d bellard
            for (i = 0; i < 64; i++) {
572 3475187d bellard
                if ((env->dtlb_tte[i] & 0x40) == 0) {
573 3475187d bellard
                    env->dtlb_tag[i] = env->dmmuregs[6];
574 3475187d bellard
                    env->dtlb_tte[i] = T1;
575 3475187d bellard
                    return;
576 3475187d bellard
                }
577 3475187d bellard
            }
578 3475187d bellard
            // error state?
579 3475187d bellard
            return;
580 3475187d bellard
        }
581 3475187d bellard
    case 0x5d: // D-MMU data access
582 3475187d bellard
        {
583 3475187d bellard
            unsigned int i = (T0 >> 3) & 0x3f;
584 3475187d bellard
585 3475187d bellard
            env->dtlb_tag[i] = env->dmmuregs[6];
586 3475187d bellard
            env->dtlb_tte[i] = T1;
587 3475187d bellard
            return;
588 3475187d bellard
        }
589 3475187d bellard
    case 0x5f: // D-MMU demap
590 83469015 bellard
    case 0x49: // Interrupt data receive
591 83469015 bellard
        // XXX
592 3475187d bellard
        return;
593 3475187d bellard
    case 0x51: // I-MMU 8k TSB pointer, RO
594 3475187d bellard
    case 0x52: // I-MMU 64k TSB pointer, RO
595 3475187d bellard
    case 0x56: // I-MMU tag read, RO
596 3475187d bellard
    case 0x59: // D-MMU 8k TSB pointer, RO
597 3475187d bellard
    case 0x5a: // D-MMU 64k TSB pointer, RO
598 3475187d bellard
    case 0x5b: // D-MMU data pointer, RO
599 3475187d bellard
    case 0x5e: // D-MMU tag read, RO
600 83469015 bellard
    case 0x48: // Interrupt dispatch, RO
601 83469015 bellard
    case 0x7f: // Incoming interrupt vector, RO
602 83469015 bellard
    case 0x82: // Primary no-fault, RO
603 83469015 bellard
    case 0x83: // Secondary no-fault, RO
604 83469015 bellard
    case 0x8a: // Primary no-fault LE, RO
605 83469015 bellard
    case 0x8b: // Secondary no-fault LE, RO
606 3475187d bellard
    default:
607 3475187d bellard
        return;
608 3475187d bellard
    }
609 3475187d bellard
}
610 3475187d bellard
#endif
611 24741ef3 bellard
#endif /* !CONFIG_USER_ONLY */
612 3475187d bellard
613 3475187d bellard
#ifndef TARGET_SPARC64
614 a0c4cb4a bellard
void helper_rett()
615 e8af50a3 bellard
{
616 af7bf89b bellard
    unsigned int cwp;
617 af7bf89b bellard
618 e8af50a3 bellard
    env->psret = 1;
619 e8af50a3 bellard
    cwp = (env->cwp + 1) & (NWINDOWS - 1); 
620 e8af50a3 bellard
    if (env->wim & (1 << cwp)) {
621 e8af50a3 bellard
        raise_exception(TT_WIN_UNF);
622 e8af50a3 bellard
    }
623 e8af50a3 bellard
    set_cwp(cwp);
624 e8af50a3 bellard
    env->psrs = env->psrps;
625 e8af50a3 bellard
}
626 3475187d bellard
#endif
627 e8af50a3 bellard
628 8d5f07fa bellard
void helper_ldfsr(void)
629 e8af50a3 bellard
{
630 7a0e1f41 bellard
    int rnd_mode;
631 e8af50a3 bellard
    switch (env->fsr & FSR_RD_MASK) {
632 e8af50a3 bellard
    case FSR_RD_NEAREST:
633 7a0e1f41 bellard
        rnd_mode = float_round_nearest_even;
634 e8af50a3 bellard
        break;
635 ed910241 bellard
    default:
636 e8af50a3 bellard
    case FSR_RD_ZERO:
637 7a0e1f41 bellard
        rnd_mode = float_round_to_zero;
638 e8af50a3 bellard
        break;
639 e8af50a3 bellard
    case FSR_RD_POS:
640 7a0e1f41 bellard
        rnd_mode = float_round_up;
641 e8af50a3 bellard
        break;
642 e8af50a3 bellard
    case FSR_RD_NEG:
643 7a0e1f41 bellard
        rnd_mode = float_round_down;
644 e8af50a3 bellard
        break;
645 e8af50a3 bellard
    }
646 7a0e1f41 bellard
    set_float_rounding_mode(rnd_mode, &env->fp_status);
647 e8af50a3 bellard
}
648 e80cfcfc bellard
649 e80cfcfc bellard
void helper_debug()
650 e80cfcfc bellard
{
651 e80cfcfc bellard
    env->exception_index = EXCP_DEBUG;
652 e80cfcfc bellard
    cpu_loop_exit();
653 e80cfcfc bellard
}
654 af7bf89b bellard
655 3475187d bellard
#ifndef TARGET_SPARC64
656 af7bf89b bellard
void do_wrpsr()
657 af7bf89b bellard
{
658 af7bf89b bellard
    PUT_PSR(env, T0);
659 af7bf89b bellard
}
660 af7bf89b bellard
661 af7bf89b bellard
void do_rdpsr()
662 af7bf89b bellard
{
663 af7bf89b bellard
    T0 = GET_PSR(env);
664 af7bf89b bellard
}
665 3475187d bellard
666 3475187d bellard
#else
667 3475187d bellard
668 3475187d bellard
void do_popc()
669 3475187d bellard
{
670 3475187d bellard
    T0 = (T1 & 0x5555555555555555ULL) + ((T1 >> 1) & 0x5555555555555555ULL);
671 3475187d bellard
    T0 = (T0 & 0x3333333333333333ULL) + ((T0 >> 2) & 0x3333333333333333ULL);
672 3475187d bellard
    T0 = (T0 & 0x0f0f0f0f0f0f0f0fULL) + ((T0 >> 4) & 0x0f0f0f0f0f0f0f0fULL);
673 3475187d bellard
    T0 = (T0 & 0x00ff00ff00ff00ffULL) + ((T0 >> 8) & 0x00ff00ff00ff00ffULL);
674 3475187d bellard
    T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL);
675 3475187d bellard
    T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL);
676 3475187d bellard
}
677 83469015 bellard
678 83469015 bellard
static inline uint64_t *get_gregset(uint64_t pstate)
679 83469015 bellard
{
680 83469015 bellard
    switch (pstate) {
681 83469015 bellard
    default:
682 83469015 bellard
    case 0:
683 83469015 bellard
        return env->bgregs;
684 83469015 bellard
    case PS_AG:
685 83469015 bellard
        return env->agregs;
686 83469015 bellard
    case PS_MG:
687 83469015 bellard
        return env->mgregs;
688 83469015 bellard
    case PS_IG:
689 83469015 bellard
        return env->igregs;
690 83469015 bellard
    }
691 83469015 bellard
}
692 83469015 bellard
693 83469015 bellard
void do_wrpstate()
694 83469015 bellard
{
695 83469015 bellard
    uint64_t new_pstate, pstate_regs, new_pstate_regs;
696 83469015 bellard
    uint64_t *src, *dst;
697 83469015 bellard
698 83469015 bellard
    new_pstate = T0 & 0xf3f;
699 83469015 bellard
    pstate_regs = env->pstate & 0xc01;
700 83469015 bellard
    new_pstate_regs = new_pstate & 0xc01;
701 83469015 bellard
    if (new_pstate_regs != pstate_regs) {
702 83469015 bellard
        // Switch global register bank
703 83469015 bellard
        src = get_gregset(new_pstate_regs);
704 83469015 bellard
        dst = get_gregset(pstate_regs);
705 83469015 bellard
        memcpy32(dst, env->gregs);
706 83469015 bellard
        memcpy32(env->gregs, src);
707 83469015 bellard
    }
708 83469015 bellard
    env->pstate = new_pstate;
709 83469015 bellard
}
710 83469015 bellard
711 83469015 bellard
void do_done(void)
712 83469015 bellard
{
713 83469015 bellard
    env->tl--;
714 83469015 bellard
    env->pc = env->tnpc[env->tl];
715 83469015 bellard
    env->npc = env->tnpc[env->tl] + 4;
716 83469015 bellard
    PUT_CCR(env, env->tstate[env->tl] >> 32);
717 83469015 bellard
    env->asi = (env->tstate[env->tl] >> 24) & 0xff;
718 83469015 bellard
    env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;
719 83469015 bellard
    set_cwp(env->tstate[env->tl] & 0xff);
720 83469015 bellard
}
721 83469015 bellard
722 83469015 bellard
void do_retry(void)
723 83469015 bellard
{
724 83469015 bellard
    env->tl--;
725 83469015 bellard
    env->pc = env->tpc[env->tl];
726 83469015 bellard
    env->npc = env->tnpc[env->tl];
727 83469015 bellard
    PUT_CCR(env, env->tstate[env->tl] >> 32);
728 83469015 bellard
    env->asi = (env->tstate[env->tl] >> 24) & 0xff;
729 83469015 bellard
    env->pstate = (env->tstate[env->tl] >> 8) & 0xfff;
730 83469015 bellard
    set_cwp(env->tstate[env->tl] & 0xff);
731 83469015 bellard
}
732 3475187d bellard
#endif
733 ee5bbe38 bellard
734 ee5bbe38 bellard
void set_cwp(int new_cwp)
735 ee5bbe38 bellard
{
736 ee5bbe38 bellard
    /* put the modified wrap registers at their proper location */
737 ee5bbe38 bellard
    if (env->cwp == (NWINDOWS - 1))
738 ee5bbe38 bellard
        memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
739 ee5bbe38 bellard
    env->cwp = new_cwp;
740 ee5bbe38 bellard
    /* put the wrap registers at their temporary location */
741 ee5bbe38 bellard
    if (new_cwp == (NWINDOWS - 1))
742 ee5bbe38 bellard
        memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
743 ee5bbe38 bellard
    env->regwptr = env->regbase + (new_cwp * 16);
744 ee5bbe38 bellard
    REGWPTR = env->regwptr;
745 ee5bbe38 bellard
}
746 ee5bbe38 bellard
747 ee5bbe38 bellard
void cpu_set_cwp(CPUState *env1, int new_cwp)
748 ee5bbe38 bellard
{
749 ee5bbe38 bellard
    CPUState *saved_env;
750 ee5bbe38 bellard
#ifdef reg_REGWPTR
751 ee5bbe38 bellard
    target_ulong *saved_regwptr;
752 ee5bbe38 bellard
#endif
753 ee5bbe38 bellard
754 ee5bbe38 bellard
    saved_env = env;
755 ee5bbe38 bellard
#ifdef reg_REGWPTR
756 ee5bbe38 bellard
    saved_regwptr = REGWPTR;
757 ee5bbe38 bellard
#endif
758 ee5bbe38 bellard
    env = env1;
759 ee5bbe38 bellard
    set_cwp(new_cwp);
760 ee5bbe38 bellard
    env = saved_env;
761 ee5bbe38 bellard
#ifdef reg_REGWPTR
762 ee5bbe38 bellard
    REGWPTR = saved_regwptr;
763 ee5bbe38 bellard
#endif
764 ee5bbe38 bellard
}
765 ee5bbe38 bellard
766 ee5bbe38 bellard
#ifdef TARGET_SPARC64
767 ee5bbe38 bellard
void do_interrupt(int intno)
768 ee5bbe38 bellard
{
769 ee5bbe38 bellard
#ifdef DEBUG_PCALL
770 ee5bbe38 bellard
    if (loglevel & CPU_LOG_INT) {
771 ee5bbe38 bellard
        static int count;
772 26a76461 bellard
        fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
773 ee5bbe38 bellard
                count, intno,
774 ee5bbe38 bellard
                env->pc,
775 ee5bbe38 bellard
                env->npc, env->regwptr[6]);
776 ee5bbe38 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
777 ee5bbe38 bellard
#if 0
778 ee5bbe38 bellard
        {
779 ee5bbe38 bellard
            int i;
780 ee5bbe38 bellard
            uint8_t *ptr;
781 ee5bbe38 bellard

782 ee5bbe38 bellard
            fprintf(logfile, "       code=");
783 ee5bbe38 bellard
            ptr = (uint8_t *)env->pc;
784 ee5bbe38 bellard
            for(i = 0; i < 16; i++) {
785 ee5bbe38 bellard
                fprintf(logfile, " %02x", ldub(ptr + i));
786 ee5bbe38 bellard
            }
787 ee5bbe38 bellard
            fprintf(logfile, "\n");
788 ee5bbe38 bellard
        }
789 ee5bbe38 bellard
#endif
790 ee5bbe38 bellard
        count++;
791 ee5bbe38 bellard
    }
792 ee5bbe38 bellard
#endif
793 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
794 83469015 bellard
    if (env->tl == MAXTL) {
795 c68ea704 bellard
        cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
796 ee5bbe38 bellard
        return;
797 ee5bbe38 bellard
    }
798 ee5bbe38 bellard
#endif
799 ee5bbe38 bellard
    env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
800 ee5bbe38 bellard
        ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
801 ee5bbe38 bellard
    env->tpc[env->tl] = env->pc;
802 ee5bbe38 bellard
    env->tnpc[env->tl] = env->npc;
803 ee5bbe38 bellard
    env->tt[env->tl] = intno;
804 83469015 bellard
    env->pstate = PS_PEF | PS_PRIV | PS_AG;
805 83469015 bellard
    env->tbr &= ~0x7fffULL;
806 83469015 bellard
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
807 83469015 bellard
    if (env->tl < MAXTL - 1) {
808 83469015 bellard
        env->tl++;
809 83469015 bellard
    } else {
810 83469015 bellard
        env->pstate |= PS_RED;
811 83469015 bellard
        if (env->tl != MAXTL)
812 83469015 bellard
            env->tl++;
813 83469015 bellard
    }
814 ee5bbe38 bellard
    env->pc = env->tbr;
815 ee5bbe38 bellard
    env->npc = env->pc + 4;
816 ee5bbe38 bellard
    env->exception_index = 0;
817 ee5bbe38 bellard
}
818 ee5bbe38 bellard
#else
819 ee5bbe38 bellard
void do_interrupt(int intno)
820 ee5bbe38 bellard
{
821 ee5bbe38 bellard
    int cwp;
822 ee5bbe38 bellard
823 ee5bbe38 bellard
#ifdef DEBUG_PCALL
824 ee5bbe38 bellard
    if (loglevel & CPU_LOG_INT) {
825 ee5bbe38 bellard
        static int count;
826 ee5bbe38 bellard
        fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
827 ee5bbe38 bellard
                count, intno,
828 ee5bbe38 bellard
                env->pc,
829 ee5bbe38 bellard
                env->npc, env->regwptr[6]);
830 ee5bbe38 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
831 ee5bbe38 bellard
#if 0
832 ee5bbe38 bellard
        {
833 ee5bbe38 bellard
            int i;
834 ee5bbe38 bellard
            uint8_t *ptr;
835 ee5bbe38 bellard

836 ee5bbe38 bellard
            fprintf(logfile, "       code=");
837 ee5bbe38 bellard
            ptr = (uint8_t *)env->pc;
838 ee5bbe38 bellard
            for(i = 0; i < 16; i++) {
839 ee5bbe38 bellard
                fprintf(logfile, " %02x", ldub(ptr + i));
840 ee5bbe38 bellard
            }
841 ee5bbe38 bellard
            fprintf(logfile, "\n");
842 ee5bbe38 bellard
        }
843 ee5bbe38 bellard
#endif
844 ee5bbe38 bellard
        count++;
845 ee5bbe38 bellard
    }
846 ee5bbe38 bellard
#endif
847 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
848 ee5bbe38 bellard
    if (env->psret == 0) {
849 c68ea704 bellard
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
850 ee5bbe38 bellard
        return;
851 ee5bbe38 bellard
    }
852 ee5bbe38 bellard
#endif
853 ee5bbe38 bellard
    env->psret = 0;
854 ee5bbe38 bellard
    cwp = (env->cwp - 1) & (NWINDOWS - 1); 
855 ee5bbe38 bellard
    set_cwp(cwp);
856 ee5bbe38 bellard
    env->regwptr[9] = env->pc;
857 ee5bbe38 bellard
    env->regwptr[10] = env->npc;
858 ee5bbe38 bellard
    env->psrps = env->psrs;
859 ee5bbe38 bellard
    env->psrs = 1;
860 ee5bbe38 bellard
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
861 ee5bbe38 bellard
    env->pc = env->tbr;
862 ee5bbe38 bellard
    env->npc = env->pc + 4;
863 ee5bbe38 bellard
    env->exception_index = 0;
864 ee5bbe38 bellard
}
865 ee5bbe38 bellard
#endif
866 ee5bbe38 bellard
867 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
868 ee5bbe38 bellard
869 ee5bbe38 bellard
#define MMUSUFFIX _mmu
870 ee5bbe38 bellard
#define GETPC() (__builtin_return_address(0))
871 ee5bbe38 bellard
872 ee5bbe38 bellard
#define SHIFT 0
873 ee5bbe38 bellard
#include "softmmu_template.h"
874 ee5bbe38 bellard
875 ee5bbe38 bellard
#define SHIFT 1
876 ee5bbe38 bellard
#include "softmmu_template.h"
877 ee5bbe38 bellard
878 ee5bbe38 bellard
#define SHIFT 2
879 ee5bbe38 bellard
#include "softmmu_template.h"
880 ee5bbe38 bellard
881 ee5bbe38 bellard
#define SHIFT 3
882 ee5bbe38 bellard
#include "softmmu_template.h"
883 ee5bbe38 bellard
884 ee5bbe38 bellard
885 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
886 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
887 ee5bbe38 bellard
   from generated code or from helper.c) */
888 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
889 ee5bbe38 bellard
void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
890 ee5bbe38 bellard
{
891 ee5bbe38 bellard
    TranslationBlock *tb;
892 ee5bbe38 bellard
    int ret;
893 ee5bbe38 bellard
    unsigned long pc;
894 ee5bbe38 bellard
    CPUState *saved_env;
895 ee5bbe38 bellard
896 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
897 ee5bbe38 bellard
       generated code */
898 ee5bbe38 bellard
    saved_env = env;
899 ee5bbe38 bellard
    env = cpu_single_env;
900 ee5bbe38 bellard
901 ee5bbe38 bellard
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
902 ee5bbe38 bellard
    if (ret) {
903 ee5bbe38 bellard
        if (retaddr) {
904 ee5bbe38 bellard
            /* now we have a real cpu fault */
905 ee5bbe38 bellard
            pc = (unsigned long)retaddr;
906 ee5bbe38 bellard
            tb = tb_find_pc(pc);
907 ee5bbe38 bellard
            if (tb) {
908 ee5bbe38 bellard
                /* the PC is inside the translated code. It means that we have
909 ee5bbe38 bellard
                   a virtual CPU fault */
910 ee5bbe38 bellard
                cpu_restore_state(tb, env, pc, (void *)T2);
911 ee5bbe38 bellard
            }
912 ee5bbe38 bellard
        }
913 ee5bbe38 bellard
        cpu_loop_exit();
914 ee5bbe38 bellard
    }
915 ee5bbe38 bellard
    env = saved_env;
916 ee5bbe38 bellard
}
917 ee5bbe38 bellard
918 ee5bbe38 bellard
#endif