Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ c5d6edc3

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

932 ee5bbe38 bellard
            fprintf(logfile, "       code=");
933 ee5bbe38 bellard
            ptr = (uint8_t *)env->pc;
934 ee5bbe38 bellard
            for(i = 0; i < 16; i++) {
935 ee5bbe38 bellard
                fprintf(logfile, " %02x", ldub(ptr + i));
936 ee5bbe38 bellard
            }
937 ee5bbe38 bellard
            fprintf(logfile, "\n");
938 ee5bbe38 bellard
        }
939 ee5bbe38 bellard
#endif
940 ee5bbe38 bellard
        count++;
941 ee5bbe38 bellard
    }
942 ee5bbe38 bellard
#endif
943 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
944 83469015 bellard
    if (env->tl == MAXTL) {
945 c68ea704 bellard
        cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
946 ee5bbe38 bellard
        return;
947 ee5bbe38 bellard
    }
948 ee5bbe38 bellard
#endif
949 ee5bbe38 bellard
    env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
950 ee5bbe38 bellard
        ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
951 ee5bbe38 bellard
    env->tpc[env->tl] = env->pc;
952 ee5bbe38 bellard
    env->tnpc[env->tl] = env->npc;
953 ee5bbe38 bellard
    env->tt[env->tl] = intno;
954 83469015 bellard
    env->pstate = PS_PEF | PS_PRIV | PS_AG;
955 83469015 bellard
    env->tbr &= ~0x7fffULL;
956 83469015 bellard
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
957 83469015 bellard
    if (env->tl < MAXTL - 1) {
958 83469015 bellard
        env->tl++;
959 83469015 bellard
    } else {
960 83469015 bellard
        env->pstate |= PS_RED;
961 83469015 bellard
        if (env->tl != MAXTL)
962 83469015 bellard
            env->tl++;
963 83469015 bellard
    }
964 ee5bbe38 bellard
    env->pc = env->tbr;
965 ee5bbe38 bellard
    env->npc = env->pc + 4;
966 ee5bbe38 bellard
    env->exception_index = 0;
967 ee5bbe38 bellard
}
968 ee5bbe38 bellard
#else
969 ee5bbe38 bellard
void do_interrupt(int intno)
970 ee5bbe38 bellard
{
971 ee5bbe38 bellard
    int cwp;
972 ee5bbe38 bellard
973 ee5bbe38 bellard
#ifdef DEBUG_PCALL
974 ee5bbe38 bellard
    if (loglevel & CPU_LOG_INT) {
975 ee5bbe38 bellard
        static int count;
976 ee5bbe38 bellard
        fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
977 ee5bbe38 bellard
                count, intno,
978 ee5bbe38 bellard
                env->pc,
979 ee5bbe38 bellard
                env->npc, env->regwptr[6]);
980 ee5bbe38 bellard
        cpu_dump_state(env, logfile, fprintf, 0);
981 ee5bbe38 bellard
#if 0
982 ee5bbe38 bellard
        {
983 ee5bbe38 bellard
            int i;
984 ee5bbe38 bellard
            uint8_t *ptr;
985 ee5bbe38 bellard

986 ee5bbe38 bellard
            fprintf(logfile, "       code=");
987 ee5bbe38 bellard
            ptr = (uint8_t *)env->pc;
988 ee5bbe38 bellard
            for(i = 0; i < 16; i++) {
989 ee5bbe38 bellard
                fprintf(logfile, " %02x", ldub(ptr + i));
990 ee5bbe38 bellard
            }
991 ee5bbe38 bellard
            fprintf(logfile, "\n");
992 ee5bbe38 bellard
        }
993 ee5bbe38 bellard
#endif
994 ee5bbe38 bellard
        count++;
995 ee5bbe38 bellard
    }
996 ee5bbe38 bellard
#endif
997 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
998 ee5bbe38 bellard
    if (env->psret == 0) {
999 c68ea704 bellard
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
1000 ee5bbe38 bellard
        return;
1001 ee5bbe38 bellard
    }
1002 ee5bbe38 bellard
#endif
1003 ee5bbe38 bellard
    env->psret = 0;
1004 ee5bbe38 bellard
    cwp = (env->cwp - 1) & (NWINDOWS - 1); 
1005 ee5bbe38 bellard
    set_cwp(cwp);
1006 ee5bbe38 bellard
    env->regwptr[9] = env->pc;
1007 ee5bbe38 bellard
    env->regwptr[10] = env->npc;
1008 ee5bbe38 bellard
    env->psrps = env->psrs;
1009 ee5bbe38 bellard
    env->psrs = 1;
1010 ee5bbe38 bellard
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
1011 ee5bbe38 bellard
    env->pc = env->tbr;
1012 ee5bbe38 bellard
    env->npc = env->pc + 4;
1013 ee5bbe38 bellard
    env->exception_index = 0;
1014 ee5bbe38 bellard
}
1015 ee5bbe38 bellard
#endif
1016 ee5bbe38 bellard
1017 ee5bbe38 bellard
#if !defined(CONFIG_USER_ONLY) 
1018 ee5bbe38 bellard
1019 ee5bbe38 bellard
#define MMUSUFFIX _mmu
1020 ee5bbe38 bellard
#define GETPC() (__builtin_return_address(0))
1021 ee5bbe38 bellard
1022 ee5bbe38 bellard
#define SHIFT 0
1023 ee5bbe38 bellard
#include "softmmu_template.h"
1024 ee5bbe38 bellard
1025 ee5bbe38 bellard
#define SHIFT 1
1026 ee5bbe38 bellard
#include "softmmu_template.h"
1027 ee5bbe38 bellard
1028 ee5bbe38 bellard
#define SHIFT 2
1029 ee5bbe38 bellard
#include "softmmu_template.h"
1030 ee5bbe38 bellard
1031 ee5bbe38 bellard
#define SHIFT 3
1032 ee5bbe38 bellard
#include "softmmu_template.h"
1033 ee5bbe38 bellard
1034 ee5bbe38 bellard
1035 ee5bbe38 bellard
/* try to fill the TLB and return an exception if error. If retaddr is
1036 ee5bbe38 bellard
   NULL, it means that the function was called in C code (i.e. not
1037 ee5bbe38 bellard
   from generated code or from helper.c) */
1038 ee5bbe38 bellard
/* XXX: fix it to restore all registers */
1039 ee5bbe38 bellard
void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
1040 ee5bbe38 bellard
{
1041 ee5bbe38 bellard
    TranslationBlock *tb;
1042 ee5bbe38 bellard
    int ret;
1043 ee5bbe38 bellard
    unsigned long pc;
1044 ee5bbe38 bellard
    CPUState *saved_env;
1045 ee5bbe38 bellard
1046 ee5bbe38 bellard
    /* XXX: hack to restore env in all cases, even if not called from
1047 ee5bbe38 bellard
       generated code */
1048 ee5bbe38 bellard
    saved_env = env;
1049 ee5bbe38 bellard
    env = cpu_single_env;
1050 ee5bbe38 bellard
1051 ee5bbe38 bellard
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
1052 ee5bbe38 bellard
    if (ret) {
1053 ee5bbe38 bellard
        if (retaddr) {
1054 ee5bbe38 bellard
            /* now we have a real cpu fault */
1055 ee5bbe38 bellard
            pc = (unsigned long)retaddr;
1056 ee5bbe38 bellard
            tb = tb_find_pc(pc);
1057 ee5bbe38 bellard
            if (tb) {
1058 ee5bbe38 bellard
                /* the PC is inside the translated code. It means that we have
1059 ee5bbe38 bellard
                   a virtual CPU fault */
1060 ee5bbe38 bellard
                cpu_restore_state(tb, env, pc, (void *)T2);
1061 ee5bbe38 bellard
            }
1062 ee5bbe38 bellard
        }
1063 ee5bbe38 bellard
        cpu_loop_exit();
1064 ee5bbe38 bellard
    }
1065 ee5bbe38 bellard
    env = saved_env;
1066 ee5bbe38 bellard
}
1067 ee5bbe38 bellard
1068 ee5bbe38 bellard
#endif