Revision 1a14026e

b/hw/sun4m.c
404 404
            qemu_register_reset(secondary_cpu_reset, env);
405 405
            env->halted = 1;
406 406
        }
407
        register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
407
        register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
408 408
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
409 409
        env->prom_addr = hwdef->slavio_base;
410 410
    }
......
579 579
    cpu_sparc_set_id(env, 0);
580 580

  
581 581
    qemu_register_reset(main_cpu_reset, env);
582
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
582
    register_savevm("cpu", 0, 4, cpu_save, cpu_load, env);
583 583
    cpu_irqs = qemu_allocate_irqs(cpu_set_irq, env, MAX_PILS);
584 584
    env->prom_addr = hwdef->slavio_base;
585 585

  
......
1391 1391
            qemu_register_reset(secondary_cpu_reset, env);
1392 1392
            env->halted = 1;
1393 1393
        }
1394
        register_savevm("cpu", i, 3, cpu_save, cpu_load, env);
1394
        register_savevm("cpu", i, 4, cpu_save, cpu_load, env);
1395 1395
        cpu_irqs[i] = qemu_allocate_irqs(cpu_set_irq, envs[i], MAX_PILS);
1396 1396
        env->prom_addr = hwdef->slavio_base;
1397 1397
    }
b/hw/sun4u.c
260 260
    bh = qemu_bh_new(hstick_irq, env);
261 261
    env->hstick = ptimer_init(bh);
262 262
    ptimer_set_period(env->hstick, 1ULL);
263
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
263
    register_savevm("cpu", 0, 4, cpu_save, cpu_load, env);
264 264
    qemu_register_reset(main_cpu_reset, env);
265 265
    main_cpu_reset(env);
266 266

  
b/linux-user/main.c
626 626
   can be found at http://www.sics.se/~psm/sparcstack.html */
627 627
static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
628 628
{
629
    index = (index + cwp * 16) & (16 * NWINDOWS - 1);
629
    index = (index + cwp * 16) % (16 * env->nwindows);
630 630
    /* wrap handling : if cwp is on the last window, then we use the
631 631
       registers 'after' the end */
632
    if (index < 8 && env->cwp == (NWINDOWS - 1))
633
        index += (16 * NWINDOWS);
632
    if (index < 8 && env->cwp == env->nwindows - 1)
633
        index += 16 * env->nwindows;
634 634
    return index;
635 635
}
636 636

  
......
656 656
{
657 657
#ifndef TARGET_SPARC64
658 658
    unsigned int new_wim;
659
    new_wim = ((env->wim >> 1) | (env->wim << (NWINDOWS - 1))) &
660
        ((1LL << NWINDOWS) - 1);
661
    save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
659
    new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
660
        ((1LL << env->nwindows) - 1);
661
    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
662 662
    env->wim = new_wim;
663 663
#else
664
    save_window_offset(env, (env->cwp - 2) & (NWINDOWS - 1));
664
    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
665 665
    env->cansave++;
666 666
    env->canrestore--;
667 667
#endif
......
672 672
    unsigned int new_wim, i, cwp1;
673 673
    abi_ulong sp_ptr;
674 674

  
675
    new_wim = ((env->wim << 1) | (env->wim >> (NWINDOWS - 1))) &
676
        ((1LL << NWINDOWS) - 1);
675
    new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
676
        ((1LL << env->nwindows) - 1);
677 677

  
678 678
    /* restore the invalid window */
679
    cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
679
    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
680 680
    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
681 681
#if defined(DEBUG_WIN)
682 682
    printf("win_underflow: sp_ptr=0x%x load_cwp=%d\n",
......
690 690
    env->wim = new_wim;
691 691
#ifdef TARGET_SPARC64
692 692
    env->canrestore++;
693
    if (env->cleanwin < NWINDOWS - 1)
694
	env->cleanwin++;
693
    if (env->cleanwin < env->nwindows - 1)
694
        env->cleanwin++;
695 695
    env->cansave--;
696 696
#endif
697 697
}
......
703 703
    offset = 1;
704 704
    for(;;) {
705 705
        /* if restore would invoke restore_window(), then we can stop */
706
        cwp1 = (env->cwp + offset) & (NWINDOWS - 1);
706
        cwp1 = cpu_cwp_inc(env, env->cwp + offset);
707 707
        if (env->wim & (1 << cwp1))
708 708
            break;
709 709
        save_window_offset(env, cwp1);
710 710
        offset++;
711 711
    }
712 712
    /* set wim so that restore will reload the registers */
713
    cwp1 = (env->cwp + 1) & (NWINDOWS - 1);
713
    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
714 714
    env->wim = 1 << cwp1;
715 715
#if defined(DEBUG_WIN)
716 716
    printf("flush_windows: nb=%d\n", offset - 1);
b/target-sparc/TODO
6 6
 slot next page)
7 7
 - Atomical instructions
8 8
 - CPU features should match real CPUs (also ASI selection)
9
 - Allow choosing of NWINDOWS (CPU model specific and as a CPU feature)
10 9
- Optimizations/improvements:
11 10
 - Condition code/branch handling like x86, also for FPU?
12 11
 - Remove remaining explicit alignment checks
b/target-sparc/cpu.h
170 170
#define PG_MODIFIED_MASK (1 << PG_MODIFIED_BIT)
171 171
#define PG_CACHE_MASK    (1 << PG_CACHE_BIT)
172 172

  
173
/* 2 <= NWINDOWS <= 32. In QEMU it must also be a power of two. */
174
#define NWINDOWS  8
173
/* 3 <= NWINDOWS <= 32. */
174
#define MIN_NWINDOWS 3
175
#define MAX_NWINDOWS 32
175 176

  
176 177
#if !defined(TARGET_SPARC64)
177 178
#define NB_MMU_MODES 2
......
222 223
    uint32_t mmu_cxr_mask;
223 224
    uint32_t mmu_sfsr_mask;
224 225
    uint32_t mmu_trcr_mask;
226
    uint32_t nwindows;
225 227
    /* NOTE: we allow 8 more registers to handle wrapping */
226
    target_ulong regbase[NWINDOWS * 16 + 8];
228
    target_ulong regbase[MAX_NWINDOWS * 16 + 8];
227 229

  
228 230
    CPU_COMMON
229 231

  
......
330 332

  
331 333
#ifndef NO_CPU_IO_DEFS
332 334
void cpu_set_cwp(CPUSPARCState *env1, int new_cwp);
335

  
336
static inline int cpu_cwp_inc(CPUSPARCState *env1, int cwp)
337
{
338
    if (unlikely(cwp >= env1->nwindows))
339
        cwp -= env1->nwindows;
340
    return cwp;
341
}
342

  
343
static inline int cpu_cwp_dec(CPUSPARCState *env1, int cwp)
344
{
345
    if (unlikely(cwp < 0))
346
        cwp += env1->nwindows;
347
    return cwp;
348
}
333 349
#endif
334 350

  
335 351
#define PUT_PSR(env, val) do { int _tmp = val;                          \
......
348 364
        env->xcc = (_tmp >> 4) << 20;                                   \
349 365
        env->psr = (_tmp & 0xf) << 20;                                  \
350 366
    } while (0)
351
#define GET_CWP64(env) (NWINDOWS - 1 - (env)->cwp)
352
#define PUT_CWP64(env, val) \
353
    cpu_set_cwp(env, NWINDOWS - 1 - ((val) & (NWINDOWS - 1)))
367
#define GET_CWP64(env) (env->nwindows - 1 - (env)->cwp)
368

  
369
static inline void PUT_CWP64(CPUSPARCState *env1, int cwp)
370
{
371
    if (unlikely(cwp >= env1->nwindows || cwp < 0))
372
        cwp = 0;
373
    cpu_set_cwp(env1, env1->nwindows - 1 - cwp);
374
}
354 375

  
355 376
#endif
356 377

  
b/target-sparc/helper.c
47 47
    uint32_t mmu_sfsr_mask;
48 48
    uint32_t mmu_trcr_mask;
49 49
    uint32_t features;
50
    uint32_t nwindows;
50 51
};
51 52

  
52 53
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
......
750 751
    change_pstate(PS_PEF | PS_PRIV | PS_AG);
751 752

  
752 753
    if (intno == TT_CLRWIN)
753
        cpu_set_cwp(env, (env->cwp - 1) & (NWINDOWS - 1));
754
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - 1));
754 755
    else if ((intno & 0x1c0) == TT_SPILL)
755
        cpu_set_cwp(env, (env->cwp - env->cansave - 2) & (NWINDOWS - 1));
756
        cpu_set_cwp(env, cpu_cwp_dec(env, env->cwp - env->cansave - 2));
756 757
    else if ((intno & 0x1c0) == TT_FILL)
757
        cpu_set_cwp(env, (env->cwp + 1) & (NWINDOWS - 1));
758
        cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
758 759
    env->tbr &= ~0x7fffULL;
759 760
    env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
760 761
    if (env->tl < MAXTL - 1) {
......
853 854
    }
854 855
#endif
855 856
    env->psret = 0;
856
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
857
    cwp = cpu_cwp_dec(env, env->cwp - 1);
857 858
    cpu_set_cwp(env, cwp);
858 859
    env->regwptr[9] = env->pc;
859 860
    env->regwptr[10] = env->npc;
......
887 888
#if defined(CONFIG_USER_ONLY)
888 889
    env->user_mode_only = 1;
889 890
#ifdef TARGET_SPARC64
890
    env->cleanwin = NWINDOWS - 2;
891
    env->cansave = NWINDOWS - 2;
891
    env->cleanwin = env->nwindows - 2;
892
    env->cansave = env->nwindows - 2;
892 893
    env->pstate = PS_RMO | PS_PEF | PS_IE;
893 894
    env->asi = 0x82; // Primary no-fault
894 895
#endif
......
921 922
    env->cpu_model_str = cpu_model;
922 923
    env->version = def->iu_version;
923 924
    env->fsr = def->fpu_version;
925
    env->nwindows = def->nwindows;
924 926
#if !defined(TARGET_SPARC64)
925 927
    env->mmu_bm = def->mmu_bm;
926 928
    env->mmu_ctpr_mask = def->mmu_ctpr_mask;
......
929 931
    env->mmu_trcr_mask = def->mmu_trcr_mask;
930 932
    env->mmuregs[0] |= def->mmu_version;
931 933
    cpu_sparc_set_id(env, 0);
934
#else
935
    env->version |= def->nwindows - 1;
932 936
#endif
933 937
    return 0;
934 938
}
......
970 974
    {
971 975
        .name = "Fujitsu Sparc64",
972 976
        .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)
973
                       | (MAXTL << 8) | (NWINDOWS - 1)),
977
                       | (MAXTL << 8)),
974 978
        .fpu_version = 0x00000000,
975 979
        .mmu_version = 0,
980
        .nwindows = 4,
976 981
        .features = CPU_DEFAULT_FEATURES,
977 982
    },
978 983
    {
979 984
        .name = "Fujitsu Sparc64 III",
980 985
        .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)
981
                       | (MAXTL << 8) | (NWINDOWS - 1)),
986
                       | (MAXTL << 8)),
982 987
        .fpu_version = 0x00000000,
983 988
        .mmu_version = 0,
989
        .nwindows = 5,
984 990
        .features = CPU_DEFAULT_FEATURES,
985 991
    },
986 992
    {
987 993
        .name = "Fujitsu Sparc64 IV",
988 994
        .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)
989
                       | (MAXTL << 8) | (NWINDOWS - 1)),
995
                       | (MAXTL << 8)),
990 996
        .fpu_version = 0x00000000,
991 997
        .mmu_version = 0,
998
        .nwindows = 8,
992 999
        .features = CPU_DEFAULT_FEATURES,
993 1000
    },
994 1001
    {
995 1002
        .name = "Fujitsu Sparc64 V",
996 1003
        .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)
997
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1004
                       | (MAXTL << 8)),
998 1005
        .fpu_version = 0x00000000,
999 1006
        .mmu_version = 0,
1007
        .nwindows = 8,
1000 1008
        .features = CPU_DEFAULT_FEATURES,
1001 1009
    },
1002 1010
    {
1003 1011
        .name = "TI UltraSparc I",
1004 1012
        .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
1005
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1013
                       | (MAXTL << 8)),
1006 1014
        .fpu_version = 0x00000000,
1007 1015
        .mmu_version = 0,
1016
        .nwindows = 8,
1008 1017
        .features = CPU_DEFAULT_FEATURES,
1009 1018
    },
1010 1019
    {
1011 1020
        .name = "TI UltraSparc II",
1012 1021
        .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)
1013
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1022
                       | (MAXTL << 8)),
1014 1023
        .fpu_version = 0x00000000,
1015 1024
        .mmu_version = 0,
1025
        .nwindows = 8,
1016 1026
        .features = CPU_DEFAULT_FEATURES,
1017 1027
    },
1018 1028
    {
1019 1029
        .name = "TI UltraSparc IIi",
1020 1030
        .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)
1021
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1031
                       | (MAXTL << 8)),
1022 1032
        .fpu_version = 0x00000000,
1023 1033
        .mmu_version = 0,
1034
        .nwindows = 8,
1024 1035
        .features = CPU_DEFAULT_FEATURES,
1025 1036
    },
1026 1037
    {
1027 1038
        .name = "TI UltraSparc IIe",
1028 1039
        .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)
1029
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1040
                       | (MAXTL << 8)),
1030 1041
        .fpu_version = 0x00000000,
1031 1042
        .mmu_version = 0,
1043
        .nwindows = 8,
1032 1044
        .features = CPU_DEFAULT_FEATURES,
1033 1045
    },
1034 1046
    {
1035 1047
        .name = "Sun UltraSparc III",
1036 1048
        .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)
1037
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1049
                       | (MAXTL << 8)),
1038 1050
        .fpu_version = 0x00000000,
1039 1051
        .mmu_version = 0,
1052
        .nwindows = 8,
1040 1053
        .features = CPU_DEFAULT_FEATURES,
1041 1054
    },
1042 1055
    {
1043 1056
        .name = "Sun UltraSparc III Cu",
1044 1057
        .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)
1045
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1058
                       | (MAXTL << 8)),
1046 1059
        .fpu_version = 0x00000000,
1047 1060
        .mmu_version = 0,
1061
        .nwindows = 8,
1048 1062
        .features = CPU_DEFAULT_FEATURES,
1049 1063
    },
1050 1064
    {
1051 1065
        .name = "Sun UltraSparc IIIi",
1052 1066
        .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)
1053
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1067
                       | (MAXTL << 8)),
1054 1068
        .fpu_version = 0x00000000,
1055 1069
        .mmu_version = 0,
1070
        .nwindows = 8,
1056 1071
        .features = CPU_DEFAULT_FEATURES,
1057 1072
    },
1058 1073
    {
1059 1074
        .name = "Sun UltraSparc IV",
1060 1075
        .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)
1061
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1076
                       | (MAXTL << 8)),
1062 1077
        .fpu_version = 0x00000000,
1063 1078
        .mmu_version = 0,
1079
        .nwindows = 8,
1064 1080
        .features = CPU_DEFAULT_FEATURES,
1065 1081
    },
1066 1082
    {
1067 1083
        .name = "Sun UltraSparc IV+",
1068 1084
        .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)
1069
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1085
                       | (MAXTL << 8)),
1070 1086
        .fpu_version = 0x00000000,
1071 1087
        .mmu_version = 0,
1088
        .nwindows = 8,
1072 1089
        .features = CPU_DEFAULT_FEATURES,
1073 1090
    },
1074 1091
    {
1075 1092
        .name = "Sun UltraSparc IIIi+",
1076 1093
        .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)
1077
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1094
                       | (MAXTL << 8)),
1078 1095
        .fpu_version = 0x00000000,
1079 1096
        .mmu_version = 0,
1097
        .nwindows = 8,
1080 1098
        .features = CPU_DEFAULT_FEATURES,
1081 1099
    },
1082 1100
    {
1083 1101
        .name = "NEC UltraSparc I",
1084 1102
        .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)
1085
                       | (MAXTL << 8) | (NWINDOWS - 1)),
1103
                       | (MAXTL << 8)),
1086 1104
        .fpu_version = 0x00000000,
1087 1105
        .mmu_version = 0,
1106
        .nwindows = 8,
1088 1107
        .features = CPU_DEFAULT_FEATURES,
1089 1108
    },
1090 1109
#else
......
1098 1117
        .mmu_cxr_mask = 0x0000003f,
1099 1118
        .mmu_sfsr_mask = 0xffffffff,
1100 1119
        .mmu_trcr_mask = 0xffffffff,
1120
        .nwindows = 7,
1101 1121
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_FSMULD,
1102 1122
    },
1103 1123
    {
......
1110 1130
        .mmu_cxr_mask = 0x000000ff,
1111 1131
        .mmu_sfsr_mask = 0x00016fff,
1112 1132
        .mmu_trcr_mask = 0x00ffffff,
1133
        .nwindows = 8,
1113 1134
        .features = CPU_DEFAULT_FEATURES,
1114 1135
    },
1115 1136
    {
......
1122 1143
        .mmu_cxr_mask = 0x000000ff,
1123 1144
        .mmu_sfsr_mask = 0x00016fff,
1124 1145
        .mmu_trcr_mask = 0xffffffff,
1146
        .nwindows = 8,
1125 1147
        .features = CPU_DEFAULT_FEATURES,
1126 1148
    },
1127 1149
    {
......
1134 1156
        .mmu_cxr_mask = 0x0000003f,
1135 1157
        .mmu_sfsr_mask = 0xffffffff,
1136 1158
        .mmu_trcr_mask = 0xffffffff,
1159
        .nwindows = 8,
1137 1160
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1138 1161
        CPU_FEATURE_FSMULD,
1139 1162
    },
......
1147 1170
        .mmu_cxr_mask = 0x0000003f,
1148 1171
        .mmu_sfsr_mask = 0xffffffff,
1149 1172
        .mmu_trcr_mask = 0xffffffff,
1173
        .nwindows = 8,
1150 1174
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1151 1175
        CPU_FEATURE_FSMULD,
1152 1176
    },
......
1160 1184
        .mmu_cxr_mask = 0x0000003f,
1161 1185
        .mmu_sfsr_mask = 0xffffffff,
1162 1186
        .mmu_trcr_mask = 0xffffffff,
1187
        .nwindows = 8,
1163 1188
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1164 1189
        CPU_FEATURE_FSMULD,
1165 1190
    },
......
1173 1198
        .mmu_cxr_mask = 0x0000ffff,
1174 1199
        .mmu_sfsr_mask = 0xffffffff,
1175 1200
        .mmu_trcr_mask = 0xffffffff,
1201
        .nwindows = 8,
1176 1202
        .features = CPU_DEFAULT_FEATURES,
1177 1203
    },
1178 1204
    {
......
1185 1211
        .mmu_cxr_mask = 0x0000003f,
1186 1212
        .mmu_sfsr_mask = 0x00016fff,
1187 1213
        .mmu_trcr_mask = 0x0000003f,
1214
        .nwindows = 7,
1188 1215
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
1189 1216
        CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
1190 1217
        CPU_FEATURE_FMUL,
......
1199 1226
        .mmu_cxr_mask = 0x000000ff,
1200 1227
        .mmu_sfsr_mask = 0x00016fff,
1201 1228
        .mmu_trcr_mask = 0x00ffffff,
1229
        .nwindows = 8,
1202 1230
        .features = CPU_DEFAULT_FEATURES,
1203 1231
    },
1204 1232
    {
......
1211 1239
        .mmu_cxr_mask = 0x000000ff,
1212 1240
        .mmu_sfsr_mask = 0x00016bff,
1213 1241
        .mmu_trcr_mask = 0x00ffffff,
1242
        .nwindows = 8,
1214 1243
        .features = CPU_DEFAULT_FEATURES,
1215 1244
    },
1216 1245
    {
......
1223 1252
        .mmu_cxr_mask = 0x0000ffff,
1224 1253
        .mmu_sfsr_mask = 0xffffffff,
1225 1254
        .mmu_trcr_mask = 0xffffffff,
1255
        .nwindows = 8,
1226 1256
        .features = CPU_DEFAULT_FEATURES,
1227 1257
    },
1228 1258
    {
......
1235 1265
        .mmu_cxr_mask = 0x0000ffff,
1236 1266
        .mmu_sfsr_mask = 0xffffffff,
1237 1267
        .mmu_trcr_mask = 0xffffffff,
1268
        .nwindows = 8,
1238 1269
        .features = CPU_DEFAULT_FEATURES,
1239 1270
    },
1240 1271
    {
......
1247 1278
        .mmu_cxr_mask = 0x0000ffff,
1248 1279
        .mmu_sfsr_mask = 0xffffffff,
1249 1280
        .mmu_trcr_mask = 0xffffffff,
1281
        .nwindows = 8,
1250 1282
        .features = CPU_DEFAULT_FEATURES,
1251 1283
    },
1252 1284
    {
......
1259 1291
        .mmu_cxr_mask = 0x0000ffff,
1260 1292
        .mmu_sfsr_mask = 0xffffffff,
1261 1293
        .mmu_trcr_mask = 0xffffffff,
1294
        .nwindows = 8,
1262 1295
        .features = CPU_DEFAULT_FEATURES,
1263 1296
    },
1264 1297
    {
......
1271 1304
        .mmu_cxr_mask = 0x0000ffff,
1272 1305
        .mmu_sfsr_mask = 0xffffffff,
1273 1306
        .mmu_trcr_mask = 0xffffffff,
1307
        .nwindows = 8,
1274 1308
        .features = CPU_DEFAULT_FEATURES,
1275 1309
    },
1276 1310
    {
......
1283 1317
        .mmu_cxr_mask = 0x0000003f,
1284 1318
        .mmu_sfsr_mask = 0xffffffff,
1285 1319
        .mmu_trcr_mask = 0xffffffff,
1320
        .nwindows = 8,
1286 1321
        .features = CPU_DEFAULT_FEATURES,
1287 1322
    },
1288 1323
    {
......
1295 1330
        .mmu_cxr_mask = 0x0000003f,
1296 1331
        .mmu_sfsr_mask = 0xffffffff,
1297 1332
        .mmu_trcr_mask = 0xffffffff,
1333
        .nwindows = 8,
1298 1334
        .features = CPU_DEFAULT_FEATURES,
1299 1335
    },
1300 1336
    {
......
1307 1343
        .mmu_cxr_mask = 0x0000003f,
1308 1344
        .mmu_sfsr_mask = 0xffffffff,
1309 1345
        .mmu_trcr_mask = 0xffffffff,
1346
        .nwindows = 8,
1310 1347
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_FSQRT |
1311 1348
        CPU_FEATURE_FSMULD,
1312 1349
    },
......
1320 1357
        .mmu_cxr_mask = 0x0000003f,
1321 1358
        .mmu_sfsr_mask = 0xffffffff,
1322 1359
        .mmu_trcr_mask = 0xffffffff,
1360
        .nwindows = 8,
1323 1361
        .features = CPU_FEATURE_FLOAT | CPU_FEATURE_MUL | CPU_FEATURE_FSQRT |
1324 1362
        CPU_FEATURE_FSMULD,
1325 1363
    },
......
1333 1371
        .mmu_cxr_mask = 0x0000003f,
1334 1372
        .mmu_sfsr_mask = 0xffffffff,
1335 1373
        .mmu_trcr_mask = 0xffffffff,
1374
        .nwindows = 8,
1336 1375
        .features = CPU_DEFAULT_FEATURES,
1337 1376
    },
1338 1377
    {
......
1345 1384
        .mmu_cxr_mask = 0x0000003f,
1346 1385
        .mmu_sfsr_mask = 0xffffffff,
1347 1386
        .mmu_trcr_mask = 0xffffffff,
1387
        .nwindows = 8,
1348 1388
        .features = CPU_DEFAULT_FEATURES,
1349 1389
    },
1350 1390
    {
......
1357 1397
        .mmu_cxr_mask = 0x0000003f,
1358 1398
        .mmu_sfsr_mask = 0xffffffff,
1359 1399
        .mmu_trcr_mask = 0xffffffff,
1400
        .nwindows = 8,
1360 1401
        .features = CPU_DEFAULT_FEATURES,
1361 1402
    },
1362 1403
#endif
......
1411 1452
    uint32_t plus_features = 0;
1412 1453
    uint32_t minus_features = 0;
1413 1454
    long long iu_version;
1414
    uint32_t fpu_version, mmu_version;
1455
    uint32_t fpu_version, mmu_version, nwindows;
1415 1456

  
1416 1457
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1417 1458
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
......
1468 1509
#ifdef DEBUG_FEATURES
1469 1510
                fprintf(stderr, "mmu_version %llx\n", mmu_version);
1470 1511
#endif
1512
            } else if (!strcmp(featurestr, "nwindows")) {
1513
                char *err;
1514

  
1515
                nwindows = strtol(val, &err, 0);
1516
                if (!*val || *err || nwindows > MAX_NWINDOWS ||
1517
                    nwindows < MIN_NWINDOWS) {
1518
                    fprintf(stderr, "bad numerical value %s\n", val);
1519
                    goto error;
1520
                }
1521
                cpu_def->nwindows = nwindows;
1522
#ifdef DEBUG_FEATURES
1523
                fprintf(stderr, "nwindows %d\n", nwindows);
1524
#endif
1471 1525
            } else {
1472 1526
                fprintf(stderr, "unrecognized feature %s\n", featurestr);
1473 1527
                goto error;
......
1497 1551
    unsigned int i;
1498 1552

  
1499 1553
    for (i = 0; i < sizeof(sparc_defs) / sizeof(sparc_def_t); i++) {
1500
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x ",
1554
        (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx " FPU %08x MMU %08x NWINS %d ",
1501 1555
                       sparc_defs[i].name,
1502 1556
                       sparc_defs[i].iu_version,
1503 1557
                       sparc_defs[i].fpu_version,
1504
                       sparc_defs[i].mmu_version);
1558
                       sparc_defs[i].mmu_version,
1559
                       sparc_defs[i].nwindows);
1505 1560
        print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
1506 1561
                       ~sparc_defs[i].features, "-");
1507 1562
        print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
......
1512 1567
    print_features(f, cpu_fprintf, -1, NULL);
1513 1568
    (*cpu_fprintf)(f, "\n");
1514 1569
    (*cpu_fprintf)(f, "Numerical features (=): iu_version fpu_version "
1515
                   "mmu_version\n");
1570
                   "mmu_version nwindows\n");
1516 1571
}
1517 1572

  
1518 1573
#define GET_FLAG(a,b) ((env->psr & a)?b:'-')
......
1558 1613
    cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d "
1559 1614
                "cleanwin %d cwp %d\n",
1560 1615
                env->cansave, env->canrestore, env->otherwin, env->wstate,
1561
                env->cleanwin, NWINDOWS - 1 - env->cwp);
1616
                env->cleanwin, env->nwindows - 1 - env->cwp);
1562 1617
#else
1563 1618
    cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n",
1564 1619
                GET_PSR(env), GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
b/target-sparc/machine.c
31 31

  
32 32
    for(i = 0; i < 8; i++)
33 33
        qemu_put_betls(f, &env->gregs[i]);
34
    for(i = 0; i < NWINDOWS * 16; i++)
34
    qemu_put_be32s(f, &env->nwindows);
35
    for(i = 0; i < env->nwindows * 16; i++)
35 36
        qemu_put_betls(f, &env->regbase[i]);
36 37

  
37 38
    /* FPU */
......
65 66
    int i;
66 67
    uint32_t tmp;
67 68

  
69
    if (version_id != 4)
70
        return -EINVAL;
68 71
    for(i = 0; i < 8; i++)
69 72
        qemu_get_betls(f, &env->gregs[i]);
70
    for(i = 0; i < NWINDOWS * 16; i++)
73
    qemu_get_be32s(f, &env->nwindows);
74
    for(i = 0; i < env->nwindows * 16; i++)
71 75
        qemu_get_betls(f, &env->regbase[i]);
72 76

  
73 77
    /* FPU */
b/target-sparc/op_helper.c
2178 2178
        raise_exception(TT_ILL_INSN);
2179 2179

  
2180 2180
    env->psret = 1;
2181
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
2181
    cwp = cpu_cwp_inc(env, env->cwp + 1) ;
2182 2182
    if (env->wim & (1 << cwp)) {
2183 2183
        raise_exception(TT_WIN_UNF);
2184 2184
    }
......
2399 2399
{
2400 2400
    uint32_t cwp;
2401 2401

  
2402
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
2402
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2403 2403
    if (env->wim & (1 << cwp)) {
2404 2404
        raise_exception(TT_WIN_OVF);
2405 2405
    }
......
2410 2410
{
2411 2411
    uint32_t cwp;
2412 2412

  
2413
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
2413
    cwp = cpu_cwp_inc(env, env->cwp + 1);
2414 2414
    if (env->wim & (1 << cwp)) {
2415 2415
        raise_exception(TT_WIN_UNF);
2416 2416
    }
......
2419 2419

  
2420 2420
void helper_wrpsr(target_ulong new_psr)
2421 2421
{
2422
    if ((new_psr & PSR_CWP) >= NWINDOWS)
2422
    if ((new_psr & PSR_CWP) >= env->nwindows)
2423 2423
        raise_exception(TT_ILL_INSN);
2424 2424
    else
2425 2425
        PUT_PSR(env, new_psr);
......
2437 2437
{
2438 2438
    uint32_t cwp;
2439 2439

  
2440
    cwp = (env->cwp - 1) & (NWINDOWS - 1);
2440
    cwp = cpu_cwp_dec(env, env->cwp - 1);
2441 2441
    if (env->cansave == 0) {
2442 2442
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
2443 2443
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
......
2458 2458
{
2459 2459
    uint32_t cwp;
2460 2460

  
2461
    cwp = (env->cwp + 1) & (NWINDOWS - 1);
2461
    cwp = cpu_cwp_inc(env, env->cwp + 1);
2462 2462
    if (env->canrestore == 0) {
2463 2463
        raise_exception(TT_FILL | (env->otherwin != 0 ?
2464 2464
                                   (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
......
2472 2472

  
2473 2473
void helper_flushw(void)
2474 2474
{
2475
    if (env->cansave != NWINDOWS - 2) {
2475
    if (env->cansave != env->nwindows - 2) {
2476 2476
        raise_exception(TT_SPILL | (env->otherwin != 0 ?
2477 2477
                                    (TT_WOTHER | ((env->wstate & 0x38) >> 1)):
2478 2478
                                    ((env->wstate & 0x7) << 2)));
......
2491 2491
void helper_restored(void)
2492 2492
{
2493 2493
    env->canrestore++;
2494
    if (env->cleanwin < NWINDOWS - 1)
2494
    if (env->cleanwin < env->nwindows - 1)
2495 2495
        env->cleanwin++;
2496 2496
    if (env->otherwin == 0)
2497 2497
        env->cansave--;
......
2622 2622
void cpu_set_cwp(CPUState *env1, int new_cwp)
2623 2623
{
2624 2624
    /* put the modified wrap registers at their proper location */
2625
    if (env1->cwp == (NWINDOWS - 1))
2626
        memcpy32(env1->regbase, env1->regbase + NWINDOWS * 16);
2625
    if (env1->cwp == env->nwindows - 1)
2626
        memcpy32(env1->regbase, env1->regbase + env->nwindows * 16);
2627 2627
    env1->cwp = new_cwp;
2628 2628
    /* put the wrap registers at their temporary location */
2629
    if (new_cwp == (NWINDOWS - 1))
2630
        memcpy32(env1->regbase + NWINDOWS * 16, env1->regbase);
2629
    if (new_cwp == env->nwindows - 1)
2630
        memcpy32(env1->regbase + env->nwindows * 16, env1->regbase);
2631 2631
    env1->regwptr = env1->regbase + (new_cwp * 16);
2632 2632
}
2633 2633

  
b/target-sparc/translate.c
3442 3442
                                goto illegal_insn;
3443 3443
                            }
3444 3444
#else
3445
                            tcg_gen_andi_tl(cpu_dst, cpu_dst,
3446
                                            ((1 << NWINDOWS) - 1));
3447 3445
                            tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_dst);
3448 3446
                            tcg_gen_st_i32(cpu_tmp32, cpu_env,
3449 3447
                                           offsetof(CPUSPARCState, wim));

Also available in: Unified diff