Statistics
| Branch: | Revision:

root / target-sparc / op_helper.c @ 81ad8ba2

History | View | Annotate | Download (40.5 kB)

1
#include "exec.h"
2

    
3
//#define DEBUG_PCALL
4
//#define DEBUG_MMU
5
//#define DEBUG_UNALIGNED
6
//#define DEBUG_UNASSIGNED
7

    
8
void raise_exception(int tt)
9
{
10
    env->exception_index = tt;
11
    cpu_loop_exit();
12
}
13

    
14
void check_ieee_exceptions()
15
{
16
     T0 = get_float_exception_flags(&env->fp_status);
17
     if (T0)
18
     {
19
        /* Copy IEEE 754 flags into FSR */
20
        if (T0 & float_flag_invalid)
21
            env->fsr |= FSR_NVC;
22
        if (T0 & float_flag_overflow)
23
            env->fsr |= FSR_OFC;
24
        if (T0 & float_flag_underflow)
25
            env->fsr |= FSR_UFC;
26
        if (T0 & float_flag_divbyzero)
27
            env->fsr |= FSR_DZC;
28
        if (T0 & float_flag_inexact)
29
            env->fsr |= FSR_NXC;
30

    
31
        if ((env->fsr & FSR_CEXC_MASK) & ((env->fsr & FSR_TEM_MASK) >> 23))
32
        {
33
            /* Unmasked exception, generate a trap */
34
            env->fsr |= FSR_FTT_IEEE_EXCP;
35
            raise_exception(TT_FP_EXCP);
36
        }
37
        else
38
        {
39
            /* Accumulate exceptions */
40
            env->fsr |= (env->fsr & FSR_CEXC_MASK) << 5;
41
        }
42
     }
43
}
44

    
45
#ifdef USE_INT_TO_FLOAT_HELPERS
46
void do_fitos(void)
47
{
48
    set_float_exception_flags(0, &env->fp_status);
49
    FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status);
50
    check_ieee_exceptions();
51
}
52

    
53
void do_fitod(void)
54
{
55
    DT0 = int32_to_float64(*((int32_t *)&FT1), &env->fp_status);
56
}
57
#endif
58

    
59
void do_fabss(void)
60
{
61
    FT0 = float32_abs(FT1);
62
}
63

    
64
#ifdef TARGET_SPARC64
65
void do_fabsd(void)
66
{
67
    DT0 = float64_abs(DT1);
68
}
69
#endif
70

    
71
void do_fsqrts(void)
72
{
73
    set_float_exception_flags(0, &env->fp_status);
74
    FT0 = float32_sqrt(FT1, &env->fp_status);
75
    check_ieee_exceptions();
76
}
77

    
78
void do_fsqrtd(void)
79
{
80
    set_float_exception_flags(0, &env->fp_status);
81
    DT0 = float64_sqrt(DT1, &env->fp_status);
82
    check_ieee_exceptions();
83
}
84

    
85
#define GEN_FCMP(name, size, reg1, reg2, FS, TRAP)                      \
86
    void glue(do_, name) (void)                                         \
87
    {                                                                   \
88
        env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS);                     \
89
        switch (glue(size, _compare) (reg1, reg2, &env->fp_status)) {   \
90
        case float_relation_unordered:                                  \
91
            T0 = (FSR_FCC1 | FSR_FCC0) << FS;                           \
92
            if ((env->fsr & FSR_NVM) || TRAP) {                         \
93
                env->fsr |= T0;                                         \
94
                env->fsr |= FSR_NVC;                                    \
95
                env->fsr |= FSR_FTT_IEEE_EXCP;                          \
96
                raise_exception(TT_FP_EXCP);                            \
97
            } else {                                                    \
98
                env->fsr |= FSR_NVA;                                    \
99
            }                                                           \
100
            break;                                                      \
101
        case float_relation_less:                                       \
102
            T0 = FSR_FCC0 << FS;                                        \
103
            break;                                                      \
104
        case float_relation_greater:                                    \
105
            T0 = FSR_FCC1 << FS;                                        \
106
            break;                                                      \
107
        default:                                                        \
108
            T0 = 0;                                                     \
109
            break;                                                      \
110
        }                                                               \
111
        env->fsr |= T0;                                                 \
112
    }
113

    
114
GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0);
115
GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0);
116

    
117
GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1);
118
GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1);
119

    
120
#ifdef TARGET_SPARC64
121
GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0);
122
GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0);
123

    
124
GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0);
125
GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0);
126

    
127
GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0);
128
GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0);
129

    
130
GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1);
131
GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1);
132

    
133
GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1);
134
GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1);
135

    
136
GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1);
137
GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1);
138
#endif
139

    
140
#ifndef TARGET_SPARC64
141
#ifndef CONFIG_USER_ONLY
142
void helper_ld_asi(int asi, int size, int sign)
143
{
144
    uint32_t ret = 0;
145

    
146
    switch (asi) {
147
    case 2: /* SuperSparc MXCC registers */
148
        break;
149
    case 3: /* MMU probe */
150
        {
151
            int mmulev;
152

    
153
            mmulev = (T0 >> 8) & 15;
154
            if (mmulev > 4)
155
                ret = 0;
156
            else {
157
                ret = mmu_probe(env, T0, mmulev);
158
                //bswap32s(&ret);
159
            }
160
#ifdef DEBUG_MMU
161
            printf("mmu_probe: 0x%08x (lev %d) -> 0x%08x\n", T0, mmulev, ret);
162
#endif
163
        }
164
        break;
165
    case 4: /* read MMU regs */
166
        {
167
            int reg = (T0 >> 8) & 0xf;
168

    
169
            ret = env->mmuregs[reg];
170
            if (reg == 3) /* Fault status cleared on read */
171
                env->mmuregs[reg] = 0;
172
#ifdef DEBUG_MMU
173
            printf("mmu_read: reg[%d] = 0x%08x\n", reg, ret);
174
#endif
175
        }
176
        break;
177
    case 9: /* Supervisor code access */
178
        switch(size) {
179
        case 1:
180
            ret = ldub_code(T0);
181
            break;
182
        case 2:
183
            ret = lduw_code(T0 & ~1);
184
            break;
185
        default:
186
        case 4:
187
            ret = ldl_code(T0 & ~3);
188
            break;
189
        case 8:
190
            ret = ldl_code(T0 & ~3);
191
            T0 = ldl_code((T0 + 4) & ~3);
192
            break;
193
        }
194
        break;
195
    case 0xa: /* User data access */
196
        switch(size) {
197
        case 1:
198
            ret = ldub_user(T0);
199
            break;
200
        case 2:
201
            ret = lduw_user(T0 & ~1);
202
            break;
203
        default:
204
        case 4:
205
            ret = ldl_user(T0 & ~3);
206
            break;
207
        case 8:
208
            ret = ldl_user(T0 & ~3);
209
            T0 = ldl_user((T0 + 4) & ~3);
210
            break;
211
        }
212
        break;
213
    case 0xb: /* Supervisor data access */
214
        switch(size) {
215
        case 1:
216
            ret = ldub_kernel(T0);
217
            break;
218
        case 2:
219
            ret = lduw_kernel(T0 & ~1);
220
            break;
221
        default:
222
        case 4:
223
            ret = ldl_kernel(T0 & ~3);
224
            break;
225
        case 8:
226
            ret = ldl_kernel(T0 & ~3);
227
            T0 = ldl_kernel((T0 + 4) & ~3);
228
            break;
229
        }
230
        break;
231
    case 0xc: /* I-cache tag */
232
    case 0xd: /* I-cache data */
233
    case 0xe: /* D-cache tag */
234
    case 0xf: /* D-cache data */
235
        break;
236
    case 0x20: /* MMU passthrough */
237
        switch(size) {
238
        case 1:
239
            ret = ldub_phys(T0);
240
            break;
241
        case 2:
242
            ret = lduw_phys(T0 & ~1);
243
            break;
244
        default:
245
        case 4:
246
            ret = ldl_phys(T0 & ~3);
247
            break;
248
        case 8:
249
            ret = ldl_phys(T0 & ~3);
250
            T0 = ldl_phys((T0 + 4) & ~3);
251
            break;
252
        }
253
        break;
254
    case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
255
    case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
256
        switch(size) {
257
        case 1:
258
            ret = ldub_phys((target_phys_addr_t)T0
259
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
260
            break;
261
        case 2:
262
            ret = lduw_phys((target_phys_addr_t)(T0 & ~1)
263
                            | ((target_phys_addr_t)(asi & 0xf) << 32));
264
            break;
265
        default:
266
        case 4:
267
            ret = ldl_phys((target_phys_addr_t)(T0 & ~3)
268
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
269
            break;
270
        case 8:
271
            ret = ldl_phys((target_phys_addr_t)(T0 & ~3)
272
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
273
            T0 = ldl_phys((target_phys_addr_t)((T0 + 4) & ~3)
274
                           | ((target_phys_addr_t)(asi & 0xf) << 32));
275
            break;
276
        }
277
        break;
278
    case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
279
    default:
280
        do_unassigned_access(T0, 0, 0, 1);
281
        ret = 0;
282
        break;
283
    }
284
    if (sign) {
285
        switch(size) {
286
        case 1:
287
            T1 = (int8_t) ret;
288
        case 2:
289
            T1 = (int16_t) ret;
290
        default:
291
            T1 = ret;
292
            break;
293
        }
294
    }
295
    else
296
        T1 = ret;
297
}
298

    
299
void helper_st_asi(int asi, int size)
300
{
301
    switch(asi) {
302
    case 2: /* SuperSparc MXCC registers */
303
        break;
304
    case 3: /* MMU flush */
305
        {
306
            int mmulev;
307

    
308
            mmulev = (T0 >> 8) & 15;
309
#ifdef DEBUG_MMU
310
            printf("mmu flush level %d\n", mmulev);
311
#endif
312
            switch (mmulev) {
313
            case 0: // flush page
314
                tlb_flush_page(env, T0 & 0xfffff000);
315
                break;
316
            case 1: // flush segment (256k)
317
            case 2: // flush region (16M)
318
            case 3: // flush context (4G)
319
            case 4: // flush entire
320
                tlb_flush(env, 1);
321
                break;
322
            default:
323
                break;
324
            }
325
#ifdef DEBUG_MMU
326
            dump_mmu(env);
327
#endif
328
            return;
329
        }
330
    case 4: /* write MMU regs */
331
        {
332
            int reg = (T0 >> 8) & 0xf;
333
            uint32_t oldreg;
334

    
335
            oldreg = env->mmuregs[reg];
336
            switch(reg) {
337
            case 0:
338
                env->mmuregs[reg] &= ~(MMU_E | MMU_NF);
339
                env->mmuregs[reg] |= T1 & (MMU_E | MMU_NF);
340
                // Mappings generated during no-fault mode or MMU
341
                // disabled mode are invalid in normal mode
342
                if (oldreg != env->mmuregs[reg])
343
                    tlb_flush(env, 1);
344
                break;
345
            case 2:
346
                env->mmuregs[reg] = T1;
347
                if (oldreg != env->mmuregs[reg]) {
348
                    /* we flush when the MMU context changes because
349
                       QEMU has no MMU context support */
350
                    tlb_flush(env, 1);
351
                }
352
                break;
353
            case 3:
354
            case 4:
355
                break;
356
            default:
357
                env->mmuregs[reg] = T1;
358
                break;
359
            }
360
#ifdef DEBUG_MMU
361
            if (oldreg != env->mmuregs[reg]) {
362
                printf("mmu change reg[%d]: 0x%08x -> 0x%08x\n", reg, oldreg, env->mmuregs[reg]);
363
            }
364
            dump_mmu(env);
365
#endif
366
            return;
367
        }
368
    case 0xa: /* User data access */
369
        switch(size) {
370
        case 1:
371
            stb_user(T0, T1);
372
            break;
373
        case 2:
374
            stw_user(T0 & ~1, T1);
375
            break;
376
        default:
377
        case 4:
378
            stl_user(T0 & ~3, T1);
379
            break;
380
        case 8:
381
            stl_user(T0 & ~3, T1);
382
            stl_user((T0 + 4) & ~3, T2);
383
            break;
384
        }
385
        break;
386
    case 0xb: /* Supervisor data access */
387
        switch(size) {
388
        case 1:
389
            stb_kernel(T0, T1);
390
            break;
391
        case 2:
392
            stw_kernel(T0 & ~1, T1);
393
            break;
394
        default:
395
        case 4:
396
            stl_kernel(T0 & ~3, T1);
397
            break;
398
        case 8:
399
            stl_kernel(T0 & ~3, T1);
400
            stl_kernel((T0 + 4) & ~3, T2);
401
            break;
402
        }
403
        break;
404
    case 0xc: /* I-cache tag */
405
    case 0xd: /* I-cache data */
406
    case 0xe: /* D-cache tag */
407
    case 0xf: /* D-cache data */
408
    case 0x10: /* I/D-cache flush page */
409
    case 0x11: /* I/D-cache flush segment */
410
    case 0x12: /* I/D-cache flush region */
411
    case 0x13: /* I/D-cache flush context */
412
    case 0x14: /* I/D-cache flush user */
413
        break;
414
    case 0x17: /* Block copy, sta access */
415
        {
416
            // value (T1) = src
417
            // address (T0) = dst
418
            // copy 32 bytes
419
            unsigned int i;
420
            uint32_t src = T1 & ~3, dst = T0 & ~3, temp;
421

    
422
            for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
423
                temp = ldl_kernel(src);
424
                stl_kernel(dst, temp);
425
            }
426
        }
427
        return;
428
    case 0x1f: /* Block fill, stda access */
429
        {
430
            // value (T1, T2)
431
            // address (T0) = dst
432
            // fill 32 bytes
433
            unsigned int i;
434
            uint32_t dst = T0 & 7;
435
            uint64_t val;
436

    
437
            val = (((uint64_t)T1) << 32) | T2;
438

    
439
            for (i = 0; i < 32; i += 8, dst += 8)
440
                stq_kernel(dst, val);
441
        }
442
        return;
443
    case 0x20: /* MMU passthrough */
444
        {
445
            switch(size) {
446
            case 1:
447
                stb_phys(T0, T1);
448
                break;
449
            case 2:
450
                stw_phys(T0 & ~1, T1);
451
                break;
452
            case 4:
453
            default:
454
                stl_phys(T0 & ~3, T1);
455
                break;
456
            case 8:
457
                stl_phys(T0 & ~3, T1);
458
                stl_phys((T0 + 4) & ~3, T2);
459
                break;
460
            }
461
        }
462
        return;
463
    case 0x2e: /* MMU passthrough, 0xexxxxxxxx */
464
    case 0x2f: /* MMU passthrough, 0xfxxxxxxxx */
465
        {
466
            switch(size) {
467
            case 1:
468
                stb_phys((target_phys_addr_t)T0
469
                         | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
470
                break;
471
            case 2:
472
                stw_phys((target_phys_addr_t)(T0 & ~1)
473
                            | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
474
                break;
475
            case 4:
476
            default:
477
                stl_phys((target_phys_addr_t)(T0 & ~3)
478
                           | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
479
                break;
480
            case 8:
481
                stl_phys((target_phys_addr_t)(T0 & ~3)
482
                           | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
483
                stl_phys((target_phys_addr_t)((T0 + 4) & ~3)
484
                           | ((target_phys_addr_t)(asi & 0xf) << 32), T1);
485
                break;
486
            }
487
        }
488
        return;
489
    case 0x31: /* Ross RT620 I-cache flush */
490
    case 0x36: /* I-cache flash clear */
491
    case 0x37: /* D-cache flash clear */
492
        break;
493
    case 9: /* Supervisor code access, XXX */
494
    case 0x21 ... 0x2d: /* MMU passthrough, unassigned */
495
    default:
496
        do_unassigned_access(T0, 1, 0, 1);
497
        return;
498
    }
499
}
500

    
501
#endif /* CONFIG_USER_ONLY */
502
#else /* TARGET_SPARC64 */
503

    
504
#ifdef CONFIG_USER_ONLY
505
void helper_ld_asi(int asi, int size, int sign)
506
{
507
    uint64_t ret = 0;
508

    
509
    if (asi < 0x80)
510
        raise_exception(TT_PRIV_ACT);
511

    
512
    switch (asi) {
513
    case 0x80: // Primary
514
    case 0x82: // Primary no-fault
515
    case 0x88: // Primary LE
516
    case 0x8a: // Primary no-fault LE
517
        {
518
            switch(size) {
519
            case 1:
520
                ret = ldub_raw(T0);
521
                break;
522
            case 2:
523
                ret = lduw_raw(T0 & ~1);
524
                break;
525
            case 4:
526
                ret = ldl_raw(T0 & ~3);
527
                break;
528
            default:
529
            case 8:
530
                ret = ldq_raw(T0 & ~7);
531
                break;
532
            }
533
        }
534
        break;
535
    case 0x81: // Secondary
536
    case 0x83: // Secondary no-fault
537
    case 0x89: // Secondary LE
538
    case 0x8b: // Secondary no-fault LE
539
        // XXX
540
        break;
541
    default:
542
        break;
543
    }
544

    
545
    /* Convert from little endian */
546
    switch (asi) {
547
    case 0x88: // Primary LE
548
    case 0x89: // Secondary LE
549
    case 0x8a: // Primary no-fault LE
550
    case 0x8b: // Secondary no-fault LE
551
        switch(size) {
552
        case 2:
553
            ret = bswap16(ret);
554
        case 4:
555
            ret = bswap32(ret);
556
        case 8:
557
            ret = bswap64(ret);
558
        default:
559
            break;
560
        }
561
    default:
562
        break;
563
    }
564

    
565
    /* Convert to signed number */
566
    if (sign) {
567
        switch(size) {
568
        case 1:
569
            ret = (int8_t) ret;
570
        case 2:
571
            ret = (int16_t) ret;
572
        case 4:
573
            ret = (int32_t) ret;
574
        default:
575
            break;
576
        }
577
    }
578
    T1 = ret;
579
}
580

    
581
void helper_st_asi(int asi, int size)
582
{
583
    if (asi < 0x80)
584
        raise_exception(TT_PRIV_ACT);
585

    
586
    /* Convert to little endian */
587
    switch (asi) {
588
    case 0x88: // Primary LE
589
    case 0x89: // Secondary LE
590
        switch(size) {
591
        case 2:
592
            T0 = bswap16(T0);
593
        case 4:
594
            T0 = bswap32(T0);
595
        case 8:
596
            T0 = bswap64(T0);
597
        default:
598
            break;
599
        }
600
    default:
601
        break;
602
    }
603

    
604
    switch(asi) {
605
    case 0x80: // Primary
606
    case 0x88: // Primary LE
607
        {
608
            switch(size) {
609
            case 1:
610
                stb_raw(T0, T1);
611
                break;
612
            case 2:
613
                stw_raw(T0 & ~1, T1);
614
                break;
615
            case 4:
616
                stl_raw(T0 & ~3, T1);
617
                break;
618
            case 8:
619
            default:
620
                stq_raw(T0 & ~7, T1);
621
                break;
622
            }
623
        }
624
        break;
625
    case 0x81: // Secondary
626
    case 0x89: // Secondary LE
627
        // XXX
628
        return;
629

    
630
    case 0x82: // Primary no-fault, RO
631
    case 0x83: // Secondary no-fault, RO
632
    case 0x8a: // Primary no-fault LE, RO
633
    case 0x8b: // Secondary no-fault LE, RO
634
    default:
635
        do_unassigned_access(T0, 1, 0, 1);
636
        return;
637
    }
638
}
639

    
640
#else /* CONFIG_USER_ONLY */
641

    
642
void helper_ld_asi(int asi, int size, int sign)
643
{
644
    uint64_t ret = 0;
645

    
646
    if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
647
        raise_exception(TT_PRIV_ACT);
648

    
649
    switch (asi) {
650
    case 0x10: // As if user primary
651
    case 0x18: // As if user primary LE
652
    case 0x80: // Primary
653
    case 0x82: // Primary no-fault
654
    case 0x88: // Primary LE
655
    case 0x8a: // Primary no-fault LE
656
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
657
            switch(size) {
658
            case 1:
659
                ret = ldub_kernel(T0);
660
                break;
661
            case 2:
662
                ret = lduw_kernel(T0 & ~1);
663
                break;
664
            case 4:
665
                ret = ldl_kernel(T0 & ~3);
666
                break;
667
            default:
668
            case 8:
669
                ret = ldq_kernel(T0 & ~7);
670
                break;
671
            }
672
        } else {
673
            switch(size) {
674
            case 1:
675
                ret = ldub_user(T0);
676
                break;
677
            case 2:
678
                ret = lduw_user(T0 & ~1);
679
                break;
680
            case 4:
681
                ret = ldl_user(T0 & ~3);
682
                break;
683
            default:
684
            case 8:
685
                ret = ldq_user(T0 & ~7);
686
                break;
687
            }
688
        }
689
        break;
690
    case 0x14: // Bypass
691
    case 0x15: // Bypass, non-cacheable
692
    case 0x1c: // Bypass LE
693
    case 0x1d: // Bypass, non-cacheable LE
694
        {
695
            switch(size) {
696
            case 1:
697
                ret = ldub_phys(T0);
698
                break;
699
            case 2:
700
                ret = lduw_phys(T0 & ~1);
701
                break;
702
            case 4:
703
                ret = ldl_phys(T0 & ~3);
704
                break;
705
            default:
706
            case 8:
707
                ret = ldq_phys(T0 & ~7);
708
                break;
709
            }
710
            break;
711
        }
712
    case 0x04: // Nucleus
713
    case 0x0c: // Nucleus Little Endian (LE)
714
    case 0x11: // As if user secondary
715
    case 0x19: // As if user secondary LE
716
    case 0x24: // Nucleus quad LDD 128 bit atomic
717
    case 0x2c: // Nucleus quad LDD 128 bit atomic
718
    case 0x4a: // UPA config
719
    case 0x81: // Secondary
720
    case 0x83: // Secondary no-fault
721
    case 0x89: // Secondary LE
722
    case 0x8b: // Secondary no-fault LE
723
        // XXX
724
        break;
725
    case 0x45: // LSU
726
        ret = env->lsu;
727
        break;
728
    case 0x50: // I-MMU regs
729
        {
730
            int reg = (T0 >> 3) & 0xf;
731

    
732
            ret = env->immuregs[reg];
733
            break;
734
        }
735
    case 0x51: // I-MMU 8k TSB pointer
736
    case 0x52: // I-MMU 64k TSB pointer
737
    case 0x55: // I-MMU data access
738
        // XXX
739
        break;
740
    case 0x56: // I-MMU tag read
741
        {
742
            unsigned int i;
743

    
744
            for (i = 0; i < 64; i++) {
745
                // Valid, ctx match, vaddr match
746
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0 &&
747
                    env->itlb_tag[i] == T0) {
748
                    ret = env->itlb_tag[i];
749
                    break;
750
                }
751
            }
752
            break;
753
        }
754
    case 0x58: // D-MMU regs
755
        {
756
            int reg = (T0 >> 3) & 0xf;
757

    
758
            ret = env->dmmuregs[reg];
759
            break;
760
        }
761
    case 0x5e: // D-MMU tag read
762
        {
763
            unsigned int i;
764

    
765
            for (i = 0; i < 64; i++) {
766
                // Valid, ctx match, vaddr match
767
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0 &&
768
                    env->dtlb_tag[i] == T0) {
769
                    ret = env->dtlb_tag[i];
770
                    break;
771
                }
772
            }
773
            break;
774
        }
775
    case 0x59: // D-MMU 8k TSB pointer
776
    case 0x5a: // D-MMU 64k TSB pointer
777
    case 0x5b: // D-MMU data pointer
778
    case 0x5d: // D-MMU data access
779
    case 0x48: // Interrupt dispatch, RO
780
    case 0x49: // Interrupt data receive
781
    case 0x7f: // Incoming interrupt vector, RO
782
        // XXX
783
        break;
784
    case 0x54: // I-MMU data in, WO
785
    case 0x57: // I-MMU demap, WO
786
    case 0x5c: // D-MMU data in, WO
787
    case 0x5f: // D-MMU demap, WO
788
    case 0x77: // Interrupt vector, WO
789
    default:
790
        do_unassigned_access(T0, 0, 0, 1);
791
        ret = 0;
792
        break;
793
    }
794

    
795
    /* Convert from little endian */
796
    switch (asi) {
797
    case 0x0c: // Nucleus Little Endian (LE)
798
    case 0x18: // As if user primary LE
799
    case 0x19: // As if user secondary LE
800
    case 0x1c: // Bypass LE
801
    case 0x1d: // Bypass, non-cacheable LE
802
    case 0x88: // Primary LE
803
    case 0x89: // Secondary LE
804
    case 0x8a: // Primary no-fault LE
805
    case 0x8b: // Secondary no-fault LE
806
        switch(size) {
807
        case 2:
808
            ret = bswap16(ret);
809
        case 4:
810
            ret = bswap32(ret);
811
        case 8:
812
            ret = bswap64(ret);
813
        default:
814
            break;
815
        }
816
    default:
817
        break;
818
    }
819

    
820
    /* Convert to signed number */
821
    if (sign) {
822
        switch(size) {
823
        case 1:
824
            ret = (int8_t) ret;
825
        case 2:
826
            ret = (int16_t) ret;
827
        case 4:
828
            ret = (int32_t) ret;
829
        default:
830
            break;
831
        }
832
    }
833
    T1 = ret;
834
}
835

    
836
void helper_st_asi(int asi, int size)
837
{
838
    if (asi < 0x80 && (env->pstate & PS_PRIV) == 0)
839
        raise_exception(TT_PRIV_ACT);
840

    
841
    /* Convert to little endian */
842
    switch (asi) {
843
    case 0x0c: // Nucleus Little Endian (LE)
844
    case 0x18: // As if user primary LE
845
    case 0x19: // As if user secondary LE
846
    case 0x1c: // Bypass LE
847
    case 0x1d: // Bypass, non-cacheable LE
848
    case 0x81: // Secondary
849
    case 0x88: // Primary LE
850
    case 0x89: // Secondary LE
851
        switch(size) {
852
        case 2:
853
            T0 = bswap16(T0);
854
        case 4:
855
            T0 = bswap32(T0);
856
        case 8:
857
            T0 = bswap64(T0);
858
        default:
859
            break;
860
        }
861
    default:
862
        break;
863
    }
864

    
865
    switch(asi) {
866
    case 0x10: // As if user primary
867
    case 0x18: // As if user primary LE
868
    case 0x80: // Primary
869
    case 0x88: // Primary LE
870
        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
871
            switch(size) {
872
            case 1:
873
                stb_kernel(T0, T1);
874
                break;
875
            case 2:
876
                stw_kernel(T0 & ~1, T1);
877
                break;
878
            case 4:
879
                stl_kernel(T0 & ~3, T1);
880
                break;
881
            case 8:
882
            default:
883
                stq_kernel(T0 & ~7, T1);
884
                break;
885
            }
886
        } else {
887
            switch(size) {
888
            case 1:
889
                stb_user(T0, T1);
890
                break;
891
            case 2:
892
                stw_user(T0 & ~1, T1);
893
                break;
894
            case 4:
895
                stl_user(T0 & ~3, T1);
896
                break;
897
            case 8:
898
            default:
899
                stq_user(T0 & ~7, T1);
900
                break;
901
            }
902
        }
903
        break;
904
    case 0x14: // Bypass
905
    case 0x15: // Bypass, non-cacheable
906
    case 0x1c: // Bypass LE
907
    case 0x1d: // Bypass, non-cacheable LE
908
        {
909
            switch(size) {
910
            case 1:
911
                stb_phys(T0, T1);
912
                break;
913
            case 2:
914
                stw_phys(T0 & ~1, T1);
915
                break;
916
            case 4:
917
                stl_phys(T0 & ~3, T1);
918
                break;
919
            case 8:
920
            default:
921
                stq_phys(T0 & ~7, T1);
922
                break;
923
            }
924
        }
925
        return;
926
    case 0x04: // Nucleus
927
    case 0x0c: // Nucleus Little Endian (LE)
928
    case 0x11: // As if user secondary
929
    case 0x19: // As if user secondary LE
930
    case 0x24: // Nucleus quad LDD 128 bit atomic
931
    case 0x2c: // Nucleus quad LDD 128 bit atomic
932
    case 0x4a: // UPA config
933
    case 0x89: // Secondary LE
934
        // XXX
935
        return;
936
    case 0x45: // LSU
937
        {
938
            uint64_t oldreg;
939

    
940
            oldreg = env->lsu;
941
            env->lsu = T1 & (DMMU_E | IMMU_E);
942
            // Mappings generated during D/I MMU disabled mode are
943
            // invalid in normal mode
944
            if (oldreg != env->lsu) {
945
#ifdef DEBUG_MMU
946
                printf("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n", oldreg, env->lsu);
947
                dump_mmu(env);
948
#endif
949
                tlb_flush(env, 1);
950
            }
951
            return;
952
        }
953
    case 0x50: // I-MMU regs
954
        {
955
            int reg = (T0 >> 3) & 0xf;
956
            uint64_t oldreg;
957

    
958
            oldreg = env->immuregs[reg];
959
            switch(reg) {
960
            case 0: // RO
961
            case 4:
962
                return;
963
            case 1: // Not in I-MMU
964
            case 2:
965
            case 7:
966
            case 8:
967
                return;
968
            case 3: // SFSR
969
                if ((T1 & 1) == 0)
970
                    T1 = 0; // Clear SFSR
971
                break;
972
            case 5: // TSB access
973
            case 6: // Tag access
974
            default:
975
                break;
976
            }
977
            env->immuregs[reg] = T1;
978
#ifdef DEBUG_MMU
979
            if (oldreg != env->immuregs[reg]) {
980
                printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
981
            }
982
            dump_mmu(env);
983
#endif
984
            return;
985
        }
986
    case 0x54: // I-MMU data in
987
        {
988
            unsigned int i;
989

    
990
            // Try finding an invalid entry
991
            for (i = 0; i < 64; i++) {
992
                if ((env->itlb_tte[i] & 0x8000000000000000ULL) == 0) {
993
                    env->itlb_tag[i] = env->immuregs[6];
994
                    env->itlb_tte[i] = T1;
995
                    return;
996
                }
997
            }
998
            // Try finding an unlocked entry
999
            for (i = 0; i < 64; i++) {
1000
                if ((env->itlb_tte[i] & 0x40) == 0) {
1001
                    env->itlb_tag[i] = env->immuregs[6];
1002
                    env->itlb_tte[i] = T1;
1003
                    return;
1004
                }
1005
            }
1006
            // error state?
1007
            return;
1008
        }
1009
    case 0x55: // I-MMU data access
1010
        {
1011
            unsigned int i = (T0 >> 3) & 0x3f;
1012

    
1013
            env->itlb_tag[i] = env->immuregs[6];
1014
            env->itlb_tte[i] = T1;
1015
            return;
1016
        }
1017
    case 0x57: // I-MMU demap
1018
        // XXX
1019
        return;
1020
    case 0x58: // D-MMU regs
1021
        {
1022
            int reg = (T0 >> 3) & 0xf;
1023
            uint64_t oldreg;
1024

    
1025
            oldreg = env->dmmuregs[reg];
1026
            switch(reg) {
1027
            case 0: // RO
1028
            case 4:
1029
                return;
1030
            case 3: // SFSR
1031
                if ((T1 & 1) == 0) {
1032
                    T1 = 0; // Clear SFSR, Fault address
1033
                    env->dmmuregs[4] = 0;
1034
                }
1035
                env->dmmuregs[reg] = T1;
1036
                break;
1037
            case 1: // Primary context
1038
            case 2: // Secondary context
1039
            case 5: // TSB access
1040
            case 6: // Tag access
1041
            case 7: // Virtual Watchpoint
1042
            case 8: // Physical Watchpoint
1043
            default:
1044
                break;
1045
            }
1046
            env->dmmuregs[reg] = T1;
1047
#ifdef DEBUG_MMU
1048
            if (oldreg != env->dmmuregs[reg]) {
1049
                printf("mmu change reg[%d]: 0x%08" PRIx64 " -> 0x%08" PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
1050
            }
1051
            dump_mmu(env);
1052
#endif
1053
            return;
1054
        }
1055
    case 0x5c: // D-MMU data in
1056
        {
1057
            unsigned int i;
1058

    
1059
            // Try finding an invalid entry
1060
            for (i = 0; i < 64; i++) {
1061
                if ((env->dtlb_tte[i] & 0x8000000000000000ULL) == 0) {
1062
                    env->dtlb_tag[i] = env->dmmuregs[6];
1063
                    env->dtlb_tte[i] = T1;
1064
                    return;
1065
                }
1066
            }
1067
            // Try finding an unlocked entry
1068
            for (i = 0; i < 64; i++) {
1069
                if ((env->dtlb_tte[i] & 0x40) == 0) {
1070
                    env->dtlb_tag[i] = env->dmmuregs[6];
1071
                    env->dtlb_tte[i] = T1;
1072
                    return;
1073
                }
1074
            }
1075
            // error state?
1076
            return;
1077
        }
1078
    case 0x5d: // D-MMU data access
1079
        {
1080
            unsigned int i = (T0 >> 3) & 0x3f;
1081

    
1082
            env->dtlb_tag[i] = env->dmmuregs[6];
1083
            env->dtlb_tte[i] = T1;
1084
            return;
1085
        }
1086
    case 0x5f: // D-MMU demap
1087
    case 0x49: // Interrupt data receive
1088
        // XXX
1089
        return;
1090
    case 0x51: // I-MMU 8k TSB pointer, RO
1091
    case 0x52: // I-MMU 64k TSB pointer, RO
1092
    case 0x56: // I-MMU tag read, RO
1093
    case 0x59: // D-MMU 8k TSB pointer, RO
1094
    case 0x5a: // D-MMU 64k TSB pointer, RO
1095
    case 0x5b: // D-MMU data pointer, RO
1096
    case 0x5e: // D-MMU tag read, RO
1097
    case 0x48: // Interrupt dispatch, RO
1098
    case 0x7f: // Incoming interrupt vector, RO
1099
    case 0x82: // Primary no-fault, RO
1100
    case 0x83: // Secondary no-fault, RO
1101
    case 0x8a: // Primary no-fault LE, RO
1102
    case 0x8b: // Secondary no-fault LE, RO
1103
    default:
1104
        do_unassigned_access(T0, 1, 0, 1);
1105
        return;
1106
    }
1107
}
1108
#endif /* CONFIG_USER_ONLY */
1109
#endif /* TARGET_SPARC64 */
1110

    
1111
#ifndef TARGET_SPARC64
1112
void helper_rett()
1113
{
1114
    unsigned int cwp;
1115

    
1116
    if (env->psret == 1)
1117
        raise_exception(TT_ILL_INSN);
1118

    
1119
    env->psret = 1;
1120
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
1121
    if (env->wim & (1 << cwp)) {
1122
        raise_exception(TT_WIN_UNF);
1123
    }
1124
    set_cwp(cwp);
1125
    env->psrs = env->psrps;
1126
}
1127
#endif
1128

    
1129
void helper_ldfsr(void)
1130
{
1131
    int rnd_mode;
1132
    switch (env->fsr & FSR_RD_MASK) {
1133
    case FSR_RD_NEAREST:
1134
        rnd_mode = float_round_nearest_even;
1135
        break;
1136
    default:
1137
    case FSR_RD_ZERO:
1138
        rnd_mode = float_round_to_zero;
1139
        break;
1140
    case FSR_RD_POS:
1141
        rnd_mode = float_round_up;
1142
        break;
1143
    case FSR_RD_NEG:
1144
        rnd_mode = float_round_down;
1145
        break;
1146
    }
1147
    set_float_rounding_mode(rnd_mode, &env->fp_status);
1148
}
1149

    
1150
void helper_debug()
1151
{
1152
    env->exception_index = EXCP_DEBUG;
1153
    cpu_loop_exit();
1154
}
1155

    
1156
#ifndef TARGET_SPARC64
1157
void do_wrpsr()
1158
{
1159
    if ((T0 & PSR_CWP) >= NWINDOWS)
1160
        raise_exception(TT_ILL_INSN);
1161
    else
1162
        PUT_PSR(env, T0);
1163
}
1164

    
1165
void do_rdpsr()
1166
{
1167
    T0 = GET_PSR(env);
1168
}
1169

    
1170
#else
1171

    
1172
void do_popc()
1173
{
1174
    T0 = (T1 & 0x5555555555555555ULL) + ((T1 >> 1) & 0x5555555555555555ULL);
1175
    T0 = (T0 & 0x3333333333333333ULL) + ((T0 >> 2) & 0x3333333333333333ULL);
1176
    T0 = (T0 & 0x0f0f0f0f0f0f0f0fULL) + ((T0 >> 4) & 0x0f0f0f0f0f0f0f0fULL);
1177
    T0 = (T0 & 0x00ff00ff00ff00ffULL) + ((T0 >> 8) & 0x00ff00ff00ff00ffULL);
1178
    T0 = (T0 & 0x0000ffff0000ffffULL) + ((T0 >> 16) & 0x0000ffff0000ffffULL);
1179
    T0 = (T0 & 0x00000000ffffffffULL) + ((T0 >> 32) & 0x00000000ffffffffULL);
1180
}
1181

    
1182
static inline uint64_t *get_gregset(uint64_t pstate)
1183
{
1184
    switch (pstate) {
1185
    default:
1186
    case 0:
1187
        return env->bgregs;
1188
    case PS_AG:
1189
        return env->agregs;
1190
    case PS_MG:
1191
        return env->mgregs;
1192
    case PS_IG:
1193
        return env->igregs;
1194
    }
1195
}
1196

    
1197
static inline void change_pstate(uint64_t new_pstate)
1198
{
1199
    uint64_t pstate_regs, new_pstate_regs;
1200
    uint64_t *src, *dst;
1201

    
1202
    pstate_regs = env->pstate & 0xc01;
1203
    new_pstate_regs = new_pstate & 0xc01;
1204
    if (new_pstate_regs != pstate_regs) {
1205
        // Switch global register bank
1206
        src = get_gregset(new_pstate_regs);
1207
        dst = get_gregset(pstate_regs);
1208
        memcpy32(dst, env->gregs);
1209
        memcpy32(env->gregs, src);
1210
    }
1211
    env->pstate = new_pstate;
1212
}
1213

    
1214
void do_wrpstate(void)
1215
{
1216
    change_pstate(T0 & 0xf3f);
1217
}
1218

    
1219
void do_done(void)
1220
{
1221
    env->tl--;
1222
    env->pc = env->tnpc[env->tl];
1223
    env->npc = env->tnpc[env->tl] + 4;
1224
    PUT_CCR(env, env->tstate[env->tl] >> 32);
1225
    env->asi = (env->tstate[env->tl] >> 24) & 0xff;
1226
    change_pstate((env->tstate[env->tl] >> 8) & 0xf3f);
1227
    PUT_CWP64(env, env->tstate[env->tl] & 0xff);
1228
}
1229

    
1230
void do_retry(void)
1231
{
1232
    env->tl--;
1233
    env->pc = env->tpc[env->tl];
1234
    env->npc = env->tnpc[env->tl];
1235
    PUT_CCR(env, env->tstate[env->tl] >> 32);
1236
    env->asi = (env->tstate[env->tl] >> 24) & 0xff;
1237
    change_pstate((env->tstate[env->tl] >> 8) & 0xf3f);
1238
    PUT_CWP64(env, env->tstate[env->tl] & 0xff);
1239
}
1240
#endif
1241

    
1242
void set_cwp(int new_cwp)
1243
{
1244
    /* put the modified wrap registers at their proper location */
1245
    if (env->cwp == (NWINDOWS - 1))
1246
        memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
1247
    env->cwp = new_cwp;
1248
    /* put the wrap registers at their temporary location */
1249
    if (new_cwp == (NWINDOWS - 1))
1250
        memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
1251
    env->regwptr = env->regbase + (new_cwp * 16);
1252
    REGWPTR = env->regwptr;
1253
}
1254

    
1255
void cpu_set_cwp(CPUState *env1, int new_cwp)
1256
{
1257
    CPUState *saved_env;
1258
#ifdef reg_REGWPTR
1259
    target_ulong *saved_regwptr;
1260
#endif
1261

    
1262
    saved_env = env;
1263
#ifdef reg_REGWPTR
1264
    saved_regwptr = REGWPTR;
1265
#endif
1266
    env = env1;
1267
    set_cwp(new_cwp);
1268
    env = saved_env;
1269
#ifdef reg_REGWPTR
1270
    REGWPTR = saved_regwptr;
1271
#endif
1272
}
1273

    
1274
#ifdef TARGET_SPARC64
1275
void do_interrupt(int intno)
1276
{
1277
#ifdef DEBUG_PCALL
1278
    if (loglevel & CPU_LOG_INT) {
1279
        static int count;
1280
        fprintf(logfile, "%6d: v=%04x pc=%016" PRIx64 " npc=%016" PRIx64 " SP=%016" PRIx64 "\n",
1281
                count, intno,
1282
                env->pc,
1283
                env->npc, env->regwptr[6]);
1284
        cpu_dump_state(env, logfile, fprintf, 0);
1285
#if 0
1286
        {
1287
            int i;
1288
            uint8_t *ptr;
1289

1290
            fprintf(logfile, "       code=");
1291
            ptr = (uint8_t *)env->pc;
1292
            for(i = 0; i < 16; i++) {
1293
                fprintf(logfile, " %02x", ldub(ptr + i));
1294
            }
1295
            fprintf(logfile, "\n");
1296
        }
1297
#endif
1298
        count++;
1299
    }
1300
#endif
1301
#if !defined(CONFIG_USER_ONLY)
1302
    if (env->tl == MAXTL) {
1303
        cpu_abort(env, "Trap 0x%04x while trap level is MAXTL, Error state", env->exception_index);
1304
        return;
1305
    }
1306
#endif
1307
    env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
1308
        ((env->pstate & 0xf3f) << 8) | GET_CWP64(env);
1309
    env->tpc[env->tl] = env->pc;
1310
    env->tnpc[env->tl] = env->npc;
1311
    env->tt[env->tl] = intno;
1312
    change_pstate(PS_PEF | PS_PRIV | PS_AG);
1313

    
1314
    if (intno == TT_CLRWIN)
1315
        set_cwp((env->cwp - 1) & (NWINDOWS - 1));
1316
    else if ((intno & 0x1c0) == TT_SPILL)
1317
        set_cwp((env->cwp - env->cansave - 2) & (NWINDOWS - 1));
1318
    else if ((intno & 0x1c0) == TT_FILL)
1319
        set_cwp((env->cwp + 1) & (NWINDOWS - 1));
1320
    env->tbr &= ~0x7fffULL;
1321
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
1322
    if (env->tl < MAXTL - 1) {
1323
        env->tl++;
1324
    } else {
1325
        env->pstate |= PS_RED;
1326
        if (env->tl != MAXTL)
1327
            env->tl++;
1328
    }
1329
    env->pc = env->tbr;
1330
    env->npc = env->pc + 4;
1331
    env->exception_index = 0;
1332
}
1333
#else
1334
void do_interrupt(int intno)
1335
{
1336
    int cwp;
1337

    
1338
#ifdef DEBUG_PCALL
1339
    if (loglevel & CPU_LOG_INT) {
1340
        static int count;
1341
        fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
1342
                count, intno,
1343
                env->pc,
1344
                env->npc, env->regwptr[6]);
1345
        cpu_dump_state(env, logfile, fprintf, 0);
1346
#if 0
1347
        {
1348
            int i;
1349
            uint8_t *ptr;
1350

1351
            fprintf(logfile, "       code=");
1352
            ptr = (uint8_t *)env->pc;
1353
            for(i = 0; i < 16; i++) {
1354
                fprintf(logfile, " %02x", ldub(ptr + i));
1355
            }
1356
            fprintf(logfile, "\n");
1357
        }
1358
#endif
1359
        count++;
1360
    }
1361
#endif
1362
#if !defined(CONFIG_USER_ONLY)
1363
    if (env->psret == 0) {
1364
        cpu_abort(env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
1365
        return;
1366
    }
1367
#endif
1368
    env->psret = 0;
1369
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
1370
    set_cwp(cwp);
1371
    env->regwptr[9] = env->pc;
1372
    env->regwptr[10] = env->npc;
1373
    env->psrps = env->psrs;
1374
    env->psrs = 1;
1375
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
1376
    env->pc = env->tbr;
1377
    env->npc = env->pc + 4;
1378
    env->exception_index = 0;
1379
}
1380
#endif
1381

    
1382
#if !defined(CONFIG_USER_ONLY)
1383

    
1384
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
1385
                                void *retaddr);
1386

    
1387
#define MMUSUFFIX _mmu
1388
#define ALIGNED_ONLY
1389
#define GETPC() (__builtin_return_address(0))
1390

    
1391
#define SHIFT 0
1392
#include "softmmu_template.h"
1393

    
1394
#define SHIFT 1
1395
#include "softmmu_template.h"
1396

    
1397
#define SHIFT 2
1398
#include "softmmu_template.h"
1399

    
1400
#define SHIFT 3
1401
#include "softmmu_template.h"
1402

    
1403
static void do_unaligned_access(target_ulong addr, int is_write, int is_user,
1404
                                void *retaddr)
1405
{
1406
#ifdef DEBUG_UNALIGNED
1407
    printf("Unaligned access to 0x%x from 0x%x\n", addr, env->pc);
1408
#endif
1409
    raise_exception(TT_UNALIGNED);
1410
}
1411

    
1412
/* try to fill the TLB and return an exception if error. If retaddr is
1413
   NULL, it means that the function was called in C code (i.e. not
1414
   from generated code or from helper.c) */
1415
/* XXX: fix it to restore all registers */
1416
void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
1417
{
1418
    TranslationBlock *tb;
1419
    int ret;
1420
    unsigned long pc;
1421
    CPUState *saved_env;
1422

    
1423
    /* XXX: hack to restore env in all cases, even if not called from
1424
       generated code */
1425
    saved_env = env;
1426
    env = cpu_single_env;
1427

    
1428
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
1429
    if (ret) {
1430
        if (retaddr) {
1431
            /* now we have a real cpu fault */
1432
            pc = (unsigned long)retaddr;
1433
            tb = tb_find_pc(pc);
1434
            if (tb) {
1435
                /* the PC is inside the translated code. It means that we have
1436
                   a virtual CPU fault */
1437
                cpu_restore_state(tb, env, pc, (void *)T2);
1438
            }
1439
        }
1440
        cpu_loop_exit();
1441
    }
1442
    env = saved_env;
1443
}
1444

    
1445
#endif
1446

    
1447
#ifndef TARGET_SPARC64
1448
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
1449
                          int is_asi)
1450
{
1451
    CPUState *saved_env;
1452

    
1453
    /* XXX: hack to restore env in all cases, even if not called from
1454
       generated code */
1455
    saved_env = env;
1456
    env = cpu_single_env;
1457
    if (env->mmuregs[3]) /* Fault status register */
1458
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
1459
    if (is_asi)
1460
        env->mmuregs[3] |= 1 << 16;
1461
    if (env->psrs)
1462
        env->mmuregs[3] |= 1 << 5;
1463
    if (is_exec)
1464
        env->mmuregs[3] |= 1 << 6;
1465
    if (is_write)
1466
        env->mmuregs[3] |= 1 << 7;
1467
    env->mmuregs[3] |= (5 << 2) | 2;
1468
    env->mmuregs[4] = addr; /* Fault address register */
1469
    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
1470
#ifdef DEBUG_UNASSIGNED
1471
        printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
1472
               "\n", addr, env->pc);
1473
#endif
1474
        if (is_exec)
1475
            raise_exception(TT_CODE_ACCESS);
1476
        else
1477
            raise_exception(TT_DATA_ACCESS);
1478
    }
1479
    env = saved_env;
1480
}
1481
#else
1482
void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
1483
                          int is_asi)
1484
{
1485
#ifdef DEBUG_UNASSIGNED
1486
    CPUState *saved_env;
1487

    
1488
    /* XXX: hack to restore env in all cases, even if not called from
1489
       generated code */
1490
    saved_env = env;
1491
    env = cpu_single_env;
1492
    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx "\n",
1493
           addr, env->pc);
1494
    env = saved_env;
1495
#endif
1496
    if (is_exec)
1497
        raise_exception(TT_CODE_ACCESS);
1498
    else
1499
        raise_exception(TT_DATA_ACCESS);
1500
}
1501
#endif
1502

    
1503
#ifdef TARGET_SPARC64
1504
void do_tick_set_count(void *opaque, uint64_t count)
1505
{
1506
#if !defined(CONFIG_USER_ONLY)
1507
    ptimer_set_count(opaque, -count);
1508
#endif
1509
}
1510

    
1511
uint64_t do_tick_get_count(void *opaque)
1512
{
1513
#if !defined(CONFIG_USER_ONLY)
1514
    return -ptimer_get_count(opaque);
1515
#else
1516
    return 0;
1517
#endif
1518
}
1519

    
1520
void do_tick_set_limit(void *opaque, uint64_t limit)
1521
{
1522
#if !defined(CONFIG_USER_ONLY)
1523
    ptimer_set_limit(opaque, -limit, 0);
1524
#endif
1525
}
1526
#endif