Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ cbeb0857

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

839 ee5bbe38 bellard
            fprintf(logfile, "       code=");
840 ee5bbe38 bellard
            ptr = (uint8_t *)env->pc;
841 ee5bbe38 bellard
            for(i = 0; i < 16; i++) {
842 ee5bbe38 bellard
                fprintf(logfile, " %02x", ldub(ptr + i));
843 ee5bbe38 bellard
            }
844 ee5bbe38 bellard
            fprintf(logfile, "\n");
845 ee5bbe38 bellard
        }
846 ee5bbe38 bellard
#endif
847 ee5bbe38 bellard
        count++;
848 ee5bbe38 bellard
    }
849 ee5bbe38 bellard
#endif
850 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
851 83469015 bellard
    if (env->tl == MAXTL) {
852 c68ea704 bellard
        cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
853 ee5bbe38 bellard
        return;
854 ee5bbe38 bellard
    }
855 ee5bbe38 bellard
#endif
856 ee5bbe38 bellard
    env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
857 ee5bbe38 bellard
        ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
858 ee5bbe38 bellard
    env->tpc[env->tl] = env->pc;
859 ee5bbe38 bellard
    env->tnpc[env->tl] = env->npc;
860 ee5bbe38 bellard
    env->tt[env->tl] = intno;
861 83469015 bellard
    env->pstate = PS_PEF | PS_PRIV | PS_AG;
862 83469015 bellard
    env->tbr &= ~0x7fffULL;
863 83469015 bellard
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
864 83469015 bellard
    if (env->tl < MAXTL - 1) {
865 83469015 bellard
        env->tl++;
866 83469015 bellard
    } else {
867 83469015 bellard
        env->pstate |= PS_RED;
868 83469015 bellard
        if (env->tl != MAXTL)
869 83469015 bellard
            env->tl++;
870 83469015 bellard
    }
871 ee5bbe38 bellard
    env->pc = env->tbr;
872 ee5bbe38 bellard
    env->npc = env->pc + 4;
873 ee5bbe38 bellard
    env->exception_index = 0;
874 ee5bbe38 bellard
}
875 ee5bbe38 bellard
#else
876 ee5bbe38 bellard
void do_interrupt(int intno)
877 ee5bbe38 bellard
{
878 ee5bbe38 bellard
    int cwp;
879 ee5bbe38 bellard
880 ee5bbe38 bellard
#ifdef DEBUG_PCALL
881 ee5bbe38 bellard
    if (loglevel & CPU_LOG_INT) {
882 ee5bbe38 bellard
        static int count;
883 ee5bbe38 bellard
        fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
884 ee5bbe38 bellard
                count, intno,
885 ee5bbe38 bellard
                env->pc,
886 ee5bbe38 bellard
                env->npc, env->regwptr[6]);
887 ee5bbe38 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
888 ee5bbe38 bellard
#if 0
889 ee5bbe38 bellard
        {
890 ee5bbe38 bellard
            int i;
891 ee5bbe38 bellard
            uint8_t *ptr;
892 ee5bbe38 bellard

893 ee5bbe38 bellard
            fprintf(logfile, "       code=");
894 ee5bbe38 bellard
            ptr = (uint8_t *)env->pc;
895 ee5bbe38 bellard
            for(i = 0; i < 16; i++) {
896 ee5bbe38 bellard
                fprintf(logfile, " %02x", ldub(ptr + i));
897 ee5bbe38 bellard
            }
898 ee5bbe38 bellard
            fprintf(logfile, "\n");
899 ee5bbe38 bellard
        }
900 ee5bbe38 bellard
#endif
901 ee5bbe38 bellard
        count++;
902 ee5bbe38 bellard
    }
903 ee5bbe38 bellard
#endif
904 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
905 ee5bbe38 bellard
    if (env->psret == 0) {
906 c68ea704 bellard
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
907 ee5bbe38 bellard
        return;
908 ee5bbe38 bellard
    }
909 ee5bbe38 bellard
#endif
910 ee5bbe38 bellard
    env->psret = 0;
911 ee5bbe38 bellard
    cwp = (env->cwp - 1) & (NWINDOWS - 1); 
912 ee5bbe38 bellard
    set_cwp(cwp);
913 ee5bbe38 bellard
    env->regwptr[9] = env->pc;
914 ee5bbe38 bellard
    env->regwptr[10] = env->npc;
915 ee5bbe38 bellard
    env->psrps = env->psrs;
916 ee5bbe38 bellard
    env->psrs = 1;
917 ee5bbe38 bellard
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
918 ee5bbe38 bellard
    env->pc = env->tbr;
919 ee5bbe38 bellard
    env->npc = env->pc + 4;
920 ee5bbe38 bellard
    env->exception_index = 0;
921 ee5bbe38 bellard
}
922 ee5bbe38 bellard
#endif
923 ee5bbe38 bellard
924 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
925 ee5bbe38 bellard
926 ee5bbe38 bellard
#define MMUSUFFIX _mmu
927 ee5bbe38 bellard
#define GETPC() (__builtin_return_address(0))
928 ee5bbe38 bellard
929 ee5bbe38 bellard
#define SHIFT 0
930 ee5bbe38 bellard
#include "softmmu_template.h"
931 ee5bbe38 bellard
932 ee5bbe38 bellard
#define SHIFT 1
933 ee5bbe38 bellard
#include "softmmu_template.h"
934 ee5bbe38 bellard
935 ee5bbe38 bellard
#define SHIFT 2
936 ee5bbe38 bellard
#include "softmmu_template.h"
937 ee5bbe38 bellard
938 ee5bbe38 bellard
#define SHIFT 3
939 ee5bbe38 bellard
#include "softmmu_template.h"
940 ee5bbe38 bellard
941 ee5bbe38 bellard
942 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
943 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
944 ee5bbe38 bellard
   from generated code or from helper.c) */
945 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
946 ee5bbe38 bellard
void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
947 ee5bbe38 bellard
{
948 ee5bbe38 bellard
    TranslationBlock *tb;
949 ee5bbe38 bellard
    int ret;
950 ee5bbe38 bellard
    unsigned long pc;
951 ee5bbe38 bellard
    CPUState *saved_env;
952 ee5bbe38 bellard
953 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
954 ee5bbe38 bellard
       generated code */
955 ee5bbe38 bellard
    saved_env = env;
956 ee5bbe38 bellard
    env = cpu_single_env;
957 ee5bbe38 bellard
958 ee5bbe38 bellard
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
959 ee5bbe38 bellard
    if (ret) {
960 ee5bbe38 bellard
        if (retaddr) {
961 ee5bbe38 bellard
            /* now we have a real cpu fault */
962 ee5bbe38 bellard
            pc = (unsigned long)retaddr;
963 ee5bbe38 bellard
            tb = tb_find_pc(pc);
964 ee5bbe38 bellard
            if (tb) {
965 ee5bbe38 bellard
                /* the PC is inside the translated code. It means that we have
966 ee5bbe38 bellard
                   a virtual CPU fault */
967 ee5bbe38 bellard
                cpu_restore_state(tb, env, pc, (void *)T2);
968 ee5bbe38 bellard
            }
969 ee5bbe38 bellard
        }
970 ee5bbe38 bellard
        cpu_loop_exit();
971 ee5bbe38 bellard
    }
972 ee5bbe38 bellard
    env = saved_env;
973 ee5bbe38 bellard
}
974 ee5bbe38 bellard
975 ee5bbe38 bellard
#endif