Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 3deaeab7

History | View | Annotate | Download (57 kB)

1
#include "exec.h"
2
#include "host-utils.h"
3

    
4
//#define DEBUG_PCALL
5
//#define DEBUG_MMU
6
//#define DEBUG_MXCC
7
//#define DEBUG_UNALIGNED
8
//#define DEBUG_UNASSIGNED
9
//#define DEBUG_ASI
10

    
11
#ifdef DEBUG_MMU
12
#define DPRINTF_MMU(fmt, args...) \
13
do { printf("MMU: " fmt , ##args); } while (0)
14
#else
15
#define DPRINTF_MMU(fmt, args...)
16
#endif
17

    
18
#ifdef DEBUG_MXCC
19
#define DPRINTF_MXCC(fmt, args...) \
20
do { printf("MXCC: " fmt , ##args); } while (0)
21
#else
22
#define DPRINTF_MXCC(fmt, args...)
23
#endif
24

    
25
#ifdef DEBUG_ASI
26
#define DPRINTF_ASI(fmt, args...) \
27
do { printf("ASI: " fmt , ##args); } while (0)
28
#else
29
#define DPRINTF_ASI(fmt, args...)
30
#endif
31

    
32
void raise_exception(int tt)
33
{
34
    env->exception_index = tt;
35
    cpu_loop_exit();
36
}
37

    
38
void check_ieee_exceptions()
39
{
40
     T0 = get_float_exception_flags(&env->fp_status);
41
     if (T0)
42
     {
43
        /* Copy IEEE 754 flags into FSR */
44
        if (T0 & float_flag_invalid)
45
            env->fsr |= FSR_NVC;
46
        if (T0 & float_flag_overflow)
47
            env->fsr |= FSR_OFC;
48
        if (T0 & float_flag_underflow)
49
            env->fsr |= FSR_UFC;
50
        if (T0 & float_flag_divbyzero)
51
            env->fsr |= FSR_DZC;
52
        if (T0 & float_flag_inexact)
53
            env->fsr |= FSR_NXC;
54

    
55
        if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23))
56
        {
57
            /* Unmasked exception, generate a trap */
58
            env->fsr |= FSR_FTT_IEEE_EXCP;
59
            raise_exception(TT_FP_EXCP);
60
        }
61
        else
62
        {
63
            /* Accumulate exceptions */
64
            env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
65
        }
66
     }
67
}
68

    
69
#ifdef USE_INT_TO_FLOAT_HELPERS
70
void do_fitos(void)
71
{
72
    set_float_exception_flags(0, &env->fp_status);
73
    FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
74
    check_ieee_exceptions();
75
}
76

    
77
void do_fitod(void)
78
{
79
    DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
80
}
81

    
82
#if defined(CONFIG_USER_ONLY)
83
void do_fitoq(void)
84
{
85
    QT0 = int32_to_float128(*((int32_t *)&FT1), &env->fp_status);
86
}
87
#endif
88

    
89
#ifdef TARGET_SPARC64
90
void do_fxtos(void)
91
{
92
    set_float_exception_flags(0, &env->fp_status);
93
    FT0 = int64_to_float32(*((int64_t *)&DT1), &env->fp_status);
94
    check_ieee_exceptions();
95
}
96

    
97
void do_fxtod(void)
98
{
99
    set_float_exception_flags(0, &env->fp_status);
100
    DT0 = int64_to_float64(*((int64_t *)&DT1), &env->fp_status);
101
    check_ieee_exceptions();
102
}
103

    
104
#if defined(CONFIG_USER_ONLY)
105
void do_fxtoq(void)
106
{
107
    set_float_exception_flags(0, &env->fp_status);
108
    QT0 = int64_to_float128(*((int32_t *)&DT1), &env->fp_status);
109
    check_ieee_exceptions();
110
}
111
#endif
112
#endif
113
#endif
114

    
115
void do_fabss(void)
116
{
117
    FT0 = float32_abs(FT1);
118
}
119

    
120
#ifdef TARGET_SPARC64
121
void do_fabsd(void)
122
{
123
    DT0 = float64_abs(DT1);
124
}
125

    
126
#if defined(CONFIG_USER_ONLY)
127
void do_fabsq(void)
128
{
129
    QT0 = float128_abs(QT1);
130
}
131
#endif
132
#endif
133

    
134
void do_fsqrts(void)
135
{
136
    set_float_exception_flags(0, &env->fp_status);
137
    FT0 = float32_sqrt(FT1, &env->fp_status);
138
    check_ieee_exceptions();
139
}
140

    
141
void do_fsqrtd(void)
142
{
143
    set_float_exception_flags(0, &env->fp_status);
144
    DT0 = float64_sqrt(DT1, &env->fp_status);
145
    check_ieee_exceptions();
146
}
147

    
148
#if defined(CONFIG_USER_ONLY)
149
void do_fsqrtq(void)
150
{
151
    set_float_exception_flags(0, &env->fp_status);
152
    QT0 = float128_sqrt(QT1, &env->fp_status);
153
    check_ieee_exceptions();
154
}
155
#endif
156

    
157
#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP)                      \
158
    void glue(do_, name) (void)                                         \
159
    {                                                                   \
160
        env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                     \
161
        switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) {   \
162
        case float_relation_unordered:                                  \
163
            T0 = (FSR_FCC1 | FSR_FCC0) << FS;                           \
164
            if ((env->fsr & FSR_NVM) || TRAP) {                         \
165
                env->fsr |= T0;                                         \
166
                env->fsr |= FSR_NVC;                                    \
167
                env->fsr |= FSR_FTT_IEEE_EXCP;                          \
168
                raise_exception(TT_FP_EXCP);                            \
169
            } else {                                                    \
170
                env->fsr |= FSR_NVA;                                    \
171
            }                                                           \
172
            break;                                                      \
173
        case float_relation_less:                                       \
174
            T0 = FSR_FCC0 << FS;                                        \
175
            break;                                                      \
176
        case float_relation_greater:                                    \
177
            T0 = FSR_FCC1 << FS;                                        \
178
            break;                                                      \
179
        default:                                                        \
180
            T0 = 0;                                                     \
181
            break;                                                      \
182
        }                                                               \
183
        env->fsr |= T0;                                                 \
184
    }
185

    
186
GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0);
187
GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0);
188

    
189
GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1);
190
GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1);
191

    
192
#ifdef CONFIG_USER_ONLY
193
GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0);
194
GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1);
195
#endif
196

    
197
#ifdef TARGET_SPARC64
198
GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0);
199
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
200

    
201
GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0);
202
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
203

    
204
GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0);
205
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
206

    
207
GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1);
208
GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
209

    
210
GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1);
211
GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
212

    
213
GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
214
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
215
#ifdef CONFIG_USER_ONLY
216
GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0);
217
GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0);
218
GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0);
219
GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1);
220
GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1);
221
GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1);
222
#endif
223
#endif
224

    
225
#ifndef TARGET_SPARC64
226
#ifndef CONFIG_USER_ONLY
227

    
228
#ifdef DEBUG_MXCC
229
static void dump_mxcc(CPUState *env)
230
{
231
    printf("mxccdata: %016llx %016llx %016llx %016llx\n",
232
        env->mxccdata[0], env->mxccdata[1], env->mxccdata[2], env->mxccdata[3]);
233
    printf("mxccregs: %016llx %016llx %016llx %016llx\n"
234
           "          %016llx %016llx %016llx %016llx\n",
235
        env->mxccregs[0], env->mxccregs[1], env->mxccregs[2], env->mxccregs[3],
236
        env->mxccregs[4], env->mxccregs[5], env->mxccregs[6], env->mxccregs[7]);
237
}
238
#endif
239

    
240
#ifdef DEBUG_ASI
241
static void dump_asi(const char * txt, uint32_t addr, int asi, int size,
242
                     uint32_t r1, uint32_t r2)
243
{
244
    switch (size)
245
    {
246
    case 1:
247
        DPRINTF_ASI("%s %08x asi 0x%02x = %02x\n", txt, addr, asi, r1 & 0xff);
248
        break;
249
    case 2:
250
        DPRINTF_ASI("%s %08x asi 0x%02x = %04x\n", txt, addr, asi, r1 & 0xffff);
251
        break;
252
    case 4:
253
        DPRINTF_ASI("%s %08x asi 0x%02x = %08x\n", txt, addr, asi, r1);
254
        break;
255
    case 8:
256
        DPRINTF_ASI("%s %08x asi 0x%02x = %016llx\n", txt, addr, asi,
257
                    r2 | ((uint64_t)r1 << 32));
258
        break;
259
    }
260
}
261
#endif
262

    
263
void helper_ld_asi(int asi, int size, int sign)
264
{
265
    uint32_t ret = 0;
266
    uint64_t tmp;
267
#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
268
    uint32_t last_T0 = T0;
269
#endif
270

    
271
    switch (asi) {
272
    case 2: /* SuperSparc MXCC registers */
273
        switch (T0) {
274
        case 0x01c00a00: /* MXCC control register */
275
            if (size == 8) {
276
                ret = env->mxccregs[3] >> 32;
277
                T0 = env->mxccregs[3];
278
            } else
279
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
280
            break;
281
        case 0x01c00a04: /* MXCC control register */
282
            if (size == 4)
283
                ret = env->mxccregs[3];
284
            else
285
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
286
            break;
287
        case 0x01c00c00: /* Module reset register */
288
            if (size == 8) {
289
                ret = env->mxccregs[5] >> 32;
290
                T0 = env->mxccregs[5];
291
                // should we do something here?
292
            } else
293
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
294
            break;
295
        case 0x01c00f00: /* MBus port address register */
296
            if (size == 8) {
297
                ret = env->mxccregs[7] >> 32;
298
                T0 = env->mxccregs[7];
299
            } else
300
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
301
            break;
302
        default:
303
            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
304
            break;
305
        }
306
        DPRINTF_MXCC("asi = %d, size = %d, sign = %d, T0 = %08x -> ret = %08x,"
307
                     "T0 = %08x\n", asi, size, sign, last_T0, ret, T0);
308
#ifdef DEBUG_MXCC
309
        dump_mxcc(env);
310
#endif
311
        break;
312
    case 3: /* MMU probe */
313
        {
314
            int mmulev;
315

    
316
            mmulev = (T0 >> 8) & 15;
317
            if (mmulev > 4)
318
                ret = 0;
319
            else {
320
                ret = mmu_probe(env, T0, mmulev);
321
                //bswap32s(&ret);
322
            }
323
            DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
324
        }
325
        break;
326
    case 4: /* read MMU regs */
327
        {
328
            int reg = (T0 >> 8) & 0x1f;
329

    
330
            ret = env->mmuregs[reg];
331
            if (reg == 3) /* Fault status cleared on read */
332
                env->mmuregs[3] = 0;
333
            else if (reg == 0x13) /* Fault status read */
334
                ret = env->mmuregs[3];
335
            else if (reg == 0x14) /* Fault address read */
336
                ret = env->mmuregs[4];
337
            DPRINTF_MMU("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
338
        }
339
        break;
340
    case 5: // Turbosparc ITLB Diagnostic
341
    case 6: // Turbosparc DTLB Diagnostic
342
    case 7: // Turbosparc IOTLB Diagnostic
343
        break;
344
    case 9: /* Supervisor code access */
345
        switch(size) {
346
        case 1:
347
            ret = ldub_code(T0);
348
            break;
349
        case 2:
350
            ret = lduw_code(T0 & ~1);
351
            break;
352
        default:
353
        case 4:
354
            ret = ldl_code(T0 & ~3);
355
            break;
356
        case 8:
357
            tmp = ldq_code(T0 & ~7);
358
            ret = tmp >> 32;
359
            T0 = tmp;
360
            break;
361
        }
362
        break;
363
    case 0xa: /* User data access */
364
        switch(size) {
365
        case 1:
366
            ret = ldub_user(T0);
367
            break;
368
        case 2:
369
            ret = lduw_user(T0 & ~1);
370
            break;
371
        default:
372
        case 4:
373
            ret = ldl_user(T0 & ~3);
374
            break;
375
        case 8:
376
            tmp = ldq_user(T0 & ~7);
377
            ret = tmp >> 32;
378
            T0 = tmp;
379
            break;
380
        }
381
        break;
382
    case 0xb: /* Supervisor data access */
383
        switch(size) {
384
        case 1:
385
            ret = ldub_kernel(T0);
386
            break;
387
        case 2:
388
            ret = lduw_kernel(T0 & ~1);
389
            break;
390
        default:
391
        case 4:
392
            ret = ldl_kernel(T0 & ~3);
393
            break;
394
        case 8:
395
            tmp = ldq_kernel(T0 & ~7);
396
            ret = tmp >> 32;
397
            T0 = tmp;
398
            break;
399
        }
400
        break;
401
    case 0xc: /* I-cache tag */
402
    case 0xd: /* I-cache data */
403
    case 0xe: /* D-cache tag */
404
    case 0xf: /* D-cache data */
405
        break;
406
    case 0x20: /* MMU passthrough */
407
        switch(size) {
408
        case 1:
409
            ret = ldub_phys(T0);
410
            break;
411
        case 2:
412
            ret = lduw_phys(T0 & ~1);
413
            break;
414
        default:
415
        case 4:
416
            ret = ldl_phys(T0 & ~3);
417
            break;
418
        case 8:
419
            tmp = ldq_phys(T0 & ~7);
420
            ret = tmp >> 32;
421
            T0 = tmp;
422
            break;
423
        }
424
        break;
425
    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
426
        switch(size) {
427
        case 1:
428
            ret = ldub_phys((target_phys_addr_t)T0
429
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
430
            break;
431
        case 2:
432
            ret = lduw_phys((target_phys_addr_t)(T0 & ~1)
433
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
434
            break;
435
        default:
436
        case 4:
437
            ret = ldl_phys((target_phys_addr_t)(T0 & ~3)
438
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
439
            break;
440
        case 8:
441
            tmp = ldq_phys((target_phys_addr_t)(T0 & ~7)
442
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
443
            ret = tmp >> 32;
444
            T0 = tmp;
445
            break;
446
        }
447
        break;
448
    case 0x30: // Turbosparc secondary cache diagnostic
449
    case 0x31: // Turbosparc RAM snoop
450
    case 0x32: // Turbosparc page table descriptor diagnostic
451
    case 0x39: /* data cache diagnostic register */
452
        ret = 0;
453
        break;
454
    case 8: /* User code access, XXX */
455
    default:
456
        do_unassigned_access(T0, 0, 0, asi);
457
        ret = 0;
458
        break;
459
    }
460
    if (sign) {
461
        switch(size) {
462
        case 1:
463
            T1 = (int8_t) ret;
464
            break;
465
        case 2:
466
            T1 = (int16_t) ret;
467
            break;
468
        default:
469
            T1 = ret;
470
            break;
471
        }
472
    }
473
    else
474
        T1 = ret;
475
#ifdef DEBUG_ASI
476
    dump_asi("read ", last_T0, asi, size, T1, T0);
477
#endif
478
}
479

    
480
void helper_st_asi(int asi, int size)
481
{
482
    switch(asi) {
483
    case 2: /* SuperSparc MXCC registers */
484
        switch (T0) {
485
        case 0x01c00000: /* MXCC stream data register 0 */
486
            if (size == 8)
487
                env->mxccdata[0] = ((uint64_t)T1 << 32) | T2;
488
            else
489
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
490
            break;
491
        case 0x01c00008: /* MXCC stream data register 1 */
492
            if (size == 8)
493
                env->mxccdata[1] = ((uint64_t)T1 << 32) | T2;
494
            else
495
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
496
            break;
497
        case 0x01c00010: /* MXCC stream data register 2 */
498
            if (size == 8)
499
                env->mxccdata[2] = ((uint64_t)T1 << 32) | T2;
500
            else
501
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
502
            break;
503
        case 0x01c00018: /* MXCC stream data register 3 */
504
            if (size == 8)
505
                env->mxccdata[3] = ((uint64_t)T1 << 32) | T2;
506
            else
507
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
508
            break;
509
        case 0x01c00100: /* MXCC stream source */
510
            if (size == 8)
511
                env->mxccregs[0] = ((uint64_t)T1 << 32) | T2;
512
            else
513
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
514
            env->mxccdata[0] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +  0);
515
            env->mxccdata[1] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) +  8);
516
            env->mxccdata[2] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 16);
517
            env->mxccdata[3] = ldq_phys((env->mxccregs[0] & 0xffffffffULL) + 24);
518
            break;
519
        case 0x01c00200: /* MXCC stream destination */
520
            if (size == 8)
521
                env->mxccregs[1] = ((uint64_t)T1 << 32) | T2;
522
            else
523
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
524
            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  0, env->mxccdata[0]);
525
            stq_phys((env->mxccregs[1] & 0xffffffffULL) +  8, env->mxccdata[1]);
526
            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 16, env->mxccdata[2]);
527
            stq_phys((env->mxccregs[1] & 0xffffffffULL) + 24, env->mxccdata[3]);
528
            break;
529
        case 0x01c00a00: /* MXCC control register */
530
            if (size == 8)
531
                env->mxccregs[3] = ((uint64_t)T1 << 32) | T2;
532
            else
533
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
534
            break;
535
        case 0x01c00a04: /* MXCC control register */
536
            if (size == 4)
537
                env->mxccregs[3] = (env->mxccregs[0xa] & 0xffffffff00000000ULL) | T1;
538
            else
539
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
540
            break;
541
        case 0x01c00e00: /* MXCC error register  */
542
            // writing a 1 bit clears the error
543
            if (size == 8)
544
                env->mxccregs[6] &= ~(((uint64_t)T1 << 32) | T2);
545
            else
546
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
547
            break;
548
        case 0x01c00f00: /* MBus port address register */
549
            if (size == 8)
550
                env->mxccregs[7] = ((uint64_t)T1 << 32) | T2;
551
            else
552
                DPRINTF_MXCC("%08x: unimplemented access size: %d\n", T0, size);
553
            break;
554
        default:
555
            DPRINTF_MXCC("%08x: unimplemented address, size: %d\n", T0, size);
556
            break;
557
        }
558
        DPRINTF_MXCC("asi = %d, size = %d, T0 = %08x, T1 = %08x\n", asi, size, T0, T1);
559
#ifdef DEBUG_MXCC
560
        dump_mxcc(env);
561
#endif
562
        break;
563
    case 3: /* MMU flush */
564
        {
565
            int mmulev;
566

    
567
            mmulev = (T0 >> 8) & 15;
568
            DPRINTF_MMU("mmu flush level %d\n", mmulev);
569
            switch (mmulev) {
570
            case 0: // flush page
571
                tlb_flush_page(env, T0 & 0xfffff000);
572
                break;
573
            case 1: // flush segment (256k)
574
            case 2: // flush region (16M)
575
            case 3: // flush context (4G)
576
            case 4: // flush entire
577
                tlb_flush(env, 1);
578
                break;
579
            default:
580
                break;
581
            }
582
#ifdef DEBUG_MMU
583
            dump_mmu(env);
584
#endif
585
        }
586
        break;
587
    case 4: /* write MMU regs */
588
        {
589
            int reg = (T0 >> 8) & 0x1f;
590
            uint32_t oldreg;
591

    
592
            oldreg = env->mmuregs[reg];
593
            switch(reg) {
594
            case 0: // Control Register
595
                env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
596
                                    (T1 & 0x00ffffff);
597
                // Mappings generated during no-fault mode or MMU
598
                // disabled mode are invalid in normal mode
599
                if ((oldreg & (MMU_E | MMU_NF | env->mmu_bm)) !=
600
                    (env->mmuregs[reg] & (MMU_E | MMU_NF | env->mmu_bm)))
601
                    tlb_flush(env, 1);
602
                break;
603
            case 1: // Context Table Pointer Register
604
                env->mmuregs[reg] = T1 & env->mmu_ctpr_mask;
605
                break;
606
            case 2: // Context Register
607
                env->mmuregs[reg] = T1 & env->mmu_cxr_mask;
608
                if (oldreg != env->mmuregs[reg]) {
609
                    /* we flush when the MMU context changes because
610
                       QEMU has no MMU context support */
611
                    tlb_flush(env, 1);
612
                }
613
                break;
614
            case 3: // Synchronous Fault Status Register with Clear
615
            case 4: // Synchronous Fault Address Register
616
                break;
617
            case 0x10: // TLB Replacement Control Register
618
                env->mmuregs[reg] = T1 & env->mmu_trcr_mask;
619
                break;
620
            case 0x13: // Synchronous Fault Status Register with Read and Clear
621
                env->mmuregs[3] = T1 & env->mmu_sfsr_mask;
622
                break;
623
            case 0x14: // Synchronous Fault Address Register
624
                env->mmuregs[4] = T1;
625
                break;
626
            default:
627
                env->mmuregs[reg] = T1;
628
                break;
629
            }
630
            if (oldreg != env->mmuregs[reg]) {
631
                DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
632
            }
633
#ifdef DEBUG_MMU
634
            dump_mmu(env);
635
#endif
636
        }
637
        break;
638
    case 5: // Turbosparc ITLB Diagnostic
639
    case 6: // Turbosparc DTLB Diagnostic
640
    case 7: // Turbosparc IOTLB Diagnostic
641
        break;
642
    case 0xa: /* User data access */
643
        switch(size) {
644
        case 1:
645
            stb_user(T0, T1);
646
            break;
647
        case 2:
648
            stw_user(T0 & ~1, T1);
649
            break;
650
        default:
651
        case 4:
652
            stl_user(T0 & ~3, T1);
653
            break;
654
        case 8:
655
            stq_user(T0 & ~7, ((uint64_t)T1 << 32) | T2);
656
            break;
657
        }
658
        break;
659
    case 0xb: /* Supervisor data access */
660
        switch(size) {
661
        case 1:
662
            stb_kernel(T0, T1);
663
            break;
664
        case 2:
665
            stw_kernel(T0 & ~1, T1);
666
            break;
667
        default:
668
        case 4:
669
            stl_kernel(T0 & ~3, T1);
670
            break;
671
        case 8:
672
            stq_kernel(T0 & ~7, ((uint64_t)T1 << 32) | T2);
673
            break;
674
        }
675
        break;
676
    case 0xc: /* I-cache tag */
677
    case 0xd: /* I-cache data */
678
    case 0xe: /* D-cache tag */
679
    case 0xf: /* D-cache data */
680
    case 0x10: /* I/D-cache flush page */
681
    case 0x11: /* I/D-cache flush segment */
682
    case 0x12: /* I/D-cache flush region */
683
    case 0x13: /* I/D-cache flush context */
684
    case 0x14: /* I/D-cache flush user */
685
        break;
686
    case 0x17: /* Block copy, sta access */
687
        {
688
            // value (T1) = src
689
            // address (T0) = dst
690
            // copy 32 bytes
691
            unsigned int i;
692
            uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
693

    
694
            for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
695
                temp = ldl_kernel(src);
696
                stl_kernel(dst, temp);
697
            }
698
        }
699
        break;
700
    case 0x1f: /* Block fill, stda access */
701
        {
702
            // value (T1, T2)
703
            // address (T0) = dst
704
            // fill 32 bytes
705
            unsigned int i;
706
            uint32_t dst = T0 & 7;
707
            uint64_t val;
708

    
709
            val = (((uint64_t)T1) << 32) | T2;
710

    
711
            for (i = 0; i < 32; i += 8, dst += 8)
712
                stq_kernel(dst, val);
713
        }
714
        break;
715
    case 0x20: /* MMU passthrough */
716
        {
717
            switch(size) {
718
            case 1:
719
                stb_phys(T0, T1);
720
                break;
721
            case 2:
722
                stw_phys(T0 & ~1, T1);
723
                break;
724
            case 4:
725
            default:
726
                stl_phys(T0 & ~3, T1);
727
                break;
728
            case 8:
729
                stq_phys(T0 & ~7, ((uint64_t)T1 << 32) | T2);
730
                break;
731
            }
732
        }
733
        break;
734
    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
735
        {
736
            switch(size) {
737
            case 1:
738
                stb_phys((target_phys_addr_t)T0
739
                         | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
740
                break;
741
            case 2:
742
                stw_phys((target_phys_addr_t)(T0 & ~1)
743
                            | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
744
                break;
745
            case 4:
746
            default:
747
                stl_phys((target_phys_addr_t)(T0 & ~3)
748
                           | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
749
                break;
750
            case 8:
751
                stq_phys((target_phys_addr_t)(T0 & ~7)
752
                           | ((target_phys_addr_t)(asi & 0xf) << 32),
753
                         ((uint64_t)T1 << 32) | T2);
754
                break;
755
            }
756
        }
757
        break;
758
    case 0x30: // store buffer tags or Turbosparc secondary cache diagnostic
759
    case 0x31: // store buffer data, Ross RT620 I-cache flush or
760
               // Turbosparc snoop RAM
761
    case 0x32: // store buffer control or Turbosparc page table descriptor diagnostic
762
    case 0x36: /* I-cache flash clear */
763
    case 0x37: /* D-cache flash clear */
764
    case 0x38: /* breakpoint diagnostics */
765
    case 0x4c: /* breakpoint action */
766
        break;
767
    case 8: /* User code access, XXX */
768
    case 9: /* Supervisor code access, XXX */
769
    default:
770
        do_unassigned_access(T0, 1, 0, asi);
771
        break;
772
    }
773
#ifdef DEBUG_ASI
774
    dump_asi("write", T0, asi, size, T1, T2);
775
#endif
776
}
777

    
778
#endif /* CONFIG_USER_ONLY */
779
#else /* TARGET_SPARC64 */
780

    
781
#ifdef CONFIG_USER_ONLY
782
void helper_ld_asi(int asi, int size, int sign)
783
{
784
    uint64_t ret = 0;
785

    
786
    if (asi < 0x80)
787
        raise_exception(TT_PRIV_ACT);
788

    
789
    switch (asi) {
790
    case 0x80: // Primary
791
    case 0x82: // Primary no-fault
792
    case 0x88: // Primary LE
793
    case 0x8a: // Primary no-fault LE
794
        {
795
            switch(size) {
796
            case 1:
797
                ret = ldub_raw(T0);
798
                break;
799
            case 2:
800
                ret = lduw_raw(T0 & ~1);
801
                break;
802
            case 4:
803
                ret = ldl_raw(T0 & ~3);
804
                break;
805
            default:
806
            case 8:
807
                ret = ldq_raw(T0 & ~7);
808
                break;
809
            }
810
        }
811
        break;
812
    case 0x81: // Secondary
813
    case 0x83: // Secondary no-fault
814
    case 0x89: // Secondary LE
815
    case 0x8b: // Secondary no-fault LE
816
        // XXX
817
        break;
818
    default:
819
        break;
820
    }
821

    
822
    /* Convert from little endian */
823
    switch (asi) {
824
    case 0x88: // Primary LE
825
    case 0x89: // Secondary LE
826
    case 0x8a: // Primary no-fault LE
827
    case 0x8b: // Secondary no-fault LE
828
        switch(size) {
829
        case 2:
830
            ret = bswap16(ret);
831
            break;
832
        case 4:
833
            ret = bswap32(ret);
834
            break;
835
        case 8:
836
            ret = bswap64(ret);
837
            break;
838
        default:
839
            break;
840
        }
841
    default:
842
        break;
843
    }
844

    
845
    /* Convert to signed number */
846
    if (sign) {
847
        switch(size) {
848
        case 1:
849
            ret = (int8_t) ret;
850
            break;
851
        case 2:
852
            ret = (int16_t) ret;
853
            break;
854
        case 4:
855
            ret = (int32_t) ret;
856
            break;
857
        default:
858
            break;
859
        }
860
    }
861
    T1 = ret;
862
}
863

    
864
void helper_st_asi(int asi, int size)
865
{
866
    if (asi < 0x80)
867
        raise_exception(TT_PRIV_ACT);
868

    
869
    /* Convert to little endian */
870
    switch (asi) {
871
    case 0x88: // Primary LE
872
    case 0x89: // Secondary LE
873
        switch(size) {
874
        case 2:
875
            T0 = bswap16(T0);
876
            break;
877
        case 4:
878
            T0 = bswap32(T0);
879
            break;
880
        case 8:
881
            T0 = bswap64(T0);
882
            break;
883
        default:
884
            break;
885
        }
886
    default:
887
        break;
888
    }
889

    
890
    switch(asi) {
891
    case 0x80: // Primary
892
    case 0x88: // Primary LE
893
        {
894
            switch(size) {
895
            case 1:
896
                stb_raw(T0, T1);
897
                break;
898
            case 2:
899
                stw_raw(T0 & ~1, T1);
900
                break;
901
            case 4:
902
                stl_raw(T0 & ~3, T1);
903
                break;
904
            case 8:
905
            default:
906
                stq_raw(T0 & ~7, T1);
907
                break;
908
            }
909
        }
910
        break;
911
    case 0x81: // Secondary
912
    case 0x89: // Secondary LE
913
        // XXX
914
        return;
915

    
916
    case 0x82: // Primary no-fault, RO
917
    case 0x83: // Secondary no-fault, RO
918
    case 0x8a: // Primary no-fault LE, RO
919
    case 0x8b: // Secondary no-fault LE, RO
920
    default:
921
        do_unassigned_access(T0, 1, 0, 1);
922
        return;
923
    }
924
}
925

    
926
#else /* CONFIG_USER_ONLY */
927

    
928
void helper_ld_asi(int asi, int size, int sign)
929
{
930
    uint64_t ret = 0;
931

    
932
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
933
        || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV)))
934
        raise_exception(TT_PRIV_ACT);
935

    
936
    switch (asi) {
937
    case 0x10: // As if user primary
938
    case 0x18: // As if user primary LE
939
    case 0x80: // Primary
940
    case 0x82: // Primary no-fault
941
    case 0x88: // Primary LE
942
    case 0x8a: // Primary no-fault LE
943
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
944
            if (env->hpstate & HS_PRIV) {
945
                switch(size) {
946
                case 1:
947
                    ret = ldub_hypv(T0);
948
                    break;
949
                case 2:
950
                    ret = lduw_hypv(T0 & ~1);
951
                    break;
952
                case 4:
953
                    ret = ldl_hypv(T0 & ~3);
954
                    break;
955
                default:
956
                case 8:
957
                    ret = ldq_hypv(T0 & ~7);
958
                    break;
959
                }
960
            } else {
961
                switch(size) {
962
                case 1:
963
                    ret = ldub_kernel(T0);
964
                    break;
965
                case 2:
966
                    ret = lduw_kernel(T0 & ~1);
967
                    break;
968
                case 4:
969
                    ret = ldl_kernel(T0 & ~3);
970
                    break;
971
                default:
972
                case 8:
973
                    ret = ldq_kernel(T0 & ~7);
974
                    break;
975
                }
976
            }
977
        } else {
978
            switch(size) {
979
            case 1:
980
                ret = ldub_user(T0);
981
                break;
982
            case 2:
983
                ret = lduw_user(T0 & ~1);
984
                break;
985
            case 4:
986
                ret = ldl_user(T0 & ~3);
987
                break;
988
            default:
989
            case 8:
990
                ret = ldq_user(T0 & ~7);
991
                break;
992
            }
993
        }
994
        break;
995
    case 0x14: // Bypass
996
    case 0x15: // Bypass, non-cacheable
997
    case 0x1c: // Bypass LE
998
    case 0x1d: // Bypass, non-cacheable LE
999
        {
1000
            switch(size) {
1001
            case 1:
1002
                ret = ldub_phys(T0);
1003
                break;
1004
            case 2:
1005
                ret = lduw_phys(T0 & ~1);
1006
                break;
1007
            case 4:
1008
                ret = ldl_phys(T0 & ~3);
1009
                break;
1010
            default:
1011
            case 8:
1012
                ret = ldq_phys(T0 & ~7);
1013
                break;
1014
            }
1015
            break;
1016
        }
1017
    case 0x04: // Nucleus
1018
    case 0x0c: // Nucleus Little Endian (LE)
1019
    case 0x11: // As if user secondary
1020
    case 0x19: // As if user secondary LE
1021
    case 0x24: // Nucleus quad LDD 128 bit atomic
1022
    case 0x2c: // Nucleus quad LDD 128 bit atomic
1023
    case 0x4a: // UPA config
1024
    case 0x81: // Secondary
1025
    case 0x83: // Secondary no-fault
1026
    case 0x89: // Secondary LE
1027
    case 0x8b: // Secondary no-fault LE
1028
        // XXX
1029
        break;
1030
    case 0x45: // LSU
1031
        ret = env->lsu;
1032
        break;
1033
    case 0x50: // I-MMU regs
1034
        {
1035
            int reg = (T0 >> 3) & 0xf;
1036

    
1037
            ret = env->immuregs[reg];
1038
            break;
1039
        }
1040
    case 0x51: // I-MMU 8k TSB pointer
1041
    case 0x52: // I-MMU 64k TSB pointer
1042
    case 0x55: // I-MMU data access
1043
        // XXX
1044
        break;
1045
    case 0x56: // I-MMU tag read
1046
        {
1047
            unsigned int i;
1048

    
1049
            for (i = 0; i < 64; i++) {
1050
                // Valid, ctx match, vaddr match
1051
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
1052
                    env->itlb_tag[i] == T0) {
1053
                    ret = env->itlb_tag[i];
1054
                    break;
1055
                }
1056
            }
1057
            break;
1058
        }
1059
    case 0x58: // D-MMU regs
1060
        {
1061
            int reg = (T0 >> 3) & 0xf;
1062

    
1063
            ret = env->dmmuregs[reg];
1064
            break;
1065
        }
1066
    case 0x5e: // D-MMU tag read
1067
        {
1068
            unsigned int i;
1069

    
1070
            for (i = 0; i < 64; i++) {
1071
                // Valid, ctx match, vaddr match
1072
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
1073
                    env->dtlb_tag[i] == T0) {
1074
                    ret = env->dtlb_tag[i];
1075
                    break;
1076
                }
1077
            }
1078
            break;
1079
        }
1080
    case 0x59: // D-MMU 8k TSB pointer
1081
    case 0x5a: // D-MMU 64k TSB pointer
1082
    case 0x5b: // D-MMU data pointer
1083
    case 0x5d: // D-MMU data access
1084
    case 0x48: // Interrupt dispatch, RO
1085
    case 0x49: // Interrupt data receive
1086
    case 0x7f: // Incoming interrupt vector, RO
1087
        // XXX
1088
        break;
1089
    case 0x54: // I-MMU data in, WO
1090
    case 0x57: // I-MMU demap, WO
1091
    case 0x5c: // D-MMU data in, WO
1092
    case 0x5f: // D-MMU demap, WO
1093
    case 0x77: // Interrupt vector, WO
1094
    default:
1095
        do_unassigned_access(T0, 0, 0, 1);
1096
        ret = 0;
1097
        break;
1098
    }
1099

    
1100
    /* Convert from little endian */
1101
    switch (asi) {
1102
    case 0x0c: // Nucleus Little Endian (LE)
1103
    case 0x18: // As if user primary LE
1104
    case 0x19: // As if user secondary LE
1105
    case 0x1c: // Bypass LE
1106
    case 0x1d: // Bypass, non-cacheable LE
1107
    case 0x88: // Primary LE
1108
    case 0x89: // Secondary LE
1109
    case 0x8a: // Primary no-fault LE
1110
    case 0x8b: // Secondary no-fault LE
1111
        switch(size) {
1112
        case 2:
1113
            ret = bswap16(ret);
1114
            break;
1115
        case 4:
1116
            ret = bswap32(ret);
1117
            break;
1118
        case 8:
1119
            ret = bswap64(ret);
1120
            break;
1121
        default:
1122
            break;
1123
        }
1124
    default:
1125
        break;
1126
    }
1127

    
1128
    /* Convert to signed number */
1129
    if (sign) {
1130
        switch(size) {
1131
        case 1:
1132
            ret = (int8_t) ret;
1133
            break;
1134
        case 2:
1135
            ret = (int16_t) ret;
1136
            break;
1137
        case 4:
1138
            ret = (int32_t) ret;
1139
            break;
1140
        default:
1141
            break;
1142
        }
1143
    }
1144
    T1 = ret;
1145
}
1146

    
1147
void helper_st_asi(int asi, int size)
1148
{
1149
    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1150
        || (asi >= 0x30 && asi < 0x80 && !(env->hpstate & HS_PRIV)))
1151
        raise_exception(TT_PRIV_ACT);
1152

    
1153
    /* Convert to little endian */
1154
    switch (asi) {
1155
    case 0x0c: // Nucleus Little Endian (LE)
1156
    case 0x18: // As if user primary LE
1157
    case 0x19: // As if user secondary LE
1158
    case 0x1c: // Bypass LE
1159
    case 0x1d: // Bypass, non-cacheable LE
1160
    case 0x88: // Primary LE
1161
    case 0x89: // Secondary LE
1162
        switch(size) {
1163
        case 2:
1164
            T0 = bswap16(T0);
1165
            break;
1166
        case 4:
1167
            T0 = bswap32(T0);
1168
            break;
1169
        case 8:
1170
            T0 = bswap64(T0);
1171
            break;
1172
        default:
1173
            break;
1174
        }
1175
    default:
1176
        break;
1177
    }
1178

    
1179
    switch(asi) {
1180
    case 0x10: // As if user primary
1181
    case 0x18: // As if user primary LE
1182
    case 0x80: // Primary
1183
    case 0x88: // Primary LE
1184
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1185
            if (env->hpstate & HS_PRIV) {
1186
                switch(size) {
1187
                case 1:
1188
                    stb_hypv(T0, T1);
1189
                    break;
1190
                case 2:
1191
                    stw_hypv(T0 & ~1, T1);
1192
                    break;
1193
                case 4:
1194
                    stl_hypv(T0 & ~3, T1);
1195
                    break;
1196
                case 8:
1197
                default:
1198
                    stq_hypv(T0 & ~7, T1);
1199
                    break;
1200
                }
1201
            } else {
1202
                switch(size) {
1203
                case 1:
1204
                    stb_kernel(T0, T1);
1205
                    break;
1206
                case 2:
1207
                    stw_kernel(T0 & ~1, T1);
1208
                    break;
1209
                case 4:
1210
                    stl_kernel(T0 & ~3, T1);
1211
                    break;
1212
                case 8:
1213
                default:
1214
                    stq_kernel(T0 & ~7, T1);
1215
                    break;
1216
                }
1217
            }
1218
        } else {
1219
            switch(size) {
1220
            case 1:
1221
                stb_user(T0, T1);
1222
                break;
1223
            case 2:
1224
                stw_user(T0 & ~1, T1);
1225
                break;
1226
            case 4:
1227
                stl_user(T0 & ~3, T1);
1228
                break;
1229
            case 8:
1230
            default:
1231
                stq_user(T0 & ~7, T1);
1232
                break;
1233
            }
1234
        }
1235
        break;
1236
    case 0x14: // Bypass
1237
    case 0x15: // Bypass, non-cacheable
1238
    case 0x1c: // Bypass LE
1239
    case 0x1d: // Bypass, non-cacheable LE
1240
        {
1241
            switch(size) {
1242
            case 1:
1243
                stb_phys(T0, T1);
1244
                break;
1245
            case 2:
1246
                stw_phys(T0 & ~1, T1);
1247
                break;
1248
            case 4:
1249
                stl_phys(T0 & ~3, T1);
1250
                break;
1251
            case 8:
1252
            default:
1253
                stq_phys(T0 & ~7, T1);
1254
                break;
1255
            }
1256
        }
1257
        return;
1258
    case 0x04: // Nucleus
1259
    case 0x0c: // Nucleus Little Endian (LE)
1260
    case 0x11: // As if user secondary
1261
    case 0x19: // As if user secondary LE
1262
    case 0x24: // Nucleus quad LDD 128 bit atomic
1263
    case 0x2c: // Nucleus quad LDD 128 bit atomic
1264
    case 0x4a: // UPA config
1265
    case 0x81: // Secondary
1266
    case 0x89: // Secondary LE
1267
        // XXX
1268
        return;
1269
    case 0x45: // LSU
1270
        {
1271
            uint64_t oldreg;
1272

    
1273
            oldreg = env->lsu;
1274
            env->lsu = T1 & (DMMU_E | IMMU_E);
1275
            // Mappings generated during D/I MMU disabled mode are
1276
            // invalid in normal mode
1277
            if (oldreg != env->lsu) {
1278
                DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
1279
#ifdef DEBUG_MMU
1280
                dump_mmu(env);
1281
#endif
1282
                tlb_flush(env, 1);
1283
            }
1284
            return;
1285
        }
1286
    case 0x50: // I-MMU regs
1287
        {
1288
            int reg = (T0 >> 3) & 0xf;
1289
            uint64_t oldreg;
1290

    
1291
            oldreg = env->immuregs[reg];
1292
            switch(reg) {
1293
            case 0: // RO
1294
            case 4:
1295
                return;
1296
            case 1: // Not in I-MMU
1297
            case 2:
1298
            case 7:
1299
            case 8:
1300
                return;
1301
            case 3: // SFSR
1302
                if ((T1 & 1) == 0)
1303
                    T1 = 0; // Clear SFSR
1304
                break;
1305
            case 5: // TSB access
1306
            case 6: // Tag access
1307
            default:
1308
                break;
1309
            }
1310
            env->immuregs[reg] = T1;
1311
            if (oldreg != env->immuregs[reg]) {
1312
                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
1313
            }
1314
#ifdef DEBUG_MMU
1315
            dump_mmu(env);
1316
#endif
1317
            return;
1318
        }
1319
    case 0x54: // I-MMU data in
1320
        {
1321
            unsigned int i;
1322

    
1323
            // Try finding an invalid entry
1324
            for (i = 0; i < 64; i++) {
1325
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
1326
                    env->itlb_tag[i] = env->immuregs[6];
1327
                    env->itlb_tte[i] = T1;
1328
                    return;
1329
                }
1330
            }
1331
            // Try finding an unlocked entry
1332
            for (i = 0; i < 64; i++) {
1333
                if ((env->itlb_tte[i] & 0x40) == 0) {
1334
                    env->itlb_tag[i] = env->immuregs[6];
1335
                    env->itlb_tte[i] = T1;
1336
                    return;
1337
                }
1338
            }
1339
            // error state?
1340
            return;
1341
        }
1342
    case 0x55: // I-MMU data access
1343
        {
1344
            unsigned int i = (T0 >> 3) & 0x3f;
1345

    
1346
            env->itlb_tag[i] = env->immuregs[6];
1347
            env->itlb_tte[i] = T1;
1348
            return;
1349
        }
1350
    case 0x57: // I-MMU demap
1351
        // XXX
1352
        return;
1353
    case 0x58: // D-MMU regs
1354
        {
1355
            int reg = (T0 >> 3) & 0xf;
1356
            uint64_t oldreg;
1357

    
1358
            oldreg = env->dmmuregs[reg];
1359
            switch(reg) {
1360
            case 0: // RO
1361
            case 4:
1362
                return;
1363
            case 3: // SFSR
1364
                if ((T1 & 1) == 0) {
1365
                    T1 = 0; // Clear SFSR, Fault address
1366
                    env->dmmuregs[4] = 0;
1367
                }
1368
                env->dmmuregs[reg] = T1;
1369
                break;
1370
            case 1: // Primary context
1371
            case 2: // Secondary context
1372
            case 5: // TSB access
1373
            case 6: // Tag access
1374
            case 7: // Virtual Watchpoint
1375
            case 8: // Physical Watchpoint
1376
            default:
1377
                break;
1378
            }
1379
            env->dmmuregs[reg] = T1;
1380
            if (oldreg != env->dmmuregs[reg]) {
1381
                DPRINTF_MMU("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
1382
            }
1383
#ifdef DEBUG_MMU
1384
            dump_mmu(env);
1385
#endif
1386
            return;
1387
        }
1388
    case 0x5c: // D-MMU data in
1389
        {
1390
            unsigned int i;
1391

    
1392
            // Try finding an invalid entry
1393
            for (i = 0; i < 64; i++) {
1394
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
1395
                    env->dtlb_tag[i] = env->dmmuregs[6];
1396
                    env->dtlb_tte[i] = T1;
1397
                    return;
1398
                }
1399
            }
1400
            // Try finding an unlocked entry
1401
            for (i = 0; i < 64; i++) {
1402
                if ((env->dtlb_tte[i] & 0x40) == 0) {
1403
                    env->dtlb_tag[i] = env->dmmuregs[6];
1404
                    env->dtlb_tte[i] = T1;
1405
                    return;
1406
                }
1407
            }
1408
            // error state?
1409
            return;
1410
        }
1411
    case 0x5d: // D-MMU data access
1412
        {
1413
            unsigned int i = (T0 >> 3) & 0x3f;
1414

    
1415
            env->dtlb_tag[i] = env->dmmuregs[6];
1416
            env->dtlb_tte[i] = T1;
1417
            return;
1418
        }
1419
    case 0x5f: // D-MMU demap
1420
    case 0x49: // Interrupt data receive
1421
        // XXX
1422
        return;
1423
    case 0x51: // I-MMU 8k TSB pointer, RO
1424
    case 0x52: // I-MMU 64k TSB pointer, RO
1425
    case 0x56: // I-MMU tag read, RO
1426
    case 0x59: // D-MMU 8k TSB pointer, RO
1427
    case 0x5a: // D-MMU 64k TSB pointer, RO
1428
    case 0x5b: // D-MMU data pointer, RO
1429
    case 0x5e: // D-MMU tag read, RO
1430
    case 0x48: // Interrupt dispatch, RO
1431
    case 0x7f: // Incoming interrupt vector, RO
1432
    case 0x82: // Primary no-fault, RO
1433
    case 0x83: // Secondary no-fault, RO
1434
    case 0x8a: // Primary no-fault LE, RO
1435
    case 0x8b: // Secondary no-fault LE, RO
1436
    default:
1437
        do_unassigned_access(T0, 1, 0, 1);
1438
        return;
1439
    }
1440
}
1441
#endif /* CONFIG_USER_ONLY */
1442

    
1443
void helper_ldf_asi(int asi, int size, int rd)
1444
{
1445
    target_ulong tmp_T0 = T0, tmp_T1 = T1;
1446
    unsigned int i;
1447

    
1448
    switch (asi) {
1449
    case 0xf0: // Block load primary
1450
    case 0xf1: // Block load secondary
1451
    case 0xf8: // Block load primary LE
1452
    case 0xf9: // Block load secondary LE
1453
        if (rd & 7) {
1454
            raise_exception(TT_ILL_INSN);
1455
            return;
1456
        }
1457
        if (T0 & 0x3f) {
1458
            raise_exception(TT_UNALIGNED);
1459
            return;
1460
        }
1461
        for (i = 0; i < 16; i++) {
1462
            helper_ld_asi(asi & 0x8f, 4, 0);
1463
            *(uint32_t *)&env->fpr[rd++] = T1;
1464
            T0 += 4;
1465
        }
1466
        T0 = tmp_T0;
1467
        T1 = tmp_T1;
1468

    
1469
        return;
1470
    default:
1471
        break;
1472
    }
1473

    
1474
    helper_ld_asi(asi, size, 0);
1475
    switch(size) {
1476
    default:
1477
    case 4:
1478
        *((uint32_t *)&FT0) = T1;
1479
        break;
1480
    case 8:
1481
        *((int64_t *)&DT0) = T1;
1482
        break;
1483
#if defined(CONFIG_USER_ONLY)
1484
    case 16:
1485
        // XXX
1486
        break;
1487
#endif
1488
    }
1489
    T1 = tmp_T1;
1490
}
1491

    
1492
void helper_stf_asi(int asi, int size, int rd)
1493
{
1494
    target_ulong tmp_T0 = T0, tmp_T1 = T1;
1495
    unsigned int i;
1496

    
1497
    switch (asi) {
1498
    case 0xf0: // Block store primary
1499
    case 0xf1: // Block store secondary
1500
    case 0xf8: // Block store primary LE
1501
    case 0xf9: // Block store secondary LE
1502
        if (rd & 7) {
1503
            raise_exception(TT_ILL_INSN);
1504
            return;
1505
        }
1506
        if (T0 & 0x3f) {
1507
            raise_exception(TT_UNALIGNED);
1508
            return;
1509
        }
1510
        for (i = 0; i < 16; i++) {
1511
            T1 = *(uint32_t *)&env->fpr[rd++];
1512
            helper_st_asi(asi & 0x8f, 4);
1513
            T0 += 4;
1514
        }
1515
        T0 = tmp_T0;
1516
        T1 = tmp_T1;
1517

    
1518
        return;
1519
    default:
1520
        break;
1521
    }
1522

    
1523
    switch(size) {
1524
    default:
1525
    case 4:
1526
        T1 = *((uint32_t *)&FT0);
1527
        break;
1528
    case 8:
1529
        T1 = *((int64_t *)&DT0);
1530
        break;
1531
#if defined(CONFIG_USER_ONLY)
1532
    case 16:
1533
        // XXX
1534
        break;
1535
#endif
1536
    }
1537
    helper_st_asi(asi, size);
1538
    T1 = tmp_T1;
1539
}
1540

    
1541
#endif /* TARGET_SPARC64 */
1542

    
1543
#ifndef TARGET_SPARC64
1544
void helper_rett()
1545
{
1546
    unsigned int cwp;
1547

    
1548
    if (env->psret == 1)
1549
        raise_exception(TT_ILL_INSN);
1550

    
1551
    env->psret = 1;
1552
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
1553
    if (env->wim & (1 << cwp)) {
1554
        raise_exception(TT_WIN_UNF);
1555
    }
1556
    set_cwp(cwp);
1557
    env->psrs = env->psrps;
1558
}
1559
#endif
1560

    
1561
void helper_ldfsr(void)
1562
{
1563
    int rnd_mode;
1564
    switch (env->fsr & FSR_RD_MASK) {
1565
    case FSR_RD_NEAREST:
1566
        rnd_mode = float_round_nearest_even;
1567
        break;
1568
    default:
1569
    case FSR_RD_ZERO:
1570
        rnd_mode = float_round_to_zero;
1571
        break;
1572
    case FSR_RD_POS:
1573
        rnd_mode = float_round_up;
1574
        break;
1575
    case FSR_RD_NEG:
1576
        rnd_mode = float_round_down;
1577
        break;
1578
    }
1579
    set_float_rounding_mode(rnd_mode, &env->fp_status);
1580
}
1581

    
1582
void helper_debug()
1583
{
1584
    env->exception_index = EXCP_DEBUG;
1585
    cpu_loop_exit();
1586
}
1587

    
1588
#ifndef TARGET_SPARC64
1589
void do_wrpsr()
1590
{
1591
    if ((T0 & PSR_CWP) >= NWINDOWS)
1592
        raise_exception(TT_ILL_INSN);
1593
    else
1594
        PUT_PSR(env, T0);
1595
}
1596

    
1597
void do_rdpsr()
1598
{
1599
    T0 = GET_PSR(env);
1600
}
1601

    
1602
#else
1603

    
1604
void do_popc()
1605
{
1606
    T0 = ctpop64(T1);
1607
}
1608

    
1609
static inline uint64_t *get_gregset(uint64_t pstate)
1610
{
1611
    switch (pstate) {
1612
    default:
1613
    case 0:
1614
        return env->bgregs;
1615
    case PS_AG:
1616
        return env->agregs;
1617
    case PS_MG:
1618
        return env->mgregs;
1619
    case PS_IG:
1620
        return env->igregs;
1621
    }
1622
}
1623

    
1624
static inline void change_pstate(uint64_t new_pstate)
1625
{
1626
    uint64_t pstate_regs, new_pstate_regs;
1627
    uint64_t *src, *dst;
1628

    
1629
    pstate_regs = env->pstate & 0xc01;
1630
    new_pstate_regs = new_pstate & 0xc01;
1631
    if (new_pstate_regs != pstate_regs) {
1632
        // Switch global register bank
1633
        src = get_gregset(new_pstate_regs);
1634
        dst = get_gregset(pstate_regs);
1635
        memcpy32(dst, env->gregs);
1636
        memcpy32(env->gregs, src);
1637
    }
1638
    env->pstate = new_pstate;
1639
}
1640

    
1641
void do_wrpstate(void)
1642
{
1643
    change_pstate(T0 & 0xf3f);
1644
}
1645

    
1646
void do_done(void)
1647
{
1648
    env->tl--;
1649
    env->pc = env->tnpc[env->tl];
1650
    env->npc = env->tnpc[env->tl] + 4;
1651
    PUT_CCR(env, env->tstate[env->tl] >> 32);
1652
    env->asi = (env->tstate[env->tl] >> 24) & 0xff;
1653
    change_pstate((env->tstate[env->tl] >> 8) & 0xf3f);
1654
    PUT_CWP64(env, env->tstate[env->tl] & 0xff);
1655
}
1656

    
1657
void do_retry(void)
1658
{
1659
    env->tl--;
1660
    env->pc = env->tpc[env->tl];
1661
    env->npc = env->tnpc[env->tl];
1662
    PUT_CCR(env, env->tstate[env->tl] >> 32);
1663
    env->asi = (env->tstate[env->tl] >> 24) & 0xff;
1664
    change_pstate((env->tstate[env->tl] >> 8) & 0xf3f);
1665
    PUT_CWP64(env, env->tstate[env->tl] & 0xff);
1666
}
1667
#endif
1668

    
1669
void set_cwp(int new_cwp)
1670
{
1671
    /* put the modified wrap registers at their proper location */
1672
    if (env->cwp == (NWINDOWS - 1))
1673
        memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
1674
    env->cwp = new_cwp;
1675
    /* put the wrap registers at their temporary location */
1676
    if (new_cwp == (NWINDOWS - 1))
1677
        memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
1678
    env->regwptr = env->regbase + (new_cwp * 16);
1679
    REGWPTR = env->regwptr;
1680
}
1681

    
1682
void cpu_set_cwp(CPUState *env1, int new_cwp)
1683
{
1684
    CPUState *saved_env;
1685
#ifdef reg_REGWPTR
1686
    target_ulong *saved_regwptr;
1687
#endif
1688

    
1689
    saved_env = env;
1690
#ifdef reg_REGWPTR
1691
    saved_regwptr = REGWPTR;
1692
#endif
1693
    env = env1;
1694
    set_cwp(new_cwp);
1695
    env = saved_env;
1696
#ifdef reg_REGWPTR
1697
    REGWPTR = saved_regwptr;
1698
#endif
1699
}
1700

    
1701
#ifdef TARGET_SPARC64
1702
#ifdef DEBUG_PCALL
1703
static const char * const excp_names[0x50] = {
1704
    [TT_TFAULT] = "Instruction Access Fault",
1705
    [TT_TMISS] = "Instruction Access MMU Miss",
1706
    [TT_CODE_ACCESS] = "Instruction Access Error",
1707
    [TT_ILL_INSN] = "Illegal Instruction",
1708
    [TT_PRIV_INSN] = "Privileged Instruction",
1709
    [TT_NFPU_INSN] = "FPU Disabled",
1710
    [TT_FP_EXCP] = "FPU Exception",
1711
    [TT_TOVF] = "Tag Overflow",
1712
    [TT_CLRWIN] = "Clean Windows",
1713
    [TT_DIV_ZERO] = "Division By Zero",
1714
    [TT_DFAULT] = "Data Access Fault",
1715
    [TT_DMISS] = "Data Access MMU Miss",
1716
    [TT_DATA_ACCESS] = "Data Access Error",
1717
    [TT_DPROT] = "Data Protection Error",
1718
    [TT_UNALIGNED] = "Unaligned Memory Access",
1719
    [TT_PRIV_ACT] = "Privileged Action",
1720
    [TT_EXTINT | 0x1] = "External Interrupt 1",
1721
    [TT_EXTINT | 0x2] = "External Interrupt 2",
1722
    [TT_EXTINT | 0x3] = "External Interrupt 3",
1723
    [TT_EXTINT | 0x4] = "External Interrupt 4",
1724
    [TT_EXTINT | 0x5] = "External Interrupt 5",
1725
    [TT_EXTINT | 0x6] = "External Interrupt 6",
1726
    [TT_EXTINT | 0x7] = "External Interrupt 7",
1727
    [TT_EXTINT | 0x8] = "External Interrupt 8",
1728
    [TT_EXTINT | 0x9] = "External Interrupt 9",
1729
    [TT_EXTINT | 0xa] = "External Interrupt 10",
1730
    [TT_EXTINT | 0xb] = "External Interrupt 11",
1731
    [TT_EXTINT | 0xc] = "External Interrupt 12",
1732
    [TT_EXTINT | 0xd] = "External Interrupt 13",
1733
    [TT_EXTINT | 0xe] = "External Interrupt 14",
1734
    [TT_EXTINT | 0xf] = "External Interrupt 15",
1735
};
1736
#endif
1737

    
1738
void do_interrupt(int intno)
1739
{
1740
#ifdef DEBUG_PCALL
1741
    if (loglevel & CPU_LOG_INT) {
1742
        static int count;
1743
        const char *name;
1744

    
1745
        if (intno < 0 || intno >= 0x180 || (intno > 0x4f && intno < 0x80))
1746
            name = "Unknown";
1747
        else if (intno >= 0x100)
1748
            name = "Trap Instruction";
1749
        else if (intno >= 0xc0)
1750
            name = "Window Fill";
1751
        else if (intno >= 0x80)
1752
            name = "Window Spill";
1753
        else {
1754
            name = excp_names[intno];
1755
            if (!name)
1756
                name = "Unknown";
1757
        }
1758

    
1759
        fprintf(logfile, "%6d: %s (v=%04x) pc=%016" PRIx64 " npc=%016" PRIx64
1760
                " SP=%016" PRIx64 "\n",
1761
                count, name, intno,
1762
                env->pc,
1763
                env->npc, env->regwptr[6]);
1764
        cpu_dump_state(env, logfile, fprintf, 0);
1765
#if 0
1766
        {
1767
            int i;
1768
            uint8_t *ptr;
1769

1770
            fprintf(logfile, "       code=");
1771
            ptr = (uint8_t *)env->pc;
1772
            for(i = 0; i < 16; i++) {
1773
                fprintf(logfile, " %02x", ldub(ptr + i));
1774
            }
1775
            fprintf(logfile, "\n");
1776
        }
1777
#endif
1778
        count++;
1779
    }
1780
#endif
1781
#if !defined(CONFIG_USER_ONLY)
1782
    if (env->tl == MAXTL) {
1783
        cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
1784
        return;
1785
    }
1786
#endif
1787
    env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
1788
        ((env->pstate & 0xf3f) << 8) | GET_CWP64(env);
1789
    env->tpc[env->tl] = env->pc;
1790
    env->tnpc[env->tl] = env->npc;
1791
    env->tt[env->tl] = intno;
1792
    change_pstate(PS_PEF | PS_PRIV | PS_AG);
1793

    
1794
    if (intno == TT_CLRWIN)
1795
        set_cwp((env->cwp - 1) & (NWINDOWS - 1));
1796
    else if ((intno & 0x1c0) == TT_SPILL)
1797
        set_cwp((env->cwp - env->cansave - 2) & (NWINDOWS - 1));
1798
    else if ((intno & 0x1c0) == TT_FILL)
1799
        set_cwp((env->cwp + 1) & (NWINDOWS - 1));
1800
    env->tbr &= ~0x7fffULL;
1801
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
1802
    if (env->tl < MAXTL - 1) {
1803
        env->tl++;
1804
    } else {
1805
        env->pstate |= PS_RED;
1806
        if (env->tl != MAXTL)
1807
            env->tl++;
1808
    }
1809
    env->pc = env->tbr;
1810
    env->npc = env->pc + 4;
1811
    env->exception_index = 0;
1812
}
1813
#else
1814
#ifdef DEBUG_PCALL
1815
static const char * const excp_names[0x80] = {
1816
    [TT_TFAULT] = "Instruction Access Fault",
1817
    [TT_ILL_INSN] = "Illegal Instruction",
1818
    [TT_PRIV_INSN] = "Privileged Instruction",
1819
    [TT_NFPU_INSN] = "FPU Disabled",
1820
    [TT_WIN_OVF] = "Window Overflow",
1821
    [TT_WIN_UNF] = "Window Underflow",
1822
    [TT_UNALIGNED] = "Unaligned Memory Access",
1823
    [TT_FP_EXCP] = "FPU Exception",
1824
    [TT_DFAULT] = "Data Access Fault",
1825
    [TT_TOVF] = "Tag Overflow",
1826
    [TT_EXTINT | 0x1] = "External Interrupt 1",
1827
    [TT_EXTINT | 0x2] = "External Interrupt 2",
1828
    [TT_EXTINT | 0x3] = "External Interrupt 3",
1829
    [TT_EXTINT | 0x4] = "External Interrupt 4",
1830
    [TT_EXTINT | 0x5] = "External Interrupt 5",
1831
    [TT_EXTINT | 0x6] = "External Interrupt 6",
1832
    [TT_EXTINT | 0x7] = "External Interrupt 7",
1833
    [TT_EXTINT | 0x8] = "External Interrupt 8",
1834
    [TT_EXTINT | 0x9] = "External Interrupt 9",
1835
    [TT_EXTINT | 0xa] = "External Interrupt 10",
1836
    [TT_EXTINT | 0xb] = "External Interrupt 11",
1837
    [TT_EXTINT | 0xc] = "External Interrupt 12",
1838
    [TT_EXTINT | 0xd] = "External Interrupt 13",
1839
    [TT_EXTINT | 0xe] = "External Interrupt 14",
1840
    [TT_EXTINT | 0xf] = "External Interrupt 15",
1841
    [TT_TOVF] = "Tag Overflow",
1842
    [TT_CODE_ACCESS] = "Instruction Access Error",
1843
    [TT_DATA_ACCESS] = "Data Access Error",
1844
    [TT_DIV_ZERO] = "Division By Zero",
1845
    [TT_NCP_INSN] = "Coprocessor Disabled",
1846
};
1847
#endif
1848

    
1849
void do_interrupt(int intno)
1850
{
1851
    int cwp;
1852

    
1853
#ifdef DEBUG_PCALL
1854
    if (loglevel & CPU_LOG_INT) {
1855
        static int count;
1856
        const char *name;
1857

    
1858
        if (intno < 0 || intno >= 0x100)
1859
            name = "Unknown";
1860
        else if (intno >= 0x80)
1861
            name = "Trap Instruction";
1862
        else {
1863
            name = excp_names[intno];
1864
            if (!name)
1865
                name = "Unknown";
1866
        }
1867

    
1868
        fprintf(logfile, "%6d: %s (v=%02x) pc=%08x npc=%08x SP=%08x\n",
1869
                count, name, intno,
1870
                env->pc,
1871
                env->npc, env->regwptr[6]);
1872
        cpu_dump_state(env, logfile, fprintf, 0);
1873
#if 0
1874
        {
1875
            int i;
1876
            uint8_t *ptr;
1877

1878
            fprintf(logfile, "       code=");
1879
            ptr = (uint8_t *)env->pc;
1880
            for(i = 0; i < 16; i++) {
1881
                fprintf(logfile, " %02x", ldub(ptr + i));
1882
            }
1883
            fprintf(logfile, "\n");
1884
        }
1885
#endif
1886
        count++;
1887
    }
1888
#endif
1889
#if !defined(CONFIG_USER_ONLY)
1890
    if (env->psret == 0) {
1891
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
1892
        return;
1893
    }
1894
#endif
1895
    env->psret = 0;
1896
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
1897
    set_cwp(cwp);
1898
    env->regwptr[9] = env->pc;
1899
    env->regwptr[10] = env->npc;
1900
    env->psrps = env->psrs;
1901
    env->psrs = 1;
1902
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
1903
    env->pc = env->tbr;
1904
    env->npc = env->pc + 4;
1905
    env->exception_index = 0;
1906
}
1907
#endif
1908

    
1909
#if !defined(CONFIG_USER_ONLY)
1910

    
1911
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
1912
                                void *retaddr);
1913

    
1914
#define MMUSUFFIX _mmu
1915
#define ALIGNED_ONLY
1916
#ifdef __s390__
1917
# define GETPC() ((void*)((unsigned long)__builtin_return_address(0) & 0x7fffffffUL))
1918
#else
1919
# define GETPC() (__builtin_return_address(0))
1920
#endif
1921

    
1922
#define SHIFT 0
1923
#include "softmmu_template.h"
1924

    
1925
#define SHIFT 1
1926
#include "softmmu_template.h"
1927

    
1928
#define SHIFT 2
1929
#include "softmmu_template.h"
1930

    
1931
#define SHIFT 3
1932
#include "softmmu_template.h"
1933

    
1934
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
1935
                                void *retaddr)
1936
{
1937
#ifdef DEBUG_UNALIGNED
1938
    printf("Unaligned access to 0x%x from 0x%x\n", addr, env->pc);
1939
#endif
1940
    raise_exception(TT_UNALIGNED);
1941
}
1942

    
1943
/* try to fill the TLB and return an exception if error. If retaddr is
1944
   NULL, it means that the function was called in C code (i.e. not
1945
   from generated code or from helper.c) */
1946
/* XXX: fix it to restore all registers */
1947
void tlb_fill(target_ulong addr, int is_write, int mmu_idx, void *retaddr)
1948
{
1949
    TranslationBlock *tb;
1950
    int ret;
1951
    unsigned long pc;
1952
    CPUState *saved_env;
1953

    
1954
    /* XXX: hack to restore env in all cases, even if not called from
1955
       generated code */
1956
    saved_env = env;
1957
    env = cpu_single_env;
1958

    
1959
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, mmu_idx, 1);
1960
    if (ret) {
1961
        if (retaddr) {
1962
            /* now we have a real cpu fault */
1963
            pc = (unsigned long)retaddr;
1964
            tb = tb_find_pc(pc);
1965
            if (tb) {
1966
                /* the PC is inside the translated code. It means that we have
1967
                   a virtual CPU fault */
1968
                cpu_restore_state(tb, env, pc, (void *)T2);
1969
            }
1970
        }
1971
        cpu_loop_exit();
1972
    }
1973
    env = saved_env;
1974
}
1975

    
1976
#endif
1977

    
1978
#ifndef TARGET_SPARC64
1979
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
1980
                          int is_asi)
1981
{
1982
    CPUState *saved_env;
1983

    
1984
    /* XXX: hack to restore env in all cases, even if not called from
1985
       generated code */
1986
    saved_env = env;
1987
    env = cpu_single_env;
1988
#ifdef DEBUG_UNASSIGNED
1989
    if (is_asi)
1990
        printf("Unassigned mem %s access to " TARGET_FMT_plx " asi 0x%02x from "
1991
               TARGET_FMT_lx "\n",
1992
               is_exec ? "exec" : is_write ? "write" : "read", addr, is_asi,
1993
               env->pc);
1994
    else
1995
        printf("Unassigned mem %s access to " TARGET_FMT_plx " from "
1996
               TARGET_FMT_lx "\n",
1997
               is_exec ? "exec" : is_write ? "write" : "read", addr, env->pc);
1998
#endif
1999
    if (env->mmuregs[3]) /* Fault status register */
2000
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
2001
    if (is_asi)
2002
        env->mmuregs[3] |= 1 << 16;
2003
    if (env->psrs)
2004
        env->mmuregs[3] |= 1 << 5;
2005
    if (is_exec)
2006
        env->mmuregs[3] |= 1 << 6;
2007
    if (is_write)
2008
        env->mmuregs[3] |= 1 << 7;
2009
    env->mmuregs[3] |= (5 << 2) | 2;
2010
    env->mmuregs[4] = addr; /* Fault address register */
2011
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
2012
        if (is_exec)
2013
            raise_exception(TT_CODE_ACCESS);
2014
        else
2015
            raise_exception(TT_DATA_ACCESS);
2016
    }
2017
    env = saved_env;
2018
}
2019
#else
2020
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
2021
                          int is_asi)
2022
{
2023
#ifdef DEBUG_UNASSIGNED
2024
    CPUState *saved_env;
2025

    
2026
    /* XXX: hack to restore env in all cases, even if not called from
2027
       generated code */
2028
    saved_env = env;
2029
    env = cpu_single_env;
2030
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx "\n",
2031
           addr, env->pc);
2032
    env = saved_env;
2033
#endif
2034
    if (is_exec)
2035
        raise_exception(TT_CODE_ACCESS);
2036
    else
2037
        raise_exception(TT_DATA_ACCESS);
2038
}
2039
#endif
2040