target-mips: optimize gen_compute_branch()
[qemu] / target-mips / machine.c
1 #include "hw/hw.h"
2 #include "hw/boards.h"
3
4 #include "exec-all.h"
5
6 void register_machines(void)
7 {
8     qemu_register_machine(&mips_malta_machine);
9     qemu_register_machine(&mips_magnum_machine);
10     qemu_register_machine(&mips_pica61_machine);
11     qemu_register_machine(&mips_mipssim_machine);
12     qemu_register_machine(&mips_machine);
13 }
14
15 static void save_tc(QEMUFile *f, TCState *tc)
16 {
17     int i;
18
19     /* Save active TC */
20     for(i = 0; i < 32; i++)
21         qemu_put_betls(f, &tc->gpr[i]);
22     qemu_put_betls(f, &tc->PC);
23     for(i = 0; i < MIPS_DSP_ACC; i++)
24         qemu_put_betls(f, &tc->HI[i]);
25     for(i = 0; i < MIPS_DSP_ACC; i++)
26         qemu_put_betls(f, &tc->LO[i]);
27     for(i = 0; i < MIPS_DSP_ACC; i++)
28         qemu_put_betls(f, &tc->ACX[i]);
29     qemu_put_betls(f, &tc->DSPControl);
30     qemu_put_sbe32s(f, &tc->CP0_TCStatus);
31     qemu_put_sbe32s(f, &tc->CP0_TCBind);
32     qemu_put_betls(f, &tc->CP0_TCHalt);
33     qemu_put_betls(f, &tc->CP0_TCContext);
34     qemu_put_betls(f, &tc->CP0_TCSchedule);
35     qemu_put_betls(f, &tc->CP0_TCScheFBack);
36     qemu_put_sbe32s(f, &tc->CP0_Debug_tcstatus);
37 }
38
39 static void save_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
40 {
41     int i;
42
43     for(i = 0; i < 32; i++)
44         qemu_put_be64s(f, &fpu->fpr[i].d);
45     qemu_put_s8s(f, &fpu->fp_status.float_detect_tininess);
46     qemu_put_s8s(f, &fpu->fp_status.float_rounding_mode);
47     qemu_put_s8s(f, &fpu->fp_status.float_exception_flags);
48     qemu_put_be32s(f, &fpu->fcr0);
49     qemu_put_be32s(f, &fpu->fcr31);
50 }
51
52 void cpu_save(QEMUFile *f, void *opaque)
53 {
54     CPUState *env = opaque;
55     int i;
56
57     /* Save active TC */
58     save_tc(f, &env->active_tc);
59
60     /* Save active FPU */
61     save_fpu(f, &env->active_fpu);
62
63     /* Save MVP */
64     qemu_put_sbe32s(f, &env->mvp->CP0_MVPControl);
65     qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf0);
66     qemu_put_sbe32s(f, &env->mvp->CP0_MVPConf1);
67
68     /* Save TLB */
69     qemu_put_be32s(f, &env->tlb->nb_tlb);
70     qemu_put_be32s(f, &env->tlb->tlb_in_use);
71     for(i = 0; i < MIPS_TLB_MAX; i++) {
72         uint16_t flags = ((env->tlb->mmu.r4k.tlb[i].G << 10) |
73                           (env->tlb->mmu.r4k.tlb[i].C0 << 7) |
74                           (env->tlb->mmu.r4k.tlb[i].C1 << 4) |
75                           (env->tlb->mmu.r4k.tlb[i].V0 << 3) |
76                           (env->tlb->mmu.r4k.tlb[i].V1 << 2) |
77                           (env->tlb->mmu.r4k.tlb[i].D0 << 1) |
78                           (env->tlb->mmu.r4k.tlb[i].D1 << 0));
79
80         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
81         qemu_put_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
82         qemu_put_8s(f, &env->tlb->mmu.r4k.tlb[i].ASID);
83         qemu_put_be16s(f, &flags);
84         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
85         qemu_put_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
86     }
87
88     /* Save CPU metastate */
89     qemu_put_be32s(f, &env->current_tc);
90     qemu_put_be32s(f, &env->current_fpu);
91     qemu_put_sbe32s(f, &env->error_code);
92     qemu_put_be32s(f, &env->hflags);
93     qemu_put_betls(f, &env->btarget);
94     i = env->bcond;
95     qemu_put_sbe32s(f, &i);
96
97     /* Save remaining CP1 registers */
98     qemu_put_sbe32s(f, &env->CP0_Index);
99     qemu_put_sbe32s(f, &env->CP0_Random);
100     qemu_put_sbe32s(f, &env->CP0_VPEControl);
101     qemu_put_sbe32s(f, &env->CP0_VPEConf0);
102     qemu_put_sbe32s(f, &env->CP0_VPEConf1);
103     qemu_put_betls(f, &env->CP0_YQMask);
104     qemu_put_betls(f, &env->CP0_VPESchedule);
105     qemu_put_betls(f, &env->CP0_VPEScheFBack);
106     qemu_put_sbe32s(f, &env->CP0_VPEOpt);
107     qemu_put_betls(f, &env->CP0_EntryLo0);
108     qemu_put_betls(f, &env->CP0_EntryLo1);
109     qemu_put_betls(f, &env->CP0_Context);
110     qemu_put_sbe32s(f, &env->CP0_PageMask);
111     qemu_put_sbe32s(f, &env->CP0_PageGrain);
112     qemu_put_sbe32s(f, &env->CP0_Wired);
113     qemu_put_sbe32s(f, &env->CP0_SRSConf0);
114     qemu_put_sbe32s(f, &env->CP0_SRSConf1);
115     qemu_put_sbe32s(f, &env->CP0_SRSConf2);
116     qemu_put_sbe32s(f, &env->CP0_SRSConf3);
117     qemu_put_sbe32s(f, &env->CP0_SRSConf4);
118     qemu_put_sbe32s(f, &env->CP0_HWREna);
119     qemu_put_betls(f, &env->CP0_BadVAddr);
120     qemu_put_sbe32s(f, &env->CP0_Count);
121     qemu_put_betls(f, &env->CP0_EntryHi);
122     qemu_put_sbe32s(f, &env->CP0_Compare);
123     qemu_put_sbe32s(f, &env->CP0_Status);
124     qemu_put_sbe32s(f, &env->CP0_IntCtl);
125     qemu_put_sbe32s(f, &env->CP0_SRSCtl);
126     qemu_put_sbe32s(f, &env->CP0_SRSMap);
127     qemu_put_sbe32s(f, &env->CP0_Cause);
128     qemu_put_betls(f, &env->CP0_EPC);
129     qemu_put_sbe32s(f, &env->CP0_PRid);
130     qemu_put_sbe32s(f, &env->CP0_EBase);
131     qemu_put_sbe32s(f, &env->CP0_Config0);
132     qemu_put_sbe32s(f, &env->CP0_Config1);
133     qemu_put_sbe32s(f, &env->CP0_Config2);
134     qemu_put_sbe32s(f, &env->CP0_Config3);
135     qemu_put_sbe32s(f, &env->CP0_Config6);
136     qemu_put_sbe32s(f, &env->CP0_Config7);
137     qemu_put_betls(f, &env->CP0_LLAddr);
138     for(i = 0; i < 8; i++)
139         qemu_put_betls(f, &env->CP0_WatchLo[i]);
140     for(i = 0; i < 8; i++)
141         qemu_put_sbe32s(f, &env->CP0_WatchHi[i]);
142     qemu_put_betls(f, &env->CP0_XContext);
143     qemu_put_sbe32s(f, &env->CP0_Framemask);
144     qemu_put_sbe32s(f, &env->CP0_Debug);
145     qemu_put_betls(f, &env->CP0_DEPC);
146     qemu_put_sbe32s(f, &env->CP0_Performance0);
147     qemu_put_sbe32s(f, &env->CP0_TagLo);
148     qemu_put_sbe32s(f, &env->CP0_DataLo);
149     qemu_put_sbe32s(f, &env->CP0_TagHi);
150     qemu_put_sbe32s(f, &env->CP0_DataHi);
151     qemu_put_betls(f, &env->CP0_ErrorEPC);
152     qemu_put_sbe32s(f, &env->CP0_DESAVE);
153
154     /* Save inactive TC state */
155     for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
156         save_tc(f, &env->tcs[i]);
157     for (i = 0; i < MIPS_FPU_MAX; i++)
158         save_fpu(f, &env->fpus[i]);
159 }
160
161 static void load_tc(QEMUFile *f, TCState *tc)
162 {
163     int i;
164
165     /* Save active TC */
166     for(i = 0; i < 32; i++)
167         qemu_get_betls(f, &tc->gpr[i]);
168     qemu_get_betls(f, &tc->PC);
169     for(i = 0; i < MIPS_DSP_ACC; i++)
170         qemu_get_betls(f, &tc->HI[i]);
171     for(i = 0; i < MIPS_DSP_ACC; i++)
172         qemu_get_betls(f, &tc->LO[i]);
173     for(i = 0; i < MIPS_DSP_ACC; i++)
174         qemu_get_betls(f, &tc->ACX[i]);
175     qemu_get_betls(f, &tc->DSPControl);
176     qemu_get_sbe32s(f, &tc->CP0_TCStatus);
177     qemu_get_sbe32s(f, &tc->CP0_TCBind);
178     qemu_get_betls(f, &tc->CP0_TCHalt);
179     qemu_get_betls(f, &tc->CP0_TCContext);
180     qemu_get_betls(f, &tc->CP0_TCSchedule);
181     qemu_get_betls(f, &tc->CP0_TCScheFBack);
182     qemu_get_sbe32s(f, &tc->CP0_Debug_tcstatus);
183 }
184
185 static void load_fpu(QEMUFile *f, CPUMIPSFPUContext *fpu)
186 {
187     int i;
188
189     for(i = 0; i < 32; i++)
190         qemu_get_be64s(f, &fpu->fpr[i].d);
191     qemu_get_s8s(f, &fpu->fp_status.float_detect_tininess);
192     qemu_get_s8s(f, &fpu->fp_status.float_rounding_mode);
193     qemu_get_s8s(f, &fpu->fp_status.float_exception_flags);
194     qemu_get_be32s(f, &fpu->fcr0);
195     qemu_get_be32s(f, &fpu->fcr31);
196 }
197
198 int cpu_load(QEMUFile *f, void *opaque, int version_id)
199 {
200     CPUState *env = opaque;
201     int i;
202
203     if (version_id != 3)
204         return -EINVAL;
205
206     /* Load active TC */
207     load_tc(f, &env->active_tc);
208
209     /* Load active FPU */
210     load_fpu(f, &env->active_fpu);
211
212     /* Load MVP */
213     qemu_get_sbe32s(f, &env->mvp->CP0_MVPControl);
214     qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf0);
215     qemu_get_sbe32s(f, &env->mvp->CP0_MVPConf1);
216
217     /* Load TLB */
218     qemu_get_be32s(f, &env->tlb->nb_tlb);
219     qemu_get_be32s(f, &env->tlb->tlb_in_use);
220     for(i = 0; i < MIPS_TLB_MAX; i++) {
221         uint16_t flags;
222
223         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].VPN);
224         qemu_get_be32s(f, &env->tlb->mmu.r4k.tlb[i].PageMask);
225         qemu_get_8s(f, &env->tlb->mmu.r4k.tlb[i].ASID);
226         qemu_get_be16s(f, &flags);
227         env->tlb->mmu.r4k.tlb[i].G = (flags >> 10) & 1;
228         env->tlb->mmu.r4k.tlb[i].C0 = (flags >> 7) & 3;
229         env->tlb->mmu.r4k.tlb[i].C1 = (flags >> 4) & 3;
230         env->tlb->mmu.r4k.tlb[i].V0 = (flags >> 3) & 1;
231         env->tlb->mmu.r4k.tlb[i].V1 = (flags >> 2) & 1;
232         env->tlb->mmu.r4k.tlb[i].D0 = (flags >> 1) & 1;
233         env->tlb->mmu.r4k.tlb[i].D1 = (flags >> 0) & 1;
234         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[0]);
235         qemu_get_betls(f, &env->tlb->mmu.r4k.tlb[i].PFN[1]);
236     }
237
238     /* Load CPU metastate */
239     qemu_get_be32s(f, &env->current_tc);
240     qemu_get_be32s(f, &env->current_fpu);
241     qemu_get_sbe32s(f, &env->error_code);
242     qemu_get_be32s(f, &env->hflags);
243     qemu_get_betls(f, &env->btarget);
244     qemu_get_sbe32s(f, &i);
245     env->bcond = i;
246
247     /* Load remaining CP1 registers */
248     qemu_get_sbe32s(f, &env->CP0_Index);
249     qemu_get_sbe32s(f, &env->CP0_Random);
250     qemu_get_sbe32s(f, &env->CP0_VPEControl);
251     qemu_get_sbe32s(f, &env->CP0_VPEConf0);
252     qemu_get_sbe32s(f, &env->CP0_VPEConf1);
253     qemu_get_betls(f, &env->CP0_YQMask);
254     qemu_get_betls(f, &env->CP0_VPESchedule);
255     qemu_get_betls(f, &env->CP0_VPEScheFBack);
256     qemu_get_sbe32s(f, &env->CP0_VPEOpt);
257     qemu_get_betls(f, &env->CP0_EntryLo0);
258     qemu_get_betls(f, &env->CP0_EntryLo1);
259     qemu_get_betls(f, &env->CP0_Context);
260     qemu_get_sbe32s(f, &env->CP0_PageMask);
261     qemu_get_sbe32s(f, &env->CP0_PageGrain);
262     qemu_get_sbe32s(f, &env->CP0_Wired);
263     qemu_get_sbe32s(f, &env->CP0_SRSConf0);
264     qemu_get_sbe32s(f, &env->CP0_SRSConf1);
265     qemu_get_sbe32s(f, &env->CP0_SRSConf2);
266     qemu_get_sbe32s(f, &env->CP0_SRSConf3);
267     qemu_get_sbe32s(f, &env->CP0_SRSConf4);
268     qemu_get_sbe32s(f, &env->CP0_HWREna);
269     qemu_get_betls(f, &env->CP0_BadVAddr);
270     qemu_get_sbe32s(f, &env->CP0_Count);
271     qemu_get_betls(f, &env->CP0_EntryHi);
272     qemu_get_sbe32s(f, &env->CP0_Compare);
273     qemu_get_sbe32s(f, &env->CP0_Status);
274     qemu_get_sbe32s(f, &env->CP0_IntCtl);
275     qemu_get_sbe32s(f, &env->CP0_SRSCtl);
276     qemu_get_sbe32s(f, &env->CP0_SRSMap);
277     qemu_get_sbe32s(f, &env->CP0_Cause);
278     qemu_get_betls(f, &env->CP0_EPC);
279     qemu_get_sbe32s(f, &env->CP0_PRid);
280     qemu_get_sbe32s(f, &env->CP0_EBase);
281     qemu_get_sbe32s(f, &env->CP0_Config0);
282     qemu_get_sbe32s(f, &env->CP0_Config1);
283     qemu_get_sbe32s(f, &env->CP0_Config2);
284     qemu_get_sbe32s(f, &env->CP0_Config3);
285     qemu_get_sbe32s(f, &env->CP0_Config6);
286     qemu_get_sbe32s(f, &env->CP0_Config7);
287     qemu_get_betls(f, &env->CP0_LLAddr);
288     for(i = 0; i < 8; i++)
289         qemu_get_betls(f, &env->CP0_WatchLo[i]);
290     for(i = 0; i < 8; i++)
291         qemu_get_sbe32s(f, &env->CP0_WatchHi[i]);
292     qemu_get_betls(f, &env->CP0_XContext);
293     qemu_get_sbe32s(f, &env->CP0_Framemask);
294     qemu_get_sbe32s(f, &env->CP0_Debug);
295     qemu_get_betls(f, &env->CP0_DEPC);
296     qemu_get_sbe32s(f, &env->CP0_Performance0);
297     qemu_get_sbe32s(f, &env->CP0_TagLo);
298     qemu_get_sbe32s(f, &env->CP0_DataLo);
299     qemu_get_sbe32s(f, &env->CP0_TagHi);
300     qemu_get_sbe32s(f, &env->CP0_DataHi);
301     qemu_get_betls(f, &env->CP0_ErrorEPC);
302     qemu_get_sbe32s(f, &env->CP0_DESAVE);
303
304     /* Load inactive TC state */
305     for (i = 0; i < MIPS_SHADOW_SET_MAX; i++)
306         load_tc(f, &env->tcs[i]);
307     for (i = 0; i < MIPS_FPU_MAX; i++)
308         load_fpu(f, &env->fpus[i]);
309
310     /* XXX: ensure compatiblity for halted bit ? */
311     tlb_flush(env, 1);
312     return 0;
313 }