target-arm: A64: Add floating-point<->integer conversion instructions
[qemu.git] / target-sparc / cpu.c
blobe7f878ee819c2cb8a5cc65553ba1fddd20b11326
1 /*
2 * Sparc CPU init helpers
4 * Copyright (c) 2003-2005 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 #include "cpu.h"
22 //#define DEBUG_FEATURES
24 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
26 /* CPUClass::reset() */
27 static void sparc_cpu_reset(CPUState *s)
29 SPARCCPU *cpu = SPARC_CPU(s);
30 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(cpu);
31 CPUSPARCState *env = &cpu->env;
33 scc->parent_reset(s);
35 memset(env, 0, offsetof(CPUSPARCState, breakpoints));
36 tlb_flush(env, 1);
37 env->cwp = 0;
38 #ifndef TARGET_SPARC64
39 env->wim = 1;
40 #endif
41 env->regwptr = env->regbase + (env->cwp * 16);
42 CC_OP = CC_OP_FLAGS;
43 #if defined(CONFIG_USER_ONLY)
44 #ifdef TARGET_SPARC64
45 env->cleanwin = env->nwindows - 2;
46 env->cansave = env->nwindows - 2;
47 env->pstate = PS_RMO | PS_PEF | PS_IE;
48 env->asi = 0x82; /* Primary no-fault */
49 #endif
50 #else
51 #if !defined(TARGET_SPARC64)
52 env->psret = 0;
53 env->psrs = 1;
54 env->psrps = 1;
55 #endif
56 #ifdef TARGET_SPARC64
57 env->pstate = PS_PRIV|PS_RED|PS_PEF|PS_AG;
58 env->hpstate = cpu_has_hypervisor(env) ? HS_PRIV : 0;
59 env->tl = env->maxtl;
60 cpu_tsptr(env)->tt = TT_POWER_ON_RESET;
61 env->lsu = 0;
62 #else
63 env->mmuregs[0] &= ~(MMU_E | MMU_NF);
64 env->mmuregs[0] |= env->def->mmu_bm;
65 #endif
66 env->pc = 0;
67 env->npc = env->pc + 4;
68 #endif
69 env->cache_control = 0;
72 static int cpu_sparc_register(CPUSPARCState *env, const char *cpu_model)
74 sparc_def_t def1, *def = &def1;
76 if (cpu_sparc_find_by_name(def, cpu_model) < 0) {
77 return -1;
80 env->def = g_new0(sparc_def_t, 1);
81 memcpy(env->def, def, sizeof(*def));
82 #if defined(CONFIG_USER_ONLY)
83 if ((env->def->features & CPU_FEATURE_FLOAT)) {
84 env->def->features |= CPU_FEATURE_FLOAT128;
86 #endif
87 env->version = def->iu_version;
88 env->fsr = def->fpu_version;
89 env->nwindows = def->nwindows;
90 #if !defined(TARGET_SPARC64)
91 env->mmuregs[0] |= def->mmu_version;
92 cpu_sparc_set_id(env, 0);
93 env->mxccregs[7] |= def->mxcc_version;
94 #else
95 env->mmu_version = def->mmu_version;
96 env->maxtl = def->maxtl;
97 env->version |= def->maxtl << 8;
98 env->version |= def->nwindows - 1;
99 #endif
100 return 0;
103 SPARCCPU *cpu_sparc_init(const char *cpu_model)
105 SPARCCPU *cpu;
106 CPUSPARCState *env;
108 cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU));
109 env = &cpu->env;
111 if (cpu_sparc_register(env, cpu_model) < 0) {
112 object_unref(OBJECT(cpu));
113 return NULL;
116 object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
118 return cpu;
121 void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu)
123 #if !defined(TARGET_SPARC64)
124 env->mxccregs[7] = ((cpu + 8) & 0xf) << 24;
125 #endif
128 static const sparc_def_t sparc_defs[] = {
129 #ifdef TARGET_SPARC64
131 .name = "Fujitsu Sparc64",
132 .iu_version = ((0x04ULL << 48) | (0x02ULL << 32) | (0ULL << 24)),
133 .fpu_version = 0x00000000,
134 .mmu_version = mmu_us_12,
135 .nwindows = 4,
136 .maxtl = 4,
137 .features = CPU_DEFAULT_FEATURES,
140 .name = "Fujitsu Sparc64 III",
141 .iu_version = ((0x04ULL << 48) | (0x03ULL << 32) | (0ULL << 24)),
142 .fpu_version = 0x00000000,
143 .mmu_version = mmu_us_12,
144 .nwindows = 5,
145 .maxtl = 4,
146 .features = CPU_DEFAULT_FEATURES,
149 .name = "Fujitsu Sparc64 IV",
150 .iu_version = ((0x04ULL << 48) | (0x04ULL << 32) | (0ULL << 24)),
151 .fpu_version = 0x00000000,
152 .mmu_version = mmu_us_12,
153 .nwindows = 8,
154 .maxtl = 5,
155 .features = CPU_DEFAULT_FEATURES,
158 .name = "Fujitsu Sparc64 V",
159 .iu_version = ((0x04ULL << 48) | (0x05ULL << 32) | (0x51ULL << 24)),
160 .fpu_version = 0x00000000,
161 .mmu_version = mmu_us_12,
162 .nwindows = 8,
163 .maxtl = 5,
164 .features = CPU_DEFAULT_FEATURES,
167 .name = "TI UltraSparc I",
168 .iu_version = ((0x17ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
169 .fpu_version = 0x00000000,
170 .mmu_version = mmu_us_12,
171 .nwindows = 8,
172 .maxtl = 5,
173 .features = CPU_DEFAULT_FEATURES,
176 .name = "TI UltraSparc II",
177 .iu_version = ((0x17ULL << 48) | (0x11ULL << 32) | (0x20ULL << 24)),
178 .fpu_version = 0x00000000,
179 .mmu_version = mmu_us_12,
180 .nwindows = 8,
181 .maxtl = 5,
182 .features = CPU_DEFAULT_FEATURES,
185 .name = "TI UltraSparc IIi",
186 .iu_version = ((0x17ULL << 48) | (0x12ULL << 32) | (0x91ULL << 24)),
187 .fpu_version = 0x00000000,
188 .mmu_version = mmu_us_12,
189 .nwindows = 8,
190 .maxtl = 5,
191 .features = CPU_DEFAULT_FEATURES,
194 .name = "TI UltraSparc IIe",
195 .iu_version = ((0x17ULL << 48) | (0x13ULL << 32) | (0x14ULL << 24)),
196 .fpu_version = 0x00000000,
197 .mmu_version = mmu_us_12,
198 .nwindows = 8,
199 .maxtl = 5,
200 .features = CPU_DEFAULT_FEATURES,
203 .name = "Sun UltraSparc III",
204 .iu_version = ((0x3eULL << 48) | (0x14ULL << 32) | (0x34ULL << 24)),
205 .fpu_version = 0x00000000,
206 .mmu_version = mmu_us_12,
207 .nwindows = 8,
208 .maxtl = 5,
209 .features = CPU_DEFAULT_FEATURES,
212 .name = "Sun UltraSparc III Cu",
213 .iu_version = ((0x3eULL << 48) | (0x15ULL << 32) | (0x41ULL << 24)),
214 .fpu_version = 0x00000000,
215 .mmu_version = mmu_us_3,
216 .nwindows = 8,
217 .maxtl = 5,
218 .features = CPU_DEFAULT_FEATURES,
221 .name = "Sun UltraSparc IIIi",
222 .iu_version = ((0x3eULL << 48) | (0x16ULL << 32) | (0x34ULL << 24)),
223 .fpu_version = 0x00000000,
224 .mmu_version = mmu_us_12,
225 .nwindows = 8,
226 .maxtl = 5,
227 .features = CPU_DEFAULT_FEATURES,
230 .name = "Sun UltraSparc IV",
231 .iu_version = ((0x3eULL << 48) | (0x18ULL << 32) | (0x31ULL << 24)),
232 .fpu_version = 0x00000000,
233 .mmu_version = mmu_us_4,
234 .nwindows = 8,
235 .maxtl = 5,
236 .features = CPU_DEFAULT_FEATURES,
239 .name = "Sun UltraSparc IV+",
240 .iu_version = ((0x3eULL << 48) | (0x19ULL << 32) | (0x22ULL << 24)),
241 .fpu_version = 0x00000000,
242 .mmu_version = mmu_us_12,
243 .nwindows = 8,
244 .maxtl = 5,
245 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_CMT,
248 .name = "Sun UltraSparc IIIi+",
249 .iu_version = ((0x3eULL << 48) | (0x22ULL << 32) | (0ULL << 24)),
250 .fpu_version = 0x00000000,
251 .mmu_version = mmu_us_3,
252 .nwindows = 8,
253 .maxtl = 5,
254 .features = CPU_DEFAULT_FEATURES,
257 .name = "Sun UltraSparc T1",
258 /* defined in sparc_ifu_fdp.v and ctu.h */
259 .iu_version = ((0x3eULL << 48) | (0x23ULL << 32) | (0x02ULL << 24)),
260 .fpu_version = 0x00000000,
261 .mmu_version = mmu_sun4v,
262 .nwindows = 8,
263 .maxtl = 6,
264 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
265 | CPU_FEATURE_GL,
268 .name = "Sun UltraSparc T2",
269 /* defined in tlu_asi_ctl.v and n2_revid_cust.v */
270 .iu_version = ((0x3eULL << 48) | (0x24ULL << 32) | (0x02ULL << 24)),
271 .fpu_version = 0x00000000,
272 .mmu_version = mmu_sun4v,
273 .nwindows = 8,
274 .maxtl = 6,
275 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_HYPV | CPU_FEATURE_CMT
276 | CPU_FEATURE_GL,
279 .name = "NEC UltraSparc I",
280 .iu_version = ((0x22ULL << 48) | (0x10ULL << 32) | (0x40ULL << 24)),
281 .fpu_version = 0x00000000,
282 .mmu_version = mmu_us_12,
283 .nwindows = 8,
284 .maxtl = 5,
285 .features = CPU_DEFAULT_FEATURES,
287 #else
289 .name = "Fujitsu MB86904",
290 .iu_version = 0x04 << 24, /* Impl 0, ver 4 */
291 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
292 .mmu_version = 0x04 << 24, /* Impl 0, ver 4 */
293 .mmu_bm = 0x00004000,
294 .mmu_ctpr_mask = 0x00ffffc0,
295 .mmu_cxr_mask = 0x000000ff,
296 .mmu_sfsr_mask = 0x00016fff,
297 .mmu_trcr_mask = 0x00ffffff,
298 .nwindows = 8,
299 .features = CPU_DEFAULT_FEATURES,
302 .name = "Fujitsu MB86907",
303 .iu_version = 0x05 << 24, /* Impl 0, ver 5 */
304 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
305 .mmu_version = 0x05 << 24, /* Impl 0, ver 5 */
306 .mmu_bm = 0x00004000,
307 .mmu_ctpr_mask = 0xffffffc0,
308 .mmu_cxr_mask = 0x000000ff,
309 .mmu_sfsr_mask = 0x00016fff,
310 .mmu_trcr_mask = 0xffffffff,
311 .nwindows = 8,
312 .features = CPU_DEFAULT_FEATURES,
315 .name = "TI MicroSparc I",
316 .iu_version = 0x41000000,
317 .fpu_version = 4 << 17,
318 .mmu_version = 0x41000000,
319 .mmu_bm = 0x00004000,
320 .mmu_ctpr_mask = 0x007ffff0,
321 .mmu_cxr_mask = 0x0000003f,
322 .mmu_sfsr_mask = 0x00016fff,
323 .mmu_trcr_mask = 0x0000003f,
324 .nwindows = 7,
325 .features = CPU_FEATURE_FLOAT | CPU_FEATURE_SWAP | CPU_FEATURE_MUL |
326 CPU_FEATURE_DIV | CPU_FEATURE_FLUSH | CPU_FEATURE_FSQRT |
327 CPU_FEATURE_FMUL,
330 .name = "TI MicroSparc II",
331 .iu_version = 0x42000000,
332 .fpu_version = 4 << 17,
333 .mmu_version = 0x02000000,
334 .mmu_bm = 0x00004000,
335 .mmu_ctpr_mask = 0x00ffffc0,
336 .mmu_cxr_mask = 0x000000ff,
337 .mmu_sfsr_mask = 0x00016fff,
338 .mmu_trcr_mask = 0x00ffffff,
339 .nwindows = 8,
340 .features = CPU_DEFAULT_FEATURES,
343 .name = "TI MicroSparc IIep",
344 .iu_version = 0x42000000,
345 .fpu_version = 4 << 17,
346 .mmu_version = 0x04000000,
347 .mmu_bm = 0x00004000,
348 .mmu_ctpr_mask = 0x00ffffc0,
349 .mmu_cxr_mask = 0x000000ff,
350 .mmu_sfsr_mask = 0x00016bff,
351 .mmu_trcr_mask = 0x00ffffff,
352 .nwindows = 8,
353 .features = CPU_DEFAULT_FEATURES,
356 .name = "TI SuperSparc 40", /* STP1020NPGA */
357 .iu_version = 0x41000000, /* SuperSPARC 2.x */
358 .fpu_version = 0 << 17,
359 .mmu_version = 0x00000800, /* SuperSPARC 2.x, no MXCC */
360 .mmu_bm = 0x00002000,
361 .mmu_ctpr_mask = 0xffffffc0,
362 .mmu_cxr_mask = 0x0000ffff,
363 .mmu_sfsr_mask = 0xffffffff,
364 .mmu_trcr_mask = 0xffffffff,
365 .nwindows = 8,
366 .features = CPU_DEFAULT_FEATURES,
369 .name = "TI SuperSparc 50", /* STP1020PGA */
370 .iu_version = 0x40000000, /* SuperSPARC 3.x */
371 .fpu_version = 0 << 17,
372 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
373 .mmu_bm = 0x00002000,
374 .mmu_ctpr_mask = 0xffffffc0,
375 .mmu_cxr_mask = 0x0000ffff,
376 .mmu_sfsr_mask = 0xffffffff,
377 .mmu_trcr_mask = 0xffffffff,
378 .nwindows = 8,
379 .features = CPU_DEFAULT_FEATURES,
382 .name = "TI SuperSparc 51",
383 .iu_version = 0x40000000, /* SuperSPARC 3.x */
384 .fpu_version = 0 << 17,
385 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
386 .mmu_bm = 0x00002000,
387 .mmu_ctpr_mask = 0xffffffc0,
388 .mmu_cxr_mask = 0x0000ffff,
389 .mmu_sfsr_mask = 0xffffffff,
390 .mmu_trcr_mask = 0xffffffff,
391 .mxcc_version = 0x00000104,
392 .nwindows = 8,
393 .features = CPU_DEFAULT_FEATURES,
396 .name = "TI SuperSparc 60", /* STP1020APGA */
397 .iu_version = 0x40000000, /* SuperSPARC 3.x */
398 .fpu_version = 0 << 17,
399 .mmu_version = 0x01000800, /* SuperSPARC 3.x, no MXCC */
400 .mmu_bm = 0x00002000,
401 .mmu_ctpr_mask = 0xffffffc0,
402 .mmu_cxr_mask = 0x0000ffff,
403 .mmu_sfsr_mask = 0xffffffff,
404 .mmu_trcr_mask = 0xffffffff,
405 .nwindows = 8,
406 .features = CPU_DEFAULT_FEATURES,
409 .name = "TI SuperSparc 61",
410 .iu_version = 0x44000000, /* SuperSPARC 3.x */
411 .fpu_version = 0 << 17,
412 .mmu_version = 0x01000000, /* SuperSPARC 3.x, MXCC */
413 .mmu_bm = 0x00002000,
414 .mmu_ctpr_mask = 0xffffffc0,
415 .mmu_cxr_mask = 0x0000ffff,
416 .mmu_sfsr_mask = 0xffffffff,
417 .mmu_trcr_mask = 0xffffffff,
418 .mxcc_version = 0x00000104,
419 .nwindows = 8,
420 .features = CPU_DEFAULT_FEATURES,
423 .name = "TI SuperSparc II",
424 .iu_version = 0x40000000, /* SuperSPARC II 1.x */
425 .fpu_version = 0 << 17,
426 .mmu_version = 0x08000000, /* SuperSPARC II 1.x, MXCC */
427 .mmu_bm = 0x00002000,
428 .mmu_ctpr_mask = 0xffffffc0,
429 .mmu_cxr_mask = 0x0000ffff,
430 .mmu_sfsr_mask = 0xffffffff,
431 .mmu_trcr_mask = 0xffffffff,
432 .mxcc_version = 0x00000104,
433 .nwindows = 8,
434 .features = CPU_DEFAULT_FEATURES,
437 .name = "LEON2",
438 .iu_version = 0xf2000000,
439 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
440 .mmu_version = 0xf2000000,
441 .mmu_bm = 0x00004000,
442 .mmu_ctpr_mask = 0x007ffff0,
443 .mmu_cxr_mask = 0x0000003f,
444 .mmu_sfsr_mask = 0xffffffff,
445 .mmu_trcr_mask = 0xffffffff,
446 .nwindows = 8,
447 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN,
450 .name = "LEON3",
451 .iu_version = 0xf3000000,
452 .fpu_version = 4 << 17, /* FPU version 4 (Meiko) */
453 .mmu_version = 0xf3000000,
454 .mmu_bm = 0x00000000,
455 .mmu_ctpr_mask = 0xfffffffc,
456 .mmu_cxr_mask = 0x000000ff,
457 .mmu_sfsr_mask = 0xffffffff,
458 .mmu_trcr_mask = 0xffffffff,
459 .nwindows = 8,
460 .features = CPU_DEFAULT_FEATURES | CPU_FEATURE_TA0_SHUTDOWN |
461 CPU_FEATURE_ASR17 | CPU_FEATURE_CACHE_CTRL | CPU_FEATURE_POWERDOWN,
463 #endif
466 static const char * const feature_name[] = {
467 "float",
468 "float128",
469 "swap",
470 "mul",
471 "div",
472 "flush",
473 "fsqrt",
474 "fmul",
475 "vis1",
476 "vis2",
477 "fsmuld",
478 "hypv",
479 "cmt",
480 "gl",
483 static void print_features(FILE *f, fprintf_function cpu_fprintf,
484 uint32_t features, const char *prefix)
486 unsigned int i;
488 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
489 if (feature_name[i] && (features & (1 << i))) {
490 if (prefix) {
491 (*cpu_fprintf)(f, "%s", prefix);
493 (*cpu_fprintf)(f, "%s ", feature_name[i]);
498 static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
500 unsigned int i;
502 for (i = 0; i < ARRAY_SIZE(feature_name); i++) {
503 if (feature_name[i] && !strcmp(flagname, feature_name[i])) {
504 *features |= 1 << i;
505 return;
508 fprintf(stderr, "CPU feature %s not found\n", flagname);
511 static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
513 unsigned int i;
514 const sparc_def_t *def = NULL;
515 char *s = g_strdup(cpu_model);
516 char *featurestr, *name = strtok(s, ",");
517 uint32_t plus_features = 0;
518 uint32_t minus_features = 0;
519 uint64_t iu_version;
520 uint32_t fpu_version, mmu_version, nwindows;
522 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
523 if (strcasecmp(name, sparc_defs[i].name) == 0) {
524 def = &sparc_defs[i];
527 if (!def) {
528 goto error;
530 memcpy(cpu_def, def, sizeof(*def));
532 featurestr = strtok(NULL, ",");
533 while (featurestr) {
534 char *val;
536 if (featurestr[0] == '+') {
537 add_flagname_to_bitmaps(featurestr + 1, &plus_features);
538 } else if (featurestr[0] == '-') {
539 add_flagname_to_bitmaps(featurestr + 1, &minus_features);
540 } else if ((val = strchr(featurestr, '='))) {
541 *val = 0; val++;
542 if (!strcmp(featurestr, "iu_version")) {
543 char *err;
545 iu_version = strtoll(val, &err, 0);
546 if (!*val || *err) {
547 fprintf(stderr, "bad numerical value %s\n", val);
548 goto error;
550 cpu_def->iu_version = iu_version;
551 #ifdef DEBUG_FEATURES
552 fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version);
553 #endif
554 } else if (!strcmp(featurestr, "fpu_version")) {
555 char *err;
557 fpu_version = strtol(val, &err, 0);
558 if (!*val || *err) {
559 fprintf(stderr, "bad numerical value %s\n", val);
560 goto error;
562 cpu_def->fpu_version = fpu_version;
563 #ifdef DEBUG_FEATURES
564 fprintf(stderr, "fpu_version %x\n", fpu_version);
565 #endif
566 } else if (!strcmp(featurestr, "mmu_version")) {
567 char *err;
569 mmu_version = strtol(val, &err, 0);
570 if (!*val || *err) {
571 fprintf(stderr, "bad numerical value %s\n", val);
572 goto error;
574 cpu_def->mmu_version = mmu_version;
575 #ifdef DEBUG_FEATURES
576 fprintf(stderr, "mmu_version %x\n", mmu_version);
577 #endif
578 } else if (!strcmp(featurestr, "nwindows")) {
579 char *err;
581 nwindows = strtol(val, &err, 0);
582 if (!*val || *err || nwindows > MAX_NWINDOWS ||
583 nwindows < MIN_NWINDOWS) {
584 fprintf(stderr, "bad numerical value %s\n", val);
585 goto error;
587 cpu_def->nwindows = nwindows;
588 #ifdef DEBUG_FEATURES
589 fprintf(stderr, "nwindows %d\n", nwindows);
590 #endif
591 } else {
592 fprintf(stderr, "unrecognized feature %s\n", featurestr);
593 goto error;
595 } else {
596 fprintf(stderr, "feature string `%s' not in format "
597 "(+feature|-feature|feature=xyz)\n", featurestr);
598 goto error;
600 featurestr = strtok(NULL, ",");
602 cpu_def->features |= plus_features;
603 cpu_def->features &= ~minus_features;
604 #ifdef DEBUG_FEATURES
605 print_features(stderr, fprintf, cpu_def->features, NULL);
606 #endif
607 g_free(s);
608 return 0;
610 error:
611 g_free(s);
612 return -1;
615 void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
617 unsigned int i;
619 for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
620 (*cpu_fprintf)(f, "Sparc %16s IU " TARGET_FMT_lx
621 " FPU %08x MMU %08x NWINS %d ",
622 sparc_defs[i].name,
623 sparc_defs[i].iu_version,
624 sparc_defs[i].fpu_version,
625 sparc_defs[i].mmu_version,
626 sparc_defs[i].nwindows);
627 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES &
628 ~sparc_defs[i].features, "-");
629 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES &
630 sparc_defs[i].features, "+");
631 (*cpu_fprintf)(f, "\n");
633 (*cpu_fprintf)(f, "Default CPU feature flags (use '-' to remove): ");
634 print_features(f, cpu_fprintf, CPU_DEFAULT_FEATURES, NULL);
635 (*cpu_fprintf)(f, "\n");
636 (*cpu_fprintf)(f, "Available CPU feature flags (use '+' to add): ");
637 print_features(f, cpu_fprintf, ~CPU_DEFAULT_FEATURES, NULL);
638 (*cpu_fprintf)(f, "\n");
639 (*cpu_fprintf)(f, "Numerical features (use '=' to set): iu_version "
640 "fpu_version mmu_version nwindows\n");
643 static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
644 uint32_t cc)
646 cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG ? 'N' : '-',
647 cc & PSR_ZERO ? 'Z' : '-', cc & PSR_OVF ? 'V' : '-',
648 cc & PSR_CARRY ? 'C' : '-');
651 #ifdef TARGET_SPARC64
652 #define REGS_PER_LINE 4
653 #else
654 #define REGS_PER_LINE 8
655 #endif
657 void sparc_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
658 int flags)
660 SPARCCPU *cpu = SPARC_CPU(cs);
661 CPUSPARCState *env = &cpu->env;
662 int i, x;
664 cpu_fprintf(f, "pc: " TARGET_FMT_lx " npc: " TARGET_FMT_lx "\n", env->pc,
665 env->npc);
667 for (i = 0; i < 8; i++) {
668 if (i % REGS_PER_LINE == 0) {
669 cpu_fprintf(f, "%%g%d-%d:", i, i + REGS_PER_LINE - 1);
671 cpu_fprintf(f, " " TARGET_FMT_lx, env->gregs[i]);
672 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
673 cpu_fprintf(f, "\n");
676 for (x = 0; x < 3; x++) {
677 for (i = 0; i < 8; i++) {
678 if (i % REGS_PER_LINE == 0) {
679 cpu_fprintf(f, "%%%c%d-%d: ",
680 x == 0 ? 'o' : (x == 1 ? 'l' : 'i'),
681 i, i + REGS_PER_LINE - 1);
683 cpu_fprintf(f, TARGET_FMT_lx " ", env->regwptr[i + x * 8]);
684 if (i % REGS_PER_LINE == REGS_PER_LINE - 1) {
685 cpu_fprintf(f, "\n");
690 for (i = 0; i < TARGET_DPREGS; i++) {
691 if ((i & 3) == 0) {
692 cpu_fprintf(f, "%%f%02d: ", i * 2);
694 cpu_fprintf(f, " %016" PRIx64, env->fpr[i].ll);
695 if ((i & 3) == 3) {
696 cpu_fprintf(f, "\n");
699 #ifdef TARGET_SPARC64
700 cpu_fprintf(f, "pstate: %08x ccr: %02x (icc: ", env->pstate,
701 (unsigned)cpu_get_ccr(env));
702 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << PSR_CARRY_SHIFT);
703 cpu_fprintf(f, " xcc: ");
704 cpu_print_cc(f, cpu_fprintf, cpu_get_ccr(env) << (PSR_CARRY_SHIFT - 4));
705 cpu_fprintf(f, ") asi: %02x tl: %d pil: %x\n", env->asi, env->tl,
706 env->psrpil);
707 cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate: %d "
708 "cleanwin: %d cwp: %d\n",
709 env->cansave, env->canrestore, env->otherwin, env->wstate,
710 env->cleanwin, env->nwindows - 1 - env->cwp);
711 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx " fprs: "
712 TARGET_FMT_lx "\n", env->fsr, env->y, env->fprs);
713 #else
714 cpu_fprintf(f, "psr: %08x (icc: ", cpu_get_psr(env));
715 cpu_print_cc(f, cpu_fprintf, cpu_get_psr(env));
716 cpu_fprintf(f, " SPE: %c%c%c) wim: %08x\n", env->psrs ? 'S' : '-',
717 env->psrps ? 'P' : '-', env->psret ? 'E' : '-',
718 env->wim);
719 cpu_fprintf(f, "fsr: " TARGET_FMT_lx " y: " TARGET_FMT_lx "\n",
720 env->fsr, env->y);
721 #endif
722 cpu_fprintf(f, "\n");
725 static void sparc_cpu_set_pc(CPUState *cs, vaddr value)
727 SPARCCPU *cpu = SPARC_CPU(cs);
729 cpu->env.pc = value;
730 cpu->env.npc = value + 4;
733 static void sparc_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
735 SPARCCPU *cpu = SPARC_CPU(cs);
737 cpu->env.pc = tb->pc;
738 cpu->env.npc = tb->cs_base;
741 static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
743 SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
745 qemu_init_vcpu(CPU(dev));
747 scc->parent_realize(dev, errp);
750 static void sparc_cpu_initfn(Object *obj)
752 CPUState *cs = CPU(obj);
753 SPARCCPU *cpu = SPARC_CPU(obj);
754 CPUSPARCState *env = &cpu->env;
756 cs->env_ptr = env;
757 cpu_exec_init(env);
759 if (tcg_enabled()) {
760 gen_intermediate_code_init(env);
764 static void sparc_cpu_uninitfn(Object *obj)
766 SPARCCPU *cpu = SPARC_CPU(obj);
767 CPUSPARCState *env = &cpu->env;
769 g_free(env->def);
772 static void sparc_cpu_class_init(ObjectClass *oc, void *data)
774 SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
775 CPUClass *cc = CPU_CLASS(oc);
776 DeviceClass *dc = DEVICE_CLASS(oc);
778 scc->parent_realize = dc->realize;
779 dc->realize = sparc_cpu_realizefn;
781 scc->parent_reset = cc->reset;
782 cc->reset = sparc_cpu_reset;
784 cc->do_interrupt = sparc_cpu_do_interrupt;
785 cc->dump_state = sparc_cpu_dump_state;
786 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
787 cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
788 #endif
789 cc->set_pc = sparc_cpu_set_pc;
790 cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
791 cc->gdb_read_register = sparc_cpu_gdb_read_register;
792 cc->gdb_write_register = sparc_cpu_gdb_write_register;
793 #ifndef CONFIG_USER_ONLY
794 cc->do_unassigned_access = sparc_cpu_unassigned_access;
795 cc->get_phys_page_debug = sparc_cpu_get_phys_page_debug;
796 #endif
798 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
799 cc->gdb_num_core_regs = 86;
800 #else
801 cc->gdb_num_core_regs = 72;
802 #endif
805 static const TypeInfo sparc_cpu_type_info = {
806 .name = TYPE_SPARC_CPU,
807 .parent = TYPE_CPU,
808 .instance_size = sizeof(SPARCCPU),
809 .instance_init = sparc_cpu_initfn,
810 .instance_finalize = sparc_cpu_uninitfn,
811 .abstract = false,
812 .class_size = sizeof(SPARCCPUClass),
813 .class_init = sparc_cpu_class_init,
816 static void sparc_cpu_register_types(void)
818 type_register_static(&sparc_cpu_type_info);
821 type_init(sparc_cpu_register_types)